Merge "Disable ds-docs-switched"
diff --git a/Android.bp b/Android.bp
index 67902b3..0c9b82e 100644
--- a/Android.bp
+++ b/Android.bp
@@ -619,3 +619,12 @@
"ProtoLibraries.bp",
"TestProtoLibraries.bp",
]
+
+java_api_contribution {
+ name: "api-stubs-docs-non-updatable-public-stubs",
+ api_surface: "public",
+ api_file: "core/api/current.txt",
+ visibility: [
+ "//build/orchestrator/apis",
+ ],
+}
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 48c44c9..fc046fb 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -598,3 +598,12 @@
],
visibility: ["//visibility:public"],
}
+
+java_api_contribution {
+ name: "frameworks-base-core-api-module-lib-stubs",
+ api_surface: "module-lib",
+ api_file: "core/api/module-lib-current.txt",
+ visibility: [
+ "//build/orchestrator/apis",
+ ],
+}
diff --git a/boot/Android.bp b/boot/Android.bp
index 24ad9de..851294c 100644
--- a/boot/Android.bp
+++ b/boot/Android.bp
@@ -23,6 +23,18 @@
default_applicable_licenses: ["frameworks_base_license"],
}
+soong_config_module_type {
+ name: "custom_platform_bootclasspath",
+ module_type: "platform_bootclasspath",
+ config_namespace: "AUTO",
+ bool_variables: [
+ "car_bootclasspath_fragment",
+ ],
+ properties: [
+ "fragments",
+ ],
+}
+
// This module provides access to information Soong has related to the
// whole platform bootclasspath. Currently, that information is provided solely
// through configuration but additional information will be added here.
@@ -41,7 +53,7 @@
//
// This module needs to be present in the build for the above processing to be
// done correctly.
-platform_bootclasspath {
+custom_platform_bootclasspath {
name: "platform-bootclasspath",
// The bootclasspath_fragments that contribute to the platform
@@ -115,17 +127,24 @@
apex: "com.android.wifi",
module: "com.android.wifi-bootclasspath-fragment",
},
- // only used for auto
- {
- apex: "com.android.car.framework",
- module: "com.android.car.framework-bootclasspath-fragment",
- },
{
apex: "com.android.virt",
module: "com.android.virt-bootclasspath-fragment",
},
],
+ soong_config_variables: {
+ car_bootclasspath_fragment: {
+ fragments: [
+ // only used for auto
+ {
+ apex: "com.android.car.framework",
+ module: "com.android.car.framework-bootclasspath-fragment",
+ },
+ ],
+ },
+ },
+
// Additional information needed by hidden api processing.
hidden_api: {
unsupported: [
diff --git a/cmds/svc/src/com/android/commands/svc/UsbCommand.java b/cmds/svc/src/com/android/commands/svc/UsbCommand.java
index 7d80493..26e20f6 100644
--- a/cmds/svc/src/com/android/commands/svc/UsbCommand.java
+++ b/cmds/svc/src/com/android/commands/svc/UsbCommand.java
@@ -29,12 +29,18 @@
import java.util.function.Consumer;
import java.util.concurrent.Executor;
import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
public class UsbCommand extends Svc.Command {
public UsbCommand() {
super("usb");
}
+ /**
+ * Counter for tracking UsbOperation operations.
+ */
+ private static final AtomicInteger sUsbOperationCount = new AtomicInteger();
+
@Override
public String shortHelp() {
return "Control Usb state";
@@ -92,8 +98,10 @@
if ("setFunctions".equals(args[1])) {
try {
+ int operationId = sUsbOperationCount.incrementAndGet();
+ System.out.println("setCurrentFunctions opId:" + operationId);
usbMgr.setCurrentFunctions(UsbManager.usbFunctionsFromString(
- args.length >= 3 ? args[2] : ""));
+ args.length >= 3 ? args[2] : ""), operationId);
} catch (RemoteException e) {
System.err.println("Error communicating with UsbManager: " + e);
}
diff --git a/core/api/current.txt b/core/api/current.txt
index a0c132f..46318ae 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -6024,7 +6024,7 @@
}
public static class Notification.Action implements android.os.Parcelable {
- ctor @Deprecated public Notification.Action(int, CharSequence, android.app.PendingIntent);
+ ctor @Deprecated public Notification.Action(int, CharSequence, @Nullable android.app.PendingIntent);
method public android.app.Notification.Action clone();
method public int describeContents();
method public boolean getAllowGeneratedReplies();
@@ -6054,8 +6054,8 @@
}
public static final class Notification.Action.Builder {
- ctor @Deprecated public Notification.Action.Builder(int, CharSequence, android.app.PendingIntent);
- ctor public Notification.Action.Builder(android.graphics.drawable.Icon, CharSequence, android.app.PendingIntent);
+ ctor @Deprecated public Notification.Action.Builder(int, CharSequence, @Nullable android.app.PendingIntent);
+ ctor public Notification.Action.Builder(android.graphics.drawable.Icon, CharSequence, @Nullable android.app.PendingIntent);
ctor public Notification.Action.Builder(android.app.Notification.Action);
method @NonNull public android.app.Notification.Action.Builder addExtras(android.os.Bundle);
method @NonNull public android.app.Notification.Action.Builder addRemoteInput(android.app.RemoteInput);
@@ -7890,6 +7890,7 @@
method public int getNetworkId();
method public boolean isEnabled();
method public boolean isFallbackToDefaultConnectionAllowed();
+ method public boolean shouldBlockNonMatchingNetworks();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.PreferentialNetworkServiceConfig> CREATOR;
field public static final int PREFERENTIAL_NETWORK_ID_1 = 1; // 0x1
@@ -7907,6 +7908,7 @@
method @NonNull public android.app.admin.PreferentialNetworkServiceConfig.Builder setFallbackToDefaultConnectionAllowed(boolean);
method @NonNull public android.app.admin.PreferentialNetworkServiceConfig.Builder setIncludedUids(@NonNull int[]);
method @NonNull public android.app.admin.PreferentialNetworkServiceConfig.Builder setNetworkId(int);
+ method @NonNull public android.app.admin.PreferentialNetworkServiceConfig.Builder setShouldBlockNonMatchingNetworks(boolean);
}
public class SecurityLog {
@@ -20609,6 +20611,7 @@
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
@@ -20627,6 +20630,9 @@
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
}
@@ -25915,6 +25921,7 @@
method @Nullable public android.media.tv.TvInputService.RecordingSession onCreateRecordingSession(@NonNull String, @NonNull String);
method @Nullable public abstract android.media.tv.TvInputService.Session onCreateSession(@NonNull String);
method @Nullable public android.media.tv.TvInputService.Session onCreateSession(@NonNull String, @NonNull String);
+ method @Nullable public android.media.tv.TvInputService.Session onCreateSession(@NonNull String, @NonNull String, @NonNull android.content.AttributionSource);
field public static final int PRIORITY_HINT_USE_CASE_TYPE_BACKGROUND = 100; // 0x64
field public static final int PRIORITY_HINT_USE_CASE_TYPE_LIVE = 400; // 0x190
field public static final int PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK = 300; // 0x12c
@@ -26075,6 +26082,7 @@
method public String getSelectedTrack(int);
method public java.util.List<android.media.tv.TvTrackInfo> getTracks(int);
method public boolean onUnhandledInputEvent(android.view.InputEvent);
+ method public void overrideTvAppAttributionSource(@NonNull android.content.AttributionSource);
method public void reset();
method public void selectTrack(int, String);
method public void sendAppPrivateCommand(@NonNull String, android.os.Bundle);
@@ -30768,7 +30776,8 @@
method public static void scaleM(float[], int, float, float, float);
method public static void setIdentityM(float[], int);
method public static void setLookAtM(float[], int, float, float, float, float, float, float, float, float, float);
- method public static void setRotateEulerM(float[], int, float, float, float);
+ method @Deprecated public static void setRotateEulerM(float[], int, float, float, float);
+ method public static void setRotateEulerM2(@NonNull float[], int, float, float, float);
method public static void setRotateM(float[], int, float, float, float, float);
method public static void translateM(float[], int, float[], int, float, float, float);
method public static void translateM(float[], int, float, float, float);
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 8d53959..3a94198 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -120,6 +120,7 @@
field public static final int GADGET_HAL_V1_0 = 10; // 0xa
field public static final int GADGET_HAL_V1_1 = 11; // 0xb
field public static final int GADGET_HAL_V1_2 = 12; // 0xc
+ field public static final int GADGET_HAL_V2_0 = 20; // 0x14
field public static final int USB_DATA_TRANSFER_RATE_10G = 10240; // 0x2800
field public static final int USB_DATA_TRANSFER_RATE_20G = 20480; // 0x5000
field public static final int USB_DATA_TRANSFER_RATE_40G = 40960; // 0xa000
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 6eddc3c0..1d39931 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -760,10 +760,12 @@
public class BroadcastOptions {
method public void clearRequireCompatChange();
+ method public boolean isDeferUntilActive();
method public boolean isPendingIntentBackgroundActivityLaunchAllowed();
method public static android.app.BroadcastOptions makeBasic();
method @RequiresPermission(android.Manifest.permission.ACCESS_BROADCAST_RESPONSE_STATS) public void recordResponseEventWhileInBackground(@IntRange(from=0) long);
method @RequiresPermission(android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND) public void setBackgroundActivityStartsAllowed(boolean);
+ method @NonNull public android.app.BroadcastOptions setDeferUntilActive(boolean);
method public void setDeliveryGroupMatchingFilter(@NonNull android.content.IntentFilter);
method public void setDeliveryGroupMatchingKey(@NonNull String, @NonNull String);
method public void setDeliveryGroupPolicy(int);
@@ -9120,14 +9122,20 @@
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enable();
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableNdefPush();
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableSecureNfc(boolean);
+ method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public java.util.Map<java.lang.String,java.lang.Boolean> getTagIntentAppPreferenceForUser(int);
method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOn();
method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOnSupported();
+ method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isTagIntentAppPreferenceSupported();
method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void registerControllerAlwaysOnListener(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcAdapter.ControllerAlwaysOnListener);
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean removeNfcUnlockHandler(android.nfc.NfcAdapter.NfcUnlockHandler);
method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean setControllerAlwaysOn(boolean);
method public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, int);
+ method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int setTagIntentAppPreferenceForUser(int, @NonNull String, boolean);
method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void unregisterControllerAlwaysOnListener(@NonNull android.nfc.NfcAdapter.ControllerAlwaysOnListener);
field public static final int FLAG_NDEF_PUSH_NO_CONFIRM = 1; // 0x1
+ field public static final int TAG_INTENT_APP_PREF_RESULT_PACKAGE_NOT_FOUND = -1; // 0xffffffff
+ field public static final int TAG_INTENT_APP_PREF_RESULT_SUCCESS = 0; // 0x0
+ field public static final int TAG_INTENT_APP_PREF_RESULT_UNAVAILABLE = -2; // 0xfffffffe
}
public static interface NfcAdapter.ControllerAlwaysOnListener {
@@ -14962,6 +14970,7 @@
field public static final String SERVICE_ID_POST_CALL = "org.3gpp.urn:urn-7:3gpp-service.ims.icsi.gsma.callunanswered";
field public static final String SERVICE_ID_SHARED_MAP = "org.3gpp.urn:urn-7:3gpp-service.ims.icsi.gsma.sharedmap";
field public static final String SERVICE_ID_SHARED_SKETCH = "org.3gpp.urn:urn-7:3gpp-service.ims.icsi.gsma.sharedsketch";
+ field public static final String SERVICE_ID_SLM = "org.openmobilealliance:StandaloneMsg";
field public static final String TUPLE_BASIC_STATUS_CLOSED = "closed";
field public static final String TUPLE_BASIC_STATUS_OPEN = "open";
}
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index c38c887..2d86051d 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1696,7 +1696,10 @@
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 8b7b7eb..16c5b08 100644
--- a/core/java/android/app/BroadcastOptions.java
+++ b/core/java/android/app/BroadcastOptions.java
@@ -66,6 +66,7 @@
private @DeliveryGroupPolicy int mDeliveryGroupPolicy;
private @Nullable String mDeliveryGroupMatchingKey;
private @Nullable IntentFilter mDeliveryGroupMatchingFilter;
+ private boolean mIsDeferUntilActive = false;
/**
* Change ID which is invalid.
@@ -688,6 +689,41 @@
}
/**
+ * Sets whether the broadcast should not run until the process is in an active process state
+ * (ie, a process exists for the app and the app is not in a cached process state).
+ *
+ * Whether an app's process state is considered active is independent of its standby bucket.
+ *
+ * A broadcast that is deferred until the process is active will not execute until the process
+ * is brought to an active state by some other action, like a job, alarm, or service binding. As
+ * a result, the broadcast may be delayed indefinitely. This deferral only applies to runtime
+ * registered receivers of a broadcast. Any manifest receivers will run immediately, similar to
+ * how a manifest receiver would start a new process in order to run a broadcast receiver.
+ *
+ * Ordered broadcasts, alarm broadcasts, interactive broadcasts, and manifest broadcasts are
+ * never deferred.
+ *
+ * Unordered broadcasts and unordered broadcasts with completion callbacks may be
+ * deferred. Completion callbacks for broadcasts deferred until active are
+ * best-effort. Completion callbacks will run when all eligible processes have finished
+ * executing the broadcast. Processes in inactive process states that defer the broadcast are
+ * not considered eligible and may not execute the broadcast prior to the completion callback.
+ *
+ * @hide
+ */
+ @SystemApi
+ public @NonNull BroadcastOptions setDeferUntilActive(boolean shouldDefer) {
+ mIsDeferUntilActive = shouldDefer;
+ return this;
+ }
+
+ /** @hide */
+ @SystemApi
+ public boolean isDeferUntilActive() {
+ return mIsDeferUntilActive;
+ }
+
+ /**
* Returns the created options as a Bundle, which can be passed to
* {@link android.content.Context#sendBroadcast(android.content.Intent)
* Context.sendBroadcast(Intent)} and related methods.
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index f320b74..b316b19 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1783,7 +1783,7 @@
* @deprecated Use {@link android.app.Notification.Action.Builder}.
*/
@Deprecated
- public Action(int icon, CharSequence title, PendingIntent intent) {
+ public Action(int icon, CharSequence title, @Nullable PendingIntent intent) {
this(Icon.createWithResource("", icon), title, intent, new Bundle(), null, true,
SEMANTIC_ACTION_NONE, false /* isContextual */, false /* requireAuth */);
}
@@ -1908,10 +1908,12 @@
* which may display them in other contexts, for example on a wearable device.
* @param icon icon to show for this action
* @param title the title of the action
- * @param intent the {@link PendingIntent} to fire when users trigger this action
+ * @param intent the {@link PendingIntent} to fire when users trigger this action. May
+ * be null, in which case the action may be rendered in a disabled presentation by the
+ * system UI.
*/
@Deprecated
- public Builder(int icon, CharSequence title, PendingIntent intent) {
+ public Builder(int icon, CharSequence title, @Nullable PendingIntent intent) {
this(Icon.createWithResource("", icon), title, intent);
}
@@ -1940,9 +1942,11 @@
*
* @param icon icon to show for this action
* @param title the title of the action
- * @param intent the {@link PendingIntent} to fire when users trigger this action
+ * @param intent the {@link PendingIntent} to fire when users trigger this action. May
+ * be null, in which case the action may be rendered in a disabled presentation by the
+ * system UI.
*/
- public Builder(Icon icon, CharSequence title, PendingIntent intent) {
+ public Builder(Icon icon, CharSequence title, @Nullable PendingIntent intent) {
this(icon, title, intent, new Bundle(), null, true, SEMANTIC_ACTION_NONE, false);
}
diff --git a/core/java/android/app/OWNERS b/core/java/android/app/OWNERS
index f2eced3..20869e0 100644
--- a/core/java/android/app/OWNERS
+++ b/core/java/android/app/OWNERS
@@ -47,6 +47,9 @@
# AppOps
per-file *AppOp* = file:/core/java/android/permission/OWNERS
+# Backup and Restore
+per-file IBackupAgent.aidl = file:/services/backup/OWNERS
+
# LocaleManager
per-file *Locale* = file:/services/core/java/com/android/server/locales/OWNERS
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 34c91c3..bfab8c9 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -2391,6 +2391,7 @@
* applied (cross profile intent filters updated). Only usesd for CTS tests.
* @hide
*/
+ @SuppressLint("ActionValue")
@TestApi
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_DATA_SHARING_RESTRICTION_APPLIED =
@@ -2401,6 +2402,7 @@
* has been changed.
* @hide
*/
+ @SuppressLint("ActionValue")
@TestApi
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_DEVICE_POLICY_CONSTANTS_CHANGED =
diff --git a/core/java/android/app/admin/PreferentialNetworkServiceConfig.java b/core/java/android/app/admin/PreferentialNetworkServiceConfig.java
index 63c9839..1e0d062 100644
--- a/core/java/android/app/admin/PreferentialNetworkServiceConfig.java
+++ b/core/java/android/app/admin/PreferentialNetworkServiceConfig.java
@@ -50,6 +50,7 @@
final boolean mIsEnabled;
final int mNetworkId;
final boolean mAllowFallbackToDefaultConnection;
+ final boolean mShouldBlockNonMatchingNetworks;
final int[] mIncludedUids;
final int[] mExcludedUids;
@@ -63,6 +64,8 @@
"preferential_network_service_network_id";
private static final String TAG_ALLOW_FALLBACK_TO_DEFAULT_CONNECTION =
"allow_fallback_to_default_connection";
+ private static final String TAG_BLOCK_NON_MATCHING_NETWORKS =
+ "block_non_matching_networks";
private static final String TAG_INCLUDED_UIDS = "included_uids";
private static final String TAG_EXCLUDED_UIDS = "excluded_uids";
private static final String ATTR_VALUE = "value";
@@ -110,10 +113,12 @@
}
private PreferentialNetworkServiceConfig(boolean isEnabled,
- boolean allowFallbackToDefaultConnection, int[] includedUids,
+ boolean allowFallbackToDefaultConnection, boolean shouldBlockNonMatchingNetworks,
+ int[] includedUids,
int[] excludedUids, @PreferentialNetworkPreferenceId int networkId) {
mIsEnabled = isEnabled;
mAllowFallbackToDefaultConnection = allowFallbackToDefaultConnection;
+ mShouldBlockNonMatchingNetworks = shouldBlockNonMatchingNetworks;
mIncludedUids = includedUids;
mExcludedUids = excludedUids;
mNetworkId = networkId;
@@ -122,6 +127,7 @@
private PreferentialNetworkServiceConfig(Parcel in) {
mIsEnabled = in.readBoolean();
mAllowFallbackToDefaultConnection = in.readBoolean();
+ mShouldBlockNonMatchingNetworks = in.readBoolean();
mNetworkId = in.readInt();
mIncludedUids = in.createIntArray();
mExcludedUids = in.createIntArray();
@@ -136,9 +142,18 @@
}
/**
- * is fallback to default network allowed. This boolean configures whether default connection
- * (default internet or wifi) should be used or not if a preferential network service
- * connection is not available.
+ * Whether fallback to the device-wide default network is allowed.
+ *
+ * This boolean configures whether the default connection (e.g. general cell network or wifi)
+ * should be used if no preferential network service connection is available. If true, the
+ * default connection will be used when no preferential service is available. If false, the
+ * UIDs subject to this configuration will have no default network.
+ * Note that while this boolean determines whether the UIDs subject to this configuration have
+ * a default network in the absence of a preferential service, apps can still explicitly decide
+ * to use another network than their default network by requesting them from the system. This
+ * boolean does not determine whether the UIDs are blocked from using such other networks.
+ * See {@link #shouldBlockNonMatchingNetworks()} for that configuration.
+ *
* @return true if fallback is allowed, else false.
*/
public boolean isFallbackToDefaultConnectionAllowed() {
@@ -146,6 +161,21 @@
}
/**
+ * Whether to block UIDs from using other networks than the preferential service.
+ *
+ * Apps can inspect the list of available networks on the device and choose to use multiple
+ * of them concurrently for performance, privacy or other reasons.
+ * This boolean configures whether the concerned UIDs should be blocked from using
+ * networks that do not match the configured preferential network service even if these
+ * networks are otherwise open to all apps.
+ *
+ * @return true if UIDs should be blocked from using the other networks, else false.
+ */
+ public boolean shouldBlockNonMatchingNetworks() {
+ return mShouldBlockNonMatchingNetworks;
+ }
+
+ /**
* Get the array of uids that are applicable for the profile preference.
*
* {@see #getExcludedUids()}
@@ -189,6 +219,7 @@
return "PreferentialNetworkServiceConfig{"
+ "mIsEnabled=" + isEnabled()
+ "mAllowFallbackToDefaultConnection=" + isFallbackToDefaultConnectionAllowed()
+ + "mBlockNonMatchingNetworks=" + shouldBlockNonMatchingNetworks()
+ "mIncludedUids=" + Arrays.toString(mIncludedUids)
+ "mExcludedUids=" + Arrays.toString(mExcludedUids)
+ "mNetworkId=" + mNetworkId
@@ -202,6 +233,7 @@
final PreferentialNetworkServiceConfig that = (PreferentialNetworkServiceConfig) o;
return mIsEnabled == that.mIsEnabled
&& mAllowFallbackToDefaultConnection == that.mAllowFallbackToDefaultConnection
+ && mShouldBlockNonMatchingNetworks == that.mShouldBlockNonMatchingNetworks
&& mNetworkId == that.mNetworkId
&& Arrays.equals(mIncludedUids, that.mIncludedUids)
&& Arrays.equals(mExcludedUids, that.mExcludedUids);
@@ -210,7 +242,8 @@
@Override
public int hashCode() {
return Objects.hash(mIsEnabled, mAllowFallbackToDefaultConnection,
- Arrays.hashCode(mIncludedUids), Arrays.hashCode(mExcludedUids), mNetworkId);
+ mShouldBlockNonMatchingNetworks, Arrays.hashCode(mIncludedUids),
+ Arrays.hashCode(mExcludedUids), mNetworkId);
}
/**
@@ -221,6 +254,7 @@
boolean mIsEnabled = false;
int mNetworkId = 0;
boolean mAllowFallbackToDefaultConnection = true;
+ boolean mShouldBlockNonMatchingNetworks = false;
int[] mIncludedUids = new int[0];
int[] mExcludedUids = new int[0];
@@ -242,10 +276,21 @@
}
/**
- * Set whether the default connection should be used as fallback.
- * This boolean configures whether the default connection (default internet or wifi)
- * should be used if a preferential network service connection is not available.
- * Default value is true
+ * Set whether fallback to the device-wide default network is allowed.
+ *
+ * This boolean configures whether the default connection (e.g. general cell network or
+ * wifi) should be used if no preferential network service connection is available. If true,
+ * the default connection will be used when no preferential service is available. If false,
+ * the UIDs subject to this configuration will have no default network.
+ * Note that while this boolean determines whether the UIDs subject to this configuration
+ * have a default network in the absence of a preferential service, apps can still
+ * explicitly decide to use another network than their default network by requesting them
+ * from the system. This boolean does not determine whether the UIDs are blocked from using
+ * such other networks.
+ * Use {@link #setShouldBlockNonMatchingNetworks(boolean)} to specify this.
+ *
+ * The default value is true.
+ *
* @param allowFallbackToDefaultConnection true if fallback is allowed else false
* @return The builder to facilitate chaining.
*/
@@ -258,6 +303,31 @@
}
/**
+ * Set whether to block UIDs from using other networks than the preferential service.
+ *
+ * Apps can inspect the list of available networks on the device and choose to use multiple
+ * of them concurrently for performance, privacy or other reasons.
+ * This boolean configures whether the concerned UIDs should be blocked from using
+ * networks that do not match the configured preferential network service even if these
+ * networks are otherwise open to all apps.
+ *
+ * The default value is false. This value can only be set to {@code true} if
+ * {@link #setFallbackToDefaultConnectionAllowed(boolean)} is set to {@code false}, because
+ * allowing fallback but blocking it does not make sense. Failure to comply with this
+ * constraint will throw when building the object.
+ *
+ * @param blockNonMatchingNetworks true if UIDs should be blocked from using non-matching
+ * networks.
+ * @return The builder to facilitate chaining.
+ */
+ @NonNull
+ public PreferentialNetworkServiceConfig.Builder setShouldBlockNonMatchingNetworks(
+ boolean blockNonMatchingNetworks) {
+ mShouldBlockNonMatchingNetworks = blockNonMatchingNetworks;
+ return this;
+ }
+
+ /**
* Set the array of uids whose network access will go through this preferential
* network service.
* {@see #setExcludedUids(int[])}
@@ -305,8 +375,13 @@
throw new IllegalStateException("Both includedUids and excludedUids "
+ "cannot be nonempty");
}
+ if (mShouldBlockNonMatchingNetworks && mAllowFallbackToDefaultConnection) {
+ throw new IllegalStateException("A config cannot both allow fallback and "
+ + "block non-matching networks");
+ }
return new PreferentialNetworkServiceConfig(mIsEnabled,
- mAllowFallbackToDefaultConnection, mIncludedUids, mExcludedUids, mNetworkId);
+ mAllowFallbackToDefaultConnection, mShouldBlockNonMatchingNetworks,
+ mIncludedUids, mExcludedUids, mNetworkId);
}
/**
@@ -331,6 +406,7 @@
public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
dest.writeBoolean(mIsEnabled);
dest.writeBoolean(mAllowFallbackToDefaultConnection);
+ dest.writeBoolean(mShouldBlockNonMatchingNetworks);
dest.writeInt(mNetworkId);
dest.writeIntArray(mIncludedUids);
dest.writeIntArray(mExcludedUids);
@@ -422,6 +498,9 @@
} else if (TAG_ALLOW_FALLBACK_TO_DEFAULT_CONNECTION.equals(tagDAM)) {
resultBuilder.setFallbackToDefaultConnectionAllowed(parser.getAttributeBoolean(
null, ATTR_VALUE, true));
+ } else if (TAG_BLOCK_NON_MATCHING_NETWORKS.equals(tagDAM)) {
+ resultBuilder.setShouldBlockNonMatchingNetworks(parser.getAttributeBoolean(
+ null, ATTR_VALUE, false));
} else if (TAG_INCLUDED_UIDS.equals(tagDAM)) {
resultBuilder.setIncludedUids(readStringListToIntArray(parser, TAG_UID));
} else if (TAG_EXCLUDED_UIDS.equals(tagDAM)) {
@@ -442,6 +521,8 @@
writeAttributeValueToXml(out, TAG_NETWORK_ID, getNetworkId());
writeAttributeValueToXml(out, TAG_ALLOW_FALLBACK_TO_DEFAULT_CONNECTION,
isFallbackToDefaultConnectionAllowed());
+ writeAttributeValueToXml(out, TAG_BLOCK_NON_MATCHING_NETWORKS,
+ shouldBlockNonMatchingNetworks());
writeAttributeValuesToXml(out, TAG_INCLUDED_UIDS, TAG_UID,
intArrayToStringList(getIncludedUids()));
writeAttributeValuesToXml(out, TAG_EXCLUDED_UIDS, TAG_UID,
@@ -459,6 +540,8 @@
pw.println(mIsEnabled);
pw.print("allowFallbackToDefaultConnection=");
pw.println(mAllowFallbackToDefaultConnection);
+ pw.print("blockNonMatchingNetworks=");
+ pw.println(mShouldBlockNonMatchingNetworks);
pw.print("includedUids=");
pw.println(mIncludedUids);
pw.print("excludedUids=");
diff --git a/core/java/android/app/admin/Provisioning_OWNERS b/core/java/android/app/admin/Provisioning_OWNERS
index c59a9dc..2e5c2df 100644
--- a/core/java/android/app/admin/Provisioning_OWNERS
+++ b/core/java/android/app/admin/Provisioning_OWNERS
@@ -1,5 +1,5 @@
# Assign bugs to android-enterprise-triage@google.com
-petuska@google.com
-nupursn@google.com
-shreyacsingh@google.com
-alexkershaw@google.com #{LAST_RESORT_SUGGESTION}
\ No newline at end of file
+mdb.ae-provisioning-reviews@google.com
+petuska@google.com #{LAST_RESORT_SUGGESTION}
+nupursn@google.com #{LAST_RESORT_SUGGESTION}
+shreyacsingh@google.com #{LAST_RESORT_SUGGESTION}
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index d83ad3d..f1e3724 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1530,6 +1530,14 @@
*/
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/hardware/soundtrigger/OWNERS b/core/java/android/hardware/soundtrigger/OWNERS
index e5d0370..01b2cb9 100644
--- a/core/java/android/hardware/soundtrigger/OWNERS
+++ b/core/java/android/hardware/soundtrigger/OWNERS
@@ -1,2 +1,2 @@
-ytai@google.com
+atneya@google.com
elaurent@google.com
diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl
index 5a44244..1e147ec 100644
--- a/core/java/android/hardware/usb/IUsbManager.aidl
+++ b/core/java/android/hardware/usb/IUsbManager.aidl
@@ -111,10 +111,10 @@
boolean isFunctionEnabled(String function);
/* Sets the current USB function. */
- void setCurrentFunctions(long functions);
+ void setCurrentFunctions(long functions, int operationId);
/* Compatibility version of setCurrentFunctions(long). */
- void setCurrentFunction(String function, boolean usbDataUnlocked);
+ void setCurrentFunction(String function, boolean usbDataUnlocked, int operationId);
/* Gets the current USB functions. */
long getCurrentFunctions();
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index 2c38f70..9d672bb 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -38,6 +38,7 @@
import android.content.pm.PackageManager.NameNotFoundException;
import android.hardware.usb.gadget.V1_0.GadgetFunction;
import android.hardware.usb.gadget.V1_2.UsbSpeed;
+import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
@@ -52,6 +53,7 @@
import java.util.Map;
import java.util.Objects;
import java.util.StringJoiner;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* This class allows you to access the state of USB and communicate with USB devices.
@@ -95,7 +97,7 @@
* If the sticky intent has not been found, that indicates USB is disconnected,
* USB is not configued, MTP function is enabled, and all the other functions are disabled.
*
- * {@hide}
+ * @hide
*/
@SystemApi
public static final String ACTION_USB_STATE =
@@ -172,7 +174,7 @@
* <p>For more information about communicating with USB accessory handshake, refer to
* <a href="https://source.android.com/devices/accessories/aoa">AOA</a> developer guide.</p>
*
- * {@hide}
+ * @hide
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
@SystemApi
@@ -184,7 +186,7 @@
* Boolean extra indicating whether USB is connected or disconnected.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast.
*
- * {@hide}
+ * @hide
*/
@SystemApi
public static final String USB_CONNECTED = "connected";
@@ -193,7 +195,7 @@
* Boolean extra indicating whether USB is connected or disconnected as host.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast.
*
- * {@hide}
+ * @hide
*/
public static final String USB_HOST_CONNECTED = "host_connected";
@@ -201,7 +203,7 @@
* Boolean extra indicating whether USB is configured.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast.
*
- * {@hide}
+ * @hide
*/
@SystemApi
public static final String USB_CONFIGURED = "configured";
@@ -212,7 +214,7 @@
* has explicitly asked for this data to be unlocked.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast.
*
- * {@hide}
+ * @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public static final String USB_DATA_UNLOCKED = "unlocked";
@@ -221,7 +223,7 @@
* A placeholder indicating that no USB function is being specified.
* Used for compatibility with old init scripts to indicate no functions vs. charging function.
*
- * {@hide}
+ * @hide
*/
@UnsupportedAppUsage
public static final String USB_FUNCTION_NONE = "none";
@@ -230,7 +232,7 @@
* Name of the adb USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast
*
- * {@hide}
+ * @hide
*/
public static final String USB_FUNCTION_ADB = "adb";
@@ -238,7 +240,7 @@
* Name of the RNDIS ethernet USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast
*
- * {@hide}
+ * @hide
*/
@SystemApi
public static final String USB_FUNCTION_RNDIS = "rndis";
@@ -247,7 +249,7 @@
* Name of the MTP USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast
*
- * {@hide}
+ * @hide
*/
public static final String USB_FUNCTION_MTP = "mtp";
@@ -255,7 +257,7 @@
* Name of the PTP USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast
*
- * {@hide}
+ * @hide
*/
public static final String USB_FUNCTION_PTP = "ptp";
@@ -263,7 +265,7 @@
* Name of the audio source USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast
*
- * {@hide}
+ * @hide
*/
public static final String USB_FUNCTION_AUDIO_SOURCE = "audio_source";
@@ -271,7 +273,7 @@
* Name of the MIDI USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast
*
- * {@hide}
+ * @hide
*/
public static final String USB_FUNCTION_MIDI = "midi";
@@ -279,7 +281,7 @@
* Name of the Accessory USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast
*
- * {@hide}
+ * @hide
*/
public static final String USB_FUNCTION_ACCESSORY = "accessory";
@@ -287,7 +289,7 @@
* Name of the NCM USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast
*
- * {@hide}
+ * @hide
*/
@SystemApi
public static final String USB_FUNCTION_NCM = "ncm";
@@ -295,32 +297,39 @@
/**
* Name of Gadget Hal Not Present;
*
- * {@hide}
+ * @hide
*/
public static final String GADGET_HAL_UNKNOWN = "unknown";
/**
* Name of the USB Gadget Hal Version v1.0;
*
- * {@hide}
+ * @hide
*/
public static final String GADGET_HAL_VERSION_1_0 = "V1_0";
/**
* Name of the USB Gadget Hal Version v1.1;
*
- * {@hide}
+ * @hide
*/
public static final String GADGET_HAL_VERSION_1_1 = "V1_1";
/**
* Name of the USB Gadget Hal Version v1.2;
*
- * {@hide}
+ * @hide
*/
public static final String GADGET_HAL_VERSION_1_2 = "V1_2";
/**
+ * Name of the USB Gadget Hal Version v2.0;
+ *
+ * @hide
+ */
+ public static final String GADGET_HAL_VERSION_2_0 = "V2_0";
+
+ /**
* Name of extra for {@link #ACTION_USB_PORT_CHANGED}
* containing the {@link UsbPort} object for the port.
*
@@ -356,7 +365,7 @@
* This is obtained with SystemClock.elapsedRealtime()
* Used in extras for {@link #ACTION_USB_ACCESSORY_HANDSHAKE} broadcasts.
*
- * {@hide}
+ * @hide
*/
@SystemApi
public static final String EXTRA_ACCESSORY_UEVENT_TIME =
@@ -370,7 +379,7 @@
* between communicating with USB accessory handshake, refer to
* <a href="https://source.android.com/devices/accessories/aoa">AOA</a> developer guide.</p>
*
- * {@hide}
+ * @hide
*/
@SystemApi
public static final String EXTRA_ACCESSORY_STRING_COUNT =
@@ -380,7 +389,7 @@
* Boolean extra indicating whether got start accessory or not
* Used in extras for {@link #ACTION_USB_ACCESSORY_HANDSHAKE} broadcasts.
*
- * {@hide}
+ * @hide
*/
@SystemApi
public static final String EXTRA_ACCESSORY_START =
@@ -392,7 +401,7 @@
* sending {@link #ACTION_USB_ACCESSORY_HANDSHAKE}.
* Used in extras for {@link #ACTION_USB_ACCESSORY_HANDSHAKE} broadcasts.
*
- * {@hide}
+ * @hide
*/
@SystemApi
public static final String EXTRA_ACCESSORY_HANDSHAKE_END =
@@ -426,7 +435,7 @@
/**
* The Value for USB gadget hal is not presented.
*
- * {@hide}
+ * @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int GADGET_HAL_NOT_SUPPORTED = -1;
@@ -434,7 +443,7 @@
/**
* Value for Gadget Hal Version v1.0.
*
- * {@hide}
+ * @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int GADGET_HAL_V1_0 = 10;
@@ -442,7 +451,7 @@
/**
* Value for Gadget Hal Version v1.1.
*
- * {@hide}
+ * @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int GADGET_HAL_V1_1 = 11;
@@ -450,15 +459,23 @@
/**
* Value for Gadget Hal Version v1.2.
*
- * {@hide}
+ * @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int GADGET_HAL_V1_2 = 12;
/**
+ * Value for Gadget Hal Version v2.0.
+ *
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static final int GADGET_HAL_V2_0 = 20;
+
+ /**
* Value for USB_STATE is not configured.
*
- * {@hide}
+ * @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int USB_DATA_TRANSFER_RATE_UNKNOWN = -1;
@@ -466,7 +483,7 @@
/**
* Value for USB Transfer Rate of Low Speed in Mbps (real value is 1.5Mbps).
*
- * {@hide}
+ * @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int USB_DATA_TRANSFER_RATE_LOW_SPEED = 2;
@@ -474,7 +491,7 @@
/**
* Value for USB Transfer Rate of Full Speed in Mbps.
*
- * {@hide}
+ * @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int USB_DATA_TRANSFER_RATE_FULL_SPEED = 12;
@@ -482,7 +499,7 @@
/**
* Value for USB Transfer Rate of High Speed in Mbps.
*
- * {@hide}
+ * @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int USB_DATA_TRANSFER_RATE_HIGH_SPEED = 480;
@@ -490,7 +507,7 @@
/**
* Value for USB Transfer Rate of Super Speed in Mbps.
*
- * {@hide}
+ * @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int USB_DATA_TRANSFER_RATE_5G = 5 * 1024;
@@ -498,7 +515,7 @@
/**
* Value for USB Transfer Rate of 10G.
*
- * {@hide}
+ * @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int USB_DATA_TRANSFER_RATE_10G = 10 * 1024;
@@ -506,7 +523,7 @@
/**
* Value for USB Transfer Rate of 20G.
*
- * {@hide}
+ * @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int USB_DATA_TRANSFER_RATE_20G = 20 * 1024;
@@ -514,7 +531,7 @@
/**
* Value for USB Transfer Rate of 40G.
*
- * {@hide}
+ * @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int USB_DATA_TRANSFER_RATE_40G = 40 * 1024;
@@ -530,7 +547,7 @@
/**
* The Value for USB hal is not presented.
*
- * {@hide}
+ * @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int USB_HAL_NOT_SUPPORTED = -1;
@@ -538,7 +555,7 @@
/**
* Value for USB Hal Version v1.0.
*
- * {@hide}
+ * @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int USB_HAL_V1_0 = 10;
@@ -546,7 +563,7 @@
/**
* Value for USB Hal Version v1.1.
*
- * {@hide}
+ * @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int USB_HAL_V1_1 = 11;
@@ -554,7 +571,7 @@
/**
* Value for USB Hal Version v1.2.
*
- * {@hide}
+ * @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int USB_HAL_V1_2 = 12;
@@ -562,7 +579,7 @@
/**
* Value for USB Hal Version v1.3.
*
- * {@hide}
+ * @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int USB_HAL_V1_3 = 13;
@@ -577,63 +594,63 @@
/**
* Code for the charging usb function. Passed into {@link #setCurrentFunctions(long)}
- * {@hide}
+ * @hide
*/
@SystemApi
public static final long FUNCTION_NONE = 0;
/**
* Code for the mtp usb function. Passed as a mask into {@link #setCurrentFunctions(long)}
- * {@hide}
+ * @hide
*/
@SystemApi
public static final long FUNCTION_MTP = GadgetFunction.MTP;
/**
* Code for the ptp usb function. Passed as a mask into {@link #setCurrentFunctions(long)}
- * {@hide}
+ * @hide
*/
@SystemApi
public static final long FUNCTION_PTP = GadgetFunction.PTP;
/**
* Code for the rndis usb function. Passed as a mask into {@link #setCurrentFunctions(long)}
- * {@hide}
+ * @hide
*/
@SystemApi
public static final long FUNCTION_RNDIS = GadgetFunction.RNDIS;
/**
* Code for the midi usb function. Passed as a mask into {@link #setCurrentFunctions(long)}
- * {@hide}
+ * @hide
*/
@SystemApi
public static final long FUNCTION_MIDI = GadgetFunction.MIDI;
/**
* Code for the accessory usb function.
- * {@hide}
+ * @hide
*/
@SystemApi
public static final long FUNCTION_ACCESSORY = GadgetFunction.ACCESSORY;
/**
* Code for the audio source usb function.
- * {@hide}
+ * @hide
*/
@SystemApi
public static final long FUNCTION_AUDIO_SOURCE = GadgetFunction.AUDIO_SOURCE;
/**
* Code for the adb usb function.
- * {@hide}
+ * @hide
*/
@SystemApi
public static final long FUNCTION_ADB = GadgetFunction.ADB;
/**
* Code for the ncm source usb function.
- * {@hide}
+ * @hide
*/
@SystemApi
public static final long FUNCTION_NCM = 1 << 10;
@@ -643,6 +660,11 @@
private static final Map<String, Long> FUNCTION_NAME_TO_CODE = new HashMap<>();
+ /**
+ * Counter for tracking UsbOperation operations.
+ */
+ private static final AtomicInteger sUsbOperationCount = new AtomicInteger();
+
static {
FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_MTP, FUNCTION_MTP);
FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_PTP, FUNCTION_PTP);
@@ -674,6 +696,7 @@
GADGET_HAL_V1_0,
GADGET_HAL_V1_1,
GADGET_HAL_V1_2,
+ GADGET_HAL_V2_0,
})
public @interface UsbGadgetHalVersion {}
@@ -692,7 +715,7 @@
private final IUsbManager mService;
/**
- * {@hide}
+ * @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public UsbManager(Context context, IUsbManager service) {
@@ -803,7 +826,7 @@
* {@link #FUNCTION_PTP} are supported.
* @return A ParcelFileDescriptor holding the valid fd, or null if the fd was not found.
*
- * {@hide}
+ * @hide
*/
public ParcelFileDescriptor getControlFd(long function) {
try {
@@ -921,7 +944,7 @@
* Only system components can call this function.
* @param device to request permissions for
*
- * {@hide}
+ * @hide
*/
public void grantPermission(UsbDevice device) {
grantPermission(device, Process.myUid());
@@ -933,7 +956,7 @@
* @param device to request permissions for
* @uid uid to give permission
*
- * {@hide}
+ * @hide
*/
public void grantPermission(UsbDevice device, int uid) {
try {
@@ -949,7 +972,7 @@
* @param device to request permissions for
* @param packageName of package to grant permissions
*
- * {@hide}
+ * @hide
*/
@SystemApi
@RequiresPermission(Manifest.permission.MANAGE_USB)
@@ -974,7 +997,7 @@
* @param function name of the USB function
* @return true if the USB function is enabled
*
- * {@hide}
+ * @hide
*/
@Deprecated
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@@ -1006,14 +1029,17 @@
* @param functions the USB function(s) to set, as a bitwise mask.
* Must satisfy {@link UsbManager#areSettableFunctions}
*
- * {@hide}
+ * @hide
*/
@SystemApi
@RequiresPermission(Manifest.permission.MANAGE_USB)
public void setCurrentFunctions(@UsbFunctionMode long functions) {
+ int operationId = sUsbOperationCount.incrementAndGet() + Binder.getCallingUid();
try {
- mService.setCurrentFunctions(functions);
+ mService.setCurrentFunctions(functions, operationId);
} catch (RemoteException e) {
+ Log.e(TAG, "setCurrentFunctions: failed to call setCurrentFunctions. functions:"
+ + functions + ", opId:" + operationId, e);
throw e.rethrowFromSystemServer();
}
}
@@ -1025,14 +1051,17 @@
* @param functions the USB function(s) to set.
* @param usbDataUnlocked unused
- * {@hide}
+ * @hide
*/
@Deprecated
@UnsupportedAppUsage
public void setCurrentFunction(String functions, boolean usbDataUnlocked) {
+ int operationId = sUsbOperationCount.incrementAndGet() + Binder.getCallingUid();
try {
- mService.setCurrentFunction(functions, usbDataUnlocked);
+ mService.setCurrentFunction(functions, usbDataUnlocked, operationId);
} catch (RemoteException e) {
+ Log.e(TAG, "setCurrentFunction: failed to call setCurrentFunction. functions:"
+ + functions + ", opId:" + operationId, e);
throw e.rethrowFromSystemServer();
}
}
@@ -1047,7 +1076,7 @@
* @return The currently enabled functions, in a bitwise mask.
* A zero mask indicates that the current function is the charging function.
*
- * {@hide}
+ * @hide
*/
@SystemApi
@RequiresPermission(Manifest.permission.MANAGE_USB)
@@ -1073,7 +1102,7 @@
* @param functions functions to set, in a bitwise mask.
* Must satisfy {@link UsbManager#areSettableFunctions}
*
- * {@hide}
+ * @hide
*/
public void setScreenUnlockedFunctions(long functions) {
try {
@@ -1089,7 +1118,7 @@
* @return The currently set screen enabled functions.
* A zero mask indicates that the screen unlocked functions feature is not enabled.
*
- * {@hide}
+ * @hide
*/
public long getScreenUnlockedFunctions() {
try {
@@ -1111,19 +1140,17 @@
*
* @return The value of currently USB Bandwidth.
*
- * {@hide}
+ * @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
@RequiresPermission(Manifest.permission.MANAGE_USB)
public int getUsbBandwidthMbps() {
int usbSpeed;
-
try {
usbSpeed = mService.getCurrentUsbSpeed();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
-
return usbSpeedToBandwidth(usbSpeed);
}
@@ -1135,7 +1162,7 @@
*
* @return a integer {@code GADGET_HAL_*} represent hal version.
*
- * {@hide}
+ * @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
@RequiresPermission(Manifest.permission.MANAGE_USB)
@@ -1155,7 +1182,7 @@
*
* @return a integer {@code USB_HAL_*} represent hal version.
*
- * {@hide}
+ * @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
@RequiresPermission(Manifest.permission.MANAGE_USB)
@@ -1451,7 +1478,7 @@
* @param usbDeviceConnectionHandler The component to handle usb connections,
* {@code null} to unset.
*
- * {@hide}
+ * @hide
*/
public void setUsbDeviceConnectionHandler(@Nullable ComponentName usbDeviceConnectionHandler) {
try {
@@ -1470,7 +1497,7 @@
*
* @return Whether the mask is settable.
*
- * {@hide}
+ * @hide
*/
public static boolean areSettableFunctions(long functions) {
return functions == FUNCTION_NONE
@@ -1484,7 +1511,7 @@
*
* @return String representation of given mask
*
- * {@hide}
+ * @hide
*/
public static String usbFunctionsToString(long functions) {
StringJoiner joiner = new StringJoiner(",");
@@ -1520,7 +1547,7 @@
*
* @return A mask of all valid functions in the string
*
- * {@hide}
+ * @hide
*/
public static long usbFunctionsFromString(String functions) {
if (functions == null || functions.equals(USB_FUNCTION_NONE)) {
@@ -1542,7 +1569,7 @@
*
* @return a value of USB bandwidth
*
- * {@hide}
+ * @hide
*/
public static int usbSpeedToBandwidth(int speed) {
switch (speed) {
@@ -1576,12 +1603,14 @@
*
* @return String representation of Usb Gadget Hal Version
*
- * {@hide}
+ * @hide
*/
public static @NonNull String usbGadgetHalVersionToString(int version) {
String halVersion;
- if (version == GADGET_HAL_V1_2) {
+ if (version == GADGET_HAL_V2_0) {
+ halVersion = GADGET_HAL_VERSION_2_0;
+ } else if (version == GADGET_HAL_V1_2) {
halVersion = GADGET_HAL_VERSION_1_2;
} else if (version == GADGET_HAL_V1_1) {
halVersion = GADGET_HAL_VERSION_1_1;
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index de107a2..8a30ef4 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -80,4 +80,10 @@
boolean isControllerAlwaysOnSupported();
void registerControllerAlwaysOnListener(in INfcControllerAlwaysOnListener listener);
void unregisterControllerAlwaysOnListener(in INfcControllerAlwaysOnListener listener);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)")
+ boolean isTagIntentAppPreferenceSupported();
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)")
+ Map getTagIntentAppPreferenceForUser(int userId);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)")
+ int setTagIntentAppPreferenceForUser(int userId, String pkg, boolean allow);
}
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index 0c7f529..7378ac7 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -17,12 +17,14 @@
package android.nfc;
import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
+import android.annotation.UserIdInt;
import android.app.Activity;
import android.app.ActivityThread;
import android.app.OnActivityPausedListener;
@@ -46,9 +48,14 @@
import android.util.Log;
import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.Objects;
import java.util.concurrent.Executor;
/**
@@ -371,6 +378,45 @@
public static final String ACTION_REQUIRE_UNLOCK_FOR_NFC =
"android.nfc.action.REQUIRE_UNLOCK_FOR_NFC";
+ /**
+ * The requested app is correctly added to the Tag intent app preference.
+ *
+ * @see #setTagIntentAppPreferenceForUser(int userId, String pkg, boolean allow)
+ * @hide
+ */
+ @SystemApi
+ public static final int TAG_INTENT_APP_PREF_RESULT_SUCCESS = 0;
+
+ /**
+ * The requested app is not installed on the device.
+ *
+ * @see #setTagIntentAppPreferenceForUser(int userId, String pkg, boolean allow)
+ * @hide
+ */
+ @SystemApi
+ public static final int TAG_INTENT_APP_PREF_RESULT_PACKAGE_NOT_FOUND = -1;
+
+ /**
+ * The NfcService is not available.
+ *
+ * @see #setTagIntentAppPreferenceForUser(int userId, String pkg, boolean allow)
+ * @hide
+ */
+ @SystemApi
+ public static final int TAG_INTENT_APP_PREF_RESULT_UNAVAILABLE = -2;
+
+ /**
+ * Possible response codes from {@link #setTagIntentAppPreferenceForUser}.
+ *
+ * @hide
+ */
+ @IntDef(prefix = { "TAG_INTENT_APP_PREF_RESULT" }, value = {
+ TAG_INTENT_APP_PREF_RESULT_SUCCESS,
+ TAG_INTENT_APP_PREF_RESULT_PACKAGE_NOT_FOUND,
+ TAG_INTENT_APP_PREF_RESULT_UNAVAILABLE})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface TagIntentAppPreferenceResult {}
+
// Guarded by NfcAdapter.class
static boolean sIsInitialized = false;
static boolean sHasNfcFeature;
@@ -2408,4 +2454,143 @@
@NonNull ControllerAlwaysOnListener listener) {
mControllerAlwaysOnListener.unregister(listener);
}
+
+
+ /**
+ * Sets whether we dispatch NFC Tag intents to the package.
+ *
+ * <p>{@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED} or
+ * {@link #ACTION_TAG_DISCOVERED} will not be dispatched to an Activity if its package is
+ * disallowed.
+ * <p>An app is added to the preference list with the allowed flag set to {@code true}
+ * when a Tag intent is dispatched to the package for the first time. This API is called
+ * by settings to note that the user wants to change this default preference.
+ *
+ * @param userId the user to whom this package name will belong to
+ * @param pkg the full name (i.e. com.google.android.tag) of the package that will be added to
+ * the preference list
+ * @param allow {@code true} to allow dispatching Tag intents to the package's activity,
+ * {@code false} otherwise
+ * @return the {@link #TagIntentAppPreferenceResult} value
+ * @throws UnsupportedOperationException if {@link isTagIntentAppPreferenceSupported} returns
+ * {@code false}
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+ @TagIntentAppPreferenceResult
+ public int setTagIntentAppPreferenceForUser(@UserIdInt int userId,
+ @NonNull String pkg, boolean allow) {
+ Objects.requireNonNull(pkg, "pkg cannot be null");
+ if (!isTagIntentAppPreferenceSupported()) {
+ Log.e(TAG, "TagIntentAppPreference is not supported");
+ throw new UnsupportedOperationException();
+ }
+ try {
+ return sService.setTagIntentAppPreferenceForUser(userId, pkg, allow);
+ } catch (RemoteException e) {
+ attemptDeadServiceRecovery(e);
+ // Try one more time
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover NFC Service.");
+ }
+ try {
+ return sService.setTagIntentAppPreferenceForUser(userId, pkg, allow);
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to recover NFC Service.");
+ }
+ return TAG_INTENT_APP_PREF_RESULT_UNAVAILABLE;
+ }
+ }
+
+
+ /**
+ * Get the Tag dispatch preference list of the UserId.
+ *
+ * <p>This returns a mapping of package names for this user id to whether we dispatch Tag
+ * intents to the package. {@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED} or
+ * {@link #ACTION_TAG_DISCOVERED} will not be dispatched to an Activity if its package is
+ * mapped to {@code false}.
+ * <p>There are three different possible cases:
+ * <p>A package not being in the preference list.
+ * It does not contain any Tag intent filters or the user never triggers a Tag detection that
+ * matches the intent filter of the package.
+ * <p>A package being mapped to {@code true}.
+ * When a package has been launched by a tag detection for the first time, the package name is
+ * put to the map and by default mapped to {@code true}. The package will receive Tag intents as
+ * usual.
+ * <p>A package being mapped to {@code false}.
+ * The user chooses to disable this package and it will not receive any Tag intents anymore.
+ *
+ * @param userId the user to whom this preference list will belong to
+ * @return a map of the UserId which indicates the mapping from package name to
+ * boolean(allow status), otherwise return an empty map
+ * @throws UnsupportedOperationException if {@link isTagIntentAppPreferenceSupported} returns
+ * {@code false}
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+ @NonNull
+ public Map<String, Boolean> getTagIntentAppPreferenceForUser(@UserIdInt int userId) {
+ if (!isTagIntentAppPreferenceSupported()) {
+ Log.e(TAG, "TagIntentAppPreference is not supported");
+ throw new UnsupportedOperationException();
+ }
+ try {
+ Map<String, Boolean> result = (Map<String, Boolean>) sService
+ .getTagIntentAppPreferenceForUser(userId);
+ return result;
+ } catch (RemoteException e) {
+ attemptDeadServiceRecovery(e);
+ // Try one more time
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover NFC Service.");
+ return Collections.emptyMap();
+ }
+ try {
+ Map<String, Boolean> result = (Map<String, Boolean>) sService
+ .getTagIntentAppPreferenceForUser(userId);
+ return result;
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to recover NFC Service.");
+ }
+ return Collections.emptyMap();
+ }
+ }
+
+ /**
+ * Checks if the device supports Tag application preference.
+ *
+ * @return {@code true} if the device supports Tag application preference, {@code false}
+ * otherwise
+ * @throws UnsupportedOperationException if FEATURE_NFC is unavailable
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+ public boolean isTagIntentAppPreferenceSupported() {
+ if (!sHasNfcFeature) {
+ throw new UnsupportedOperationException();
+ }
+ try {
+ return sService.isTagIntentAppPreferenceSupported();
+ } catch (RemoteException e) {
+ attemptDeadServiceRecovery(e);
+ // Try one more time
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover NFC Service.");
+ return false;
+ }
+ try {
+ return sService.isTagIntentAppPreferenceSupported();
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to recover NFC Service.");
+ }
+ return false;
+ }
+ }
}
diff --git a/core/java/android/nfc/OWNERS b/core/java/android/nfc/OWNERS
index 6aaf039..9a2e446 100644
--- a/core/java/android/nfc/OWNERS
+++ b/core/java/android/nfc/OWNERS
@@ -1,4 +1,5 @@
# Bug component: 48448
-zachoverflow@google.com
+sattiraju@google.com
+henrichataing@google.com
alisher@google.com
diff --git a/core/java/android/nfc/cardemulation/OWNERS b/core/java/android/nfc/cardemulation/OWNERS
index 6aaf039..9a2e446 100644
--- a/core/java/android/nfc/cardemulation/OWNERS
+++ b/core/java/android/nfc/cardemulation/OWNERS
@@ -1,4 +1,5 @@
# Bug component: 48448
-zachoverflow@google.com
+sattiraju@google.com
+henrichataing@google.com
alisher@google.com
diff --git a/core/java/android/nfc/dta/OWNERS b/core/java/android/nfc/dta/OWNERS
index 6aaf039..9a2e446 100644
--- a/core/java/android/nfc/dta/OWNERS
+++ b/core/java/android/nfc/dta/OWNERS
@@ -1,4 +1,5 @@
# Bug component: 48448
-zachoverflow@google.com
+sattiraju@google.com
+henrichataing@google.com
alisher@google.com
diff --git a/core/java/android/nfc/tech/OWNERS b/core/java/android/nfc/tech/OWNERS
index 6aaf039..9a2e446 100644
--- a/core/java/android/nfc/tech/OWNERS
+++ b/core/java/android/nfc/tech/OWNERS
@@ -1,4 +1,5 @@
# Bug component: 48448
-zachoverflow@google.com
+sattiraju@google.com
+henrichataing@google.com
alisher@google.com
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index aa56105..0cb7df7 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -358,16 +358,16 @@
* Return the Linux UID assigned to the process that sent the transaction
* currently being processed.
*
- * Logs WTF if the current thread is not currently
+ * Slog.wtf if the current thread is not currently
* executing an incoming transaction and the calling identity has not been
* explicitly set with {@link #clearCallingIdentity()}
*
* @hide
*/
- public static final int getCallingUidOrWtf() {
+ public static final int getCallingUidOrWtf(String message) {
if (!isDirectlyHandlingTransaction() && !hasExplicitIdentity()) {
- Log.wtfStack(TAG,
- "Thread is not in a binder transaction, "
+ Slog.wtf(TAG,
+ message + ": Thread is not in a binder transaction, "
+ "and the calling identity has not been "
+ "explicitly set with clearCallingIdentity");
}
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 249f486..832f23c 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -61,6 +61,17 @@
/** 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 @@
/** 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/os/Debug.java b/core/java/android/os/Debug.java
index c731a80..2d16dc3 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -1006,12 +1006,15 @@
// been replaced with an implementation that will suspendAll and
// send VM_START.
System.out.println("Waiting for debugger first packet");
+
+ mWaiting = true;
while (!isDebuggerConnected()) {
try {
Thread.sleep(100);
} catch (InterruptedException ie) {
}
}
+ mWaiting = false;
System.out.println("Debug.suspendAllAndSentVmStart");
VMDebug.suspendAllAndSendVmStart();
diff --git a/core/java/android/security/net/config/SystemCertificateSource.java b/core/java/android/security/net/config/SystemCertificateSource.java
index 4892312..13f7e5d 100644
--- a/core/java/android/security/net/config/SystemCertificateSource.java
+++ b/core/java/android/security/net/config/SystemCertificateSource.java
@@ -41,7 +41,7 @@
private static File getDirectory() {
// TODO(miguelaranda): figure out correct code path.
File updatable_dir = new File("/apex/com.android.conscrypt/cacerts");
- if (updatable_dir.exists()) {
+ if (updatable_dir.exists() && !(updatable_dir.list().length == 0)) {
return updatable_dir;
}
return new File(System.getenv("ANDROID_ROOT") + "/etc/security/cacerts");
diff --git a/core/java/android/security/rkp/IRegistration.aidl b/core/java/android/security/rkp/IRegistration.aidl
index 6522a45..8ec13b9 100644
--- a/core/java/android/security/rkp/IRegistration.aidl
+++ b/core/java/android/security/rkp/IRegistration.aidl
@@ -17,6 +17,7 @@
package android.security.rkp;
import android.security.rkp.IGetKeyCallback;
+import android.security.rkp.IStoreUpgradedKeyCallback;
/**
* This interface is associated with the registration of an
@@ -70,16 +71,18 @@
* mechanism, see the documentation for IKeyMintDevice.upgradeKey.
*
* Once a key has been upgraded, the IRegistration where the key is stored
- * needs to be told about the new blob. After calling storeUpgradedKey,
+ * needs to be told about the new blob. After calling storeUpgradedKeyAsync,
* getKey will return the new key blob instead of the old one.
*
* Note that this function does NOT extend the lifetime of key blobs. The
* certificate for the key is unchanged, and the key will still expire at
- * the same time it would have if storeUpgradedKey had never been called.
+ * the same time it would have if storeUpgradedKeyAsync had never been called.
*
* @param oldKeyBlob The old key blob to be replaced by {@code newKeyBlob}.
- *
* @param newKeyblob The new blob to replace {@code oldKeyBlob}.
+ * @param callback Receives the result of the call. A callback must only
+ * be used with one {@code storeUpgradedKeyAsync} call at a time.
*/
- void storeUpgradedKey(in byte[] oldKeyBlob, in byte[] newKeyBlob);
+ void storeUpgradedKeyAsync(
+ in byte[] oldKeyBlob, in byte[] newKeyBlob, IStoreUpgradedKeyCallback callback);
}
diff --git a/core/java/android/security/rkp/IStoreUpgradedKeyCallback.aidl b/core/java/android/security/rkp/IStoreUpgradedKeyCallback.aidl
new file mode 100644
index 0000000..7f72fa0
--- /dev/null
+++ b/core/java/android/security/rkp/IStoreUpgradedKeyCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 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 android.security.rkp;
+
+/**
+ * Callback interface for storing an upgraded remotely provisioned key blob.
+ * {@link IRegistration}.
+ *
+ * @hide
+ */
+oneway interface IStoreUpgradedKeyCallback {
+ /**
+ * Called in response to {@link IRegistration.storeUpgradedKeyAsync}, indicating
+ * a remotely-provisioned key is available.
+ */
+ void onSuccess();
+
+ /**
+ * Called when an error has occurred while trying to store an upgraded
+ * remotely provisioned key.
+ *
+ * @param error A description of what failed, suitable for logging.
+ */
+ void onError(String error);
+}
diff --git a/core/java/android/service/quickaccesswallet/OWNERS b/core/java/android/service/quickaccesswallet/OWNERS
new file mode 100644
index 0000000..232ee02
--- /dev/null
+++ b/core/java/android/service/quickaccesswallet/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 802986
+asc@google.com
+juliacr@google.com
+steell@google.com
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 23e1505..62211c4 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -1502,7 +1502,7 @@
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 0b0bfb1..26b0214 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -463,7 +463,7 @@
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 a821606..2de3dfd 100644
--- a/core/java/android/window/TaskFragmentTransaction.java
+++ b/core/java/android/window/TaskFragmentTransaction.java
@@ -126,7 +126,7 @@
/** 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 970728f..69660ae 100644
--- a/core/java/com/android/internal/app/OWNERS
+++ b/core/java/com/android/internal/app/OWNERS
@@ -3,6 +3,7 @@
per-file *Chooser* = file:/packages/SystemUI/OWNERS
per-file SimpleIconFactory.java = file:/packages/SystemUI/OWNERS
per-file AbstractMultiProfilePagerAdapter.java = file:/packages/SystemUI/OWNERS
+per-file *EmptyStateProvider.java = file:/packages/SystemUI/OWNERS
per-file NetInitiatedActivity.java = file:/location/java/android/location/OWNERS
per-file *BatteryStats* = file:/BATTERY_STATS_OWNERS
@@ -10,6 +11,7 @@
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/expresslog/Counter.java b/core/java/com/android/internal/expresslog/Counter.java
index 7571073..cc37c69 100644
--- a/core/java/com/android/internal/expresslog/Counter.java
+++ b/core/java/com/android/internal/expresslog/Counter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,9 +39,7 @@
* @hide
*/
public static void logIncrement(@NonNull String metricId, long amount) {
- final long metricIdHash = hashString(metricId);
+ final long metricIdHash = Utils.hashString(metricId);
FrameworkStatsLog.write(FrameworkStatsLog.EXPRESS_EVENT_REPORTED, metricIdHash, amount);
}
-
- private static native long hashString(String stringToHash);
}
diff --git a/core/java/com/android/internal/expresslog/Utils.java b/core/java/com/android/internal/expresslog/Utils.java
new file mode 100644
index 0000000..d82192f
--- /dev/null
+++ b/core/java/com/android/internal/expresslog/Utils.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.expresslog;
+
+final class Utils {
+ static native long hashString(String stringToHash);
+}
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index deafd19..05cad77 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -178,7 +178,14 @@
* 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 @@
? 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 fe8a59e..bfcd65d 100644
--- a/core/java/com/android/internal/util/TraceBuffer.java
+++ b/core/java/com/android/internal/util/TraceBuffer.java
@@ -193,7 +193,7 @@
}
/**
- * 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/ConversationLayout.java b/core/java/com/android/internal/widget/ConversationLayout.java
index 5f8acff..3fb2318 100644
--- a/core/java/com/android/internal/widget/ConversationLayout.java
+++ b/core/java/com/android/internal/widget/ConversationLayout.java
@@ -927,7 +927,8 @@
message = messages.get(i - histSize);
}
boolean isNewGroup = currentGroup == null;
- Person sender = message.getMessage().getSenderPerson();
+ Person sender =
+ message.getMessage() == null ? null : message.getMessage().getSenderPerson();
CharSequence key = getKey(sender);
isNewGroup |= !TextUtils.equals(key, currentSenderKey);
if (isNewGroup) {
@@ -1190,7 +1191,8 @@
return null;
}
final MessagingMessage messagingMessage = mMessages.get(mMessages.size() - 1);
- final CharSequence text = messagingMessage.getMessage().getText();
+ final CharSequence text = messagingMessage.getMessage() == null ? null
+ : messagingMessage.getMessage().getText();
if (text == null && messagingMessage instanceof MessagingImageMessage) {
final String unformatted =
getResources().getString(R.string.conversation_single_line_image_placeholder);
diff --git a/core/java/com/android/internal/widget/MessagingGroup.java b/core/java/com/android/internal/widget/MessagingGroup.java
index 146cb3f..30e4099 100644
--- a/core/java/com/android/internal/widget/MessagingGroup.java
+++ b/core/java/com/android/internal/widget/MessagingGroup.java
@@ -492,7 +492,9 @@
int color = mSendingSpinnerContainer.getVisibility() == View.VISIBLE
? mSendingTextColor : mTextColor;
for (MessagingMessage message : mMessages) {
- message.setColor(message.getMessage().isRemoteInputHistory() ? color : mTextColor);
+ final boolean isRemoteInputHistory =
+ message.getMessage() != null && message.getMessage().isRemoteInputHistory();
+ message.setColor(isRemoteInputHistory ? color : mTextColor);
}
}
}
diff --git a/core/java/com/android/internal/widget/MessagingLayout.java b/core/java/com/android/internal/widget/MessagingLayout.java
index 9ac6ef7..a270b28 100644
--- a/core/java/com/android/internal/widget/MessagingLayout.java
+++ b/core/java/com/android/internal/widget/MessagingLayout.java
@@ -470,7 +470,8 @@
message = messages.get(i - histSize);
}
boolean isNewGroup = currentGroup == null;
- Person sender = message.getMessage().getSenderPerson();
+ Person sender =
+ message.getMessage() == null ? null : message.getMessage().getSenderPerson();
CharSequence key = sender == null ? null
: sender.getKey() == null ? sender.getName() : sender.getKey();
isNewGroup |= !TextUtils.equals(key, currentSenderKey);
diff --git a/core/java/com/android/internal/widget/MessagingMessage.java b/core/java/com/android/internal/widget/MessagingMessage.java
index 2cc0d23..5ecd3b8 100644
--- a/core/java/com/android/internal/widget/MessagingMessage.java
+++ b/core/java/com/android/internal/widget/MessagingMessage.java
@@ -68,6 +68,10 @@
default boolean sameAs(Notification.MessagingStyle.Message message) {
Notification.MessagingStyle.Message ownMessage = getMessage();
+ // We have to make sure both messages are not null to go further comparison
+ if (message == null || ownMessage == null) {
+ return message == ownMessage;
+ }
if (!Objects.equals(message.getText(), ownMessage.getText())) {
return false;
}
diff --git a/core/java/com/android/internal/widget/RecyclerView.java b/core/java/com/android/internal/widget/RecyclerView.java
index e27557a..4a74d5f 100644
--- a/core/java/com/android/internal/widget/RecyclerView.java
+++ b/core/java/com/android/internal/widget/RecyclerView.java
@@ -10087,7 +10087,7 @@
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/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index 00b0105..088c001 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -1521,6 +1521,8 @@
addFeature(PackageManager.FEATURE_IPSEC_TUNNELS, 0);
}
+ enableIpSecTunnelMigrationOnVsrUAndAbove();
+
if (isErofsSupported()) {
if (isKernelVersionAtLeast(5, 10)) {
addFeature(PackageManager.FEATURE_EROFS, 0);
@@ -1534,6 +1536,18 @@
}
}
+ // This method only enables a new Android feature added in U and will not have impact on app
+ // compatibility
+ @SuppressWarnings("AndroidFrameworkCompatChange")
+ private void enableIpSecTunnelMigrationOnVsrUAndAbove() {
+ final int vsrApi =
+ SystemProperties.getInt(
+ "ro.vendor.api_level", Build.VERSION.DEVICE_INITIAL_SDK_INT);
+ if (vsrApi > Build.VERSION_CODES.TIRAMISU) {
+ addFeature(PackageManager.FEATURE_IPSEC_TUNNEL_MIGRATION, 0);
+ }
+ }
+
private void addFeature(String name, int version) {
FeatureInfo fi = mAvailableFeatures.get(name);
if (fi == null) {
diff --git a/core/java/com/android/server/backup/OWNERS b/core/java/com/android/server/backup/OWNERS
new file mode 100644
index 0000000..d99779e
--- /dev/null
+++ b/core/java/com/android/server/backup/OWNERS
@@ -0,0 +1 @@
+include /services/backup/OWNERS
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 681f194..b5b7c0f 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -40,6 +40,12 @@
cppflags: ["-Wno-conversion-null"],
+ product_variables: {
+ eng: {
+ cflags: ["-DNO_RESET_STACK_PROTECTOR"],
+ },
+ },
+
cpp_std: "gnu++20",
srcs: [
@@ -215,7 +221,7 @@
"android_content_res_Configuration.cpp",
"android_security_Scrypt.cpp",
"com_android_internal_content_om_OverlayConfig.cpp",
- "com_android_internal_expresslog_Counter.cpp",
+ "com_android_internal_expresslog_Utils.cpp",
"com_android_internal_net_NetworkUtilsInternal.cpp",
"com_android_internal_os_ClassLoaderFactory.cpp",
"com_android_internal_os_FuseAppLoop.cpp",
@@ -260,7 +266,6 @@
"av-types-aidl-cpp",
"android.hardware.camera.device@3.2",
"libandroid_net",
- "libandroidicu",
"libbattery",
"libnetdutils",
"libmemtrack",
@@ -280,6 +285,7 @@
"libpermission",
"libsensor",
"libinput",
+ "libicu",
"libcamera_client",
"libcamera_metadata",
"libprocinfo",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 7dd46a6..9c7f0a8 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -196,7 +196,7 @@
extern int register_com_android_internal_content_F2fsUtils(JNIEnv* env);
extern int register_com_android_internal_content_NativeLibraryHelper(JNIEnv *env);
extern int register_com_android_internal_content_om_OverlayConfig(JNIEnv *env);
-extern int register_com_android_internal_expresslog_Counter(JNIEnv* env);
+extern int register_com_android_internal_expresslog_Utils(JNIEnv* env);
extern int register_com_android_internal_net_NetworkUtilsInternal(JNIEnv* env);
extern int register_com_android_internal_os_ClassLoaderFactory(JNIEnv* env);
extern int register_com_android_internal_os_FuseAppLoop(JNIEnv* env);
@@ -1591,7 +1591,7 @@
REG_JNI(register_android_os_SharedMemory),
REG_JNI(register_android_os_incremental_IncrementalManager),
REG_JNI(register_com_android_internal_content_om_OverlayConfig),
- REG_JNI(register_com_android_internal_expresslog_Counter),
+ REG_JNI(register_com_android_internal_expresslog_Utils),
REG_JNI(register_com_android_internal_net_NetworkUtilsInternal),
REG_JNI(register_com_android_internal_os_ClassLoaderFactory),
REG_JNI(register_com_android_internal_os_LongArrayMultiStateCounter),
diff --git a/core/jni/OWNERS b/core/jni/OWNERS
index 53594e1..c99a27a 100644
--- a/core/jni/OWNERS
+++ b/core/jni/OWNERS
@@ -70,6 +70,7 @@
per-file android_graphics_* = file:/graphics/java/android/graphics/OWNERS
per-file *HardwareBuffer* = file:/graphics/java/android/graphics/OWNERS
per-file android_hardware_SyncFence.cpp = file:/graphics/java/android/graphics/OWNERS
+per-file android_hardware_OverlayProperties.cpp = file:/graphics/java/android/graphics/OWNERS
per-file android_os_GraphicsEnvironment.cpp = file:platform/frameworks/native:/opengl/OWNERS
### Text ###
diff --git a/core/jni/android/opengl/util.cpp b/core/jni/android/opengl/util.cpp
index d852265..1c6c95f 100644
--- a/core/jni/android/opengl/util.cpp
+++ b/core/jni/android/opengl/util.cpp
@@ -541,87 +541,6 @@
indices.mData, indexCount);
}
-#define I(_i, _j) ((_j)+ 4*(_i))
-
-static
-void multiplyMM(float* r, const float* lhs, const float* rhs)
-{
- for (int i=0 ; i<4 ; i++) {
- const float rhs_i0 = rhs[ I(i,0) ];
- float ri0 = lhs[ I(0,0) ] * rhs_i0;
- float ri1 = lhs[ I(0,1) ] * rhs_i0;
- float ri2 = lhs[ I(0,2) ] * rhs_i0;
- float ri3 = lhs[ I(0,3) ] * rhs_i0;
- for (int j=1 ; j<4 ; j++) {
- const float rhs_ij = rhs[ I(i,j) ];
- ri0 += lhs[ I(j,0) ] * rhs_ij;
- ri1 += lhs[ I(j,1) ] * rhs_ij;
- ri2 += lhs[ I(j,2) ] * rhs_ij;
- ri3 += lhs[ I(j,3) ] * rhs_ij;
- }
- r[ I(i,0) ] = ri0;
- r[ I(i,1) ] = ri1;
- r[ I(i,2) ] = ri2;
- r[ I(i,3) ] = ri3;
- }
-}
-
-static
-void util_multiplyMM(JNIEnv *env, jclass clazz,
- jfloatArray result_ref, jint resultOffset,
- jfloatArray lhs_ref, jint lhsOffset,
- jfloatArray rhs_ref, jint rhsOffset) {
-
- FloatArrayHelper resultMat(env, result_ref, resultOffset, 16);
- FloatArrayHelper lhs(env, lhs_ref, lhsOffset, 16);
- FloatArrayHelper rhs(env, rhs_ref, rhsOffset, 16);
-
- bool checkOK = resultMat.check() && lhs.check() && rhs.check();
-
- if ( !checkOK ) {
- return;
- }
-
- resultMat.bind();
- lhs.bind();
- rhs.bind();
-
- multiplyMM(resultMat.mData, lhs.mData, rhs.mData);
-
- resultMat.commitChanges();
-}
-
-static
-void multiplyMV(float* r, const float* lhs, const float* rhs)
-{
- mx4transform(rhs[0], rhs[1], rhs[2], rhs[3], lhs, r);
-}
-
-static
-void util_multiplyMV(JNIEnv *env, jclass clazz,
- jfloatArray result_ref, jint resultOffset,
- jfloatArray lhs_ref, jint lhsOffset,
- jfloatArray rhs_ref, jint rhsOffset) {
-
- FloatArrayHelper resultV(env, result_ref, resultOffset, 4);
- FloatArrayHelper lhs(env, lhs_ref, lhsOffset, 16);
- FloatArrayHelper rhs(env, rhs_ref, rhsOffset, 4);
-
- bool checkOK = resultV.check() && lhs.check() && rhs.check();
-
- if ( !checkOK ) {
- return;
- }
-
- resultV.bind();
- lhs.bind();
- rhs.bind();
-
- multiplyMV(resultV.mData, lhs.mData, rhs.mData);
-
- resultV.commitChanges();
-}
-
// ---------------------------------------------------------------------------
// The internal format is no longer the same as pixel format, per Table 2 in
@@ -1009,11 +928,6 @@
* JNI registration
*/
-static const JNINativeMethod gMatrixMethods[] = {
- { "multiplyMM", "([FI[FI[FI)V", (void*)util_multiplyMM },
- { "multiplyMV", "([FI[FI[FI)V", (void*)util_multiplyMV },
-};
-
static const JNINativeMethod gVisibilityMethods[] = {
{ "computeBoundingSphere", "([FII[FI)V", (void*)util_computeBoundingSphere },
{ "frustumCullSpheres", "([FI[FII[III)I", (void*)util_frustumCullSpheres },
@@ -1046,7 +960,6 @@
} ClassRegistrationInfo;
static const ClassRegistrationInfo gClasses[] = {
- {"android/opengl/Matrix", gMatrixMethods, NELEM(gMatrixMethods)},
{"android/opengl/Visibility", gVisibilityMethods, NELEM(gVisibilityMethods)},
{"android/opengl/GLUtils", gUtilsMethods, NELEM(gUtilsMethods)},
{"android/opengl/ETC1", gEtc1Methods, NELEM(gEtc1Methods)},
diff --git a/core/jni/com_android_internal_expresslog_Counter.cpp b/core/jni/com_android_internal_expresslog_Utils.cpp
similarity index 83%
rename from core/jni/com_android_internal_expresslog_Counter.cpp
rename to core/jni/com_android_internal_expresslog_Utils.cpp
index d4a8c23..d33a7bd 100644
--- a/core/jni/com_android_internal_expresslog_Counter.cpp
+++ b/core/jni/com_android_internal_expresslog_Utils.cpp
@@ -26,7 +26,7 @@
static jclass g_stringClass = nullptr;
/**
- * Class: com_android_internal_expresslog_Counter
+ * Class: com_android_internal_expresslog_Utils
* Method: hashString
* Signature: (Ljava/lang/String;)J
*/
@@ -43,15 +43,15 @@
{"hashString", "(Ljava/lang/String;)J", (void*)hashString},
};
-static const char* const kCounterPathName = "com/android/internal/expresslog/Counter";
+static const char* const kUtilsPathName = "com/android/internal/expresslog/Utils";
namespace android {
-int register_com_android_internal_expresslog_Counter(JNIEnv* env) {
+int register_com_android_internal_expresslog_Utils(JNIEnv* env) {
jclass stringClass = FindClassOrDie(env, "java/lang/String");
g_stringClass = MakeGlobalRefOrDie(env, stringClass);
- return RegisterMethodsOrDie(env, kCounterPathName, g_methods, NELEM(g_methods));
+ return RegisterMethodsOrDie(env, kUtilsPathName, g_methods, NELEM(g_methods));
}
} // namespace android
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index d3a3492..963a83e 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -353,6 +353,7 @@
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 @@
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 @@
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/core/res/OWNERS b/core/res/OWNERS
index b878189..bce500c 100644
--- a/core/res/OWNERS
+++ b/core/res/OWNERS
@@ -23,8 +23,8 @@
# WindowManager team
# TODO(262451702): Move WindowManager configs out of config.xml in a separate file
-per-file core/res/res/values/config.xml = file:/services/core/java/com/android/server/wm/OWNERS
-per-file core/res/res/values/symbols.xml = file:/services/core/java/com/android/server/wm/OWNERS
+per-file res/values/config.xml = file:/services/core/java/com/android/server/wm/OWNERS
+per-file res/values/symbols.xml = file:/services/core/java/com/android/server/wm/OWNERS
# Resources finalization
per-file res/xml/public-staging.xml = file:/tools/aapt2/OWNERS
diff --git a/keystore/java/android/security/KeyStoreException.java b/keystore/java/android/security/KeyStoreException.java
index 6536e43..cb75779 100644
--- a/keystore/java/android/security/KeyStoreException.java
+++ b/keystore/java/android/security/KeyStoreException.java
@@ -265,7 +265,7 @@
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 @@
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 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 @@
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 @@
@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 @@
? 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 @@
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 2830d7eff..4715045 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -801,25 +801,32 @@
));
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/Android.bp b/libs/hwui/Android.bp
index 2800e31..404d00a 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -214,6 +214,15 @@
path: "apex/java",
}
+java_api_contribution {
+ name: "framework-graphics-public-stubs",
+ api_surface: "public",
+ api_file: "api/current.txt",
+ visibility: [
+ "//build/orchestrator/apis",
+ ],
+}
+
// ------------------------
// APEX
// ------------------------
diff --git a/libs/hwui/jni/Paint.cpp b/libs/hwui/jni/Paint.cpp
index f768632..293e280 100644
--- a/libs/hwui/jni/Paint.cpp
+++ b/libs/hwui/jni/Paint.cpp
@@ -35,7 +35,6 @@
#include "SkShader.h"
#include "SkBlendMode.h"
#include "unicode/uloc.h"
-#include "unicode/ushape.h"
#include "utils/Blur.h"
#include <hwui/BlurDrawLooper.h>
diff --git a/media/aidl/android/media/soundtrigger_middleware/OWNERS b/media/aidl/android/media/soundtrigger_middleware/OWNERS
index e5d0370..01b2cb9 100644
--- a/media/aidl/android/media/soundtrigger_middleware/OWNERS
+++ b/media/aidl/android/media/soundtrigger_middleware/OWNERS
@@ -1,2 +1,2 @@
-ytai@google.com
+atneya@google.com
elaurent@google.com
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index d51f1e1..f61c427 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -266,15 +266,19 @@
@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 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 4957300..993155f 100644
--- a/media/java/android/media/ImageUtils.java
+++ b/media/java/android/media/ImageUtils.java
@@ -84,6 +84,7 @@
public static int getNumPlanesForHardwareBufferFormat(int hardwareBufferFormat) {
switch(hardwareBufferFormat) {
case HardwareBuffer.YCBCR_420_888:
+ case HardwareBuffer.YCBCR_P010:
return 3;
case HardwareBuffer.RGBA_8888:
case HardwareBuffer.RGBX_8888:
diff --git a/media/java/android/media/soundtrigger/OWNERS b/media/java/android/media/soundtrigger/OWNERS
index e5d0370..01b2cb9 100644
--- a/media/java/android/media/soundtrigger/OWNERS
+++ b/media/java/android/media/soundtrigger/OWNERS
@@ -1,2 +1,2 @@
-ytai@google.com
+atneya@google.com
elaurent@google.com
diff --git a/media/java/android/media/tv/ITvInputManager.aidl b/media/java/android/media/tv/ITvInputManager.aidl
index 2a33ee6..1d2198e 100644
--- a/media/java/android/media/tv/ITvInputManager.aidl
+++ b/media/java/android/media/tv/ITvInputManager.aidl
@@ -16,6 +16,7 @@
package android.media.tv;
+import android.content.AttributionSource;
import android.content.ComponentName;
import android.content.Intent;
import android.graphics.Rect;
@@ -62,7 +63,7 @@
void addBlockedRating(in String rating, int userId);
void removeBlockedRating(in String rating, int userId);
- void createSession(in ITvInputClient client, in String inputId, boolean isRecordingSession,
+ void createSession(in ITvInputClient client, in String inputId, in AttributionSource tvAppAttributionSource, boolean isRecordingSession,
int seq, int userId);
void releaseSession(in IBinder sessionToken, int userId);
int getClientPid(in String sessionId);
diff --git a/media/java/android/media/tv/ITvInputService.aidl b/media/java/android/media/tv/ITvInputService.aidl
index 64a23a2..be73c0c 100755
--- a/media/java/android/media/tv/ITvInputService.aidl
+++ b/media/java/android/media/tv/ITvInputService.aidl
@@ -16,6 +16,7 @@
package android.media.tv;
+import android.content.AttributionSource;
import android.hardware.hdmi.HdmiDeviceInfo;
import android.media.tv.ITvInputServiceCallback;
import android.media.tv.ITvInputSessionCallback;
@@ -30,7 +31,7 @@
oneway void registerCallback(in ITvInputServiceCallback callback);
oneway void unregisterCallback(in ITvInputServiceCallback callback);
oneway void createSession(in InputChannel channel, in ITvInputSessionCallback callback,
- in String inputId, in String sessionId);
+ in String inputId, in String sessionId, in AttributionSource tvAppAttributionSource);
oneway void createRecordingSession(in ITvInputSessionCallback callback, in String inputId,
in String sessionId);
List<String> getAvailableExtensionInterfaceNames();
diff --git a/media/java/android/media/tv/ITvInputSessionWrapper.java b/media/java/android/media/tv/ITvInputSessionWrapper.java
index 8911f6c..6c10990 100644
--- a/media/java/android/media/tv/ITvInputSessionWrapper.java
+++ b/media/java/android/media/tv/ITvInputSessionWrapper.java
@@ -30,7 +30,6 @@
import android.view.InputEvent;
import android.view.InputEventReceiver;
import android.view.Surface;
-
import com.android.internal.os.HandlerCaller;
import com.android.internal.os.SomeArgs;
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index 149c2f4..819cd0c 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -25,6 +25,7 @@
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
+import android.content.AttributionSource;
import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
@@ -53,9 +54,7 @@
import android.view.KeyEvent;
import android.view.Surface;
import android.view.View;
-
import com.android.internal.util.Preconditions;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -1835,13 +1834,15 @@
* of the given TV input.
*
* @param inputId The ID of the TV input.
+ * @param tvAppAttributionSource The Attribution Source of the TV App.
* @param callback A callback used to receive the created session.
* @param handler A {@link Handler} that the session creation will be delivered to.
* @hide
*/
- public void createSession(@NonNull String inputId, @NonNull final SessionCallback callback,
- @NonNull Handler handler) {
- createSessionInternal(inputId, false, callback, handler);
+ public void createSession(@NonNull String inputId,
+ @NonNull AttributionSource tvAppAttributionSource,
+ @NonNull final SessionCallback callback, @NonNull Handler handler) {
+ createSessionInternal(inputId, tvAppAttributionSource, false, callback, handler);
}
/**
@@ -1866,7 +1867,7 @@
* @param useCase the use case type of the client.
* {@see TvInputService#PriorityHintUseCaseType}.
* @param sessionId the unique id of the session owned by the client.
- * {@see TvInputService#onCreateSession(String, String)}.
+ * {@see TvInputService#onCreateSession(String, String, AttributionSource)}.
*
* @return the use case priority value for the given use case type and the client's foreground
* or background status.
@@ -1917,11 +1918,11 @@
*/
public void createRecordingSession(@NonNull String inputId,
@NonNull final SessionCallback callback, @NonNull Handler handler) {
- createSessionInternal(inputId, true, callback, handler);
+ createSessionInternal(inputId, null, true, callback, handler);
}
- private void createSessionInternal(String inputId, boolean isRecordingSession,
- SessionCallback callback, Handler handler) {
+ private void createSessionInternal(String inputId, AttributionSource tvAppAttributionSource,
+ boolean isRecordingSession, SessionCallback callback, Handler handler) {
Preconditions.checkNotNull(inputId);
Preconditions.checkNotNull(callback);
Preconditions.checkNotNull(handler);
@@ -1930,7 +1931,8 @@
int seq = mNextSeq++;
mSessionCallbackRecordMap.put(seq, record);
try {
- mService.createSession(mClient, inputId, isRecordingSession, seq, mUserId);
+ mService.createSession(
+ mClient, inputId, tvAppAttributionSource, isRecordingSession, seq, mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2101,8 +2103,8 @@
* @param deviceId The device ID to acquire Hardware for.
* @param info The TV input which will use the acquired Hardware.
* @param tvInputSessionId a String returned to TIS when the session was created.
- * {@see TvInputService#onCreateSession(String, String)}. If null, the client will be
- * treated as a background app.
+ * {@see TvInputService#onCreateSession(String, String, AttributionSource)}. If null, the
+ * client will be treated as a background app.
* @param priorityHint The use case of the client. {@see TvInputService#PriorityHintUseCaseType}
* @param executor the executor on which the listener would be invoked.
* @param callback A callback to receive updates on Hardware.
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index 70acf25..f3e5d14 100755
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -26,6 +26,7 @@
import android.app.ActivityManager;
import android.app.Service;
import android.compat.annotation.UnsupportedAppUsage;
+import android.content.AttributionSource;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
@@ -57,10 +58,8 @@
import android.view.WindowManager;
import android.view.accessibility.CaptioningManager;
import android.widget.FrameLayout;
-
import com.android.internal.os.SomeArgs;
import com.android.internal.util.Preconditions;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -171,7 +170,7 @@
@Override
public void createSession(InputChannel channel, ITvInputSessionCallback cb,
- String inputId, String sessionId) {
+ String inputId, String sessionId, AttributionSource tvAppAttributionSource) {
if (channel == null) {
Log.w(TAG, "Creating session without input channel");
}
@@ -183,6 +182,7 @@
args.arg2 = cb;
args.arg3 = inputId;
args.arg4 = sessionId;
+ args.arg5 = tvAppAttributionSource;
mServiceHandler.obtainMessage(ServiceHandler.DO_CREATE_SESSION,
args).sendToTarget();
}
@@ -370,6 +370,24 @@
}
/**
+ * Returns a concrete implementation of {@link Session}.
+ *
+ * <p>For any apps that needs sessionId to request tuner resources from TunerResourceManager and
+ * needs to specify custom AttributionSource to AudioTrack, it needs to override this method to
+ * get the sessionId and AttrubutionSource passed. When no overriding, this method calls {@link
+ * #onCreateSession(String, String)} defaultly.
+ *
+ * @param inputId The ID of the TV input associated with the session.
+ * @param sessionId the unique sessionId created by TIF when session is created.
+ * @param tvAppAttributionSource The Attribution Source of the TV App.
+ */
+ @Nullable
+ public Session onCreateSession(@NonNull String inputId, @NonNull String sessionId,
+ @NonNull AttributionSource tvAppAttributionSource) {
+ return onCreateSession(inputId, sessionId);
+ }
+
+ /**
* Returns a concrete implementation of {@link RecordingSession}.
*
* <p>For any apps that needs sessionId to request tuner resources from TunerResourceManager,
@@ -1107,7 +1125,7 @@
public abstract void onSetStreamVolume(@FloatRange(from = 0.0, to = 1.0) float volume);
/**
- * called when broadcast info is requested.
+ * Called when broadcast info is requested.
*
* @param request broadcast info request
*/
@@ -1115,7 +1133,7 @@
}
/**
- * called when broadcast info is removed.
+ * Called when broadcast info is removed.
*/
public void onRemoveBroadcastInfo(int requestId) {
}
@@ -2444,8 +2462,10 @@
ITvInputSessionCallback cb = (ITvInputSessionCallback) args.arg2;
String inputId = (String) args.arg3;
String sessionId = (String) args.arg4;
+ AttributionSource tvAppAttributionSource = (AttributionSource) args.arg5;
args.recycle();
- Session sessionImpl = onCreateSession(inputId, sessionId);
+ Session sessionImpl =
+ onCreateSession(inputId, sessionId, tvAppAttributionSource);
if (sessionImpl == null) {
try {
// Failed to create a session.
@@ -2481,7 +2501,7 @@
proxySession.mServiceHandler = mServiceHandler;
TvInputManager manager = (TvInputManager) getSystemService(
Context.TV_INPUT_SERVICE);
- manager.createSession(hardwareInputId,
+ manager.createSession(hardwareInputId, tvAppAttributionSource,
proxySession.mHardwareSessionCallback, mServiceHandler);
} else {
SomeArgs someArgs = SomeArgs.obtain();
diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java
index ff3d06c..de9acc3 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -21,6 +21,7 @@
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
+import android.content.AttributionSource;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Resources;
@@ -51,7 +52,6 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewRootImpl;
-
import java.lang.ref.WeakReference;
import java.util.ArrayDeque;
import java.util.List;
@@ -111,6 +111,7 @@
private int mSurfaceViewTop;
private int mSurfaceViewBottom;
private TimeShiftPositionCallback mTimeShiftPositionCallback;
+ private AttributionSource mTvAppAttributionSource;
private final SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback() {
@Override
@@ -185,6 +186,7 @@
mDefStyleAttr = defStyleAttr;
resetSurfaceView();
mTvInputManager = (TvInputManager) getContext().getSystemService(Context.TV_INPUT_SERVICE);
+ mTvAppAttributionSource = getContext().getAttributionSource();
}
/**
@@ -304,6 +306,22 @@
}
/**
+ * Override default attribution source of TV App.
+ *
+ * <p>An attribution source of TV App is used to attribute work to TV Input Service.
+ * The default attribution source is created by {@link Context#getAttributionSource()}.
+ * Call this method before calling {@link #tune(String, Uri, Bundle)} or {@link
+ * #timeShiftPlay(String, Uri)} to override the default attribution source.
+ *
+ * @param tvAppAttributionSource The attribution source of the TV App.
+ */
+ public void overrideTvAppAttributionSource(@NonNull AttributionSource tvAppAttributionSource) {
+ if (tvAppAttributionSource != null) {
+ mTvAppAttributionSource = tvAppAttributionSource;
+ }
+ }
+
+ /**
* Tunes to a given channel.
*
* @param inputId The ID of the TV input for the given channel.
@@ -355,7 +373,8 @@
// is obsolete and should ignore it.
mSessionCallback = new MySessionCallback(inputId, channelUri, params);
if (mTvInputManager != null) {
- mTvInputManager.createSession(inputId, mSessionCallback, mHandler);
+ mTvInputManager.createSession(
+ inputId, mTvAppAttributionSource, mSessionCallback, mHandler);
}
}
}
@@ -526,7 +545,8 @@
resetInternal();
mSessionCallback = new MySessionCallback(inputId, recordedProgramUri);
if (mTvInputManager != null) {
- mTvInputManager.createSession(inputId, mSessionCallback, mHandler);
+ mTvInputManager.createSession(
+ inputId, mTvAppAttributionSource, mSessionCallback, mHandler);
}
}
}
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index d8705a7..5b0c2a2 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -2432,13 +2432,12 @@
throwExceptionAsNecessary(env, BAD_VALUE);
return;
}
- NativeCryptoInfo cryptoInfo = [env, cryptoInfoObj, size]{
- if (cryptoInfoObj == nullptr) {
- return NativeCryptoInfo{size};
- } else {
- return NativeCryptoInfo{env, cryptoInfoObj};
- }
- }();
+ auto cryptoInfo =
+ cryptoInfoObj ? NativeCryptoInfo{size} : NativeCryptoInfo{env, cryptoInfoObj};
+ if (env->ExceptionCheck()) {
+ // Creation of cryptoInfo failed. Let the exception bubble up.
+ return;
+ }
err = codec->queueEncryptedLinearBlock(
index,
memory,
diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp
index 681d76a..b70818d 100644
--- a/media/jni/android_media_MediaDrm.cpp
+++ b/media/jni/android_media_MediaDrm.cpp
@@ -1021,9 +1021,10 @@
static jbyteArray android_media_MediaDrm_getSupportedCryptoSchemesNative(JNIEnv *env) {
sp<IDrm> drm = android::DrmUtils::MakeDrm();
+ if (drm == NULL) return env->NewByteArray(0);
+
std::vector<uint8_t> bv;
drm->getSupportedSchemes(bv);
-
jbyteArray jUuidBytes = env->NewByteArray(bv.size());
env->SetByteArrayRegion(jUuidBytes, 0, bv.size(), reinterpret_cast<const jbyte *>(bv.data()));
return jUuidBytes;
diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt
index 4aa5bbf..a386923 100644
--- a/native/android/libandroid.map.txt
+++ b/native/android/libandroid.map.txt
@@ -1,9 +1,9 @@
LIBANDROID {
global:
- AActivityManager_addUidImportanceListener; # apex # introduced=31
- AActivityManager_removeUidImportanceListener; # apex # introduced=31
- AActivityManager_isUidActive; # apex # introduced=31
- AActivityManager_getUidImportance; # apex # introduced=31
+ AActivityManager_addUidImportanceListener; # systemapi # introduced=31
+ AActivityManager_removeUidImportanceListener; # systemapi # introduced=31
+ AActivityManager_isUidActive; # systemapi # introduced=31
+ AActivityManager_getUidImportance; # systemapi # introduced=31
AAssetDir_close;
AAssetDir_getNextFileName;
AAssetDir_rewind;
diff --git a/omapi/OWNERS b/omapi/OWNERS
index 5682fd3..1dce1e0 100644
--- a/omapi/OWNERS
+++ b/omapi/OWNERS
@@ -1,5 +1,6 @@
# Bug component: 456592
-zachoverflow@google.com
+sattiraju@google.com
+henrichataing@google.com
alisher@google.com
jackcwyu@google.com
diff --git a/omapi/java/android/se/OWNERS b/omapi/java/android/se/OWNERS
index 5682fd3..1dce1e0 100644
--- a/omapi/java/android/se/OWNERS
+++ b/omapi/java/android/se/OWNERS
@@ -1,5 +1,6 @@
# Bug component: 456592
-zachoverflow@google.com
+sattiraju@google.com
+henrichataing@google.com
alisher@google.com
jackcwyu@google.com
diff --git a/omapi/java/android/se/omapi/OWNERS b/omapi/java/android/se/omapi/OWNERS
index 5682fd3..1dce1e0 100644
--- a/omapi/java/android/se/omapi/OWNERS
+++ b/omapi/java/android/se/omapi/OWNERS
@@ -1,5 +1,6 @@
# Bug component: 456592
-zachoverflow@google.com
+sattiraju@google.com
+henrichataing@google.com
alisher@google.com
jackcwyu@google.com
diff --git a/opengl/java/android/opengl/Matrix.java b/opengl/java/android/opengl/Matrix.java
index ce3f57e..5ae341b 100644
--- a/opengl/java/android/opengl/Matrix.java
+++ b/opengl/java/android/opengl/Matrix.java
@@ -16,6 +16,8 @@
package android.opengl;
+import androidx.annotation.NonNull;
+
/**
* Matrix math utilities. These methods operate on OpenGL ES format
* matrices and vectors stored in float arrays.
@@ -38,7 +40,11 @@
public class Matrix {
/** Temporary memory for operations that need temporary matrix data. */
- private final static float[] sTemp = new float[32];
+ private static final ThreadLocal<float[]> ThreadTmp = new ThreadLocal() {
+ @Override protected float[] initialValue() {
+ return new float[32];
+ }
+ };
/**
* @deprecated All methods are static, do not instantiate this class.
@@ -46,6 +52,40 @@
@Deprecated
public Matrix() {}
+ private static boolean overlap(
+ float[] a, int aStart, int aLength, float[] b, int bStart, int bLength) {
+ if (a != b) {
+ return false;
+ }
+
+ if (aStart == bStart) {
+ return true;
+ }
+
+ int aEnd = aStart + aLength;
+ int bEnd = bStart + bLength;
+
+ if (aEnd == bEnd) {
+ return true;
+ }
+
+ if (aStart < bStart && bStart < aEnd) {
+ return true;
+ }
+ if (aStart < bEnd && bEnd < aEnd) {
+ return true;
+ }
+
+ if (bStart < aStart && aStart < bEnd) {
+ return true;
+ }
+ if (bStart < aEnd && aEnd < bEnd) {
+ return true;
+ }
+
+ return false;
+ }
+
/**
* Multiplies two 4x4 matrices together and stores the result in a third 4x4
* matrix. In matrix notation: result = lhs x rhs. Due to the way
@@ -53,9 +93,9 @@
* effect as first multiplying by the rhs matrix, then multiplying by
* the lhs matrix. This is the opposite of what you might expect.
* <p>
- * The same float array may be passed for result, lhs, and/or rhs. However,
- * the result element values are undefined if the result elements overlap
- * either the lhs or rhs elements.
+ * The same float array may be passed for result, lhs, and/or rhs. This
+ * operation is expected to do the correct thing if the result elements
+ * overlap with either of the lhs or rhs elements.
*
* @param result The float array that holds the result.
* @param resultOffset The offset into the result array where the result is
@@ -65,20 +105,101 @@
* @param rhs The float array that holds the right-hand-side matrix.
* @param rhsOffset The offset into the rhs array where the rhs is stored.
*
- * @throws IllegalArgumentException if result, lhs, or rhs are null, or if
- * resultOffset + 16 > result.length or lhsOffset + 16 > lhs.length or
- * rhsOffset + 16 > rhs.length.
+ * @throws IllegalArgumentException under any of the following conditions:
+ * result, lhs, or rhs are null;
+ * resultOffset + 16 > result.length
+ * or lhsOffset + 16 > lhs.length
+ * or rhsOffset + 16 > rhs.length;
+ * resultOffset < 0 or lhsOffset < 0 or rhsOffset < 0
*/
- public static native void multiplyMM(float[] result, int resultOffset,
- float[] lhs, int lhsOffset, float[] rhs, int rhsOffset);
+ public static void multiplyMM(float[] result, int resultOffset,
+ float[] lhs, int lhsOffset, float[] rhs, int rhsOffset) {
+ // error checking
+ if (result == null) {
+ throw new IllegalArgumentException("result == null");
+ }
+ if (lhs == null) {
+ throw new IllegalArgumentException("lhs == null");
+ }
+ if (rhs == null) {
+ throw new IllegalArgumentException("rhs == null");
+ }
+ if (resultOffset < 0) {
+ throw new IllegalArgumentException("resultOffset < 0");
+ }
+ if (lhsOffset < 0) {
+ throw new IllegalArgumentException("lhsOffset < 0");
+ }
+ if (rhsOffset < 0) {
+ throw new IllegalArgumentException("rhsOffset < 0");
+ }
+ if (result.length < resultOffset + 16) {
+ throw new IllegalArgumentException("result.length < resultOffset + 16");
+ }
+ if (lhs.length < lhsOffset + 16) {
+ throw new IllegalArgumentException("lhs.length < lhsOffset + 16");
+ }
+ if (rhs.length < rhsOffset + 16) {
+ throw new IllegalArgumentException("rhs.length < rhsOffset + 16");
+ }
+
+ // Check for overlap between rhs and result or lhs and result
+ if ( overlap(result, resultOffset, 16, lhs, lhsOffset, 16)
+ || overlap(result, resultOffset, 16, rhs, rhsOffset, 16) ) {
+ float[] tmp = ThreadTmp.get();
+ for (int i=0; i<4; i++) {
+ final float rhs_i0 = rhs[ 4*i + 0 + rhsOffset ];
+ float ri0 = lhs[ 0 + lhsOffset ] * rhs_i0;
+ float ri1 = lhs[ 1 + lhsOffset ] * rhs_i0;
+ float ri2 = lhs[ 2 + lhsOffset ] * rhs_i0;
+ float ri3 = lhs[ 3 + lhsOffset ] * rhs_i0;
+ for (int j=1; j<4; j++) {
+ final float rhs_ij = rhs[ 4*i + j + rhsOffset];
+ ri0 += lhs[ 4*j + 0 + lhsOffset ] * rhs_ij;
+ ri1 += lhs[ 4*j + 1 + lhsOffset ] * rhs_ij;
+ ri2 += lhs[ 4*j + 2 + lhsOffset ] * rhs_ij;
+ ri3 += lhs[ 4*j + 3 + lhsOffset ] * rhs_ij;
+ }
+ tmp[ 4*i + 0 ] = ri0;
+ tmp[ 4*i + 1 ] = ri1;
+ tmp[ 4*i + 2 ] = ri2;
+ tmp[ 4*i + 3 ] = ri3;
+ }
+
+ // copy from tmp to result
+ for (int i=0; i < 16; i++) {
+ result[ i + resultOffset ] = tmp[ i ];
+ }
+
+ } else {
+ for (int i=0; i<4; i++) {
+ final float rhs_i0 = rhs[ 4*i + 0 + rhsOffset ];
+ float ri0 = lhs[ 0 + lhsOffset ] * rhs_i0;
+ float ri1 = lhs[ 1 + lhsOffset ] * rhs_i0;
+ float ri2 = lhs[ 2 + lhsOffset ] * rhs_i0;
+ float ri3 = lhs[ 3 + lhsOffset ] * rhs_i0;
+ for (int j=1; j<4; j++) {
+ final float rhs_ij = rhs[ 4*i + j + rhsOffset];
+ ri0 += lhs[ 4*j + 0 + lhsOffset ] * rhs_ij;
+ ri1 += lhs[ 4*j + 1 + lhsOffset ] * rhs_ij;
+ ri2 += lhs[ 4*j + 2 + lhsOffset ] * rhs_ij;
+ ri3 += lhs[ 4*j + 3 + lhsOffset ] * rhs_ij;
+ }
+ result[ 4*i + 0 + resultOffset ] = ri0;
+ result[ 4*i + 1 + resultOffset ] = ri1;
+ result[ 4*i + 2 + resultOffset ] = ri2;
+ result[ 4*i + 3 + resultOffset ] = ri3;
+ }
+ }
+ }
/**
* Multiplies a 4 element vector by a 4x4 matrix and stores the result in a
* 4-element column vector. In matrix notation: result = lhs x rhs
* <p>
* The same float array may be passed for resultVec, lhsMat, and/or rhsVec.
- * However, the resultVec element values are undefined if the resultVec
- * elements overlap either the lhsMat or rhsVec elements.
+ * This operation is expected to do the correct thing if the result elements
+ * overlap with either of the lhs or rhs elements.
*
* @param resultVec The float array that holds the result vector.
* @param resultVecOffset The offset into the result array where the result
@@ -89,14 +210,67 @@
* @param rhsVecOffset The offset into the rhs vector where the rhs vector
* is stored.
*
- * @throws IllegalArgumentException if resultVec, lhsMat,
- * or rhsVec are null, or if resultVecOffset + 4 > resultVec.length
- * or lhsMatOffset + 16 > lhsMat.length or
- * rhsVecOffset + 4 > rhsVec.length.
+ * @throws IllegalArgumentException under any of the following conditions:
+ * resultVec, lhsMat, or rhsVec are null;
+ * resultVecOffset + 4 > resultVec.length
+ * or lhsMatOffset + 16 > lhsMat.length
+ * or rhsVecOffset + 4 > rhsVec.length;
+ * resultVecOffset < 0 or lhsMatOffset < 0 or rhsVecOffset < 0
*/
- public static native void multiplyMV(float[] resultVec,
+ public static void multiplyMV(float[] resultVec,
int resultVecOffset, float[] lhsMat, int lhsMatOffset,
- float[] rhsVec, int rhsVecOffset);
+ float[] rhsVec, int rhsVecOffset) {
+ // error checking
+ if (resultVec == null) {
+ throw new IllegalArgumentException("resultVec == null");
+ }
+ if (lhsMat == null) {
+ throw new IllegalArgumentException("lhsMat == null");
+ }
+ if (rhsVec == null) {
+ throw new IllegalArgumentException("rhsVec == null");
+ }
+ if (resultVecOffset < 0) {
+ throw new IllegalArgumentException("resultVecOffset < 0");
+ }
+ if (lhsMatOffset < 0) {
+ throw new IllegalArgumentException("lhsMatOffset < 0");
+ }
+ if (rhsVecOffset < 0) {
+ throw new IllegalArgumentException("rhsVecOffset < 0");
+ }
+ if (resultVec.length < resultVecOffset + 4) {
+ throw new IllegalArgumentException("resultVec.length < resultVecOffset + 4");
+ }
+ if (lhsMat.length < lhsMatOffset + 16) {
+ throw new IllegalArgumentException("lhsMat.length < lhsMatOffset + 16");
+ }
+ if (rhsVec.length < rhsVecOffset + 4) {
+ throw new IllegalArgumentException("rhsVec.length < rhsVecOffset + 4");
+ }
+
+ float tmp0 = lhsMat[0 + 4 * 0 + lhsMatOffset] * rhsVec[0 + rhsVecOffset] +
+ lhsMat[0 + 4 * 1 + lhsMatOffset] * rhsVec[1 + rhsVecOffset] +
+ lhsMat[0 + 4 * 2 + lhsMatOffset] * rhsVec[2 + rhsVecOffset] +
+ lhsMat[0 + 4 * 3 + lhsMatOffset] * rhsVec[3 + rhsVecOffset];
+ float tmp1 = lhsMat[1 + 4 * 0 + lhsMatOffset] * rhsVec[0 + rhsVecOffset] +
+ lhsMat[1 + 4 * 1 + lhsMatOffset] * rhsVec[1 + rhsVecOffset] +
+ lhsMat[1 + 4 * 2 + lhsMatOffset] * rhsVec[2 + rhsVecOffset] +
+ lhsMat[1 + 4 * 3 + lhsMatOffset] * rhsVec[3 + rhsVecOffset];
+ float tmp2 = lhsMat[2 + 4 * 0 + lhsMatOffset] * rhsVec[0 + rhsVecOffset] +
+ lhsMat[2 + 4 * 1 + lhsMatOffset] * rhsVec[1 + rhsVecOffset] +
+ lhsMat[2 + 4 * 2 + lhsMatOffset] * rhsVec[2 + rhsVecOffset] +
+ lhsMat[2 + 4 * 3 + lhsMatOffset] * rhsVec[3 + rhsVecOffset];
+ float tmp3 = lhsMat[3 + 4 * 0 + lhsMatOffset] * rhsVec[0 + rhsVecOffset] +
+ lhsMat[3 + 4 * 1 + lhsMatOffset] * rhsVec[1 + rhsVecOffset] +
+ lhsMat[3 + 4 * 2 + lhsMatOffset] * rhsVec[2 + rhsVecOffset] +
+ lhsMat[3 + 4 * 3 + lhsMatOffset] * rhsVec[3 + rhsVecOffset];
+
+ resultVec[ 0 + resultVecOffset ] = tmp0;
+ resultVec[ 1 + resultVecOffset ] = tmp1;
+ resultVec[ 2 + resultVecOffset ] = tmp2;
+ resultVec[ 3 + resultVecOffset ] = tmp3;
+ }
/**
* Transposes a 4 x 4 matrix.
@@ -537,10 +711,9 @@
public static void rotateM(float[] rm, int rmOffset,
float[] m, int mOffset,
float a, float x, float y, float z) {
- synchronized(sTemp) {
- setRotateM(sTemp, 0, a, x, y, z);
- multiplyMM(rm, rmOffset, m, mOffset, sTemp, 0);
- }
+ float[] tmp = ThreadTmp.get();
+ setRotateM(tmp, 16, a, x, y, z);
+ multiplyMM(rm, rmOffset, m, mOffset, tmp, 16);
}
/**
@@ -556,11 +729,7 @@
*/
public static void rotateM(float[] m, int mOffset,
float a, float x, float y, float z) {
- synchronized(sTemp) {
- setRotateM(sTemp, 0, a, x, y, z);
- multiplyMM(sTemp, 16, m, mOffset, sTemp, 0);
- System.arraycopy(sTemp, 16, m, mOffset, 16);
- }
+ rotateM(m, mOffset, m, mOffset, a, x, y, z);
}
/**
@@ -640,9 +809,14 @@
* @param rm returns the result
* @param rmOffset index into rm where the result matrix starts
* @param x angle of rotation, in degrees
- * @param y angle of rotation, in degrees
+ * @param y is broken, do not use
* @param z angle of rotation, in degrees
+ *
+ * @deprecated This method is incorrect around the y axis. This method is
+ * deprecated and replaced (below) by setRotateEulerM2 which
+ * behaves correctly
*/
+ @Deprecated
public static void setRotateEulerM(float[] rm, int rmOffset,
float x, float y, float z) {
x *= (float) (Math.PI / 180.0f);
@@ -679,6 +853,64 @@
}
/**
+ * Converts Euler angles to a rotation matrix.
+ *
+ * @param rm returns the result
+ * @param rmOffset index into rm where the result matrix starts
+ * @param x angle of rotation, in degrees
+ * @param y angle of rotation, in degrees
+ * @param z angle of rotation, in degrees
+ *
+ * @throws IllegalArgumentException if rm is null;
+ * or if rmOffset + 16 > rm.length;
+ * rmOffset < 0
+ */
+ public static void setRotateEulerM2(@NonNull float[] rm, int rmOffset,
+ float x, float y, float z) {
+ if (rm == null) {
+ throw new IllegalArgumentException("rm == null");
+ }
+ if (rmOffset < 0) {
+ throw new IllegalArgumentException("rmOffset < 0");
+ }
+ if (rm.length < rmOffset + 16) {
+ throw new IllegalArgumentException("rm.length < rmOffset + 16");
+ }
+
+ x *= (float) (Math.PI / 180.0f);
+ y *= (float) (Math.PI / 180.0f);
+ z *= (float) (Math.PI / 180.0f);
+ float cx = (float) Math.cos(x);
+ float sx = (float) Math.sin(x);
+ float cy = (float) Math.cos(y);
+ float sy = (float) Math.sin(y);
+ float cz = (float) Math.cos(z);
+ float sz = (float) Math.sin(z);
+ float cxsy = cx * sy;
+ float sxsy = sx * sy;
+
+ rm[rmOffset + 0] = cy * cz;
+ rm[rmOffset + 1] = -cy * sz;
+ rm[rmOffset + 2] = sy;
+ rm[rmOffset + 3] = 0.0f;
+
+ rm[rmOffset + 4] = sxsy * cz + cx * sz;
+ rm[rmOffset + 5] = -sxsy * sz + cx * cz;
+ rm[rmOffset + 6] = -sx * cy;
+ rm[rmOffset + 7] = 0.0f;
+
+ rm[rmOffset + 8] = -cxsy * cz + sx * sz;
+ rm[rmOffset + 9] = cxsy * sz + sx * cz;
+ rm[rmOffset + 10] = cx * cy;
+ rm[rmOffset + 11] = 0.0f;
+
+ rm[rmOffset + 12] = 0.0f;
+ rm[rmOffset + 13] = 0.0f;
+ rm[rmOffset + 14] = 0.0f;
+ rm[rmOffset + 15] = 1.0f;
+ }
+
+ /**
* Defines a viewing transformation in terms of an eye point, a center of
* view, and an up vector.
*
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothBroadcastUtils.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothBroadcastUtils.java
index 1f72609..a80061e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothBroadcastUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothBroadcastUtils.java
@@ -53,8 +53,8 @@
static final String PREFIX_BT_SYNC_INTERVAL = "SI:";
static final String PREFIX_BT_IS_ENCRYPTED = "E:";
static final String PREFIX_BT_BROADCAST_CODE = "C:";
- static final String PREFIX_BT_PRESENTATION_DELAY = "D:";
- static final String PREFIX_BT_SUBGROUPS = "G:";
+ static final String PREFIX_BT_PRESENTATION_DELAY = "PD:";
+ static final String PREFIX_BT_SUBGROUPS = "SG:";
static final String PREFIX_BT_ANDROID_VERSION = "V:";
// BluetoothLeBroadcastSubgroup
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.java
index aff9a6e..c61ebc0 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.java
@@ -28,7 +28,9 @@
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -38,6 +40,43 @@
private static final String METADATA_START = "<";
private static final String METADATA_END = ">";
private static final String PATTERN_REGEX = "<(.*?)>";
+ private static final String PATTERN_BT_BROADCAST_METADATA =
+ "T:<(.*?)>;+D:<(.*?)>;+AS:<(.*?)>;+B:<(.*?)>;+SI:<(.*?)>;+E:<(.*?)>;+C:<(.*?)>;"
+ + "+PD:<(.*?)>;+SG:(.*)";
+ private static final String PATTERN_BT_SUBGROUP =
+ "CID:<(.*?)>;+CC:<(.*?);>;+AC:<(.*?);>;+CP:<(.*?)>;+BC:<(.*)>;>;";
+ private static final String PATTERN_BT_CHANNEL = "CI:<(.*?)>;+BCCM:<(.*?);>;";
+
+ /* Index for BluetoothLeBroadcastMetadata */
+ private static int MATCH_INDEX_ADDRESS_TYPE = 1;
+ private static int MATCH_INDEX_DEVICE = 2;
+ private static int MATCH_INDEX_ADVERTISING_SID = 3;
+ private static int MATCH_INDEX_BROADCAST_ID = 4;
+ private static int MATCH_INDEX_SYNC_INTERVAL = 5;
+ private static int MATCH_INDEX_IS_ENCRYPTED = 6;
+ private static int MATCH_INDEX_BROADCAST_CODE = 7;
+ private static int MATCH_INDEX_PRESENTATION_DELAY = 8;
+ private static int MATCH_INDEX_SUBGROUPS = 9;
+
+ /* Index for BluetoothLeBroadcastSubgroup */
+ private static int MATCH_INDEX_CODEC_ID = 1;
+ private static int MATCH_INDEX_CODEC_CONFIG = 2;
+ private static int MATCH_INDEX_AUDIO_CONTENT = 3;
+ private static int MATCH_INDEX_CHANNEL_PREF = 4;
+ private static int MATCH_INDEX_BROADCAST_CHANNEL = 5;
+
+ /* Index for BluetoothLeAudioCodecConfigMetadata */
+ private static int LIST_INDEX_AUDIO_LOCATION = 0;
+ private static int LIST_INDEX_CODEC_CONFIG_RAW_METADATA = 1;
+
+ /* Index for BluetoothLeAudioContentMetadata */
+ private static int LIST_INDEX_PROGRAM_INFO = 0;
+ private static int LIST_INDEX_LANGUAGE = 1;
+ private static int LIST_INDEX_AUDIO_CONTENT_RAW_METADATA = 2;
+
+ /* Index for BluetoothLeBroadcastChannel */
+ private static int MATCH_INDEX_CHANNEL_INDEX = 1;
+ private static int MATCH_INDEX_CHANNEL_CODEC_CONFIG = 2;
private BluetoothLeBroadcastSubgroup mSubgroup;
private List<BluetoothLeBroadcastSubgroup> mSubgroupList;
@@ -55,17 +94,20 @@
private byte[] mBroadcastCode;
// BluetoothLeBroadcastSubgroup
- private long mCodecId;
+ private int mCodecId;
private BluetoothLeAudioContentMetadata mContentMetadata;
private BluetoothLeAudioCodecConfigMetadata mConfigMetadata;
- private BluetoothLeBroadcastChannel mChannel;
+ private Boolean mNoChannelPreference;
+ private List<BluetoothLeBroadcastChannel> mChannel;
// BluetoothLeAudioCodecConfigMetadata
private long mAudioLocation;
+ private byte[] mCodecConfigMetadata;
// BluetoothLeAudioContentMetadata
private String mLanguage;
private String mProgramInfo;
+ private byte[] mAudioContentMetadata;
// BluetoothLeBroadcastChannel
private boolean mIsSelected;
@@ -135,6 +177,7 @@
for (BluetoothLeBroadcastSubgroup subgroup: subgroupList) {
String audioCodec = convertAudioCodecConfigToString(subgroup.getCodecSpecificConfig());
String audioContent = convertAudioContentToString(subgroup.getContentMetadata());
+ boolean hasChannelPreference = subgroup.hasChannelPreference();
String channels = convertChannelToString(subgroup.getChannels());
subgroupString = new StringBuilder()
.append(BluetoothBroadcastUtils.PREFIX_BTSG_CODEC_ID)
@@ -146,6 +189,9 @@
.append(BluetoothBroadcastUtils.PREFIX_BTSG_AUDIO_CONTENT)
.append(METADATA_START).append(audioContent).append(METADATA_END)
.append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
+ .append(BluetoothBroadcastUtils.PREFIX_BTSG_CHANNEL_PREF)
+ .append(METADATA_START).append(hasChannelPreference).append(METADATA_END)
+ .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
.append(BluetoothBroadcastUtils.PREFIX_BTSG_BROADCAST_CHANNEL)
.append(METADATA_START).append(channels).append(METADATA_END)
.append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
@@ -211,26 +257,35 @@
if (DEBUG) {
Log.d(TAG, "Convert " + qrCodeString + "to BluetoothLeBroadcastMetadata");
}
- Pattern pattern = Pattern.compile(PATTERN_REGEX);
+
+ Pattern pattern = Pattern.compile(PATTERN_BT_BROADCAST_METADATA);
Matcher match = pattern.matcher(qrCodeString);
if (match.find()) {
- ArrayList<String> resultList = new ArrayList<>();
- resultList.add(match.group(1));
- mSourceAddressType = Integer.parseInt(resultList.get(0));
+ mSourceAddressType = Integer.parseInt(match.group(MATCH_INDEX_ADDRESS_TYPE));
mSourceDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(
- resultList.get(1));
- mSourceAdvertisingSid = Integer.parseInt(resultList.get(2));
- mBroadcastId = Integer.parseInt(resultList.get(3));
- mPaSyncInterval = Integer.parseInt(resultList.get(4));
- mIsEncrypted = Boolean.valueOf(resultList.get(5));
- mBroadcastCode = resultList.get(6).getBytes();
- mPresentationDelayMicros = Integer.parseInt(resultList.get(7));
- mSubgroup = convertToSubgroup(resultList.get(8));
+ match.group(MATCH_INDEX_DEVICE));
+ mSourceAdvertisingSid = Integer.parseInt(match.group(MATCH_INDEX_ADVERTISING_SID));
+ mBroadcastId = Integer.parseInt(match.group(MATCH_INDEX_BROADCAST_ID));
+ mPaSyncInterval = Integer.parseInt(match.group(MATCH_INDEX_SYNC_INTERVAL));
+ mIsEncrypted = Boolean.valueOf(match.group(MATCH_INDEX_IS_ENCRYPTED));
+ mBroadcastCode = match.group(MATCH_INDEX_BROADCAST_CODE).getBytes();
+ mPresentationDelayMicros =
+ Integer.parseInt(match.group(MATCH_INDEX_PRESENTATION_DELAY));
if (DEBUG) {
- Log.d(TAG, "Converted qrCodeString result: " + match.group());
+ Log.d(TAG, "Converted qrCodeString result: "
+ + " ,Type = " + mSourceAddressType
+ + " ,Device = " + mSourceDevice
+ + " ,AdSid = " + mSourceAdvertisingSid
+ + " ,BroadcastId = " + mBroadcastId
+ + " ,paSync = " + mPaSyncInterval
+ + " ,encrypted = " + mIsEncrypted
+ + " ,BroadcastCode = " + Arrays.toString(mBroadcastCode)
+ + " ,delay = " + mPresentationDelayMicros);
}
+ mSubgroup = convertToSubgroup(match.group(MATCH_INDEX_SUBGROUPS));
+
return new BluetoothLeBroadcastMetadata.Builder()
.setSourceDevice(mSourceDevice, mSourceAddressType)
.setSourceAdvertisingSid(mSourceAdvertisingSid)
@@ -254,26 +309,26 @@
if (DEBUG) {
Log.d(TAG, "Convert " + subgroupString + "to BluetoothLeBroadcastSubgroup");
}
- Pattern pattern = Pattern.compile(PATTERN_REGEX);
+ Pattern pattern = Pattern.compile(PATTERN_BT_SUBGROUP);
Matcher match = pattern.matcher(subgroupString);
if (match.find()) {
- ArrayList<String> resultList = new ArrayList<>();
- resultList.add(match.group(1));
- mCodecId = Long.getLong(resultList.get(0));
- mConfigMetadata = convertToConfigMetadata(resultList.get(1));
- mContentMetadata = convertToContentMetadata(resultList.get(2));
- mChannel = convertToChannel(resultList.get(3), mConfigMetadata);
+ mCodecId = Integer.parseInt(match.group(MATCH_INDEX_CODEC_ID));
+ mConfigMetadata = convertToConfigMetadata(match.group(MATCH_INDEX_CODEC_CONFIG));
+ mContentMetadata = convertToContentMetadata(match.group(MATCH_INDEX_AUDIO_CONTENT));
+ mNoChannelPreference = Boolean.valueOf(match.group(MATCH_INDEX_CHANNEL_PREF));
+ mChannel =
+ convertToChannel(match.group(MATCH_INDEX_BROADCAST_CHANNEL), mConfigMetadata);
- if (DEBUG) {
- Log.d(TAG, "Converted subgroupString result: " + match.group());
+ BluetoothLeBroadcastSubgroup.Builder subgroupBuilder =
+ new BluetoothLeBroadcastSubgroup.Builder();
+ subgroupBuilder.setCodecId(mCodecId);
+ subgroupBuilder.setCodecSpecificConfig(mConfigMetadata);
+ subgroupBuilder.setContentMetadata(mContentMetadata);
+
+ for (BluetoothLeBroadcastChannel channel : mChannel) {
+ subgroupBuilder.addChannel(channel);
}
-
- return new BluetoothLeBroadcastSubgroup.Builder()
- .setCodecId(mCodecId)
- .setCodecSpecificConfig(mConfigMetadata)
- .setContentMetadata(mContentMetadata)
- .addChannel(mChannel)
- .build();
+ return subgroupBuilder.build();
} else {
if (DEBUG) {
Log.d(TAG,
@@ -291,15 +346,17 @@
}
Pattern pattern = Pattern.compile(PATTERN_REGEX);
Matcher match = pattern.matcher(configMetadataString);
- if (match.find()) {
- ArrayList<String> resultList = new ArrayList<>();
+ ArrayList<String> resultList = new ArrayList<>();
+ while (match.find()) {
resultList.add(match.group(1));
- mAudioLocation = Long.getLong(resultList.get(0));
-
- if (DEBUG) {
- Log.d(TAG, "Converted configMetadataString result: " + match.group());
- }
-
+ Log.d(TAG, "Codec Config match : " + match.group(1));
+ }
+ if (DEBUG) {
+ Log.d(TAG, "Converted configMetadataString result: " + resultList.size());
+ }
+ if (resultList.size() > 0) {
+ mAudioLocation = Long.parseLong(resultList.get(LIST_INDEX_AUDIO_LOCATION));
+ mCodecConfigMetadata = resultList.get(LIST_INDEX_CODEC_CONFIG_RAW_METADATA).getBytes();
return new BluetoothLeAudioCodecConfigMetadata.Builder()
.setAudioLocation(mAudioLocation)
.build();
@@ -319,14 +376,25 @@
}
Pattern pattern = Pattern.compile(PATTERN_REGEX);
Matcher match = pattern.matcher(contentMetadataString);
- if (match.find()) {
- ArrayList<String> resultList = new ArrayList<>();
+ ArrayList<String> resultList = new ArrayList<>();
+ while (match.find()) {
+ Log.d(TAG, "Audio Content match : " + match.group(1));
resultList.add(match.group(1));
- mProgramInfo = resultList.get(0);
- mLanguage = resultList.get(1);
+ }
+ if (DEBUG) {
+ Log.d(TAG, "Converted contentMetadataString result: " + resultList.size());
+ }
+ if (resultList.size() > 0) {
+ mProgramInfo = resultList.get(LIST_INDEX_PROGRAM_INFO);
+ mLanguage = resultList.get(LIST_INDEX_LANGUAGE);
+ mAudioContentMetadata =
+ resultList.get(LIST_INDEX_AUDIO_CONTENT_RAW_METADATA).getBytes();
- if (DEBUG) {
- Log.d(TAG, "Converted contentMetadataString result: " + match.group());
+ /* TODO(b/265253566) : Need to set the default value for language when the user starts
+ * the broadcast.
+ */
+ if (mLanguage.equals("null")) {
+ mLanguage = "eng";
}
return new BluetoothLeAudioContentMetadata.Builder()
@@ -342,28 +410,34 @@
}
}
- private BluetoothLeBroadcastChannel convertToChannel(String channelString,
+ private List<BluetoothLeBroadcastChannel> convertToChannel(String channelString,
BluetoothLeAudioCodecConfigMetadata configMetadata) {
if (DEBUG) {
Log.d(TAG, "Convert " + channelString + "to BluetoothLeBroadcastChannel");
}
- Pattern pattern = Pattern.compile(PATTERN_REGEX);
+ Pattern pattern = Pattern.compile(PATTERN_BT_CHANNEL);
Matcher match = pattern.matcher(channelString);
- if (match.find()) {
- ArrayList<String> resultList = new ArrayList<>();
- resultList.add(match.group(1));
- mIsSelected = Boolean.valueOf(resultList.get(0));
- mChannelIndex = Integer.parseInt(resultList.get(1));
+ Map<Integer, BluetoothLeAudioCodecConfigMetadata> channel =
+ new HashMap<Integer, BluetoothLeAudioCodecConfigMetadata>();
+ while (match.find()) {
+ channel.put(Integer.parseInt(match.group(MATCH_INDEX_CHANNEL_INDEX)),
+ convertToConfigMetadata(match.group(MATCH_INDEX_CHANNEL_CODEC_CONFIG)));
+ }
- if (DEBUG) {
- Log.d(TAG, "Converted channelString result: " + match.group());
+ if (channel.size() > 0) {
+ mIsSelected = false;
+ ArrayList<BluetoothLeBroadcastChannel> broadcastChannelList = new ArrayList<>();
+ for (Map.Entry<Integer, BluetoothLeAudioCodecConfigMetadata> entry :
+ channel.entrySet()) {
+
+ broadcastChannelList.add(
+ new BluetoothLeBroadcastChannel.Builder()
+ .setSelected(mIsSelected)
+ .setChannelIndex(entry.getKey())
+ .setCodecMetadata(entry.getValue())
+ .build());
}
-
- return new BluetoothLeBroadcastChannel.Builder()
- .setSelected(mIsSelected)
- .setChannelIndex(mChannelIndex)
- .setCodecMetadata(configMetadata)
- .build();
+ return broadcastChannelList;
} else {
if (DEBUG) {
Log.d(TAG,
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/OWNERS b/packages/SettingsLib/src/com/android/settingslib/media/OWNERS
index d40f322..3cae39f 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/checks/Android.bp b/packages/SystemUI/checks/Android.bp
index 9671add..29668d1 100644
--- a/packages/SystemUI/checks/Android.bp
+++ b/packages/SystemUI/checks/Android.bp
@@ -37,12 +37,6 @@
java_test_host {
name: "SystemUILintCheckerTest",
- // TODO(b/239881504): Since this test was written, Android
- // Lint was updated, and now includes classes that were
- // compiled for java 15. The soong build doesn't support
- // java 15 yet, so we can't compile against "lint". Disable
- // the test until java 15 is supported.
- enabled: false,
srcs: [
"tests/**/*.kt",
"tests/**/*.java",
@@ -55,5 +49,19 @@
],
test_options: {
unit_test: true,
+ tradefed_options: [
+ {
+ // lint bundles in some classes that were built with older versions
+ // of libraries, and no longer load. Since tradefed tries to load
+ // all classes in the jar to look for tests, it crashes loading them.
+ // Exclude these classes from tradefed's search.
+ name: "exclude-paths",
+ value: "org/apache",
+ },
+ {
+ name: "exclude-paths",
+ value: "META-INF",
+ },
+ ],
},
}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
index 50a10bc..14d45d2 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 @@
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 @@
// 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 df81c0e..90313eb 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 @@
}
/**
- * @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 9a6fa8e..8a6897c 100644
--- a/rs/jni/Android.bp
+++ b/rs/jni/Android.bp
@@ -51,4 +51,10 @@
"-Wunreachable-code",
"-Wno-deprecated-declarations",
],
+
+ target: {
+ android_riscv64: {
+ enabled: false,
+ },
+ },
}
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index abc4937..f10f930 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 @@
}
/**
- * 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 @@
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 bf71e6b..821927d 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -143,14 +143,15 @@
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
"android.hardware.health-V2.1-java", // HIDL
- "android.hardware.health-V1-java", // AIDL
+ "android.hardware.health-V2-java", // AIDL
"android.hardware.health-translate-java",
"android.hardware.light-V1-java",
"android.hardware.tv.cec-V1.1-java",
diff --git a/services/core/java/android/os/BatteryStatsInternal.java b/services/core/java/android/os/BatteryStatsInternal.java
index d49cc11..4a2fc89 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 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/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags
index 68fd0c1..9743ba4 100644
--- a/services/core/java/com/android/server/EventLogTags.logtags
+++ b/services/core/java/com/android/server/EventLogTags.logtags
@@ -223,8 +223,8 @@
# ---------------------------
# NetworkStatsService.java
# ---------------------------
-51100 netstats_mobile_sample (dev_rx_bytes|2|2),(dev_tx_bytes|2|2),(dev_rx_pkts|2|1),(dev_tx_pkts|2|1),(xt_rx_bytes|2|2),(xt_tx_bytes|2|2),(xt_rx_pkts|2|1),(xt_tx_pkts|2|1),(uid_rx_bytes|2|2),(uid_tx_bytes|2|2),(uid_rx_pkts|2|1),(uid_tx_pkts|2|1),(trusted_time|2|3)
-51101 netstats_wifi_sample (dev_rx_bytes|2|2),(dev_tx_bytes|2|2),(dev_rx_pkts|2|1),(dev_tx_pkts|2|1),(xt_rx_bytes|2|2),(xt_tx_bytes|2|2),(xt_rx_pkts|2|1),(xt_tx_pkts|2|1),(uid_rx_bytes|2|2),(uid_tx_bytes|2|2),(uid_rx_pkts|2|1),(uid_tx_pkts|2|1),(trusted_time|2|3)
+51100 netstats_mobile_sample (xt_rx_bytes|2|2),(xt_tx_bytes|2|2),(xt_rx_pkts|2|1),(xt_tx_pkts|2|1),(uid_rx_bytes|2|2),(uid_tx_bytes|2|2),(uid_rx_pkts|2|1),(uid_tx_pkts|2|1),(trusted_time|2|3)
+51101 netstats_wifi_sample (xt_rx_bytes|2|2),(xt_tx_bytes|2|2),(xt_rx_pkts|2|1),(xt_tx_pkts|2|1),(uid_rx_bytes|2|2),(uid_tx_bytes|2|2),(uid_rx_pkts|2|1),(uid_tx_pkts|2|1),(trusted_time|2|3)
# ---------------------------
diff --git a/services/core/java/com/android/server/VpnManagerService.java b/services/core/java/com/android/server/VpnManagerService.java
index ae50b23..2b43ef4 100644
--- a/services/core/java/com/android/server/VpnManagerService.java
+++ b/services/core/java/com/android/server/VpnManagerService.java
@@ -22,6 +22,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UserIdInt;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -67,6 +68,7 @@
import com.android.server.connectivity.Vpn;
import com.android.server.connectivity.VpnProfileStore;
import com.android.server.net.LockdownVpnTracker;
+import com.android.server.pm.UserManagerInternal;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -93,6 +95,7 @@
private final INetworkManagementService mNMS;
private final INetd mNetd;
private final UserManager mUserManager;
+ private final int mMainUserId;
@VisibleForTesting
@GuardedBy("mVpns")
@@ -145,6 +148,12 @@
Vpn vpn, VpnProfile profile) {
return new LockdownVpnTracker(context, handler, vpn, profile);
}
+
+ /** Get the main user on the device. */
+ public @UserIdInt int getMainUserId() {
+ // TODO(b/265785220): Change to use UserManager method instead.
+ return LocalServices.getService(UserManagerInternal.class).getMainUserId();
+ }
}
public VpnManagerService(Context context, Dependencies deps) {
@@ -159,6 +168,7 @@
mNMS = mDeps.getINetworkManagementService();
mNetd = mDeps.getNetd();
mUserManager = mContext.getSystemService(UserManager.class);
+ mMainUserId = mDeps.getMainUserId();
registerReceivers();
log("VpnManagerService starting up");
}
@@ -478,11 +488,12 @@
@Override
public boolean updateLockdownVpn() {
- // Allow the system UID for the system server and for Settings.
+ // Allow the system UID for the system server and for Settings (from user 0 or main user).
// Also, for unit tests, allow the process that ConnectivityService is running in.
if (mDeps.getCallingUid() != Process.SYSTEM_UID
+ && mDeps.getCallingUid() != UserHandle.getUid(mMainUserId, Process.SYSTEM_UID)
&& Binder.getCallingPid() != Process.myPid()) {
- logw("Lockdown VPN only available to system process or AID_SYSTEM");
+ logw("Lockdown VPN only available to system process or AID_SYSTEM on main user");
return false;
}
@@ -697,7 +708,7 @@
intentFilter,
null /* broadcastPermission */,
mHandler);
- mContext.createContextAsUser(UserHandle.SYSTEM, 0 /* flags */).registerReceiver(
+ mContext.createContextAsUser(UserHandle.of(mMainUserId), 0 /* flags */).registerReceiver(
mUserPresentReceiver,
new IntentFilter(Intent.ACTION_USER_PRESENT),
null /* broadcastPermission */,
@@ -735,6 +746,7 @@
if (LockdownVpnTracker.ACTION_LOCKDOWN_RESET.equals(action)) {
onVpnLockdownReset();
+ return;
}
// UserId should be filled for below intents, check the existence.
@@ -795,7 +807,7 @@
userVpn = mDeps.createVpn(mHandler.getLooper(), mContext, mNMS, mNetd, userId);
mVpns.put(userId, userVpn);
- if (user.isPrimary() && isLockdownVpnEnabled()) {
+ if (userId == mMainUserId && isLockdownVpnEnabled()) {
updateLockdownVpn();
}
}
@@ -910,15 +922,9 @@
}
private void onUserUnlocked(int userId) {
- UserInfo user = mUserManager.getUserInfo(userId);
- if (user == null) {
- logw("Unlocked user doesn't exist. UserId: " + userId);
- return;
- }
-
synchronized (mVpns) {
// User present may be sent because of an unlock, which might mean an unlocked keystore.
- if (user.isPrimary() && isLockdownVpnEnabled()) {
+ if (userId == mMainUserId && isLockdownVpnEnabled()) {
updateLockdownVpn();
} else {
startAlwaysOnVpn(userId);
@@ -984,7 +990,7 @@
}
// Turn Always-on VPN off
- if (mLockdownEnabled && userId == UserHandle.USER_SYSTEM) {
+ if (mLockdownEnabled && userId == mMainUserId) {
final long ident = Binder.clearCallingIdentity();
try {
mVpnProfileStore.remove(Credentials.LOCKDOWN_VPN);
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 606a09c..b02dd52 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 @@
}
@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/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index bc939d6..4afaca2f 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -2428,7 +2428,7 @@
}
state.setCurRawAdj(adj);
-
+ adj = psr.modifyRawOomAdj(adj);
if (adj > state.getMaxAdj()) {
adj = state.getMaxAdj();
if (adj <= ProcessList.PERCEPTIBLE_LOW_APP_ADJ) {
@@ -2458,7 +2458,7 @@
// it when computing the final cached adj later. Note that we don't need to
// worry about this for max adj above, since max adj will always be used to
// keep it out of the cached vaues.
- state.setCurAdj(psr.modifyRawOomAdj(adj));
+ state.setCurAdj(adj);
state.setCurCapability(capability);
state.setCurrentSchedulingGroup(schedGroup);
state.setCurProcState(procState);
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 8886f0a..b8ff26e 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -98,7 +98,6 @@
DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
DeviceConfig.NAMESPACE_SURFACE_FLINGER_NATIVE_BOOT,
DeviceConfig.NAMESPACE_SWCODEC_NATIVE,
- DeviceConfig.NAMESPACE_TETHERING,
DeviceConfig.NAMESPACE_VENDOR_SYSTEM_NATIVE,
DeviceConfig.NAMESPACE_VENDOR_SYSTEM_NATIVE_BOOT,
DeviceConfig.NAMESPACE_VIRTUALIZATION_FRAMEWORK_NATIVE,
diff --git a/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java b/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java
index dce1c96..39c649b 100644
--- a/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java
+++ b/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java
@@ -111,7 +111,7 @@
bb.order(ByteOrder.LITTLE_ENDIAN);
final int msgLen = bb.getInt();
- if (msgLen <= 0 || msgLen > MAX_CLIPBOARD_BYTES) {
+ if (msgLen < 0 || msgLen > MAX_CLIPBOARD_BYTES) {
throw new ProtocolException("Clipboard message length: " + msgLen + " out of bounds.");
}
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index b153c1b..2f16a58 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -845,6 +845,15 @@
for (int i = 0; i < userDisabledHdrTypeStrings.length; i++) {
mUserDisabledHdrTypes[i] = Integer.parseInt(userDisabledHdrTypeStrings[i]);
}
+
+ if (!mAreUserDisabledHdrTypesAllowed) {
+ mLogicalDisplayMapper.forEachLocked(
+ display -> {
+ display.setUserDisabledHdrTypes(mUserDisabledHdrTypes);
+ handleLogicalDisplayChangedLocked(display);
+ });
+ }
+
} catch (NumberFormatException e) {
Slog.e(TAG, "Failed to parse USER_DISABLED_HDR_FORMATS. "
+ "Clearing the setting.", e);
@@ -872,6 +881,15 @@
Settings.Global.USER_PREFERRED_RESOLUTION_WIDTH, Display.INVALID_DISPLAY_WIDTH);
Display.Mode mode = new Display.Mode(width, height, refreshRate);
mUserPreferredMode = isResolutionAndRefreshRateValid(mode) ? mode : null;
+ if (mUserPreferredMode != null) {
+ mDisplayDeviceRepo.forEachLocked((DisplayDevice device) -> {
+ device.setUserPreferredDisplayModeLocked(mode);
+ });
+ } else {
+ mLogicalDisplayMapper.forEachLocked((LogicalDisplay display) -> {
+ configurePreferredDisplayModeLocked(display);
+ });
+ }
}
private DisplayInfo getDisplayInfoForFrameRateOverride(DisplayEventReceiver.FrameRateOverride[]
@@ -2213,7 +2231,9 @@
}
// fallthrough
default:
- Slog.w(TAG, "Display " + info + " does not support input device matching.");
+ if (DEBUG) {
+ Slog.w(TAG, "Display " + info + " does not support input device matching.");
+ }
}
return Optional.empty();
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 89719ce..958eb64 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 @@
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/pm/UserManagerInternal.java b/services/core/java/com/android/server/pm/UserManagerInternal.java
index 8dc9428..cc58e5c 100644
--- a/services/core/java/com/android/server/pm/UserManagerInternal.java
+++ b/services/core/java/com/android/server/pm/UserManagerInternal.java
@@ -305,4 +305,10 @@
* for users that already existed on-disk from an older version of Android.
*/
public abstract boolean shouldIgnorePrepareStorageErrors(int userId);
+
+ /**
+ * Returns the user id of the main user, or {@link android.os.UserHandle#USER_NULL} if there is
+ * no main user.
+ */
+ public abstract @UserIdInt int getMainUserId();
}
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index b3dcf72..0a465e9 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -6359,6 +6359,11 @@
return userData != null && userData.getIgnorePrepareStorageErrors();
}
}
+
+ @Override
+ public @UserIdInt int getMainUserId() {
+ return UserHandle.USER_SYSTEM;
+ }
}
/**
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index a82d4ea..5096ad1 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -61,6 +61,7 @@
public final class ShutdownThread extends Thread {
// constants
+ private static final boolean DEBUG = false;
private static final String TAG = "ShutdownThread";
private static final int ACTION_DONE_POLL_WAIT_MS = 500;
private static final int RADIOS_STATE_POLL_SLEEP_MS = 100;
@@ -161,7 +162,9 @@
// any additional calls are just returned
synchronized (sIsStartedGuard) {
if (sIsStarted) {
- Log.d(TAG, "Request to shutdown already running, returning.");
+ if (DEBUG) {
+ Log.d(TAG, "Request to shutdown already running, returning.");
+ }
return;
}
}
@@ -178,7 +181,9 @@
? com.android.internal.R.string.shutdown_confirm_question
: com.android.internal.R.string.shutdown_confirm);
- Log.d(TAG, "Notifying thread to start shutdown longPressBehavior=" + longPressBehavior);
+ if (DEBUG) {
+ Log.d(TAG, "Notifying thread to start shutdown longPressBehavior=" + longPressBehavior);
+ }
if (confirm) {
final CloseDialogReceiver closer = new CloseDialogReceiver(context);
@@ -348,26 +353,34 @@
}
private static boolean showSysuiReboot() {
- Log.d(TAG, "Attempting to use SysUI shutdown UI");
+ if (DEBUG) {
+ Log.d(TAG, "Attempting to use SysUI shutdown UI");
+ }
try {
StatusBarManagerInternal service = LocalServices.getService(
StatusBarManagerInternal.class);
if (service.showShutdownUi(mReboot, mReason)) {
// Sysui will handle shutdown UI.
- Log.d(TAG, "SysUI handling shutdown UI");
+ if (DEBUG) {
+ Log.d(TAG, "SysUI handling shutdown UI");
+ }
return true;
}
} catch (Exception e) {
// If anything went wrong, ignore it and use fallback ui
}
- Log.d(TAG, "SysUI is unavailable");
+ if (DEBUG) {
+ Log.d(TAG, "SysUI is unavailable");
+ }
return false;
}
private static void beginShutdownSequence(Context context) {
synchronized (sIsStartedGuard) {
if (sIsStarted) {
- Log.d(TAG, "Shutdown sequence already running, returning.");
+ if (DEBUG) {
+ Log.d(TAG, "Shutdown sequence already running, returning.");
+ }
return;
}
sIsStarted = true;
diff --git a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
index 1321873..9d5173a 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.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.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.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 @@
/**
* 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 @@
* 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 @@
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 @@
return true;
}
- android.hardware.boot.V1_2.IBootControl bootControl;
+ IBootControl bootControl;
try {
bootControl = mInjector.getBootControl();
} catch (RemoteException e) {
@@ -972,8 +983,8 @@
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 @@
/**
* 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 @@
/**
* 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 0000000..65325c2
--- /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/rollback/RollbackStore.java b/services/core/java/com/android/server/rollback/RollbackStore.java
index f973f5c..8068c6f 100644
--- a/services/core/java/com/android/server/rollback/RollbackStore.java
+++ b/services/core/java/com/android/server/rollback/RollbackStore.java
@@ -249,7 +249,7 @@
targetDir.mkdirs();
File targetFile = new File(targetDir, sourceFile.getName());
- boolean fallbackToCopy = !isLinkPossible(sourceFile, targetFile);
+ boolean fallbackToCopy = !isLinkPossible(sourceFile, targetDir);
if (!fallbackToCopy) {
try {
// Create a hard link to avoid copy
diff --git a/services/core/java/com/android/server/security/rkp/RemoteProvisioningRegistration.java b/services/core/java/com/android/server/security/rkp/RemoteProvisioningRegistration.java
index 868f34b..0e92709 100644
--- a/services/core/java/com/android/server/security/rkp/RemoteProvisioningRegistration.java
+++ b/services/core/java/com/android/server/security/rkp/RemoteProvisioningRegistration.java
@@ -21,10 +21,12 @@
import android.os.OutcomeReceiver;
import android.security.rkp.IGetKeyCallback;
import android.security.rkp.IRegistration;
+import android.security.rkp.IStoreUpgradedKeyCallback;
import android.security.rkp.service.RegistrationProxy;
import android.security.rkp.service.RemotelyProvisionedKey;
import android.util.Log;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
@@ -36,8 +38,10 @@
*/
final class RemoteProvisioningRegistration extends IRegistration.Stub {
static final String TAG = RemoteProvisioningService.TAG;
- private final ConcurrentHashMap<IGetKeyCallback, CancellationSignal> mOperations =
+ private final ConcurrentHashMap<IGetKeyCallback, CancellationSignal> mGetKeyOperations =
new ConcurrentHashMap<>();
+ private final Set<IStoreUpgradedKeyCallback> mStoreUpgradedKeyOperations =
+ ConcurrentHashMap.newKeySet();
private final RegistrationProxy mRegistration;
private final Executor mExecutor;
@@ -49,7 +53,7 @@
@Override
public void onResult(RemotelyProvisionedKey result) {
- mOperations.remove(mCallback);
+ mGetKeyOperations.remove(mCallback);
Log.i(TAG, "Successfully fetched key for client " + mCallback.hashCode());
android.security.rkp.RemotelyProvisionedKey parcelable =
new android.security.rkp.RemotelyProvisionedKey();
@@ -60,7 +64,7 @@
@Override
public void onError(Exception e) {
- mOperations.remove(mCallback);
+ mGetKeyOperations.remove(mCallback);
if (e instanceof OperationCanceledException) {
Log.i(TAG, "Operation cancelled for client " + mCallback.hashCode());
wrapCallback(mCallback::onCancel);
@@ -79,7 +83,7 @@
@Override
public void getKey(int keyId, IGetKeyCallback callback) {
CancellationSignal cancellationSignal = new CancellationSignal();
- if (mOperations.putIfAbsent(callback, cancellationSignal) != null) {
+ if (mGetKeyOperations.putIfAbsent(callback, cancellationSignal) != null) {
Log.e(TAG, "Client can only request one call at a time " + callback.hashCode());
throw new IllegalArgumentException(
"Callback is already associated with an existing operation: "
@@ -92,14 +96,14 @@
new GetKeyReceiver(callback));
} catch (Exception e) {
Log.e(TAG, "getKeyAsync threw an exception for client " + callback.hashCode(), e);
- mOperations.remove(callback);
+ mGetKeyOperations.remove(callback);
wrapCallback(() -> callback.onError(e.getMessage()));
}
}
@Override
public void cancelGetKey(IGetKeyCallback callback) {
- CancellationSignal cancellationSignal = mOperations.remove(callback);
+ CancellationSignal cancellationSignal = mGetKeyOperations.remove(callback);
if (cancellationSignal == null) {
throw new IllegalArgumentException(
"Invalid client in cancelGetKey: " + callback.hashCode());
@@ -110,9 +114,35 @@
}
@Override
- public void storeUpgradedKey(byte[] oldKeyBlob, byte[] newKeyBlob) {
- // TODO(b/262748535)
- Log.e(TAG, "RegistrationBinder.storeUpgradedKey NOT YET IMPLEMENTED");
+ public void storeUpgradedKeyAsync(byte[] oldKeyBlob, byte[] newKeyBlob,
+ IStoreUpgradedKeyCallback callback) {
+ if (!mStoreUpgradedKeyOperations.add(callback)) {
+ throw new IllegalArgumentException(
+ "Callback is already associated with an existing operation: "
+ + callback.hashCode());
+ }
+
+ try {
+ mRegistration.storeUpgradedKeyAsync(oldKeyBlob, newKeyBlob, mExecutor,
+ new OutcomeReceiver<>() {
+ @Override
+ public void onResult(Void result) {
+ mStoreUpgradedKeyOperations.remove(callback);
+ wrapCallback(callback::onSuccess);
+ }
+
+ @Override
+ public void onError(Exception e) {
+ mStoreUpgradedKeyOperations.remove(callback);
+ wrapCallback(() -> callback.onError(e.getMessage()));
+ }
+ });
+ } catch (Exception e) {
+ Log.e(TAG, "storeUpgradedKeyAsync threw an exception for client "
+ + callback.hashCode(), e);
+ mStoreUpgradedKeyOperations.remove(callback);
+ wrapCallback(() -> callback.onError(e.getMessage()));
+ }
}
interface CallbackRunner {
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/OWNERS b/services/core/java/com/android/server/soundtrigger_middleware/OWNERS
index e5d0370..01b2cb9 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/OWNERS
+++ b/services/core/java/com/android/server/soundtrigger_middleware/OWNERS
@@ -1,2 +1,2 @@
-ytai@google.com
+atneya@google.com
elaurent@google.com
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index b95d372..8bc7bcc 100755
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -24,6 +24,7 @@
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
+import android.content.AttributionSource;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -90,7 +91,6 @@
import android.util.SparseArray;
import android.view.InputChannel;
import android.view.Surface;
-
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.content.PackageMonitor;
@@ -101,9 +101,7 @@
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.IoThread;
import com.android.server.SystemService;
-
import dalvik.annotation.optimization.NeverCompile;
-
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
@@ -813,7 +811,7 @@
@GuardedBy("mLock")
private boolean createSessionInternalLocked(ITvInputService service, IBinder sessionToken,
- int userId) {
+ int userId, AttributionSource tvAppAttributionSource) {
UserState userState = getOrCreateUserStateLocked(userId);
SessionState sessionState = userState.sessionStateMap.get(sessionToken);
if (DEBUG) {
@@ -832,8 +830,8 @@
service.createRecordingSession(
callback, sessionState.inputId, sessionState.sessionId);
} else {
- service.createSession(
- channels[1], callback, sessionState.inputId, sessionState.sessionId);
+ service.createSession(channels[1], callback, sessionState.inputId,
+ sessionState.sessionId, tvAppAttributionSource);
}
} catch (RemoteException e) {
Slog.e(TAG, "error in createSession", e);
@@ -1485,7 +1483,8 @@
@Override
public void createSession(final ITvInputClient client, final String inputId,
- boolean isRecordingSession, int seq, int userId) {
+ AttributionSource tvAppAttributionSource, boolean isRecordingSession, int seq,
+ int userId) {
final int callingUid = Binder.getCallingUid();
final int callingPid = Binder.getCallingPid();
final int resolvedUserId = resolveCallingUserId(callingPid, callingUid,
@@ -1556,7 +1555,7 @@
if (serviceState.service != null) {
if (!createSessionInternalLocked(serviceState.service, sessionToken,
- resolvedUserId)) {
+ resolvedUserId, tvAppAttributionSource)) {
removeSessionStateLocked(sessionToken, resolvedUserId);
}
} else {
@@ -3113,7 +3112,8 @@
// And create sessions, if any.
for (IBinder sessionToken : serviceState.sessionTokens) {
- if (!createSessionInternalLocked(serviceState.service, sessionToken, mUserId)) {
+ if (!createSessionInternalLocked(
+ serviceState.service, sessionToken, mUserId, null)) {
tokensToBeRemoved.add(sessionToken);
}
}
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 7f22242..efbd7a8 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 @@
}
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/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index ec67414..1a3e7d1 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -1904,7 +1904,8 @@
}
boolean shouldSleepActivities() {
- return false;
+ final Task task = getRootTask();
+ return task != null && task.shouldSleepActivities();
}
@Override
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 20d9cce..55fb599 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -136,6 +136,7 @@
import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT;
import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE;
+import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_BLOCKING;
import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK;
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
@@ -18330,6 +18331,9 @@
if (preferentialNetworkServiceConfig.isEnabled()) {
if (preferentialNetworkServiceConfig.isFallbackToDefaultConnectionAllowed()) {
preferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE);
+ } else if (preferentialNetworkServiceConfig.shouldBlockNonMatchingNetworks()) {
+ preferenceBuilder.setPreference(
+ PROFILE_NETWORK_PREFERENCE_ENTERPRISE_BLOCKING);
} else {
preferenceBuilder.setPreference(
PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK);
diff --git a/services/incremental/TEST_MAPPING b/services/incremental/TEST_MAPPING
index 9fe090a..3976a70 100644
--- a/services/incremental/TEST_MAPPING
+++ b/services/incremental/TEST_MAPPING
@@ -36,5 +36,10 @@
}
]
}
+ ],
+ "kernel-presubmit": [
+ {
+ "name": "CtsIncrementalInstallHostTestCases"
+ }
]
}
diff --git a/services/tests/RemoteProvisioningServiceTests/src/com/android/server/security/rkp/RemoteProvisioningRegistrationTest.java b/services/tests/RemoteProvisioningServiceTests/src/com/android/server/security/rkp/RemoteProvisioningRegistrationTest.java
index 470f2be..7b361d3 100644
--- a/services/tests/RemoteProvisioningServiceTests/src/com/android/server/security/rkp/RemoteProvisioningRegistrationTest.java
+++ b/services/tests/RemoteProvisioningServiceTests/src/com/android/server/security/rkp/RemoteProvisioningRegistrationTest.java
@@ -34,7 +34,9 @@
import android.os.CancellationSignal;
import android.os.OperationCanceledException;
import android.os.OutcomeReceiver;
+import android.os.RemoteException;
import android.security.rkp.IGetKeyCallback;
+import android.security.rkp.IStoreUpgradedKeyCallback;
import android.security.rkp.service.RegistrationProxy;
import android.security.rkp.service.RemotelyProvisionedKey;
@@ -72,6 +74,12 @@
return answerVoid(answer);
}
+ // answerVoid wrapper for mocking storeUpgradeKeyAsync.
+ static Answer<Void> answerStoreUpgradedKeyAsync(
+ VoidAnswer4<byte[], byte[], Executor, OutcomeReceiver<Void, Exception>> answer) {
+ return answerVoid(answer);
+ }
+
// matcher helper, making it easier to match the different key types
private android.security.rkp.RemotelyProvisionedKey matches(
RemotelyProvisionedKey expectedKey) {
@@ -178,16 +186,63 @@
@Test
public void storeUpgradedKeySuccess() throws Exception {
- // TODO(b/262748535)
+ doAnswer(
+ answerStoreUpgradedKeyAsync((oldBlob, newBlob, executor, receiver) ->
+ executor.execute(() -> receiver.onResult(null))))
+ .when(mRegistrationProxy)
+ .storeUpgradedKeyAsync(any(), any(), any(), any());
+
+ IStoreUpgradedKeyCallback callback = mock(IStoreUpgradedKeyCallback.class);
+ mRegistration.storeUpgradedKeyAsync(new byte[0], new byte[0], callback);
+ verify(callback).onSuccess();
+ verifyNoMoreInteractions(callback);
}
@Test
public void storeUpgradedKeyFails() throws Exception {
- // TODO(b/262748535)
+ final String errorString = "this is a failure";
+ doAnswer(
+ answerStoreUpgradedKeyAsync((oldBlob, newBlob, executor, receiver) ->
+ executor.execute(() -> receiver.onError(new RemoteException(errorString)))))
+ .when(mRegistrationProxy)
+ .storeUpgradedKeyAsync(any(), any(), any(), any());
+
+ IStoreUpgradedKeyCallback callback = mock(IStoreUpgradedKeyCallback.class);
+ mRegistration.storeUpgradedKeyAsync(new byte[0], new byte[0], callback);
+ verify(callback).onError(errorString);
+ verifyNoMoreInteractions(callback);
}
@Test
- public void storeUpgradedCatchesExceptionFromProxy() throws Exception {
- // TODO(b/262748535)
+ public void storeUpgradedKeyHandlesException() throws Exception {
+ final String errorString = "all aboard the failboat, toot toot";
+ doThrow(new IllegalArgumentException(errorString))
+ .when(mRegistrationProxy)
+ .storeUpgradedKeyAsync(any(), any(), any(), any());
+
+ IStoreUpgradedKeyCallback callback = mock(IStoreUpgradedKeyCallback.class);
+ mRegistration.storeUpgradedKeyAsync(new byte[0], new byte[0], callback);
+ verify(callback).onError(errorString);
+ verifyNoMoreInteractions(callback);
}
+
+ @Test
+ public void storeUpgradedKeyDuplicateCallback() throws Exception {
+ IStoreUpgradedKeyCallback callback = mock(IStoreUpgradedKeyCallback.class);
+
+ doAnswer(
+ answerStoreUpgradedKeyAsync((oldBlob, newBlob, executor, receiver) -> {
+ assertThrows(IllegalArgumentException.class,
+ () -> mRegistration.storeUpgradedKeyAsync(new byte[0], new byte[0],
+ callback));
+ executor.execute(() -> receiver.onResult(null));
+ }))
+ .when(mRegistrationProxy)
+ .storeUpgradedKeyAsync(any(), any(), any(), any());
+
+ mRegistration.storeUpgradedKeyAsync(new byte[0], new byte[0], callback);
+ verify(callback).onSuccess();
+ verifyNoMoreInteractions(callback);
+ }
+
}
diff --git a/services/tests/mockingservicestests/OWNERS b/services/tests/mockingservicestests/OWNERS
index 4dda51f..0640d52 100644
--- a/services/tests/mockingservicestests/OWNERS
+++ b/services/tests/mockingservicestests/OWNERS
@@ -6,3 +6,6 @@
per-file FakeServiceConnector.java = file:/GAME_MANAGER_OWNERS
per-file Game* = file:/GAME_MANAGER_OWNERS
per-file res/xml/game_manager* = file:/GAME_MANAGER_OWNERS
+
+# General utilities
+per-file services/tests/mockingservicestests/src/com/android/server/*.java=felipeal@google.com
diff --git a/services/tests/mockingservicestests/src/com/android/server/power/OWNERS b/services/tests/mockingservicestests/src/com/android/server/power/OWNERS
index d68066b..fb62520 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 5234bb7..63d6768 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 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 27e953f..f1cf48b 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/services/usb/Android.bp b/services/usb/Android.bp
index 3b50fa4..5716b66 100644
--- a/services/usb/Android.bp
+++ b/services/usb/Android.bp
@@ -29,9 +29,10 @@
"android.hardware.usb-V1.1-java",
"android.hardware.usb-V1.2-java",
"android.hardware.usb-V1.3-java",
- "android.hardware.usb-V1-java",
+ "android.hardware.usb-V1-java",
"android.hardware.usb.gadget-V1.0-java",
"android.hardware.usb.gadget-V1.1-java",
"android.hardware.usb.gadget-V1.2-java",
+ "android.hardware.usb.gadget-V1-java",
],
}
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index d580995..1b92699 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -44,6 +44,7 @@
import android.debug.AdbNotifications;
import android.debug.AdbTransportType;
import android.debug.IAdbTransport;
+import android.hardware.usb.IUsbOperationInternal;
import android.hardware.usb.ParcelableUsbPort;
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbConfiguration;
@@ -54,9 +55,7 @@
import android.hardware.usb.UsbPort;
import android.hardware.usb.UsbPortStatus;
import android.hardware.usb.gadget.V1_0.GadgetFunction;
-import android.hardware.usb.gadget.V1_0.IUsbGadget;
import android.hardware.usb.gadget.V1_0.Status;
-import android.hardware.usb.gadget.V1_2.IUsbGadgetCallback;
import android.hardware.usb.gadget.V1_2.UsbSpeed;
import android.hidl.manager.V1_0.IServiceManager;
import android.hidl.manager.V1_0.IServiceNotification;
@@ -88,9 +87,12 @@
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.os.SomeArgs;
+import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.dump.DualDumpOutputStream;
import com.android.server.FgThread;
import com.android.server.LocalServices;
+import com.android.server.usb.hal.gadget.UsbGadgetHal;
+import com.android.server.usb.hal.gadget.UsbGadgetHalInstance;
import com.android.server.wm.ActivityTaskManagerInternal;
import java.io.File;
@@ -105,6 +107,7 @@
import java.util.NoSuchElementException;
import java.util.Scanner;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* UsbDeviceManager manages USB state in device mode.
@@ -215,6 +218,13 @@
private static UsbDeviceLogger sEventLogger;
+ private UsbGadgetHal mUsbGadgetHal;
+
+ /**
+ * Counter for tracking UsbOperation operations.
+ */
+ private static final AtomicInteger sUsbOperationCount = new AtomicInteger();
+
static {
sDenyInterfaces = new HashSet<>();
sDenyInterfaces.add(UsbConstants.USB_CLASS_AUDIO);
@@ -297,15 +307,11 @@
mHasUsbAccessory = pm.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY);
initRndisAddress();
+ int operationId = sUsbOperationCount.incrementAndGet();
boolean halNotPresent = false;
- try {
- IUsbGadget.getService(true);
- } catch (RemoteException e) {
- Slog.e(TAG, "USB GADGET HAL present but exception thrown", e);
- } catch (NoSuchElementException e) {
- halNotPresent = true;
- Slog.i(TAG, "USB GADGET HAL not present in the device", e);
- }
+
+ mUsbGadgetHal = UsbGadgetHalInstance.getInstance(this, null);
+ Slog.d(TAG, "getInstance done");
mControlFds = new HashMap<>();
FileDescriptor mtpFd = nativeOpenControl(UsbManager.USB_FUNCTION_MTP);
@@ -319,7 +325,7 @@
}
mControlFds.put(UsbManager.FUNCTION_PTP, ptpFd);
- if (halNotPresent) {
+ if (mUsbGadgetHal == null) {
/**
* Initialze the legacy UsbHandler
*/
@@ -333,6 +339,8 @@
alsaManager, permissionManager);
}
+ mHandler.handlerInitDone(operationId);
+
if (nativeIsStartRequested()) {
if (DEBUG) Slog.d(TAG, "accessory attached at boot");
startAccessoryMode();
@@ -454,6 +462,8 @@
private void startAccessoryMode() {
if (!mHasUsbAccessory) return;
+ int operationId = sUsbOperationCount.incrementAndGet();
+
mAccessoryStrings = nativeGetAccessoryStrings();
boolean enableAudio = (nativeGetAudioMode() == AUDIO_MODE_SOURCE);
// don't start accessory mode if our mandatory strings have not been set
@@ -474,7 +484,7 @@
ACCESSORY_REQUEST_TIMEOUT);
mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_ACCESSORY_HANDSHAKE_TIMEOUT),
ACCESSORY_HANDSHAKE_TIMEOUT);
- setCurrentFunctions(functions);
+ setCurrentFunctions(functions, operationId);
}
}
@@ -503,6 +513,20 @@
}
}
+ public static void logAndPrint(int priority, IndentingPrintWriter pw, String msg) {
+ Slog.println(priority, TAG, msg);
+ if (pw != null) {
+ pw.println(msg);
+ }
+ }
+
+ public static void logAndPrintException(IndentingPrintWriter pw, String msg, Exception e) {
+ Slog.e(TAG, msg, e);
+ if (pw != null) {
+ pw.println(msg + e);
+ }
+ }
+
abstract static class UsbHandler extends Handler {
// current USB state
@@ -605,6 +629,19 @@
sendMessage(m);
}
+ public boolean sendMessage(int what) {
+ removeMessages(what);
+ Message m = Message.obtain(this, what);
+ return sendMessageDelayed(m,0);
+ }
+
+ public void sendMessage(int what, int operationId) {
+ removeMessages(what);
+ Message m = Message.obtain(this, what);
+ m.arg1 = operationId;
+ sendMessage(m);
+ }
+
public void sendMessage(int what, Object arg) {
removeMessages(what);
Message m = Message.obtain(this, what);
@@ -612,6 +649,22 @@
sendMessage(m);
}
+ public void sendMessage(int what, Object arg, int operationId) {
+ removeMessages(what);
+ Message m = Message.obtain(this, what);
+ m.obj = arg;
+ m.arg1 = operationId;
+ sendMessage(m);
+ }
+
+ public void sendMessage(int what, boolean arg, int operationId) {
+ removeMessages(what);
+ Message m = Message.obtain(this, what);
+ m.arg1 = (arg ? 1 : 0);
+ m.arg2 = operationId;
+ sendMessage(m);
+ }
+
public void sendMessage(int what, Object arg, boolean arg1) {
removeMessages(what);
Message m = Message.obtain(this, what);
@@ -620,6 +673,15 @@
sendMessage(m);
}
+ public void sendMessage(int what, long arg, boolean arg1, int operationId) {
+ removeMessages(what);
+ Message m = Message.obtain(this, what);
+ m.obj = arg;
+ m.arg1 = (arg1 ? 1 : 0);
+ m.arg2 = operationId;
+ sendMessage(m);
+ }
+
public void sendMessage(int what, boolean arg1, boolean arg2) {
removeMessages(what);
Message m = Message.obtain(this, what);
@@ -677,7 +739,7 @@
sendMessageDelayed(msg, HOST_STATE_UPDATE_DELAY);
}
- private void setAdbEnabled(boolean enable) {
+ private void setAdbEnabled(boolean enable, int operationId) {
if (DEBUG) Slog.d(TAG, "setAdbEnabled: " + enable);
if (enable) {
@@ -686,7 +748,7 @@
setSystemProperty(USB_PERSISTENT_CONFIG_PROPERTY, "");
}
- setEnabledFunctions(mCurrentFunctions, true);
+ setEnabledFunctions(mCurrentFunctions, true, operationId);
updateAdbNotification(false);
}
@@ -698,6 +760,8 @@
private void updateCurrentAccessory() {
// We are entering accessory mode if we have received a request from the host
// and the request has not timed out yet.
+ int operationId = sUsbOperationCount.incrementAndGet();
+
boolean enteringAccessoryMode = hasMessages(MSG_ACCESSORY_MODE_ENTER_TIMEOUT);
if (mConfigured && enteringAccessoryMode) {
@@ -729,18 +793,18 @@
}
} else {
if (!enteringAccessoryMode) {
- notifyAccessoryModeExit();
+ notifyAccessoryModeExit(operationId);
} else if (DEBUG) {
Slog.v(TAG, "Debouncing accessory mode exit");
}
}
}
- private void notifyAccessoryModeExit() {
+ private void notifyAccessoryModeExit(int operationId) {
// make sure accessory mode is off
// and restore default functions
Slog.d(TAG, "exited USB accessory mode");
- setEnabledFunctions(UsbManager.FUNCTION_NONE, false);
+ setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId);
if (mCurrentAccessory != null) {
if (mBootCompleted) {
@@ -866,8 +930,8 @@
mMidiEnabled && mConfigured, mMidiCard, mMidiDevice);
}
- private void setScreenUnlockedFunctions() {
- setEnabledFunctions(mScreenUnlockedFunctions, false);
+ private void setScreenUnlockedFunctions(int operationId) {
+ setEnabledFunctions(mScreenUnlockedFunctions, false, operationId);
}
private static class AdbTransport extends IAdbTransport.Stub {
@@ -880,7 +944,8 @@
@Override
public void onAdbEnabled(boolean enabled, byte transportType) {
if (transportType == AdbTransportType.USB) {
- mHandler.sendMessage(MSG_ENABLE_ADB, enabled);
+ int operationId = sUsbOperationCount.incrementAndGet();
+ mHandler.sendMessage(MSG_ENABLE_ADB, enabled, operationId);
}
}
}
@@ -903,6 +968,7 @@
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_UPDATE_STATE:
+ int operationId = sUsbOperationCount.incrementAndGet();
mConnected = (msg.arg1 == 1);
mConfigured = (msg.arg2 == 1);
@@ -920,9 +986,9 @@
// restore defaults when USB is disconnected
if (!mScreenLocked
&& mScreenUnlockedFunctions != UsbManager.FUNCTION_NONE) {
- setScreenUnlockedFunctions();
+ setScreenUnlockedFunctions(operationId);
} else {
- setEnabledFunctions(UsbManager.FUNCTION_NONE, false);
+ setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId);
}
}
updateUsbFunctions();
@@ -1026,13 +1092,15 @@
updateUsbNotification(false);
break;
case MSG_ENABLE_ADB:
- setAdbEnabled(msg.arg1 == 1);
+ setAdbEnabled(msg.arg1 == 1, msg.arg2);
break;
case MSG_SET_CURRENT_FUNCTIONS:
long functions = (Long) msg.obj;
- setEnabledFunctions(functions, false);
+ operationId = (int) msg.arg1;
+ setEnabledFunctions(functions, false, operationId);
break;
case MSG_SET_SCREEN_UNLOCKED_FUNCTIONS:
+ operationId = sUsbOperationCount.incrementAndGet();
mScreenUnlockedFunctions = (Long) msg.obj;
if (mSettings != null) {
SharedPreferences.Editor editor = mSettings.edit();
@@ -1043,12 +1111,13 @@
}
if (!mScreenLocked && mScreenUnlockedFunctions != UsbManager.FUNCTION_NONE) {
// If the screen is unlocked, also set current functions.
- setScreenUnlockedFunctions();
+ setScreenUnlockedFunctions(operationId);
} else {
- setEnabledFunctions(UsbManager.FUNCTION_NONE, false);
+ setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId);
}
break;
case MSG_UPDATE_SCREEN_LOCK:
+ operationId = sUsbOperationCount.incrementAndGet();
if (msg.arg1 == 1 == mScreenLocked) {
break;
}
@@ -1058,23 +1127,25 @@
}
if (mScreenLocked) {
if (!mConnected) {
- setEnabledFunctions(UsbManager.FUNCTION_NONE, false);
+ setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId);
}
} else {
if (mScreenUnlockedFunctions != UsbManager.FUNCTION_NONE
&& mCurrentFunctions == UsbManager.FUNCTION_NONE) {
// Set the screen unlocked functions if current function is charging.
- setScreenUnlockedFunctions();
+ setScreenUnlockedFunctions(operationId);
}
}
break;
case MSG_UPDATE_USER_RESTRICTIONS:
+ operationId = sUsbOperationCount.incrementAndGet();
// Restart the USB stack if USB transfer is enabled but no longer allowed.
if (isUsbDataTransferActive(mCurrentFunctions) && !isUsbTransferAllowed()) {
- setEnabledFunctions(UsbManager.FUNCTION_NONE, true);
+ setEnabledFunctions(UsbManager.FUNCTION_NONE, true, operationId);
}
break;
case MSG_SYSTEM_READY:
+ operationId = sUsbOperationCount.incrementAndGet();
mNotificationManager = (NotificationManager)
mContext.getSystemService(Context.NOTIFICATION_SERVICE);
@@ -1092,17 +1163,19 @@
NotificationManager.IMPORTANCE_HIGH));
}
mSystemReady = true;
- finishBoot();
+ finishBoot(operationId);
break;
case MSG_LOCALE_CHANGED:
updateAdbNotification(true);
updateUsbNotification(true);
break;
case MSG_BOOT_COMPLETED:
+ operationId = sUsbOperationCount.incrementAndGet();
mBootCompleted = true;
- finishBoot();
+ finishBoot(operationId);
break;
case MSG_USER_SWITCHED: {
+ operationId = sUsbOperationCount.incrementAndGet();
if (mCurrentUser != msg.arg1) {
if (DEBUG) {
Slog.v(TAG, "Current user switched to " + msg.arg1);
@@ -1115,16 +1188,18 @@
mSettings.getString(String.format(Locale.ENGLISH,
UNLOCKED_CONFIG_PREF, mCurrentUser), ""));
}
- setEnabledFunctions(UsbManager.FUNCTION_NONE, false);
+ setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId);
}
break;
}
case MSG_ACCESSORY_MODE_ENTER_TIMEOUT: {
+ operationId = sUsbOperationCount.incrementAndGet();
if (DEBUG) {
- Slog.v(TAG, "Accessory mode enter timeout: " + mConnected);
+ Slog.v(TAG, "Accessory mode enter timeout: " + mConnected
+ + " ,operationId: " + operationId);
}
if (!mConnected || (mCurrentFunctions & UsbManager.FUNCTION_ACCESSORY) == 0) {
- notifyAccessoryModeExit();
+ notifyAccessoryModeExit(operationId);
}
break;
}
@@ -1147,7 +1222,9 @@
}
}
- protected void finishBoot() {
+ public abstract void handlerInitDone(int operationId);
+
+ protected void finishBoot(int operationId) {
if (mBootCompleted && mCurrentUsbFunctionsReceived && mSystemReady) {
if (mPendingBootBroadcast) {
updateUsbStateBroadcastIfNeeded(getAppliedFunctions(mCurrentFunctions));
@@ -1155,9 +1232,9 @@
}
if (!mScreenLocked
&& mScreenUnlockedFunctions != UsbManager.FUNCTION_NONE) {
- setScreenUnlockedFunctions();
+ setScreenUnlockedFunctions(operationId);
} else {
- setEnabledFunctions(UsbManager.FUNCTION_NONE, false);
+ setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId);
}
if (mCurrentAccessory != null) {
mUsbDeviceManager.getCurrentSettings().accessoryAttached(mCurrentAccessory);
@@ -1491,7 +1568,8 @@
/**
* Evaluates USB function policies and applies the change accordingly.
*/
- protected abstract void setEnabledFunctions(long functions, boolean forceRestart);
+ protected abstract void setEnabledFunctions(long functions,
+ boolean forceRestart, int operationId);
public void setAccessoryUEventTime(long accessoryConnectionStartTime) {
mAccessoryConnectionStartTime = accessoryConnectionStartTime;
@@ -1506,6 +1584,11 @@
mSendStringCount = 0;
mStartAccessory = false;
}
+
+ public abstract void setCurrentUsbFunctionsCb(long functions,
+ int status, int mRequest, long mFunctions, boolean mChargingFunctions);
+
+ public abstract void getUsbSpeedCb(int speed);
}
private static final class UsbHandlerLegacy extends UsbHandler {
@@ -1524,6 +1607,11 @@
private String mCurrentFunctionsStr;
private boolean mUsbDataUnlocked;
+ /**
+ * Keeps track of the latest setCurrentUsbFunctions request number.
+ */
+ private int mCurrentRequest = 0;
+
UsbHandlerLegacy(Looper looper, Context context, UsbDeviceManager deviceManager,
UsbAlsaManager alsaManager, UsbPermissionManager permissionManager) {
super(looper, context, deviceManager, alsaManager, permissionManager);
@@ -1557,6 +1645,10 @@
}
}
+ @Override
+ public void handlerInitDone(int operationId) {
+ }
+
private void readOemUsbOverrideConfig(Context context) {
String[] configList = context.getResources().getStringArray(
com.android.internal.R.array.config_oemUsbModeOverride);
@@ -1659,11 +1751,14 @@
}
@Override
- protected void setEnabledFunctions(long usbFunctions, boolean forceRestart) {
+ protected void setEnabledFunctions(long usbFunctions,
+ boolean forceRestart, int operationId) {
boolean usbDataUnlocked = isUsbDataTransferActive(usbFunctions);
if (DEBUG) {
- Slog.d(TAG, "setEnabledFunctions functions=" + usbFunctions + ", "
- + "forceRestart=" + forceRestart + ", usbDataUnlocked=" + usbDataUnlocked);
+ Slog.d(TAG, "setEnabledFunctions functions=" + usbFunctions +
+ " ,forceRestart=" + forceRestart +
+ " ,usbDataUnlocked=" + usbDataUnlocked +
+ " ,operationId=" + operationId);
}
if (usbDataUnlocked != mUsbDataUnlocked) {
@@ -1759,7 +1854,6 @@
|| !mCurrentFunctionsStr.equals(functions)
|| !mCurrentFunctionsApplied
|| forceRestart) {
- Slog.i(TAG, "Setting USB config to " + functions);
mCurrentFunctionsStr = functions;
mCurrentOemFunctions = oemFunctions;
mCurrentFunctionsApplied = false;
@@ -1855,15 +1949,18 @@
if (charAfter < functions.length() && functions.charAt(charAfter) != ',') return false;
return true;
}
+
+ @Override
+ public void setCurrentUsbFunctionsCb(long functions,
+ int status, int mRequest, long mFunctions, boolean mChargingFunctions){
+ }
+
+ @Override
+ public void getUsbSpeedCb(int speed){
+ }
}
- private static final class UsbHandlerHal extends UsbHandler {
-
- /**
- * Proxy object for the usb gadget hal daemon.
- */
- @GuardedBy("mGadgetProxyLock")
- private IUsbGadget mGadgetProxy;
+ private final class UsbHandlerHal extends UsbHandler {
private final Object mGadgetProxyLock = new Object();
@@ -1910,33 +2007,20 @@
UsbHandlerHal(Looper looper, Context context, UsbDeviceManager deviceManager,
UsbAlsaManager alsaManager, UsbPermissionManager permissionManager) {
super(looper, context, deviceManager, alsaManager, permissionManager);
+ int operationId = sUsbOperationCount.incrementAndGet();
try {
- ServiceNotification serviceNotification = new ServiceNotification();
-
- boolean ret = IServiceManager.getService()
- .registerForNotifications(GADGET_HAL_FQ_NAME, "", serviceNotification);
- if (!ret) {
- Slog.e(TAG, "Failed to register usb gadget service start notification");
- return;
- }
synchronized (mGadgetProxyLock) {
- mGadgetProxy = IUsbGadget.getService(true);
- mGadgetProxy.linkToDeath(new UsbGadgetDeathRecipient(),
- USB_GADGET_HAL_DEATH_COOKIE);
mCurrentFunctions = UsbManager.FUNCTION_NONE;
mCurrentUsbFunctionsRequested = true;
mUsbSpeed = UsbSpeed.UNKNOWN;
mCurrentGadgetHalVersion = UsbManager.GADGET_HAL_V1_0;
- mGadgetProxy.getCurrentUsbFunctions(new UsbGadgetCallback());
+ updateUsbGadgetHalVersion();
}
String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim();
updateState(state);
- updateUsbGadgetHalVersion();
} catch (NoSuchElementException e) {
Slog.e(TAG, "Usb gadget hal not found", e);
- } catch (RemoteException e) {
- Slog.e(TAG, "Usb Gadget hal not responding", e);
} catch (Exception e) {
Slog.e(TAG, "Error initializing UsbHandler", e);
}
@@ -1949,7 +2033,7 @@
if (cookie == USB_GADGET_HAL_DEATH_COOKIE) {
Slog.e(TAG, "Usb Gadget hal service died cookie: " + cookie);
synchronized (mGadgetProxyLock) {
- mGadgetProxy = null;
+ mUsbGadgetHal = null;
}
}
}
@@ -1972,18 +2056,22 @@
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SET_CHARGING_FUNCTIONS:
- setEnabledFunctions(UsbManager.FUNCTION_NONE, false);
+ int operationId = sUsbOperationCount.incrementAndGet();
+ setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId);
break;
case MSG_SET_FUNCTIONS_TIMEOUT:
- Slog.e(TAG, "Set functions timed out! no reply from usb hal");
+ operationId = sUsbOperationCount.incrementAndGet();
+ Slog.e(TAG, "Set functions timed out! no reply from usb hal"
+ + " ,operationId:" + operationId);
if (msg.arg1 != 1) {
// Set this since default function may be selected from Developer options
- setEnabledFunctions(mScreenUnlockedFunctions, false);
+ setEnabledFunctions(mScreenUnlockedFunctions, false, operationId);
}
break;
case MSG_GET_CURRENT_USB_FUNCTIONS:
Slog.i(TAG, "processing MSG_GET_CURRENT_USB_FUNCTIONS");
mCurrentUsbFunctionsReceived = true;
+ operationId = msg.arg2;
if (mCurrentUsbFunctionsRequested) {
Slog.i(TAG, "updating mCurrentFunctions");
@@ -1993,91 +2081,71 @@
"mCurrentFunctions:" + mCurrentFunctions + "applied:" + msg.arg1);
mCurrentFunctionsApplied = msg.arg1 == 1;
}
- finishBoot();
+ finishBoot(operationId);
break;
case MSG_FUNCTION_SWITCH_TIMEOUT:
/**
* Dont force to default when the configuration is already set to default.
*/
+ operationId = sUsbOperationCount.incrementAndGet();
if (msg.arg1 != 1) {
// Set this since default function may be selected from Developer options
- setEnabledFunctions(mScreenUnlockedFunctions, false);
+ setEnabledFunctions(mScreenUnlockedFunctions, false, operationId);
}
break;
case MSG_GADGET_HAL_REGISTERED:
boolean preexisting = msg.arg1 == 1;
+ operationId = sUsbOperationCount.incrementAndGet();
synchronized (mGadgetProxyLock) {
try {
- mGadgetProxy = IUsbGadget.getService();
- mGadgetProxy.linkToDeath(new UsbGadgetDeathRecipient(),
- USB_GADGET_HAL_DEATH_COOKIE);
+ mUsbGadgetHal = UsbGadgetHalInstance.getInstance(mUsbDeviceManager,
+ null);
if (!mCurrentFunctionsApplied && !preexisting) {
- setEnabledFunctions(mCurrentFunctions, false);
+ setEnabledFunctions(mCurrentFunctions, false, operationId);
}
} catch (NoSuchElementException e) {
Slog.e(TAG, "Usb gadget hal not found", e);
- } catch (RemoteException e) {
- Slog.e(TAG, "Usb Gadget hal not responding", e);
}
}
break;
case MSG_RESET_USB_GADGET:
synchronized (mGadgetProxyLock) {
- if (mGadgetProxy == null) {
- Slog.e(TAG, "reset Usb Gadget mGadgetProxy is null");
+ if (mUsbGadgetHal == null) {
+ Slog.e(TAG, "reset Usb Gadget mUsbGadgetHal is null");
break;
}
try {
- android.hardware.usb.gadget.V1_1.IUsbGadget gadgetProxy =
- android.hardware.usb.gadget.V1_1.IUsbGadget
- .castFrom(mGadgetProxy);
- gadgetProxy.reset();
- } catch (RemoteException e) {
+ mUsbGadgetHal.reset();
+ } catch (Exception e) {
Slog.e(TAG, "reset Usb Gadget failed", e);
}
}
break;
case MSG_UPDATE_USB_SPEED:
- synchronized (mGadgetProxyLock) {
- if (mGadgetProxy == null) {
- Slog.e(TAG, "mGadgetProxy is null");
- break;
- }
+ operationId = sUsbOperationCount.incrementAndGet();
+ if (mUsbGadgetHal == null) {
+ Slog.e(TAG, "mGadgetHal is null, operationId:" + operationId);
+ break;
+ }
- try {
- android.hardware.usb.gadget.V1_2.IUsbGadget gadgetProxy =
- android.hardware.usb.gadget.V1_2.IUsbGadget
- .castFrom(mGadgetProxy);
- if (gadgetProxy != null) {
- gadgetProxy.getUsbSpeed(new UsbGadgetCallback());
- }
- } catch (RemoteException e) {
- Slog.e(TAG, "get UsbSpeed failed", e);
- }
+ try {
+ mUsbGadgetHal.getUsbSpeed(operationId);
+ } catch (Exception e) {
+ Slog.e(TAG, "get UsbSpeed failed", e);
}
break;
case MSG_UPDATE_HAL_VERSION:
- synchronized (mGadgetProxyLock) {
- if (mGadgetProxy == null) {
- Slog.e(TAG, "mGadgetProxy is null");
- break;
+ if (mUsbGadgetHal == null) {
+ Slog.e(TAG, "mUsbGadgetHal is null");
+ break;
+ }
+ else {
+ try {
+ mCurrentGadgetHalVersion = mUsbGadgetHal.getGadgetHalVersion();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "update Usb gadget version failed", e);
}
-
- android.hardware.usb.gadget.V1_2.IUsbGadget gadgetProxy =
- android.hardware.usb.gadget.V1_2.IUsbGadget.castFrom(mGadgetProxy);
- if (gadgetProxy == null) {
- android.hardware.usb.gadget.V1_1.IUsbGadget gadgetProxyV1By1 =
- android.hardware.usb.gadget.V1_1.IUsbGadget
- .castFrom(mGadgetProxy);
- if (gadgetProxyV1By1 == null) {
- mCurrentGadgetHalVersion = UsbManager.GADGET_HAL_V1_0;
- break;
- }
- mCurrentGadgetHalVersion = UsbManager.GADGET_HAL_V1_1;
- break;
- }
- mCurrentGadgetHalVersion = UsbManager.GADGET_HAL_V1_2;
}
break;
default:
@@ -2085,56 +2153,31 @@
}
}
- private class UsbGadgetCallback extends IUsbGadgetCallback.Stub {
- int mRequest;
- long mFunctions;
- boolean mChargingFunctions;
+ @Override
+ public void setCurrentUsbFunctionsCb(long functions,
+ int status, int mRequest, long mFunctions, boolean mChargingFunctions) {
- UsbGadgetCallback() {
+ if ((mCurrentRequest != mRequest) || !hasMessages(MSG_SET_FUNCTIONS_TIMEOUT)
+ || (mFunctions != functions)) {
+ return;
}
- UsbGadgetCallback(int request, long functions,
- boolean chargingFunctions) {
- mRequest = request;
- mFunctions = functions;
- mChargingFunctions = chargingFunctions;
- }
-
- @Override
- public void setCurrentUsbFunctionsCb(long functions,
- int status) {
- /**
- * Callback called for a previous setCurrenUsbFunction
- */
- if ((mCurrentRequest != mRequest) || !hasMessages(MSG_SET_FUNCTIONS_TIMEOUT)
- || (mFunctions != functions)) {
- return;
- }
-
- removeMessages(MSG_SET_FUNCTIONS_TIMEOUT);
- Slog.e(TAG, "notifyCurrentFunction request:" + mRequest + " status:" + status);
- if (status == Status.SUCCESS) {
- mCurrentFunctionsApplied = true;
- } else if (!mChargingFunctions) {
- Slog.e(TAG, "Setting default fuctions");
- sendEmptyMessage(MSG_SET_CHARGING_FUNCTIONS);
- }
- }
-
- @Override
- public void getCurrentUsbFunctionsCb(long functions,
- int status) {
- sendMessage(MSG_GET_CURRENT_USB_FUNCTIONS, functions,
- status == Status.FUNCTIONS_APPLIED);
- }
-
- @Override
- public void getUsbSpeedCb(int speed) {
- mUsbSpeed = speed;
+ removeMessages(MSG_SET_FUNCTIONS_TIMEOUT);
+ Slog.i(TAG, "notifyCurrentFunction request:" + mRequest + " status:" + status);
+ if (status == Status.SUCCESS) {
+ mCurrentFunctionsApplied = true;
+ } else if (!mChargingFunctions) {
+ Slog.e(TAG, "Setting default fuctions");
+ sendEmptyMessage(MSG_SET_CHARGING_FUNCTIONS);
}
}
- private void setUsbConfig(long config, boolean chargingFunctions) {
+ @Override
+ public void getUsbSpeedCb(int speed) {
+ mUsbSpeed = speed;
+ }
+
+ private void setUsbConfig(long config, boolean chargingFunctions, int operationId) {
if (true) Slog.d(TAG, "setUsbConfig(" + config + ") request:" + ++mCurrentRequest);
/**
* Cancel any ongoing requests, if present.
@@ -2144,8 +2187,8 @@
removeMessages(MSG_SET_CHARGING_FUNCTIONS);
synchronized (mGadgetProxyLock) {
- if (mGadgetProxy == null) {
- Slog.e(TAG, "setUsbConfig mGadgetProxy is null");
+ if (mUsbGadgetHal == null) {
+ Slog.e(TAG, "setUsbConfig mUsbGadgetHal is null");
return;
}
try {
@@ -2162,10 +2205,9 @@
LocalServices.getService(AdbManagerInternal.class)
.stopAdbdForTransport(AdbTransportType.USB);
}
- UsbGadgetCallback usbGadgetCallback = new UsbGadgetCallback(mCurrentRequest,
- config, chargingFunctions);
- mGadgetProxy.setCurrentUsbFunctions(config, usbGadgetCallback,
- SET_FUNCTIONS_TIMEOUT_MS - SET_FUNCTIONS_LEEWAY_MS);
+ mUsbGadgetHal.setCurrentUsbFunctions(mCurrentRequest,
+ config, chargingFunctions,
+ SET_FUNCTIONS_TIMEOUT_MS - SET_FUNCTIONS_LEEWAY_MS, operationId);
sendMessageDelayed(MSG_SET_FUNCTIONS_TIMEOUT, chargingFunctions,
SET_FUNCTIONS_TIMEOUT_MS);
if (mConnected) {
@@ -2174,17 +2216,19 @@
SET_FUNCTIONS_TIMEOUT_MS + ENUMERATION_TIME_OUT_MS);
}
if (DEBUG) Slog.d(TAG, "timeout message queued");
- } catch (RemoteException e) {
+ } catch (Exception e) {//RemoteException e) {
Slog.e(TAG, "Remoteexception while calling setCurrentUsbFunctions", e);
}
}
}
@Override
- protected void setEnabledFunctions(long functions, boolean forceRestart) {
+ protected void setEnabledFunctions(long functions, boolean forceRestart, int operationId) {
if (DEBUG) {
- Slog.d(TAG, "setEnabledFunctions functions=" + functions + ", "
- + "forceRestart=" + forceRestart);
+ Slog.d(TAG, "setEnabledFunctionsi " +
+ "functions=" + functions +
+ ", forceRestart=" + forceRestart +
+ ", operationId=" + operationId);
}
if (mCurrentGadgetHalVersion < UsbManager.GADGET_HAL_V1_2) {
if ((functions & UsbManager.FUNCTION_NCM) != 0) {
@@ -2205,7 +2249,7 @@
functions = getAppliedFunctions(functions);
// Set the new USB configuration.
- setUsbConfig(functions, chargingFunctions);
+ setUsbConfig(functions, chargingFunctions, operationId);
if (mBootCompleted && isUsbDataTransferActive(functions)) {
// Start up dependent services.
@@ -2213,6 +2257,11 @@
}
}
}
+
+ @Override
+ public void handlerInitDone(int operationId) {
+ mUsbGadgetHal.getCurrentUsbFunctions(operationId);
+ }
}
/* returns the currently attached USB accessory */
@@ -2254,6 +2303,21 @@
return mHandler.getGadgetHalVersion();
}
+ public void setCurrentUsbFunctionsCb(long functions,
+ int status, int mRequest, long mFunctions, boolean mChargingFunctions) {
+ mHandler.setCurrentUsbFunctionsCb(functions, status,
+ mRequest, mFunctions, mChargingFunctions);
+ }
+
+ public void getCurrentUsbFunctionsCb(long functions, int status) {
+ mHandler.sendMessage(MSG_GET_CURRENT_USB_FUNCTIONS, functions,
+ status == Status.FUNCTIONS_APPLIED);
+ }
+
+ public void getUsbSpeedCb(int speed) {
+ mHandler.getUsbSpeedCb(speed);
+ }
+
/**
* Returns a dup of the control file descriptor for the given function.
*/
@@ -2279,7 +2343,7 @@
*
* @param functions The functions to set, or empty to set the charging function.
*/
- public void setCurrentFunctions(long functions) {
+ public void setCurrentFunctions(long functions, int operationId) {
if (DEBUG) {
Slog.d(TAG, "setCurrentFunctions(" + UsbManager.usbFunctionsToString(functions) + ")");
}
@@ -2296,7 +2360,7 @@
} else if (functions == UsbManager.FUNCTION_ACCESSORY) {
MetricsLogger.action(mContext, MetricsEvent.ACTION_USB_CONFIG_ACCESSORY);
}
- mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions);
+ mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions, operationId);
}
/**
@@ -2324,7 +2388,8 @@
}
private void onAdbEnabled(boolean enabled) {
- mHandler.sendMessage(MSG_ENABLE_ADB, enabled);
+ int operationId = sUsbOperationCount.incrementAndGet();
+ mHandler.sendMessage(MSG_ENABLE_ADB, enabled, operationId);
}
/**
diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java
index 86f877f..6e0d799 100644
--- a/services/usb/java/com/android/server/usb/UsbService.java
+++ b/services/usb/java/com/android/server/usb/UsbService.java
@@ -605,16 +605,16 @@
}
@Override
- public void setCurrentFunctions(long functions) {
+ public void setCurrentFunctions(long functions, int operationId) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
Preconditions.checkArgument(UsbManager.areSettableFunctions(functions));
Preconditions.checkState(mDeviceManager != null);
- mDeviceManager.setCurrentFunctions(functions);
+ mDeviceManager.setCurrentFunctions(functions, operationId);
}
@Override
- public void setCurrentFunction(String functions, boolean usbDataUnlocked) {
- setCurrentFunctions(UsbManager.usbFunctionsFromString(functions));
+ public void setCurrentFunction(String functions, boolean usbDataUnlocked, int operationId) {
+ setCurrentFunctions(UsbManager.usbFunctionsFromString(functions), operationId);
}
@Override
diff --git a/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetAidl.java b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetAidl.java
new file mode 100644
index 0000000..bdfe60a
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetAidl.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2022 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.usb.hal.gadget;
+
+import static android.hardware.usb.UsbManager.GADGET_HAL_V2_0;
+
+import static com.android.server.usb.UsbDeviceManager.logAndPrint;
+import static com.android.server.usb.UsbDeviceManager.logAndPrintException;
+
+import android.annotation.Nullable;
+import android.hardware.usb.gadget.IUsbGadget;
+import android.hardware.usb.gadget.IUsbGadgetCallback;
+import android.hardware.usb.UsbManager.UsbGadgetHalVersion;
+import android.os.ServiceManager;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+import android.util.LongSparseArray;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.usb.UsbDeviceManager;
+
+import java.util.ArrayList;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+
+/**
+ * Implements the methods to interact with AIDL USB HAL.
+ */
+public final class UsbGadgetAidl implements UsbGadgetHal {
+ private static final String TAG = UsbGadgetAidl.class.getSimpleName();
+ private static final String USB_GADGET_AIDL_SERVICE = IUsbGadget.DESCRIPTOR + "/default";
+ // Proxy object for the usb gadget hal daemon.
+ @GuardedBy("mGadgetProxyLock")
+ private IUsbGadget mGadgetProxy;
+ private final UsbDeviceManager mDeviceManager;
+ public final IndentingPrintWriter mPw;
+ // Mutex for all mutable shared state.
+ private final Object mGadgetProxyLock = new Object();
+ // Callback when the UsbDevice status is changed by the kernel.
+ private UsbGadgetCallback mUsbGadgetCallback;
+
+ public @UsbGadgetHalVersion int getGadgetHalVersion() throws RemoteException {
+ synchronized (mGadgetProxyLock) {
+ if (mGadgetProxy == null) {
+ throw new RemoteException("IUsb not initialized yet");
+ }
+ }
+ Slog.i(TAG, "USB Gadget HAL AIDL version: GADGET_HAL_V2_0");
+ return GADGET_HAL_V2_0;
+ }
+
+ @Override
+ public void systemReady() {
+ }
+
+ public void serviceDied() {
+ logAndPrint(Log.ERROR, mPw, "Usb Gadget AIDL hal service died");
+ synchronized (mGadgetProxyLock) {
+ mGadgetProxy = null;
+ }
+ connectToProxy(null);
+ }
+
+ private void connectToProxy(IndentingPrintWriter pw) {
+ synchronized (mGadgetProxyLock) {
+ if (mGadgetProxy != null) {
+ return;
+ }
+
+ try {
+ mGadgetProxy = IUsbGadget.Stub.asInterface(
+ ServiceManager.waitForService(USB_GADGET_AIDL_SERVICE));
+ } catch (NoSuchElementException e) {
+ logAndPrintException(pw, "connectToProxy: usb gadget hal service not found."
+ + " Did the service fail to start?", e);
+ }
+ }
+ }
+
+ static boolean isServicePresent(IndentingPrintWriter pw) {
+ try {
+ return ServiceManager.isDeclared(USB_GADGET_AIDL_SERVICE);
+ } catch (NoSuchElementException e) {
+ logAndPrintException(pw, "connectToProxy: usb gadget Aidl hal service not found.", e);
+ }
+
+ return false;
+ }
+
+ public UsbGadgetAidl(UsbDeviceManager deviceManager, IndentingPrintWriter pw) {
+ mDeviceManager = Objects.requireNonNull(deviceManager);
+ mPw = pw;
+ connectToProxy(mPw);
+ }
+
+ @Override
+ public void getCurrentUsbFunctions(long operationId) {
+ synchronized (mGadgetProxyLock) {
+ try {
+ mGadgetProxy.getCurrentUsbFunctions(new UsbGadgetCallback(), operationId);
+ } catch (RemoteException e) {
+ logAndPrintException(mPw,
+ "RemoteException while calling getCurrentUsbFunctions"
+ + ", opID:" + operationId, e);
+ return;
+ }
+ }
+ }
+
+ @Override
+ public void getUsbSpeed(long operationId) {
+ try {
+ synchronized (mGadgetProxyLock) {
+ mGadgetProxy.getUsbSpeed(new UsbGadgetCallback(), operationId);
+ }
+ } catch (RemoteException e) {
+ logAndPrintException(mPw,
+ "RemoteException while calling getUsbSpeed"
+ + ", opID:" + operationId, e);
+ return;
+ }
+ }
+
+ @Override
+ public void reset() {
+ try {
+ synchronized (mGadgetProxyLock) {
+ mGadgetProxy.reset();
+ }
+ } catch (RemoteException e) {
+ logAndPrintException(mPw,
+ "RemoteException while calling getUsbSpeed", e);
+ return;
+ }
+ }
+
+ @Override
+ public void setCurrentUsbFunctions(int mRequest, long mFunctions,
+ boolean mChargingFunctions, int timeout, long operationId) {
+ try {
+ mUsbGadgetCallback = new UsbGadgetCallback(mRequest,
+ mFunctions, mChargingFunctions);
+ synchronized (mGadgetProxyLock) {
+ mGadgetProxy.setCurrentUsbFunctions(mFunctions, mUsbGadgetCallback,
+ timeout, operationId);
+ }
+ } catch (RemoteException e) {
+ logAndPrintException(mPw,
+ "RemoteException while calling setCurrentUsbFunctions: "
+ + "mRequest=" + mRequest
+ + ", mFunctions=" + mFunctions
+ + ", mChargingFunctions=" + mChargingFunctions
+ + ", timeout=" + timeout
+ + ", opID:" + operationId, e);
+ return;
+ }
+ }
+
+ private class UsbGadgetCallback extends IUsbGadgetCallback.Stub {
+ public int mRequest;
+ public long mFunctions;
+ public boolean mChargingFunctions;
+
+ UsbGadgetCallback() {
+ }
+
+ UsbGadgetCallback(int request, long functions,
+ boolean chargingFunctions) {
+ mRequest = request;
+ mFunctions = functions;
+ mChargingFunctions = chargingFunctions;
+ }
+
+ @Override
+ public void setCurrentUsbFunctionsCb(long functions,
+ int status, long transactionId) {
+ mDeviceManager.setCurrentUsbFunctionsCb(functions, status,
+ mRequest, mFunctions, mChargingFunctions);
+ }
+
+ @Override
+ public void getCurrentUsbFunctionsCb(long functions,
+ int status, long transactionId) {
+ mDeviceManager.getCurrentUsbFunctionsCb(functions, status);
+ }
+
+ @Override
+ public void getUsbSpeedCb(int speed, long transactionId) {
+ mDeviceManager.getUsbSpeedCb(speed);
+ }
+
+ @Override
+ public String getInterfaceHash() {
+ return IUsbGadgetCallback.HASH;
+ }
+
+ @Override
+ public int getInterfaceVersion() {
+ return IUsbGadgetCallback.VERSION;
+ }
+ }
+}
+
diff --git a/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHal.java b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHal.java
new file mode 100644
index 0000000..267247b
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHal.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2022 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.usb.hal.gadget;
+
+import android.annotation.IntDef;
+import android.hardware.usb.gadget.IUsbGadgetCallback;
+import android.hardware.usb.IUsbOperationInternal;
+import android.hardware.usb.UsbManager.UsbHalVersion;
+import android.os.RemoteException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.String;
+
+/**
+ * @hide
+ */
+public interface UsbGadgetHal {
+ /**
+ * Power role: This USB port can act as a source (provide power).
+ * @hide
+ */
+ public static final int HAL_POWER_ROLE_SOURCE = 1;
+
+ /**
+ * Power role: This USB port can act as a sink (receive power).
+ * @hide
+ */
+ public static final int HAL_POWER_ROLE_SINK = 2;
+
+ @IntDef(prefix = { "HAL_POWER_ROLE_" }, value = {
+ HAL_POWER_ROLE_SOURCE,
+ HAL_POWER_ROLE_SINK
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface HalUsbPowerRole{}
+
+ /**
+ * Data role: This USB port can act as a host (access data services).
+ * @hide
+ */
+ public static final int HAL_DATA_ROLE_HOST = 1;
+
+ /**
+ * Data role: This USB port can act as a device (offer data services).
+ * @hide
+ */
+ public static final int HAL_DATA_ROLE_DEVICE = 2;
+
+ @IntDef(prefix = { "HAL_DATA_ROLE_" }, value = {
+ HAL_DATA_ROLE_HOST,
+ HAL_DATA_ROLE_DEVICE
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface HalUsbDataRole{}
+
+ /**
+ * This USB port can act as a downstream facing port (host).
+ *
+ * @hide
+ */
+ public static final int HAL_MODE_DFP = 1;
+
+ /**
+ * This USB port can act as an upstream facing port (device).
+ *
+ * @hide
+ */
+ public static final int HAL_MODE_UFP = 2;
+ @IntDef(prefix = { "HAL_MODE_" }, value = {
+ HAL_MODE_DFP,
+ HAL_MODE_UFP,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface HalUsbPortMode{}
+
+ /**
+ * UsbPortManager would call this when the system is done booting.
+ */
+ public void systemReady();
+
+ /**
+ * This function is used to query the USB functions included in the
+ * current USB configuration.
+ *
+ * @param transactionId Used for tracking the current request and is passed down to the HAL
+ * implementation as needed.
+ */
+ public void getCurrentUsbFunctions(long transactionId);
+
+ /**
+ * The function is used to query current USB speed.
+ *
+ * @param transactionId Used for tracking the current request and is passed down to the HAL
+ * implementation as needed.
+ */
+ public void getUsbSpeed(long transactionId);
+
+ /**
+ * This function is used to reset USB gadget driver.
+ * Performs USB data connection reset. The connection will disconnect and
+ * reconnect.
+ */
+ public void reset();
+
+ /**
+ * Invoked to query the version of current gadget hal implementation.
+ */
+ public @UsbHalVersion int getGadgetHalVersion() throws RemoteException;
+
+ /**
+ * This function is used to set the current USB gadget configuration.
+ * The USB gadget needs to be torn down if a USB configuration is already
+ * active.
+ *
+ * @param functions list of functions defined by GadgetFunction to be
+ * included in the gadget composition.
+ * @param timeout The maximum time (in milliseconds) within which the
+ * IUsbGadgetCallback needs to be returned.
+ * @param transactionId Used for tracking the current request and is passed down to the HAL
+ * implementation as needed.
+ */
+ public void setCurrentUsbFunctions(int request, long functions,
+ boolean chargingFunctions, int timeout, long transactionId);
+}
+
diff --git a/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHalInstance.java b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHalInstance.java
new file mode 100644
index 0000000..d268315
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHalInstance.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 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.usb.hal.gadget;
+
+import static com.android.server.usb.UsbPortManager.logAndPrint;
+
+import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.usb.hal.gadget.UsbGadgetHidl;
+import com.android.server.usb.hal.gadget.UsbGadgetAidl;
+import com.android.server.usb.UsbDeviceManager;
+
+import android.util.Log;
+/**
+ * Helper class that queries the underlying hal layer to populate UsbPortHal instance.
+ */
+public final class UsbGadgetHalInstance {
+
+ public static UsbGadgetHal getInstance(UsbDeviceManager deviceManager,
+ IndentingPrintWriter pw) {
+
+ logAndPrint(Log.DEBUG, pw, "Querying USB Gadget HAL version");
+ if (UsbGadgetAidl.isServicePresent(null)) {
+ logAndPrint(Log.INFO, pw, "USB Gadget HAL AIDL present");
+ return new UsbGadgetAidl(deviceManager, pw);
+ }
+ if (UsbGadgetHidl.isServicePresent(null)) {
+ logAndPrint(Log.INFO, pw, "USB Gadget HAL HIDL present");
+ return new UsbGadgetHidl(deviceManager, pw);
+ }
+
+ logAndPrint(Log.ERROR, pw, "USB Gadget HAL AIDL/HIDL not present");
+ return null;
+ }
+}
+
diff --git a/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHidl.java b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHidl.java
new file mode 100644
index 0000000..3e5ecc5
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHidl.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2022 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.usb.hal.gadget;
+
+import static android.hardware.usb.UsbManager.GADGET_HAL_NOT_SUPPORTED;
+import static android.hardware.usb.UsbManager.GADGET_HAL_V1_0;
+import static android.hardware.usb.UsbManager.GADGET_HAL_V1_1;
+import static android.hardware.usb.UsbManager.GADGET_HAL_V1_2;
+
+import static com.android.server.usb.UsbDeviceManager.logAndPrint;
+import static com.android.server.usb.UsbDeviceManager.logAndPrintException;
+
+import android.annotation.Nullable;
+import android.hardware.usb.gadget.V1_0.Status;
+import android.hardware.usb.gadget.V1_0.IUsbGadget;
+import android.hardware.usb.gadget.V1_2.IUsbGadgetCallback;
+import android.hardware.usb.gadget.V1_2.UsbSpeed;
+import android.hardware.usb.UsbAccessory;
+import android.hardware.usb.UsbManager;
+import android.hardware.usb.UsbManager.UsbGadgetHalVersion;
+import android.hardware.usb.UsbManager.UsbHalVersion;
+import android.hidl.manager.V1_0.IServiceManager;
+import android.hidl.manager.V1_0.IServiceNotification;
+import android.os.IHwBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.usb.UsbDeviceManager;
+
+import java.util.ArrayList;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+/**
+ *
+ */
+public final class UsbGadgetHidl implements UsbGadgetHal {
+ // Cookie sent for usb gadget hal death notification.
+ private static final int USB_GADGET_HAL_DEATH_COOKIE = 2000;
+ // Proxy object for the usb gadget hal daemon.
+ @GuardedBy("mGadgetProxyLock")
+ private IUsbGadget mGadgetProxy;
+ private UsbDeviceManager mDeviceManager;
+ private final IndentingPrintWriter mPw;
+ // Mutex for all mutable shared state.
+ private final Object mGadgetProxyLock = new Object();
+ private UsbGadgetCallback mUsbGadgetCallback;
+
+ public @UsbGadgetHalVersion int getGadgetHalVersion() throws RemoteException {
+ int version;
+ synchronized(mGadgetProxyLock) {
+ if (mGadgetProxy == null) {
+ throw new RemoteException("IUsbGadget not initialized yet");
+ }
+ if (android.hardware.usb.gadget.V1_2.IUsbGadget.castFrom(mGadgetProxy) != null) {
+ version = UsbManager.GADGET_HAL_V1_2;
+ } else if (android.hardware.usb.gadget.V1_1.IUsbGadget.castFrom(mGadgetProxy) != null) {
+ version = UsbManager.GADGET_HAL_V1_1;
+ } else {
+ version = UsbManager.GADGET_HAL_V1_0;
+ }
+ logAndPrint(Log.INFO, mPw, "USB Gadget HAL HIDL version: " + version);
+ return version;
+ }
+ }
+
+ final class DeathRecipient implements IHwBinder.DeathRecipient {
+ private final IndentingPrintWriter mPw;
+
+ DeathRecipient(IndentingPrintWriter pw) {
+ mPw = pw;
+ }
+
+ @Override
+ public void serviceDied(long cookie) {
+ if (cookie == USB_GADGET_HAL_DEATH_COOKIE) {
+ logAndPrint(Log.ERROR, mPw, "Usb Gadget hal service died cookie: " + cookie);
+ synchronized (mGadgetProxyLock) {
+ mGadgetProxy = null;
+ }
+ }
+ }
+ }
+
+ final class ServiceNotification extends IServiceNotification.Stub {
+ @Override
+ public void onRegistration(String fqName, String name, boolean preexisting) {
+ logAndPrint(Log.INFO, mPw, "Usb gadget hal service started " + fqName + " " + name);
+ connectToProxy(null);
+ }
+ }
+
+ private void connectToProxy(IndentingPrintWriter pw) {
+ synchronized (mGadgetProxyLock) {
+ if (mGadgetProxy != null) {
+ return;
+ }
+
+ try {
+ mGadgetProxy = IUsbGadget.getService();
+ mGadgetProxy.linkToDeath(new DeathRecipient(pw), USB_GADGET_HAL_DEATH_COOKIE);
+ } catch (NoSuchElementException e) {
+ logAndPrintException(pw, "connectToProxy: usb gadget hal service not found."
+ + " Did the service fail to start?", e);
+ } catch (RemoteException e) {
+ logAndPrintException(pw, "connectToProxy: usb gadget hal service not responding"
+ , e);
+ }
+ }
+ }
+
+ @Override
+ public void systemReady() {
+ }
+
+ static boolean isServicePresent(IndentingPrintWriter pw) {
+ try {
+ IUsbGadget.getService(true);
+ } catch (NoSuchElementException e) {
+ logAndPrintException(pw, "connectToProxy: usb gadget hidl hal service not found.", e);
+ return false;
+ } catch (RemoteException e) {
+ logAndPrintException(pw, "IUSBGadget hal service present but failed to get service", e);
+ }
+
+ return true;
+ }
+
+ public UsbGadgetHidl(UsbDeviceManager deviceManager, IndentingPrintWriter pw) {
+ mDeviceManager = Objects.requireNonNull(deviceManager);
+ mPw = pw;
+ try {
+ ServiceNotification serviceNotification = new ServiceNotification();
+
+ boolean ret = IServiceManager.getService()
+ .registerForNotifications("android.hardware.usb.gadget@1.0::IUsbGadget",
+ "", serviceNotification);
+ if (!ret) {
+ logAndPrint(Log.ERROR, pw, "Failed to register service start notification");
+ }
+ } catch (RemoteException e) {
+ logAndPrintException(pw, "Failed to register service start notification", e);
+ return;
+ }
+ connectToProxy(mPw);
+ }
+
+ @Override
+ public void getCurrentUsbFunctions(long transactionId) {
+ try {
+ synchronized(mGadgetProxyLock) {
+ mGadgetProxy.getCurrentUsbFunctions(new UsbGadgetCallback());
+ }
+ } catch (RemoteException e) {
+ logAndPrintException(mPw,
+ "RemoteException while calling getCurrentUsbFunctions", e);
+ return;
+ }
+ }
+
+ @Override
+ public void getUsbSpeed(long transactionId) {
+ try {
+ synchronized(mGadgetProxyLock) {
+ if (android.hardware.usb.gadget.V1_2.IUsbGadget.castFrom(mGadgetProxy) != null) {
+ android.hardware.usb.gadget.V1_2.IUsbGadget gadgetProxy =
+ android.hardware.usb.gadget.V1_2.IUsbGadget.castFrom(mGadgetProxy);
+ gadgetProxy.getUsbSpeed(new UsbGadgetCallback());
+ }
+ }
+ } catch (RemoteException e) {
+ logAndPrintException(mPw, "get UsbSpeed failed", e);
+ }
+ }
+
+ @Override
+ public void reset() {
+ try {
+ synchronized(mGadgetProxyLock) {
+ if (android.hardware.usb.gadget.V1_2.IUsbGadget.castFrom(mGadgetProxy) != null) {
+ android.hardware.usb.gadget.V1_2.IUsbGadget gadgetProxy =
+ android.hardware.usb.gadget.V1_2.IUsbGadget.castFrom(mGadgetProxy);
+ gadgetProxy.reset();
+ }
+ }
+ } catch (RemoteException e) {
+ logAndPrintException(mPw,
+ "RemoteException while calling getUsbSpeed", e);
+ return;
+ }
+ }
+
+ @Override
+ public void setCurrentUsbFunctions(int mRequest, long mFunctions,
+ boolean mChargingFunctions, int timeout, long operationId) {
+ try {
+ mUsbGadgetCallback = new UsbGadgetCallback(null, mRequest,
+ mFunctions, mChargingFunctions);
+ synchronized(mGadgetProxyLock) {
+ mGadgetProxy.setCurrentUsbFunctions(mFunctions, mUsbGadgetCallback, timeout);
+ }
+ } catch (RemoteException e) {
+ logAndPrintException(mPw,
+ "RemoteException while calling setCurrentUsbFunctions"
+ + " mRequest = " + mRequest
+ + ", mFunctions = " + mFunctions
+ + ", timeout = " + timeout
+ + ", mChargingFunctions = " + mChargingFunctions
+ + ", operationId =" + operationId, e);
+ return;
+ }
+ }
+
+ private class UsbGadgetCallback extends IUsbGadgetCallback.Stub {
+ public int mRequest;
+ public long mFunctions;
+ public boolean mChargingFunctions;
+
+ UsbGadgetCallback() {
+ }
+ UsbGadgetCallback(IndentingPrintWriter pw, int request,
+ long functions, boolean chargingFunctions) {
+ mRequest = request;
+ mFunctions = functions;
+ mChargingFunctions = chargingFunctions;
+ }
+
+ @Override
+ public void setCurrentUsbFunctionsCb(long functions,
+ int status) {
+ mDeviceManager.setCurrentUsbFunctionsCb(functions, status,
+ mRequest, mFunctions, mChargingFunctions);
+ }
+
+ @Override
+ public void getCurrentUsbFunctionsCb(long functions,
+ int status) {
+ mDeviceManager.getCurrentUsbFunctionsCb(functions, status);
+ }
+
+ @Override
+ public void getUsbSpeedCb(int speed) {
+ mDeviceManager.getUsbSpeedCb(speed);
+ }
+ }
+}
+
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/OWNERS b/services/voiceinteraction/java/com/android/server/soundtrigger/OWNERS
index e5d0370..01b2cb9 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/OWNERS
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/OWNERS
@@ -1,2 +1,2 @@
-ytai@google.com
+atneya@google.com
elaurent@google.com
diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java
index c2b65f8..845449e 100644
--- a/telephony/java/android/telephony/SmsMessage.java
+++ b/telephony/java/android/telephony/SmsMessage.java
@@ -1020,6 +1020,26 @@
}
/**
+ * Return the encoding type of a received SMS message, which is specified using ENCODING_*
+ * GSM: defined in android.telephony.SmsConstants
+ * CDMA: defined in android.telephony.cdma.UserData
+ *
+ * @hide
+ */
+ public int getReceivedEncodingType() {
+ return mWrappedSmsMessage.getReceivedEncodingType();
+ }
+
+ /**
+ * Check if format of the message is 3GPP.
+ *
+ * @hide
+ */
+ public boolean is3gpp() {
+ return (mWrappedSmsMessage instanceof com.android.internal.telephony.gsm.SmsMessage);
+ }
+
+ /**
* Determines whether or not to use CDMA format for MO SMS.
* If SMS over IMS is supported, then format is based on IMS SMS format,
* otherwise format is based on current phone type.
diff --git a/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java b/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java
index 6a6c306..74bac22 100644
--- a/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java
+++ b/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java
@@ -147,7 +147,7 @@
"org.3gpp.urn:urn-7:3gpp-application.ims.iari.rcs.chatbot";
/**
- * The service ID used to indicate that the Standalone Messaging is available.
+ * The service ID used to indicate that the Chatbot using Standalone Messaging is available.
* <p>
* See the GSMA RCC.07 specification for more information.
*/
@@ -161,6 +161,14 @@
*/
public static final String SERVICE_ID_CHATBOT_ROLE = "org.gsma.rcs.isbot";
+ /**
+ * The service ID used to indicate that the Standalone Messaging is available.
+ * <p>
+ * See the GSMA RCC.07 RCS5_1_advanced_communications_specification_v4.0 specification
+ * for more information.
+ */
+ public static final String SERVICE_ID_SLM = "org.openmobilealliance:StandaloneMsg";
+
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@StringDef(prefix = "SERVICE_ID_", value = {
@@ -177,7 +185,8 @@
SERVICE_ID_SHARED_SKETCH,
SERVICE_ID_CHATBOT,
SERVICE_ID_CHATBOT_STANDALONE,
- SERVICE_ID_CHATBOT_ROLE
+ SERVICE_ID_CHATBOT_ROLE,
+ SERVICE_ID_SLM
})
public @interface ServiceId {}
diff --git a/telephony/java/com/android/internal/telephony/SmsMessageBase.java b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
index 6d46ed3..0cc1e98 100644
--- a/telephony/java/com/android/internal/telephony/SmsMessageBase.java
+++ b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
@@ -16,6 +16,8 @@
package com.android.internal.telephony;
+import static com.android.internal.telephony.SmsConstants.ENCODING_UNKNOWN;
+
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Build;
import android.telephony.SmsMessage;
@@ -94,6 +96,15 @@
protected boolean mMwiDontStore;
/**
+ * The encoding type of a received SMS message, which is specified using ENCODING_*
+ * GSM: defined in android.telephony.SmsConstants
+ * CDMA: defined in android.telephony.cdma.UserData
+ *
+ * @hide
+ */
+ protected int mReceivedEncodingType = ENCODING_UNKNOWN;
+
+ /**
* Indicates status for messages stored on the ICC.
*/
protected int mStatusOnIcc = -1;
@@ -512,4 +523,8 @@
return mRecipientAddress.getAddressString();
}
+
+ public int getReceivedEncodingType() {
+ return mReceivedEncodingType;
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
index f636276..b51ba31 100644
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -780,6 +780,7 @@
mUserData = mBearerData.userData.payload;
mUserDataHeader = mBearerData.userData.userDataHeader;
mMessageBody = mBearerData.userData.payloadStr;
+ mReceivedEncodingType = mBearerData.userData.msgEncoding;
}
if (mOriginatingAddress != null) {
@@ -860,6 +861,9 @@
Rlog.w(LOG_TAG, "BearerData.decode() returned null");
return null;
}
+ if (bData.userData != null) {
+ mReceivedEncodingType = bData.userData.msgEncoding;
+ }
if (Rlog.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) {
Rlog.d(LOG_TAG, "MT raw BearerData = " + HexDump.toHexString(mEnvelope.bearerData));
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
index 7a5bf06..09ead31 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
@@ -1462,28 +1462,28 @@
} else {
switch ((mDataCodingScheme >> 2) & 0x3) {
case 0: // GSM 7 bit default alphabet
- encodingType = ENCODING_7BIT;
- break;
+ encodingType = ENCODING_7BIT;
+ break;
case 2: // UCS 2 (16bit)
- encodingType = ENCODING_16BIT;
- break;
+ encodingType = ENCODING_16BIT;
+ break;
case 1: // 8 bit data
- //Support decoding the user data payload as pack GSM 8-bit (a GSM alphabet string
- //that's stored in 8-bit unpacked format) characters.
- if (r.getBoolean(com.android.internal.
- R.bool.config_sms_decode_gsm_8bit_data)) {
- encodingType = ENCODING_8BIT;
- break;
- }
+ // Support decoding the user data payload as pack GSM 8-bit (a GSM alphabet
+ // string that's stored in 8-bit unpacked format) characters.
+ if (r.getBoolean(com.android.internal
+ .R.bool.config_sms_decode_gsm_8bit_data)) {
+ encodingType = ENCODING_8BIT;
+ break;
+ }
case 3: // reserved
- Rlog.w(LOG_TAG, "1 - Unsupported SMS data coding scheme "
- + (mDataCodingScheme & 0xff));
- encodingType = r.getInteger(
- com.android.internal.R.integer.default_reserved_data_coding_scheme);
- break;
+ Rlog.w(LOG_TAG, "1 - Unsupported SMS data coding scheme "
+ + (mDataCodingScheme & 0xff));
+ encodingType = r.getInteger(
+ com.android.internal.R.integer.default_reserved_data_coding_scheme);
+ break;
}
}
} else if ((mDataCodingScheme & 0xf0) == 0xf0) {
@@ -1558,6 +1558,7 @@
encodingType == ENCODING_7BIT);
this.mUserData = p.getUserData();
this.mUserDataHeader = p.getUserDataHeader();
+ this.mReceivedEncodingType = encodingType;
/*
* Look for voice mail indication in TP_UDH TS23.040 9.2.3.24
diff --git a/tests/CanvasCompare/Android.bp b/tests/CanvasCompare/Android.bp
deleted file mode 100644
index 9883115..0000000
--- a/tests/CanvasCompare/Android.bp
+++ /dev/null
@@ -1,63 +0,0 @@
-//
-// Copyright (C) 2012 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-package {
- // See: http://go/android-license-faq
- default_applicable_licenses: [
- "frameworks_base_license",
- ],
-}
-
-android_test {
- name: "CanvasCompare",
- srcs: [
- "src/**/*.java",
- ":CanvasCompare-rscript{CanvasCompare.srcjar}",
- ],
- resource_zips: [
- ":CanvasCompare-rscript{CanvasCompare.res.zip}",
- ],
- platform_apis: true,
- libs: [
- "android.test.runner",
- "android.test.base",
- ],
- static_libs: ["junit"],
-}
-
-genrule {
- name: "CanvasCompare-rscript",
- srcs: [
- "src/**/*.rscript",
- ":rs_script_api",
- ":rs_clang_headers",
- ],
- tools: [
- "llvm-rs-cc",
- "soong_zip",
- ],
- out: [
- "CanvasCompare.srcjar",
- "CanvasCompare.res.zip",
- ],
- cmd: "for f in $(locations src/**/*.rscript); do " +
- " $(location llvm-rs-cc) -o $(genDir)/res/raw -p $(genDir)/src " +
- " -I $$(dirname $$(echo $(locations :rs_script_api) | awk '{ print $$1 }')) " +
- " -I $$(dirname $$(echo $(locations :rs_clang_headers) | awk '{ print $$1 }')) $${f}; " +
- "done && " +
- "$(location soong_zip) -srcjar -o $(location CanvasCompare.srcjar) -C $(genDir)/src -D $(genDir)/src &&" +
- "$(location soong_zip) -o $(location CanvasCompare.res.zip) -C $(genDir)/res -D $(genDir)/res",
-}
diff --git a/tests/CanvasCompare/AndroidManifest.xml b/tests/CanvasCompare/AndroidManifest.xml
deleted file mode 100644
index 2734e7f..0000000
--- a/tests/CanvasCompare/AndroidManifest.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.test.hwuicompare">
-
- <uses-permission android:name="android.permission.INTERNET"/>
- <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
-
- <application android:label="@string/app_name"
- android:theme="@android:style/Theme.Holo.Light.NoActionBar">
- <activity android:name="AutomaticActivity"
- android:label="CanvasAutoCompare"
- android:exported="true">
- <intent-filter>
- <action android:name="android.intent.action.MAIN"/>
- <category android:name="android.intent.category.LAUNCHER"/>
- </intent-filter>
- </activity>
- <activity android:name="ManualActivity"
- android:label="CanvasManualCompare"
- android:exported="true">
- <intent-filter>
- <action android:name="android.intent.action.MAIN"/>
- <category android:name="android.intent.category.LAUNCHER"/>
- </intent-filter>
- </activity>
- <uses-library android:name="android.test.runner"/>
- </application>
- <instrumentation android:name="android.test.InstrumentationTestRunner"
- android:targetPackage="com.android.test.hwuicompare"
- android:label="HW/SW Canvas comparison tool."/>
-
-</manifest>
diff --git a/tests/CanvasCompare/OWNERS b/tests/CanvasCompare/OWNERS
deleted file mode 100644
index c88a9f8..0000000
--- a/tests/CanvasCompare/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-include /libs/hwui/OWNERS
diff --git a/tests/CanvasCompare/res/drawable/sunset1.jpg b/tests/CanvasCompare/res/drawable/sunset1.jpg
deleted file mode 100644
index 3b4e056..0000000
--- a/tests/CanvasCompare/res/drawable/sunset1.jpg
+++ /dev/null
Binary files differ
diff --git a/tests/CanvasCompare/res/layout/automatic_layout.xml b/tests/CanvasCompare/res/layout/automatic_layout.xml
deleted file mode 100644
index e049ec0..0000000
--- a/tests/CanvasCompare/res/layout/automatic_layout.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
-
- <com.android.test.hwuicompare.MainView
- android:id="@+id/hardware_view"
- android:layout_width="@dimen/layer_width"
- android:layout_height="@dimen/layer_width" />
-
- <ImageView
- android:id="@+id/software_image_view"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true" />
-
- <ImageView
- android:id="@+id/hardware_image_view"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentBottom="true"
- android:layout_alignParentRight="true" />
-
-</RelativeLayout>
diff --git a/tests/CanvasCompare/res/layout/manual_layout.xml b/tests/CanvasCompare/res/layout/manual_layout.xml
deleted file mode 100644
index 1a9288c..0000000
--- a/tests/CanvasCompare/res/layout/manual_layout.xml
+++ /dev/null
@@ -1,119 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="center_horizontal"
- android:orientation="vertical" >
-
- <HorizontalScrollView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" >
-
- <LinearLayout
- android:id="@+id/spinner_layout"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal" />
- </HorizontalScrollView>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="0dip"
- android:layout_weight="1"
- android:baselineAligned="true"
- android:orientation="horizontal" >
-
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:gravity="center"
- android:orientation="horizontal" >
-
- <com.android.test.hwuicompare.MainView
- android:id="@+id/hardware_view"
- android:layout_width="@dimen/layer_width"
- android:layout_height="@dimen/layer_width" />
- </LinearLayout>
-
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:gravity="center"
- android:orientation="horizontal" >
-
- <com.android.test.hwuicompare.MainView
- android:id="@+id/software_view"
- android:layout_width="@dimen/layer_width"
- android:layout_height="@dimen/layer_width" />
- </LinearLayout>
- </LinearLayout>
-
- <ImageView
- android:id="@+id/compare_image_view"
- android:layout_width="@dimen/layer_width_double"
- android:layout_height="@dimen/layer_height_double"
- android:filter="false" />
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:orientation="horizontal" >
-
- <ImageButton
- android:id="@+id/previous"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:contentDescription="@string/previous_combination"
- android:src="@android:drawable/ic_media_previous" />
-
- <ImageButton
- android:id="@+id/next"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:contentDescription="@string/next_combination"
- android:src="@android:drawable/ic_media_next" />
-
- <TextView
- android:id="@+id/current_error"
- android:layout_width="100dp"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:textAppearance="?android:attr/textAppearanceLarge" />
-
- <Button
- android:id="@+id/show_hardware_version"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/show_hardware_version" />
-
- <Button
- android:id="@+id/show_software_version"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/show_software_version" />
-
- <Button
- android:id="@+id/show_error_heatmap"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/show_error_heatmap" />
- </LinearLayout>
-
-</LinearLayout>
diff --git a/tests/CanvasCompare/res/values/strings.xml b/tests/CanvasCompare/res/values/strings.xml
deleted file mode 100644
index edd4610..0000000
--- a/tests/CanvasCompare/res/values/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<resources>
- <string name="app_name">Canvas Compare Test</string>
-
- <!-- show hardware rendered version of the layer -->
- <string name="show_hardware_version">Hardware</string>
- <!-- show software rendered version of the layer -->
- <string name="show_software_version">Software</string>
- <!-- show layer error -->
- <string name="show_error_values">Error</string>
- <!-- show layer error heatmap -->
- <string name="show_error_heatmap">Heatmap</string>
- <!-- select and display the next combination of painting options-->
- <string name="next_combination">Next Combination</string>
- <!-- select and display the previous combination of painting options-->
- <string name="previous_combination">Previous Combination</string>
-</resources>
diff --git a/tests/CanvasCompare/res/values/values.xml b/tests/CanvasCompare/res/values/values.xml
deleted file mode 100644
index f69378d..0000000
--- a/tests/CanvasCompare/res/values/values.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<resources>
-
- <!-- NOTE: the below MUST be multiples of 64 -->
- <dimen name="layer_height">320px</dimen>
- <dimen name="layer_width">320px</dimen>
-
- <dimen name="layer_height_double">640px</dimen>
- <dimen name="layer_width_double">640px</dimen>
-
-</resources>
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/AutomaticActivity.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/AutomaticActivity.java
deleted file mode 100644
index 8ccd4e2..0000000
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/AutomaticActivity.java
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.test.hwuicompare;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.TreeSet;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import android.os.Bundle;
-import android.os.Environment;
-import android.os.Trace;
-import android.util.Log;
-import android.widget.ImageView;
-import android.widget.Toast;
-
-public class AutomaticActivity extends CompareActivity {
- private static final String LOG_TAG = "AutomaticActivity";
- private static final float ERROR_DISPLAY_THRESHOLD = 0.01f;
- protected static final boolean DRAW_BITMAPS = false;
-
- /**
- * Threshold of error change required to consider a test regressed/improved
- */
- private static final float ERROR_CHANGE_THRESHOLD = 0.001f;
-
- private static final float[] ERROR_CUTOFFS = {
- 0, 0.005f, 0.01f, 0.02f, 0.05f, 0.1f, 0.25f, 0.5f, 1f, 2f
- };
-
- private final float[] mErrorRates = new float[ERROR_CUTOFFS.length];
- private float mTotalTests = 0;
- private float mTotalError = 0;
- private int mTestsRegressed = 0;
- private int mTestsImproved = 0;
-
- private ImageView mSoftwareImageView = null;
- private ImageView mHardwareImageView = null;
-
-
- public abstract static class FinalCallback {
- abstract void report(String name, float value);
- void complete() {};
- }
-
- private final ArrayList<FinalCallback> mFinalCallbacks = new ArrayList<FinalCallback>();
-
- Runnable mRunnable = new Runnable() {
- @Override
- public void run() {
- loadBitmaps();
- if (mSoftwareBitmap == null || mHardwareBitmap == null) {
- Log.e(LOG_TAG, "bitmap is null");
- return;
- }
-
- if (DRAW_BITMAPS) {
- mSoftwareImageView.setImageBitmap(mSoftwareBitmap);
- mHardwareImageView.setImageBitmap(mHardwareBitmap);
- }
-
- Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, "calculateError");
- float error = mErrorCalculator.calcErrorRS(mSoftwareBitmap, mHardwareBitmap);
- Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
-
- final String[] modifierNames = DisplayModifier.getLastAppliedModifications();
- handleError(modifierNames, error);
-
- if (DisplayModifier.step()) {
- finishTest();
- } else {
- mHardwareView.invalidate();
- if (DRAW_BITMAPS) {
- mSoftwareImageView.invalidate();
- mHardwareImageView.invalidate();
- }
- }
- mHandler.removeCallbacks(mRunnable);
- }
- };
-
- @Override
- protected void onPause() {
- super.onPause();
- mHandler.removeCallbacks(mRunnable);
- };
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.automatic_layout);
-
- mSoftwareImageView = findViewById(R.id.software_image_view);
- mHardwareImageView = findViewById(R.id.hardware_image_view);
-
- onCreateCommon(mRunnable);
- beginTest();
- }
-
- private static class TestResult {
- TestResult(String label, float error) {
- mLabel = label;
- mTotalError = error;
- mCount = 1;
- }
- public void addInto(float error) {
- mTotalError += error;
- mCount++;
- }
- public float getAverage() {
- return mTotalError / mCount;
- }
- final String mLabel;
- float mTotalError;
- int mCount;
- }
-
- JSONObject mOutputJson = null;
- JSONObject mInputJson = null;
- final HashMap<String, TestResult> mModifierResults = new HashMap<String, TestResult>();
- final HashMap<String, TestResult> mIndividualResults = new HashMap<String, TestResult>();
- final HashMap<String, TestResult> mModifierDiffResults = new HashMap<String, TestResult>();
- final HashMap<String, TestResult> mIndividualDiffResults = new HashMap<String, TestResult>();
- private void beginTest() {
- mFinalCallbacks.add(new FinalCallback() {
- @Override
- void report(String name, float value) {
- Log.d(LOG_TAG, name + " " + value);
- };
- });
-
- File inputFile = new File(Environment.getExternalStorageDirectory(),
- "CanvasCompareInput.json");
- if (inputFile.exists() && inputFile.canRead() && inputFile.length() > 0) {
- try {
- FileInputStream inputStream = new FileInputStream(inputFile);
- Log.d(LOG_TAG, "Parsing input file...");
- StringBuffer content = new StringBuffer((int)inputFile.length());
- byte[] buffer = new byte[1024];
- while (inputStream.read(buffer) != -1) {
- content.append(new String(buffer));
- }
- mInputJson = new JSONObject(content.toString());
- inputStream.close();
- Log.d(LOG_TAG, "Parsed input file with " + mInputJson.length() + " entries");
- } catch (JSONException e) {
- Log.e(LOG_TAG, "error parsing input json", e);
- } catch (IOException e) {
- Log.e(LOG_TAG, "error reading input json from sd", e);
- }
- }
-
- mOutputJson = new JSONObject();
- }
-
- private static void logTestResultHash(String label, HashMap<String, TestResult> map) {
- Log.d(LOG_TAG, "---------------");
- Log.d(LOG_TAG, label + ":");
- Log.d(LOG_TAG, "---------------");
- TreeSet<TestResult> set = new TreeSet<TestResult>(new Comparator<TestResult>() {
- @Override
- public int compare(TestResult lhs, TestResult rhs) {
- if (lhs == rhs) return 0; // don't need to worry about complex equality
-
- int cmp = Float.compare(lhs.getAverage(), rhs.getAverage());
- if (cmp != 0) {
- return cmp;
- }
- return lhs.mLabel.compareTo(rhs.mLabel);
- }
- });
-
- for (TestResult t : map.values()) {
- set.add(t);
- }
-
- for (TestResult t : set.descendingSet()) {
- if (Math.abs(t.getAverage()) > ERROR_DISPLAY_THRESHOLD) {
- Log.d(LOG_TAG, String.format("%2.4f : %s", t.getAverage(), t.mLabel));
- }
- }
- Log.d(LOG_TAG, "");
- }
-
- private void finishTest() {
- for (FinalCallback c : mFinalCallbacks) {
- c.report("averageError", (mTotalError / mTotalTests));
- for (int i = 1; i < ERROR_CUTOFFS.length; i++) {
- c.report(String.format("tests with error over %1.3f", ERROR_CUTOFFS[i]),
- mErrorRates[i]);
- }
- if (mInputJson != null) {
- c.report("tests regressed", mTestsRegressed);
- c.report("tests improved", mTestsImproved);
- }
- c.complete();
- }
-
- try {
- if (mOutputJson != null) {
- String outputString = mOutputJson.toString(4);
- File outputFile = new File(Environment.getExternalStorageDirectory(),
- "CanvasCompareOutput.json");
- FileOutputStream outputStream = new FileOutputStream(outputFile);
- outputStream.write(outputString.getBytes());
- outputStream.close();
- Log.d(LOG_TAG, "Saved output file with " + mOutputJson.length() + " entries");
- }
- } catch (JSONException e) {
- Log.e(LOG_TAG, "error during JSON stringify", e);
- } catch (IOException e) {
- Log.e(LOG_TAG, "error storing JSON output on sd", e);
- }
-
- logTestResultHash("Modifier change vs previous", mModifierDiffResults);
- logTestResultHash("Invidual test change vs previous", mIndividualDiffResults);
- logTestResultHash("Modifier average test results", mModifierResults);
- logTestResultHash("Individual test results", mIndividualResults);
-
- Toast.makeText(getApplicationContext(), "done!", Toast.LENGTH_SHORT).show();
- finish();
- }
-
- /**
- * Inserts the error value into all TestResult objects, associated with each of its modifiers
- */
- private static void addForAllModifiers(String fullName, float error, String[] modifierNames,
- HashMap<String, TestResult> modifierResults) {
- for (String modifierName : modifierNames) {
- TestResult r = modifierResults.get(fullName);
- if (r == null) {
- modifierResults.put(modifierName, new TestResult(modifierName, error));
- } else {
- r.addInto(error);
- }
- }
- }
-
- private void handleError(final String[] modifierNames, final float error) {
- String fullName = "";
- for (String s : modifierNames) {
- fullName = fullName.concat("." + s);
- }
- fullName = fullName.substring(1);
-
- float deltaError = 0;
- if (mInputJson != null) {
- try {
- deltaError = error - (float)mInputJson.getDouble(fullName);
- } catch (JSONException e) {
- Log.w(LOG_TAG, "Warning: unable to read from input json", e);
- }
- if (deltaError > ERROR_CHANGE_THRESHOLD) mTestsRegressed++;
- if (deltaError < -ERROR_CHANGE_THRESHOLD) mTestsImproved++;
- mIndividualDiffResults.put(fullName, new TestResult(fullName, deltaError));
- addForAllModifiers(fullName, deltaError, modifierNames, mModifierDiffResults);
- }
-
- mIndividualResults.put(fullName, new TestResult(fullName, error));
- addForAllModifiers(fullName, error, modifierNames, mModifierResults);
-
- try {
- if (mOutputJson != null) {
- mOutputJson.put(fullName, error);
- }
- } catch (JSONException e) {
- Log.e(LOG_TAG, "exception during JSON recording", e);
- mOutputJson = null;
- }
-
- for (int i = 0; i < ERROR_CUTOFFS.length; i++) {
- if (error <= ERROR_CUTOFFS[i]) break;
- mErrorRates[i]++;
- }
- mTotalError += error;
- mTotalTests++;
- }
-
- @Override
- protected boolean forceRecreateBitmaps() {
- // disable, unless needed for drawing into imageviews
- return DRAW_BITMAPS;
- }
-
- // FOR TESTING
- public void setFinalCallback(FinalCallback c) {
- mFinalCallbacks.add(c);
- }
-}
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/CompareActivity.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/CompareActivity.java
deleted file mode 100644
index 0dec1de..0000000
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/CompareActivity.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.test.hwuicompare;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import com.android.test.hwuicompare.R;
-
-import android.app.Activity;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.drawable.ColorDrawable;
-import android.os.Handler;
-import android.os.Trace;
-import android.util.Log;
-import android.view.View;
-
-abstract public class CompareActivity extends Activity {
- private static final String LOG_TAG = "CompareActivity";
-
- protected MainView mHardwareView = null;
-
- protected Bitmap mSoftwareBitmap;
- protected Bitmap mHardwareBitmap;
-
- protected ErrorCalculator mErrorCalculator;
-
- protected Handler mHandler;
-
- Runnable mDrawCallback = null;
- protected boolean mRedrewFlag = true;
-
- protected void onCreateCommon(final Runnable postDrawCallback) {
- mDrawCallback = new Runnable() {
- @Override
- public void run() {
- mRedrewFlag = true;
- mHandler.post(postDrawCallback);
- };
- };
- getWindow().setBackgroundDrawable(new ColorDrawable(0xffefefef));
- ResourceModifiers.init(getResources());
-
- mHardwareView = findViewById(R.id.hardware_view);
- mHardwareView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
- mHardwareView.setBackgroundColor(Color.WHITE);
- mHardwareView.addDrawCallback(mDrawCallback);
-
- int width = getResources().getDimensionPixelSize(R.dimen.layer_width);
- int height = getResources().getDimensionPixelSize(R.dimen.layer_height);
- mSoftwareBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- mHardwareBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
-
- mErrorCalculator = new ErrorCalculator(getApplicationContext(), getResources());
-
- mHandler = new Handler();
- }
-
- protected abstract boolean forceRecreateBitmaps();
-
- protected void loadBitmaps() {
- Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, "loadBitmaps");
- if (forceRecreateBitmaps()) {
- int width = mSoftwareBitmap.getWidth();
- int height = mSoftwareBitmap.getHeight();
-
- mSoftwareBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- mHardwareBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- }
-
- Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, "softwareDraw");
- mHardwareView.draw(new Canvas(mSoftwareBitmap));
- Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
-
- try {
- Method getHardwareLayer = View.class.getDeclaredMethod("getHardwareLayer");
- if (!getHardwareLayer.isAccessible())
- getHardwareLayer.setAccessible(true);
- Object hardwareLayer = getHardwareLayer.invoke(mHardwareView);
- if (hardwareLayer == null) {
- Log.d(LOG_TAG, "failure to access hardware layer");
- return;
- }
- Method copyInto = hardwareLayer.getClass()
- .getDeclaredMethod("copyInto", Bitmap.class);
- if (!copyInto.isAccessible())
- copyInto.setAccessible(true);
-
- Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, "copyInto");
- boolean success = (Boolean) copyInto.invoke(hardwareLayer, mHardwareBitmap);
- Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
- if (!success) {
- Log.d(LOG_TAG, "failure to copy hardware layer into bitmap");
- }
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- }
- Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
- }
-}
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/DisplayModifier.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/DisplayModifier.java
deleted file mode 100644
index 4bcf5a4..0000000
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/DisplayModifier.java
+++ /dev/null
@@ -1,503 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.test.hwuicompare;
-
-import static java.util.Map.entry;
-
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.RectF;
-import android.util.Log;
-
-import java.util.Map;
-import java.util.Map.Entry;
-
-public abstract class DisplayModifier {
-
- // automated tests ignore any combination of operations that don't together return TOTAL_MASK
- protected final static int TOTAL_MASK = 0x1F;
-
- // if we're filling, ensure we're not also sweeping over stroke parameters
- protected final static int SWEEP_STROKE_WIDTH_BIT = 0x1 << 0;
- protected final static int SWEEP_STROKE_CAP_BIT = 0x1 << 1;
- protected final static int SWEEP_STROKE_JOIN_BIT = 0x1 << 2;
-
- protected final static int SWEEP_SHADER_BIT = 0x1 << 3; // only allow non-simple shaders to use rectangle drawing
- protected final static int SWEEP_TRANSFORM_BIT = 0x1 << 4; // only sweep over specified transforms
-
- abstract public void modifyDrawing(Paint paint, Canvas canvas);
- protected int mask() { return 0x0; };
-
- private static final RectF gRect = new RectF(0, 0, 200, 175);
- private static final float[] gPts = new float[] {
- 0, 100, 100, 0, 100, 200, 200, 100
- };
-
- private static final int NUM_PARALLEL_LINES = 24;
- private static final float[] gTriPts = new float[] {
- 75, 0, 130, 130, 130, 130, 0, 130, 0, 130, 75, 0
- };
- private static final float[] gLinePts = new float[NUM_PARALLEL_LINES * 8 + gTriPts.length];
- static {
- int index;
- for (index = 0; index < gTriPts.length; index++) {
- gLinePts[index] = gTriPts[index];
- }
- float val = 0;
- for (int i = 0; i < NUM_PARALLEL_LINES; i++) {
- gLinePts[index + 0] = 150;
- gLinePts[index + 1] = val;
- gLinePts[index + 2] = 300;
- gLinePts[index + 3] = val;
- index += 4;
- val += 8 + (2.0f/NUM_PARALLEL_LINES);
- }
- val = 0;
- for (int i = 0; i < NUM_PARALLEL_LINES; i++) {
- gLinePts[index + 0] = val;
- gLinePts[index + 1] = 150;
- gLinePts[index + 2] = val;
- gLinePts[index + 3] = 300;
- index += 4;
- val += 8 + (2.0f/NUM_PARALLEL_LINES);
- }
- };
-
- @SuppressWarnings("serial")
- private static final Map<String, Map<String, DisplayModifier>> gMaps = Map.of(
- "aa", Map.of(
- "true", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- paint.setAntiAlias(true);
- }
- },
- "false", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- paint.setAntiAlias(false);
- }
- }),
- "style", Map.of(
- "fill", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- paint.setStyle(Paint.Style.FILL);
- }
- },
- "stroke", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- paint.setStyle(Paint.Style.STROKE);
- }
- @Override
- protected int mask() { return SWEEP_STROKE_WIDTH_BIT; }
- },
- "fillAndStroke", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- paint.setStyle(Paint.Style.FILL_AND_STROKE);
- }
-
- @Override
- protected int mask() { return SWEEP_STROKE_WIDTH_BIT; }
- }),
- "strokeWidth", Map.of(
- "hair", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- paint.setStrokeWidth(0);
- }
- @Override
- protected int mask() { return SWEEP_STROKE_WIDTH_BIT; }
- },
- "0.3", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- paint.setStrokeWidth(0.3f);
- }
- },
- "1", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- paint.setStrokeWidth(1);
- }
- },
- "5", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- paint.setStrokeWidth(5);
- }
- },
- "30", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- paint.setStrokeWidth(30);
- }
- }),
- "strokeCap", Map.of(
- "butt", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- paint.setStrokeCap(Paint.Cap.BUTT);
- }
- @Override
- protected int mask() { return SWEEP_STROKE_CAP_BIT; }
- },
- "round", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- paint.setStrokeCap(Paint.Cap.ROUND);
- }
- },
- "square", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- paint.setStrokeCap(Paint.Cap.SQUARE);
- }
- }),
- "strokeJoin", Map.of(
- "bevel", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- paint.setStrokeJoin(Paint.Join.BEVEL);
- }
- @Override
- protected int mask() { return SWEEP_STROKE_JOIN_BIT; }
- },
- "round", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- paint.setStrokeJoin(Paint.Join.ROUND);
- }
- },
- "miter", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- paint.setStrokeJoin(Paint.Join.MITER);
- }
- }),
- // TODO: add miter0, miter1 etc to test miter distances
- "transform", Map.of(
- "noTransform", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {}
- @Override
- protected int mask() { return SWEEP_TRANSFORM_BIT; };
- },
- "rotate5", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- canvas.rotate(5);
- }
- },
- "rotate45", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- canvas.rotate(45);
- }
- },
- "rotate90", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- canvas.rotate(90);
- canvas.translate(0, -200);
- }
- },
- "scale2x2", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- canvas.scale(2, 2);
- }
- @Override
- protected int mask() { return SWEEP_TRANSFORM_BIT; };
- },
- "rot20scl1x4", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- canvas.rotate(20);
- canvas.scale(1, 4);
- }
- @Override
- protected int mask() { return SWEEP_TRANSFORM_BIT; };
- }),
- "shader", Map.ofEntries(
- entry("noShader", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {}
- @Override
- protected int mask() { return SWEEP_SHADER_BIT; };
- }),
- entry("repeatShader", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- paint.setShader(ResourceModifiers.instance().mRepeatShader);
- }
- @Override
- protected int mask() { return SWEEP_SHADER_BIT; };
- }),
- entry("translatedShader", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- paint.setShader(ResourceModifiers.instance().mTranslatedShader);
- }
- }),
- entry("scaledShader", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- paint.setShader(ResourceModifiers.instance().mScaledShader);
- }
- }),
- entry("horGradient", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- paint.setShader(ResourceModifiers.instance().mHorGradient);
- }
- }),
- entry("diagGradient", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- paint.setShader(ResourceModifiers.instance().mDiagGradient);
- }
- @Override
- protected int mask() { return SWEEP_SHADER_BIT; };
- }),
- entry("vertGradient", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- paint.setShader(ResourceModifiers.instance().mVertGradient);
- }
- }),
- entry("radGradient", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- paint.setShader(ResourceModifiers.instance().mRadGradient);
- }
- }),
- entry("sweepGradient", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- paint.setShader(ResourceModifiers.instance().mSweepGradient);
- }
- }),
- entry("composeShader", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- paint.setShader(ResourceModifiers.instance().mComposeShader);
- }
- }),
- entry("bad composeShader", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- paint.setShader(ResourceModifiers.instance().mBadComposeShader);
- }
- }),
- entry("bad composeShader 2", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- paint.setShader(ResourceModifiers.instance().mAnotherBadComposeShader);
- }
- })),
- "drawing", Map.ofEntries(
- entry("roundRect", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- canvas.drawRoundRect(gRect, 20, 20, paint);
- }
- }),
- entry("rect", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- canvas.drawRect(gRect, paint);
- }
- @Override
- protected int mask() { return SWEEP_SHADER_BIT | SWEEP_STROKE_CAP_BIT; };
- }),
- entry("circle", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- canvas.drawCircle(100, 100, 75, paint);
- }
- }),
- entry("oval", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- canvas.drawOval(gRect, paint);
- }
- }),
- entry("lines", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- canvas.drawLines(gLinePts, paint);
- }
- @Override
- protected int mask() { return SWEEP_STROKE_CAP_BIT; };
- }),
- entry("plusPoints", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- canvas.drawPoints(gPts, paint);
- }
- }),
- entry("text", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- paint.setTextSize(36);
- canvas.drawText("TEXTTEST", 0, 50, paint);
- }
- }),
- entry("shadowtext", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- paint.setTextSize(36);
- paint.setShadowLayer(3.0f, 0.0f, 3.0f, 0xffff00ff);
- canvas.drawText("TEXTTEST", 0, 50, paint);
- }
- }),
- entry("bitmapMesh", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- canvas.drawBitmapMesh(ResourceModifiers.instance().mBitmap, 3, 3,
- ResourceModifiers.instance().mBitmapVertices, 0, null, 0, null);
- }
- }),
- entry("arc", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- canvas.drawArc(gRect, 260, 285, false, paint);
- }
- @Override
- protected int mask() { return SWEEP_STROKE_CAP_BIT; };
- }),
- entry("arcFromCenter", new DisplayModifier() {
- @Override
- public void modifyDrawing(Paint paint, Canvas canvas) {
- canvas.drawArc(gRect, 260, 285, true, paint);
- }
- @Override
- protected int mask() { return SWEEP_STROKE_JOIN_BIT; };
- })));
- // WARNING: DON'T PUT MORE MAPS BELOW THIS
-
- private static Map<String, DisplayModifier> getMapAtIndex(int index) {
- for (Map<String, DisplayModifier> map : gMaps.values()) {
- if (index == 0) {
- return map;
- }
- index--;
- }
- return null;
- }
-
- // indices instead of iterators for easier bidirectional traversal
- private static final int mIndices[] = new int[gMaps.size()];
- private static final String[] mLastAppliedModifications = new String[gMaps.size()];
-
- private static boolean stepInternal(boolean forward) {
- int modifierMapIndex = gMaps.size() - 1;
- while (modifierMapIndex >= 0) {
- Map<String, DisplayModifier> map = getMapAtIndex(modifierMapIndex);
- mIndices[modifierMapIndex] += (forward ? 1 : -1);
-
- if (mIndices[modifierMapIndex] >= 0 && mIndices[modifierMapIndex] < map.size()) {
- break;
- }
-
- mIndices[modifierMapIndex] = (forward ? 0 : map.size() - 1);
- modifierMapIndex--;
- }
- return modifierMapIndex < 0; // true if resetting
- }
-
- public static boolean step() {
- boolean ret = false;
- do {
- ret |= stepInternal(true);
- } while (!checkModificationStateMask());
- return ret;
- }
-
- public static boolean stepBack() {
- boolean ret = false;
- do {
- ret |= stepInternal(false);
- } while (!checkModificationStateMask());
- return ret;
- }
-
- private static boolean checkModificationStateMask() {
- int operatorMask = 0x0;
- int mapIndex = 0;
- for (Map<String, DisplayModifier> map : gMaps.values()) {
- int displayModifierIndex = mIndices[mapIndex];
- for (Entry<String, DisplayModifier> modifierEntry : map.entrySet()) {
- if (displayModifierIndex == 0) {
- mLastAppliedModifications[mapIndex] = modifierEntry.getKey();
- operatorMask |= modifierEntry.getValue().mask();
- break;
- }
- displayModifierIndex--;
- }
- mapIndex++;
- }
- return operatorMask == TOTAL_MASK;
- }
-
- public static void apply(Paint paint, Canvas canvas) {
- int mapIndex = 0;
- for (Map<String, DisplayModifier> map : gMaps.values()) {
- int displayModifierIndex = mIndices[mapIndex];
- for (Entry<String, DisplayModifier> modifierEntry : map.entrySet()) {
- if (displayModifierIndex == 0) {
- mLastAppliedModifications[mapIndex] = modifierEntry.getKey();
- modifierEntry.getValue().modifyDrawing(paint, canvas);
- break;
- }
- displayModifierIndex--;
- }
- mapIndex++;
- }
- }
-
- public static String[] getLastAppliedModifications() {
- return mLastAppliedModifications.clone();
- }
-
- public static String[][] getStrings() {
- String[][] keys = new String[gMaps.size()][];
-
- int i = 0;
- for (Map<String, DisplayModifier> map : gMaps.values()) {
- keys[i] = new String[map.size()];
- int j = 0;
- for (String key : map.keySet()) {
- keys[i][j++] = key;
- }
- i++;
- }
-
- return keys;
- }
-
- public static void setIndex(int mapIndex, int newIndexValue) {
- mIndices[mapIndex] = newIndexValue;
- }
-
- public static int[] getIndices() {
- return mIndices;
- }
-}
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/ErrorCalculator.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/ErrorCalculator.java
deleted file mode 100644
index d402699..0000000
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/ErrorCalculator.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.test.hwuicompare;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.Color;
-import android.renderscript.Allocation;
-import android.renderscript.Element;
-import android.renderscript.RenderScript;
-import android.util.Log;
-
-public class ErrorCalculator {
- private static final String LOG_TAG = "ErrorCalculator";
- private static final int REGION_SIZE = 8;
-
- private static final boolean LOG_TIMING = false;
- private static final boolean LOG_CALC = false;
-
- private RenderScript mRS;
- private Allocation mIdealPixelsAllocation;
- private Allocation mGivenPixelsAllocation;
- private Allocation mOutputPixelsAllocation;
-
- private Allocation mInputRowsAllocation;
- private Allocation mOutputRegionsAllocation;
-
- private ScriptC_errorCalculator mScript;
-
- private int[] mOutputRowRegions;
-
- public ErrorCalculator(Context c, Resources resources) {
- int width = resources.getDimensionPixelSize(R.dimen.layer_width);
- int height = resources.getDimensionPixelSize(R.dimen.layer_height);
- mOutputRowRegions = new int[height / REGION_SIZE];
-
- mRS = RenderScript.create(c);
- int[] rowIndices = new int[height / REGION_SIZE];
- for (int i = 0; i < rowIndices.length; i++)
- rowIndices[i] = i * REGION_SIZE;
-
- mScript = new ScriptC_errorCalculator(mRS);
- mScript.set_HEIGHT(height);
- mScript.set_WIDTH(width);
- mScript.set_REGION_SIZE(REGION_SIZE);
-
- mInputRowsAllocation = Allocation.createSized(mRS, Element.I32(mRS), rowIndices.length,
- Allocation.USAGE_SCRIPT);
- mInputRowsAllocation.copyFrom(rowIndices);
- mOutputRegionsAllocation = Allocation.createSized(mRS, Element.I32(mRS),
- mOutputRowRegions.length, Allocation.USAGE_SCRIPT);
- }
-
-
- private static long startMillis, middleMillis;
-
- public float calcErrorRS(Bitmap ideal, Bitmap given) {
- if (LOG_TIMING) {
- startMillis = System.currentTimeMillis();
- }
-
- mIdealPixelsAllocation = Allocation.createFromBitmap(mRS, ideal,
- Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
- mGivenPixelsAllocation = Allocation.createFromBitmap(mRS, given,
- Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
-
- mScript.set_ideal(mIdealPixelsAllocation);
- mScript.set_given(mGivenPixelsAllocation);
-
- mScript.forEach_countInterestingRegions(mInputRowsAllocation, mOutputRegionsAllocation);
- mOutputRegionsAllocation.copyTo(mOutputRowRegions);
-
- int regionCount = 0;
- for (int region : mOutputRowRegions) {
- regionCount += region;
- }
- int interestingPixels = Math.max(1, regionCount) * REGION_SIZE * REGION_SIZE;
-
- if (LOG_TIMING) {
- long startMillis2 = System.currentTimeMillis();
- }
-
- mScript.forEach_accumulateError(mInputRowsAllocation, mOutputRegionsAllocation);
- mOutputRegionsAllocation.copyTo(mOutputRowRegions);
- float totalError = 0;
- for (int row : mOutputRowRegions) {
- totalError += row;
- }
- totalError /= 1024.0f;
-
- if (LOG_TIMING) {
- long finalMillis = System.currentTimeMillis();
- Log.d(LOG_TAG, "rs: first part took " + (middleMillis - startMillis) + "ms");
- Log.d(LOG_TAG, "rs: last part took " + (finalMillis - middleMillis) + "ms");
- }
- if (LOG_CALC) {
- Log.d(LOG_TAG, "rs: error " + totalError + ", pixels " + interestingPixels);
- }
- return totalError / interestingPixels;
- }
-
- public void calcErrorHeatmapRS(Bitmap ideal, Bitmap given, Bitmap output) {
- mIdealPixelsAllocation = Allocation.createFromBitmap(mRS, ideal,
- Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
- mGivenPixelsAllocation = Allocation.createFromBitmap(mRS, given,
- Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
-
- mScript.set_ideal(mIdealPixelsAllocation);
- mScript.set_given(mGivenPixelsAllocation);
-
- mOutputPixelsAllocation = Allocation.createFromBitmap(mRS, output,
- Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
- mScript.forEach_displayDifference(mOutputPixelsAllocation, mOutputPixelsAllocation);
- mOutputPixelsAllocation.copyTo(output);
- }
-
- public static float calcError(Bitmap ideal, Bitmap given) {
- if (LOG_TIMING) {
- startMillis = System.currentTimeMillis();
- }
-
- int interestingRegions = 0;
- for (int x = 0; x < ideal.getWidth(); x += REGION_SIZE) {
- for (int y = 0; y < ideal.getWidth(); y += REGION_SIZE) {
- if (inspectRegion(ideal, x, y)) {
- interestingRegions++;
- }
- }
- }
-
- int interestingPixels = Math.max(1, interestingRegions) * REGION_SIZE * REGION_SIZE;
-
- if (LOG_TIMING) {
- long startMillis2 = System.currentTimeMillis();
- }
-
- float totalError = 0;
- for (int x = 0; x < ideal.getWidth(); x++) {
- for (int y = 0; y < ideal.getHeight(); y++) {
- int idealColor = ideal.getPixel(x, y);
- int givenColor = given.getPixel(x, y);
- if (idealColor == givenColor)
- continue;
- totalError += Math.abs(Color.red(idealColor) - Color.red(givenColor));
- totalError += Math.abs(Color.green(idealColor) - Color.green(givenColor));
- totalError += Math.abs(Color.blue(idealColor) - Color.blue(givenColor));
- totalError += Math.abs(Color.alpha(idealColor) - Color.alpha(givenColor));
- }
- }
- totalError /= 1024.0f;
- if (LOG_TIMING) {
- long finalMillis = System.currentTimeMillis();
- Log.d(LOG_TAG, "dvk: first part took " + (middleMillis - startMillis) + "ms");
- Log.d(LOG_TAG, "dvk: last part took " + (finalMillis - middleMillis) + "ms");
- }
- if (LOG_CALC) {
- Log.d(LOG_TAG, "dvk: error " + totalError + ", pixels " + interestingPixels);
- }
- return totalError / interestingPixels;
- }
-
- private static boolean inspectRegion(Bitmap ideal, int x, int y) {
- int regionColor = ideal.getPixel(x, y);
- for (int i = 0; i < REGION_SIZE; i++) {
- for (int j = 0; j < REGION_SIZE; j++) {
- if (ideal.getPixel(x + i, y + j) != regionColor)
- return true;
- }
- }
- return false;
- }
-}
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/MainView.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/MainView.java
deleted file mode 100644
index 454fe7b..0000000
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/MainView.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.test.hwuicompare;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.util.AttributeSet;
-import android.view.View;
-
-public class MainView extends View {
- Paint mPaint = new Paint();
-
- public MainView(Context context) {
- super(context);
- }
-
- public MainView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public MainView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
-
- mPaint.reset();
- DisplayModifier.apply(mPaint, canvas);
-
- if (mDrawCallback != null) {
- mDrawCallback.run();
- }
- }
-
- private Runnable mDrawCallback;
- public void addDrawCallback(Runnable drawCallback) {
- mDrawCallback = drawCallback;
- }
-}
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/ManualActivity.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/ManualActivity.java
deleted file mode 100644
index 405ff65..0000000
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/ManualActivity.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.test.hwuicompare;
-
-import com.android.test.hwuicompare.R;
-
-import android.graphics.Bitmap;
-import android.graphics.Color;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.Button;
-import android.widget.ImageButton;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.Spinner;
-import android.widget.TextView;
-
-public class ManualActivity extends CompareActivity {
- private static final String LOG_TAG = "ManualActivity";
- private ImageView mCompareImageView;
- private Bitmap mCompareBitmap;
- private TextView mErrorTextView;
- private MainView mSoftwareView;
-
- private static final int COMPARE_VIEW_UNINITIALIZED = -1;
- private static final int COMPARE_VIEW_HARDWARE = 0;
- private static final int COMPARE_VIEW_SOFTWARE = 1;
- private static final int COMPARE_VIEW_HEATMAP = 2; // TODO: add more like this? any ideas?
-
- private int mCompareImageViewState = COMPARE_VIEW_UNINITIALIZED;
- private int mLastCompareImageViewState = COMPARE_VIEW_UNINITIALIZED;
-
- Runnable mRunnable = new Runnable() {
- @Override
- public void run() {
- Log.d(LOG_TAG, "mRunnable running, mRedrewFlag = " + mRedrewFlag);
-
- if (mRedrewFlag) {
- loadBitmaps();
- // recalculate error
- float error = mErrorCalculator.calcErrorRS(mSoftwareBitmap, mHardwareBitmap);
- String modname = "";
- for (String s : DisplayModifier.getLastAppliedModifications()) {
- modname = modname.concat(s + ".");
- }
-
- Log.d(LOG_TAG, "error for " + modname + " is " + error);
- mErrorTextView.setText(String.format("%.4f", error));
- }
-
- if (mCompareImageViewState != mLastCompareImageViewState || mRedrewFlag) {
- switch (mCompareImageViewState) {
- case COMPARE_VIEW_UNINITIALIZED:
- // set to hardware
- case COMPARE_VIEW_HARDWARE:
- mCompareImageView.setImageBitmap(mHardwareBitmap);
- break;
- case COMPARE_VIEW_SOFTWARE:
- mCompareImageView.setImageBitmap(mSoftwareBitmap);
- break;
- case COMPARE_VIEW_HEATMAP:
- mErrorCalculator.calcErrorHeatmapRS(mSoftwareBitmap, mHardwareBitmap,
- mCompareBitmap);
- mCompareImageView.setImageBitmap(mCompareBitmap);
- break;
- }
- mCompareImageView.getDrawable().setFilterBitmap(false);
- mCompareImageView.invalidate();
- }
-
- mLastCompareImageViewState = mCompareImageViewState;
- mRedrewFlag = false;
- mHandler.removeCallbacks(mRunnable);
- }
- };
-
- private void redrawViews() {
- mHardwareView.invalidate();
- mSoftwareView.invalidate();
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.manual_layout);
- onCreateCommon(mRunnable);
-
- mSoftwareView = (MainView) findViewById(R.id.software_view);
- mSoftwareView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
- mSoftwareView.setBackgroundColor(Color.WHITE);
- mSoftwareView.addDrawCallback(mDrawCallback);
-
- mCompareImageView = (ImageView) findViewById(R.id.compare_image_view);
-
- int width = getResources().getDimensionPixelSize(R.dimen.layer_width);
- int height = getResources().getDimensionPixelSize(R.dimen.layer_height);
- mCompareBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
-
- mErrorTextView = (TextView) findViewById(R.id.current_error);
- ((ImageButton) findViewById(R.id.next)).setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- DisplayModifier.step();
- updateSpinners();
- redrawViews();
- }
- });
- ((ImageButton) findViewById(R.id.previous)).setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- DisplayModifier.stepBack();
- updateSpinners();
- redrawViews();
- }
- });
- ((Button) findViewById(R.id.show_hardware_version))
- .setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- mCompareImageViewState = COMPARE_VIEW_HARDWARE;
- mHandler.post(mRunnable);
- }
- });
- ((Button) findViewById(R.id.show_software_version))
- .setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- mCompareImageViewState = COMPARE_VIEW_SOFTWARE;
- mHandler.post(mRunnable);
- }
- });
- ((Button) findViewById(R.id.show_error_heatmap)).setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- mCompareImageViewState = COMPARE_VIEW_HEATMAP;
- mHandler.post(mRunnable);
- }
- });
-
- buildSpinnerLayout();
- }
-
- private class DisplayModifierSpinner extends Spinner {
- private final int mIndex;
-
- public DisplayModifierSpinner(int index) {
- super(ManualActivity.this);
- mIndex = index;
- setOnItemSelectedListener(new OnItemSelectedListener() {
-
- @Override
- public void onItemSelected(AdapterView<?> parentView, View selectedItem,
- int position, long id) {
- DisplayModifier.setIndex(mIndex, position);
- redrawViews();
- }
-
- @Override
- public void onNothingSelected(AdapterView<?> parentView) {
- }
- });
- }
- }
-
- private Spinner[] mSpinners;
-
- private void buildSpinnerLayout() {
- LinearLayout layout = (LinearLayout) findViewById(R.id.spinner_layout);
- String[][] mapsStrings = DisplayModifier.getStrings();
- mSpinners = new Spinner[mapsStrings.length];
- int index = 0;
- for (String[] spinnerValues : mapsStrings) {
- mSpinners[index] = new DisplayModifierSpinner(index);
- mSpinners[index].setAdapter(new ArrayAdapter<String>(this,
- android.R.layout.simple_spinner_dropdown_item, spinnerValues));
- layout.addView(mSpinners[index]);
- index++;
- }
- Log.d(LOG_TAG, "created " + index + " spinners");
- }
-
- private void updateSpinners() {
- int[] indices = DisplayModifier.getIndices();
- for (int i = 0; i < mSpinners.length; i++) {
- mSpinners[i].setSelection(indices[i]);
- }
- }
-
- @Override
- protected boolean forceRecreateBitmaps() {
- // continually recreate bitmaps to avoid modifying bitmaps currently being drawn
- return true;
- }
-}
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/ResourceModifiers.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/ResourceModifiers.java
deleted file mode 100644
index d522481..0000000
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/ResourceModifiers.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.test.hwuicompare;
-
-import com.android.test.hwuicompare.R;
-
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.BitmapShader;
-import android.graphics.Color;
-import android.graphics.ComposeShader;
-import android.graphics.LinearGradient;
-import android.graphics.PorterDuff;
-import android.graphics.RadialGradient;
-import android.graphics.SweepGradient;
-import android.graphics.Matrix;
-import android.graphics.Shader;
-
-public class ResourceModifiers {
- public final BitmapShader mRepeatShader;
- public final BitmapShader mTranslatedShader;
- public final BitmapShader mScaledShader;
- private final int mTexWidth;
- private final int mTexHeight;
- private final float mDrawWidth;
- private final float mDrawHeight;
- public final LinearGradient mHorGradient;
- public final LinearGradient mDiagGradient;
- public final LinearGradient mVertGradient;
- public final RadialGradient mRadGradient;
- public final SweepGradient mSweepGradient;
- public final ComposeShader mComposeShader;
- public final ComposeShader mBadComposeShader;
- public final ComposeShader mAnotherBadComposeShader;
- public final Bitmap mBitmap;
- private final Matrix mMtx1;
- private final Matrix mMtx2;
- private final Matrix mMtx3;
-
- public final float[] mBitmapVertices;
- public final int[] mBitmapColors;
-
- private static ResourceModifiers sInstance = null;
- public static ResourceModifiers instance() { return sInstance; }
- public static void init(Resources resources) {
- sInstance = new ResourceModifiers(resources);
- }
-
- public ResourceModifiers(Resources resources) {
- mBitmap = BitmapFactory.decodeResource(resources, R.drawable.sunset1);
- mTexWidth = mBitmap.getWidth();
- mTexHeight = mBitmap.getHeight();
-
- mDrawWidth = resources.getDimensionPixelSize(R.dimen.layer_width);
- mDrawHeight = resources.getDimensionPixelSize(R.dimen.layer_height);
-
- mRepeatShader = new BitmapShader(mBitmap, Shader.TileMode.REPEAT,
- Shader.TileMode.REPEAT);
-
- mTranslatedShader = new BitmapShader(mBitmap, Shader.TileMode.REPEAT,
- Shader.TileMode.REPEAT);
- mMtx1 = new Matrix();
- mMtx1.setTranslate(mTexWidth / 2.0f, mTexHeight / 2.0f);
- mMtx1.postRotate(45, 0, 0);
- mTranslatedShader.setLocalMatrix(mMtx1);
-
- mScaledShader = new BitmapShader(mBitmap, Shader.TileMode.MIRROR,
- Shader.TileMode.MIRROR);
- mMtx2 = new Matrix();
- mMtx2.setScale(0.5f, 0.5f);
- mScaledShader.setLocalMatrix(mMtx2);
-
- mHorGradient = new LinearGradient(0.0f, 0.0f, 1.0f, 0.0f,
- Color.RED, Color.GREEN, Shader.TileMode.CLAMP);
- mMtx3 = new Matrix();
- mMtx3.setScale(mDrawHeight, 1.0f);
- mMtx3.postRotate(-90.0f);
- mMtx3.postTranslate(0.0f, mDrawHeight);
- mHorGradient.setLocalMatrix(mMtx3);
-
- mDiagGradient = new LinearGradient(0.0f, 0.0f, mDrawWidth / 2.0f, mDrawHeight / 2.0f,
- Color.BLUE, Color.RED, Shader.TileMode.CLAMP);
-
- mVertGradient = new LinearGradient(0.0f, 0.0f, 0.0f, mDrawHeight / 2.0f,
- Color.YELLOW, Color.MAGENTA, Shader.TileMode.MIRROR);
-
- mSweepGradient = new SweepGradient(mDrawWidth / 2.0f, mDrawHeight / 2.0f,
- Color.YELLOW, Color.MAGENTA);
-
- mComposeShader = new ComposeShader(mRepeatShader, mHorGradient,
- PorterDuff.Mode.MULTIPLY);
-
- final float width = mBitmap.getWidth() / 8.0f;
- final float height = mBitmap.getHeight() / 8.0f;
-
- mBitmapVertices = new float[] {
- 0.0f, 0.0f, width, 0.0f, width * 2, 0.0f, width * 3, 0.0f,
- 0.0f, height, width, height, width * 2, height, width * 4, height,
- 0.0f, height * 2, width, height * 2, width * 2, height * 2, width * 3, height * 2,
- 0.0f, height * 4, width, height * 4, width * 2, height * 4, width * 4, height * 4,
- };
-
- mBitmapColors = new int[] {
- 0xffff0000, 0xff00ff00, 0xff0000ff, 0xffff0000,
- 0xff0000ff, 0xffff0000, 0xff00ff00, 0xff00ff00,
- 0xff00ff00, 0xff0000ff, 0xffff0000, 0xff00ff00,
- 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ff0000,
- };
-
- // Use a repeating gradient with many colors to test the non simple case.
- mRadGradient = new RadialGradient(mDrawWidth / 4.0f, mDrawHeight / 4.0f, 4.0f,
- mBitmapColors, null, Shader.TileMode.REPEAT);
-
- mBadComposeShader = new ComposeShader(mRadGradient, mComposeShader,
- PorterDuff.Mode.MULTIPLY);
-
- mAnotherBadComposeShader = new ComposeShader(mRadGradient, mVertGradient,
- PorterDuff.Mode.MULTIPLY);
- }
-
-}
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/Test.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/Test.java
deleted file mode 100644
index 1ff153c..0000000
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/Test.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package com.android.test.hwuicompare;
-
-import com.android.test.hwuicompare.AutomaticActivity.FinalCallback;
-
-import android.os.Bundle;
-import android.test.ActivityInstrumentationTestCase2;
-
-public class Test extends ActivityInstrumentationTestCase2<AutomaticActivity> {
- AutomaticActivity mActivity;
- private Bundle mBundle;
-
- public Test() {
- super(AutomaticActivity.class);
- }
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mBundle = new Bundle();
- mActivity = getActivity();
- mActivity.setFinalCallback(new FinalCallback() {
-
- @Override
- void report(String key, float value) {
- mBundle.putFloat(key, value);
- }
- @Override
- void complete() {
- synchronized(mBundle) {
- mBundle.notify();
- }
- }
- });
- }
-
- public void testCanvas() {
- synchronized(mBundle) {
- try {
- mBundle.wait();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- getInstrumentation().sendStatus(0, mBundle);
- }
-}
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rscript b/tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rscript
deleted file mode 100644
index 0a1742e..0000000
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rscript
+++ /dev/null
@@ -1,61 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(com.android.test.hwuicompare)
-
-int REGION_SIZE;
-int WIDTH;
-int HEIGHT;
-
-rs_allocation ideal;
-rs_allocation given;
-
-void countInterestingRegions(const int32_t *v_in, int32_t *v_out) {
- int y = v_in[0];
- v_out[0] = 0;
-
- for (int x = 0; x < HEIGHT; x += REGION_SIZE) {
- bool interestingRegion = false;
- uchar4 regionColor = rsGetElementAt_uchar4(ideal, x, y);
- for (int i = 0; i < REGION_SIZE && !interestingRegion; i++) {
- for (int j = 0; j < REGION_SIZE && !interestingRegion; j++) {
- uchar4 testVal = rsGetElementAt_uchar4(ideal, x + j, y + i);
- interestingRegion |= (testVal.r != regionColor.r);
- interestingRegion |= (testVal.g != regionColor.g);
- interestingRegion |= (testVal.b != regionColor.b);
- interestingRegion |= (testVal.a != regionColor.a);
- }
- }
- if (interestingRegion) {
- v_out[0]++;
- }
- }
-}
-
-void accumulateError(const int32_t *v_in, int32_t *v_out) {
- int startY = v_in[0];
- int error = 0;
- for (int y = startY; y < startY + REGION_SIZE; y++) {
- for (int x = 0; x < HEIGHT; x++) {
- uchar4 idealPixel = rsGetElementAt_uchar4(ideal, x, y);
- uchar4 givenPixel = rsGetElementAt_uchar4(given, x, y);
-
- error += abs(idealPixel.x - givenPixel.x);
- error += abs(idealPixel.y - givenPixel.y);
- error += abs(idealPixel.z - givenPixel.z);
- error += abs(idealPixel.w - givenPixel.w);
- }
- }
- v_out[0] = error;
-}
-
-void displayDifference(const uchar4 *v_in, uchar4 *v_out, uint32_t x, uint32_t y) {
- float4 idealPixel = rsGetElementAt_float4(ideal, x, y);
- float4 givenPixel = rsGetElementAt_float4(given, x, y);
-
- float4 diff = idealPixel - givenPixel;
- float totalDiff = diff.x + diff.y + diff.z + diff.w;
- if (totalDiff < 0) {
- v_out[0] = rsPackColorTo8888(0, 0, clamp(-totalDiff/2.f, 0.f, 1.f));
- } else {
- v_out[0] = rsPackColorTo8888(clamp(totalDiff/2.f, 0.f, 1.f), 0, 0);
- }
-}
diff --git a/tests/Internal/src/com/android/internal/app/OWNERS b/tests/Internal/src/com/android/internal/app/OWNERS
new file mode 100644
index 0000000..d55dc78
--- /dev/null
+++ b/tests/Internal/src/com/android/internal/app/OWNERS
@@ -0,0 +1,2 @@
+# Locale related test
+per-file *Locale* = file:/services/core/java/com/android/server/locales/OWNERS
diff --git a/tests/UsbManagerTests/lib/src/com/android/server/usblib/UsbManagerTestLib.java b/tests/UsbManagerTests/lib/src/com/android/server/usblib/UsbManagerTestLib.java
index 782439f..98bf541 100644
--- a/tests/UsbManagerTests/lib/src/com/android/server/usblib/UsbManagerTestLib.java
+++ b/tests/UsbManagerTests/lib/src/com/android/server/usblib/UsbManagerTestLib.java
@@ -24,12 +24,15 @@
import android.content.Context;
import android.hardware.usb.UsbManager;
+import android.os.Binder;
import android.os.RemoteException;
import android.util.Log;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.concurrent.atomic.AtomicInteger;
+
/**
* Unit tests lib for {@link android.hardware.usb.UsbManager}.
*/
@@ -42,6 +45,11 @@
private UsbManager mUsbManagerMock;
@Mock private android.hardware.usb.IUsbManager mMockUsbService;
+ /**
+ * Counter for tracking UsbOperation operations.
+ */
+ private static final AtomicInteger sUsbOperationCount = new AtomicInteger();
+
public UsbManagerTestLib(Context context) {
MockitoAnnotations.initMocks(this);
mContext = context;
@@ -82,10 +90,11 @@
}
private void testSetCurrentFunctionsMock_Matched(long functions) {
+ int operationId = sUsbOperationCount.incrementAndGet() + Binder.getCallingUid();
try {
setCurrentFunctions(functions);
- verify(mMockUsbService).setCurrentFunctions(eq(functions));
+ verify(mMockUsbService).setCurrentFunctions(eq(functions), operationId);
} catch (RemoteException remEx) {
Log.w(TAG, "RemoteException");
}
@@ -106,9 +115,10 @@
}
public void testSetCurrentFunctionsEx(long functions) throws Exception {
+ int operationId = sUsbOperationCount.incrementAndGet() + Binder.getCallingUid();
setCurrentFunctions(functions);
- verify(mMockUsbService).setCurrentFunctions(eq(functions));
+ verify(mMockUsbService).setCurrentFunctions(eq(functions), operationId);
}
public void testGetCurrentFunctions_shouldMatched() {
diff --git a/tests/UsbTests/src/com/android/server/usb/UsbHandlerTest.java b/tests/UsbTests/src/com/android/server/usb/UsbHandlerTest.java
index 861d221..e06a4cb 100644
--- a/tests/UsbTests/src/com/android/server/usb/UsbHandlerTest.java
+++ b/tests/UsbTests/src/com/android/server/usb/UsbHandlerTest.java
@@ -98,7 +98,7 @@
}
@Override
- protected void setEnabledFunctions(long functions, boolean force) {
+ protected void setEnabledFunctions(long functions, boolean force, int operationId) {
mCurrentFunctions = functions;
}
@@ -134,6 +134,20 @@
protected void sendStickyBroadcast(Intent intent) {
mBroadcastedIntent = intent;
}
+
+ @Override
+ public void handlerInitDone(int operationId) {
+ }
+
+ @Override
+ public void setCurrentUsbFunctionsCb(long functions,
+ int status, int mRequest, long mFunctions, boolean mChargingFunctions){
+ }
+
+ @Override
+ public void getUsbSpeedCb(int speed){
+ }
+
}
@Before