Merge "Fix missing ProtoLog viewer config in some tracing instances" into main
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 03eab7c..9c93c3a 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -3434,6 +3434,23 @@
package android.companion.virtual {
+ @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") public final class ActivityPolicyExemption implements android.os.Parcelable {
+ method public int describeContents();
+ method @Nullable public android.content.ComponentName getComponentName();
+ method public int getDisplayId();
+ method @Nullable public String getPackageName();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.companion.virtual.ActivityPolicyExemption> CREATOR;
+ }
+
+ public static final class ActivityPolicyExemption.Builder {
+ ctor public ActivityPolicyExemption.Builder();
+ method @NonNull public android.companion.virtual.ActivityPolicyExemption build();
+ method @NonNull public android.companion.virtual.ActivityPolicyExemption.Builder setComponentName(@NonNull android.content.ComponentName);
+ method @NonNull public android.companion.virtual.ActivityPolicyExemption.Builder setDisplayId(int);
+ method @NonNull public android.companion.virtual.ActivityPolicyExemption.Builder setPackageName(@NonNull String);
+ }
+
public final class VirtualDevice implements android.os.Parcelable {
method @FlaggedApi("android.companion.virtual.flags.vdm_public_apis") public boolean hasCustomAudioInputSupport();
method @FlaggedApi("android.companion.virtual.flags.vdm_public_apis") public boolean hasCustomCameraSupport();
@@ -3467,9 +3484,7 @@
public static class VirtualDeviceManager.VirtualDevice implements java.lang.AutoCloseable {
method public void addActivityListener(@NonNull java.util.concurrent.Executor, @NonNull android.companion.virtual.VirtualDeviceManager.ActivityListener);
method @FlaggedApi("android.companion.virtual.flags.dynamic_policy") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void addActivityPolicyExemption(@NonNull android.content.ComponentName);
- method @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void addActivityPolicyExemption(@NonNull String);
- method @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void addActivityPolicyExemption(@NonNull android.content.ComponentName, int);
- method @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void addActivityPolicyExemption(@NonNull String, int);
+ method @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void addActivityPolicyExemption(@NonNull android.companion.virtual.ActivityPolicyExemption);
method public void addSoundEffectListener(@NonNull java.util.concurrent.Executor, @NonNull android.companion.virtual.VirtualDeviceManager.SoundEffectListener);
method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void close();
method @NonNull public android.content.Context createContext();
@@ -3494,9 +3509,7 @@
method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void registerIntentInterceptor(@NonNull android.content.IntentFilter, @NonNull java.util.concurrent.Executor, @NonNull android.companion.virtual.VirtualDeviceManager.IntentInterceptorCallback);
method public void removeActivityListener(@NonNull android.companion.virtual.VirtualDeviceManager.ActivityListener);
method @FlaggedApi("android.companion.virtual.flags.dynamic_policy") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void removeActivityPolicyExemption(@NonNull android.content.ComponentName);
- method @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void removeActivityPolicyExemption(@NonNull String);
- method @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void removeActivityPolicyExemption(@NonNull android.content.ComponentName, int);
- method @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void removeActivityPolicyExemption(@NonNull String, int);
+ method @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void removeActivityPolicyExemption(@NonNull android.companion.virtual.ActivityPolicyExemption);
method public void removeSoundEffectListener(@NonNull android.companion.virtual.VirtualDeviceManager.SoundEffectListener);
method @FlaggedApi("android.companion.virtual.flags.dynamic_policy") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void setDevicePolicy(int, int);
method @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void setDevicePolicy(int, int, int);
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 80764af..dbf9afd 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -112,6 +112,8 @@
import android.permission.PermissionControllerManager;
import android.permission.PermissionManager;
import android.provider.Settings;
+import android.ravenwood.annotation.RavenwoodKeepPartialClass;
+import android.ravenwood.annotation.RavenwoodReplace;
import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
@@ -157,6 +159,7 @@
import java.util.function.Function;
/** @hide */
+@RavenwoodKeepPartialClass
public class ApplicationPackageManager extends PackageManager {
private static final String TAG = "ApplicationPackageManager";
private static final boolean DEBUG_ICONS = false;
@@ -2163,6 +2166,7 @@
}
@UnsupportedAppUsage
+ @RavenwoodReplace(reason = "<cinit> crashes due to unsupported class PropertyInvalidatedCache")
static void configurationChanged() {
synchronized (sSync) {
sIconCache.clear();
@@ -2170,6 +2174,10 @@
}
}
+ private static void configurationChanged$ravenwood() {
+ /* no-op */
+ }
+
@UnsupportedAppUsage
protected ApplicationPackageManager(ContextImpl context, IPackageManager pm) {
mContext = context;
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 2d5dad0..84a4eb4 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -41,6 +41,7 @@
import android.os.Process;
import android.os.Trace;
import android.ravenwood.annotation.RavenwoodKeepWholeClass;
+import android.ravenwood.annotation.RavenwoodReplace;
import android.ravenwood.annotation.RavenwoodThrow;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -1409,6 +1410,7 @@
return newKey;
}
+ @RavenwoodThrow(reason = "AppInfo update not supported")
public void appendPendingAppInfoUpdate(@NonNull String[] oldSourceDirs,
@NonNull ApplicationInfo appInfo) {
synchronized (mLock) {
@@ -1427,6 +1429,7 @@
}
}
+ @RavenwoodReplace(reason = "AppInfo update not supported")
public final void applyAllPendingAppInfoUpdates() {
synchronized (mLock) {
if (mPendingAppInfoUpdates != null) {
@@ -1439,6 +1442,10 @@
}
}
+ private void applyAllPendingAppInfoUpdates$ravenwood() {
+ /* no-op */
+ }
+
public final boolean applyConfigurationToResources(@NonNull Configuration config,
@Nullable CompatibilityInfo compat) {
synchronized (mLock) {
diff --git a/core/java/android/app/appfunctions/AppFunctionManager.java b/core/java/android/app/appfunctions/AppFunctionManager.java
index 4b6f406..b6240a7 100644
--- a/core/java/android/app/appfunctions/AppFunctionManager.java
+++ b/core/java/android/app/appfunctions/AppFunctionManager.java
@@ -54,9 +54,9 @@
*
* @hide
*/
- public AppFunctionManager(IAppFunctionManager mService, Context context) {
- this.mService = mService;
- this.mContext = context;
+ public AppFunctionManager(IAppFunctionManager service, Context context) {
+ mService = service;
+ mContext = context;
}
/**
@@ -114,7 +114,7 @@
}
});
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ throw e.rethrowFromSystemServer();
}
}
}
diff --git a/core/java/android/app/appfunctions/IAppFunctionManager.aidl b/core/java/android/app/appfunctions/IAppFunctionManager.aidl
index ef37095..28827bb 100644
--- a/core/java/android/app/appfunctions/IAppFunctionManager.aidl
+++ b/core/java/android/app/appfunctions/IAppFunctionManager.aidl
@@ -31,6 +31,7 @@
* @param request the request to execute an app function.
* @param callback the callback to report the result.
*/
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(anyOf = {android.Manifest.permission.EXECUTE_APP_FUNCTIONS_TRUSTED,android.Manifest.permission.EXECUTE_APP_FUNCTIONS}, conditional = true)")
void executeAppFunction(
in ExecuteAppFunctionAidlRequest request,
in IExecuteAppFunctionCallback callback
diff --git a/core/java/android/companion/virtual/ActivityPolicyExemption.aidl b/core/java/android/companion/virtual/ActivityPolicyExemption.aidl
new file mode 100644
index 0000000..2f89da3
--- /dev/null
+++ b/core/java/android/companion/virtual/ActivityPolicyExemption.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2024 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.companion.virtual;
+
+parcelable ActivityPolicyExemption;
diff --git a/core/java/android/companion/virtual/ActivityPolicyExemption.java b/core/java/android/companion/virtual/ActivityPolicyExemption.java
new file mode 100644
index 0000000..c81bb43
--- /dev/null
+++ b/core/java/android/companion/virtual/ActivityPolicyExemption.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2024 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.companion.virtual;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.companion.virtualdevice.flags.Flags;
+import android.content.ComponentName;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.view.Display;
+
+import java.util.Objects;
+
+/**
+ * Specifies an exemption from the current default activity launch policy of a virtual device.
+ *
+ * <p>Note that changing the virtual device's activity launch policy will clear all current
+ * exemptions.</p>
+ *
+ * @see VirtualDeviceParams#POLICY_TYPE_ACTIVITY
+ * @see VirtualDeviceManager.VirtualDevice#setDevicePolicy
+ * @see VirtualDeviceManager.VirtualDevice#addActivityPolicyExemption(ActivityPolicyExemption)
+ * @see VirtualDeviceManager.VirtualDevice#removeActivityPolicyExemption(ActivityPolicyExemption)
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_ACTIVITY_CONTROL_API)
+@SystemApi
+public final class ActivityPolicyExemption implements Parcelable {
+
+ private final @Nullable ComponentName mComponentName;
+ private final @Nullable String mPackageName;
+ private final int mDisplayId;
+
+ private ActivityPolicyExemption(@Nullable ComponentName componentName,
+ @Nullable String packageName, int displayId) {
+ mComponentName = componentName;
+ mPackageName = packageName;
+ mDisplayId = displayId;
+ }
+
+ private ActivityPolicyExemption(@NonNull Parcel parcel) {
+ mComponentName = parcel.readTypedObject(ComponentName.CREATOR);
+ mPackageName = parcel.readString8();
+ mDisplayId = parcel.readInt();
+ }
+
+ /**
+ * Returns the exempt component name if this is a component level exemption, {@code null}
+ * otherwise.
+ *
+ * @see Builder#setComponentName(ComponentName)
+ */
+ public @Nullable ComponentName getComponentName() {
+ return mComponentName;
+ }
+
+ /**
+ * Returns the exempt package name if this is a package level exemption, {@code null} otherwise.
+ *
+ * @see Builder#setPackageName(String)
+ */
+ public @Nullable String getPackageName() {
+ return mPackageName;
+ }
+
+ /**
+ * Returns the display ID relevant for this exemption if it is specific to a single display,
+ * {@link Display#INVALID_DISPLAY} otherwise.
+ *
+ * @see Builder#setDisplayId(int)
+ */
+ public int getDisplayId() {
+ return mDisplayId;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeTypedObject(mComponentName, flags);
+ dest.writeString8(mPackageName);
+ dest.writeInt(mDisplayId);
+ }
+
+ @NonNull
+ public static final Parcelable.Creator<ActivityPolicyExemption> CREATOR =
+ new Parcelable.Creator<>() {
+ public ActivityPolicyExemption createFromParcel(Parcel in) {
+ return new ActivityPolicyExemption(in);
+ }
+
+ public ActivityPolicyExemption[] newArray(int size) {
+ return new ActivityPolicyExemption[size];
+ }
+ };
+
+ /**
+ * Builder for {@link ActivityPolicyExemption}.
+ */
+ public static final class Builder {
+
+ private @Nullable ComponentName mComponentName;
+ private @Nullable String mPackageName;
+ private int mDisplayId = Display.INVALID_DISPLAY;
+
+ /**
+ * Specifies a component level exemption from the current default activity launch policy.
+ *
+ * <p>If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} allows activity
+ * launches by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_DEFAULT}),
+ * then the specified component will be blocked from launching.
+ * If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} blocks activity launches
+ * by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_CUSTOM}), then the
+ * specified component will be allowed to launch.</p>
+ *
+ * <p>Setting a component name will clear any previously set package name.</p>
+ */
+ public @NonNull Builder setComponentName(@NonNull ComponentName componentName) {
+ mComponentName = Objects.requireNonNull(componentName);
+ mPackageName = null;
+ return this;
+ }
+
+ /**
+ * Specifies a package level exemption from the current default activity launch policy.
+ *
+ * <p>If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} allows activity
+ * launches by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_DEFAULT}),
+ * then all activities from the specified package will be blocked from launching.
+ * If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} blocks activity launches
+ * by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_CUSTOM}), then all
+ * activities from the specified package will be allowed to launch.</p>
+ *
+ * <p>Package level exemptions are independent of component level exemptions created via
+ * {@link #setComponentName(ComponentName)}, i.e. removing a package exemption will not
+ * remove any existing component exemptions, even if the component belongs to that package.
+ * </p>
+ *
+ * <p>Setting a package name will clear any previously set component name.</p>
+ */
+ public @NonNull Builder setPackageName(@NonNull String packageName) {
+ mComponentName = null;
+ mPackageName = Objects.requireNonNull(packageName);
+ return this;
+ }
+
+ /**
+ * Makes this exemption specific to the display with the given ID. If unset, or set to
+ * {@link Display#INVALID_DISPLAY}, then the exemption is applied to all displays that
+ * belong to the virtual device.
+ *
+ * @param displayId the ID of the display, for which to apply the exemption. The display
+ * must belong to the virtual device.
+ */
+ public @NonNull Builder setDisplayId(int displayId) {
+ mDisplayId = displayId;
+ return this;
+ }
+
+ /**
+ * Builds the {@link ActivityPolicyExemption} instance.
+ *
+ * @throws IllegalArgumentException if neither the component name nor the package name are
+ * set.
+ */
+ @NonNull
+ public ActivityPolicyExemption build() {
+ if ((mComponentName == null) == (mPackageName == null)) {
+ throw new IllegalArgumentException(
+ "Either component name or package name must be set");
+ }
+ return new ActivityPolicyExemption(mComponentName, mPackageName, mDisplayId);
+ }
+ }
+}
diff --git a/core/java/android/companion/virtual/IVirtualDevice.aidl b/core/java/android/companion/virtual/IVirtualDevice.aidl
index 56d5a74..8916ce2 100644
--- a/core/java/android/companion/virtual/IVirtualDevice.aidl
+++ b/core/java/android/companion/virtual/IVirtualDevice.aidl
@@ -17,6 +17,7 @@
package android.companion.virtual;
import android.app.PendingIntent;
+import android.companion.virtual.ActivityPolicyExemption;
import android.companion.virtual.IVirtualDeviceActivityListener;
import android.companion.virtual.IVirtualDeviceIntentInterceptor;
import android.companion.virtual.IVirtualDeviceSoundEffectListener;
@@ -103,25 +104,13 @@
* Adds an exemption to the default activity launch policy.
*/
@EnforcePermission("CREATE_VIRTUAL_DEVICE")
- void addActivityPolicyExemption(in ComponentName exemption);
+ void addActivityPolicyExemption(in ActivityPolicyExemption exemption);
/**
* Removes an exemption to the default activity launch policy.
*/
@EnforcePermission("CREATE_VIRTUAL_DEVICE")
- void removeActivityPolicyExemption(in ComponentName exemption);
-
- /**
- * Adds a package level exemption to the default activity launch policy.
- */
- @EnforcePermission("CREATE_VIRTUAL_DEVICE")
- void addActivityPolicyPackageExemption(in String exemption);
-
- /**
- * Removes a package level exemption to the default activity launch policy.
- */
- @EnforcePermission("CREATE_VIRTUAL_DEVICE")
- void removeActivityPolicyPackageExemption(in String exemption);
+ void removeActivityPolicyExemption(in ActivityPolicyExemption exemption);
/**
* Specifies a policy for this virtual device on the given display.
@@ -130,30 +119,6 @@
void setDevicePolicyForDisplay(int displayId, int policyType, int devicePolicy);
/**
- * Adds an exemption to the default activity launch policy on the given display.
- */
- @EnforcePermission("CREATE_VIRTUAL_DEVICE")
- void addActivityPolicyExemptionForDisplay(int displayId, in ComponentName exemption);
-
- /**
- * Removes an exemption to the default activity launch policy on the given display.
- */
- @EnforcePermission("CREATE_VIRTUAL_DEVICE")
- void removeActivityPolicyExemptionForDisplay(int displayId, in ComponentName exemption);
-
- /**
- * Adds a package level exemption to the default activity launch policy on the given display.
- */
- @EnforcePermission("CREATE_VIRTUAL_DEVICE")
- void addActivityPolicyPackageExemptionForDisplay(int displayId, in String exemption);
-
- /**
- * Removes a package level exemption to the default activity launch policy on the given display.
- */
- @EnforcePermission("CREATE_VIRTUAL_DEVICE")
- void removeActivityPolicyPackageExemptionForDisplay(int displayId, in String exemption);
-
- /**
* Notifies that an audio session being started.
*/
@EnforcePermission("CREATE_VIRTUAL_DEVICE")
diff --git a/core/java/android/companion/virtual/VirtualDeviceInternal.java b/core/java/android/companion/virtual/VirtualDeviceInternal.java
index e83f46a..b7bf2d1 100644
--- a/core/java/android/companion/virtual/VirtualDeviceInternal.java
+++ b/core/java/android/companion/virtual/VirtualDeviceInternal.java
@@ -306,39 +306,22 @@
}
}
- void addActivityPolicyExemption(@NonNull ComponentName componentName) {
+ void addActivityPolicyExemption(@NonNull ActivityPolicyExemption exemption) {
try {
- mVirtualDevice.addActivityPolicyExemption(componentName);
+ mVirtualDevice.addActivityPolicyExemption(exemption);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
- void removeActivityPolicyExemption(@NonNull ComponentName componentName) {
+ void removeActivityPolicyExemption(@NonNull ActivityPolicyExemption exemption) {
try {
- mVirtualDevice.removeActivityPolicyExemption(componentName);
+ mVirtualDevice.removeActivityPolicyExemption(exemption);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
- void addActivityPolicyPackageExemption(@NonNull String packageName) {
- try {
- mVirtualDevice.addActivityPolicyPackageExemption(packageName);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- void removeActivityPolicyPackageExemption(@NonNull String packageName) {
- try {
- mVirtualDevice.removeActivityPolicyPackageExemption(packageName);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
-
void setDevicePolicyForDisplay(int displayId,
@VirtualDeviceParams.DynamicDisplayPolicyType int policyType,
@VirtualDeviceParams.DevicePolicy int devicePolicy) {
@@ -358,40 +341,6 @@
}
}
- void addActivityPolicyExemptionForDisplay(int displayId, @NonNull ComponentName componentName) {
- try {
- mVirtualDevice.addActivityPolicyExemptionForDisplay(displayId, componentName);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- void removeActivityPolicyExemptionForDisplay(int displayId,
- @NonNull ComponentName componentName) {
- try {
- mVirtualDevice.removeActivityPolicyExemptionForDisplay(displayId, componentName);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- void addActivityPolicyPackageExemptionForDisplay(int displayId, @NonNull String packageName) {
- try {
- mVirtualDevice.addActivityPolicyPackageExemptionForDisplay(displayId, packageName);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- void removeActivityPolicyPackageExemptionForDisplay(int displayId,
- @NonNull String packageName) {
- try {
- mVirtualDevice.removeActivityPolicyPackageExemptionForDisplay(displayId, packageName);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
@NonNull
VirtualDpad createVirtualDpad(@NonNull VirtualDpadConfig config) {
try {
diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java
index 9e32cba..40aa6837 100644
--- a/core/java/android/companion/virtual/VirtualDeviceManager.java
+++ b/core/java/android/companion/virtual/VirtualDeviceManager.java
@@ -765,14 +765,15 @@
* <p>Note that changing the activity launch policy will clear current set of exempt
* components.</p>
*
- * @see #removeActivityPolicyExemption
+ * @see #removeActivityPolicyExemption(ComponentName)
* @see #setDevicePolicy
*/
@FlaggedApi(Flags.FLAG_DYNAMIC_POLICY)
@RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
public void addActivityPolicyExemption(@NonNull ComponentName componentName) {
- mVirtualDeviceInternal.addActivityPolicyExemption(
- Objects.requireNonNull(componentName));
+ addActivityPolicyExemption(new ActivityPolicyExemption.Builder()
+ .setComponentName(componentName)
+ .build());
}
/**
@@ -788,70 +789,54 @@
* <p>Note that changing the activity launch policy will clear current set of exempt
* components.</p>
*
- * @see #addActivityPolicyExemption
+ * @see #addActivityPolicyExemption(ComponentName)
* @see #setDevicePolicy
*/
@FlaggedApi(Flags.FLAG_DYNAMIC_POLICY)
@RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
public void removeActivityPolicyExemption(@NonNull ComponentName componentName) {
- mVirtualDeviceInternal.removeActivityPolicyExemption(
- Objects.requireNonNull(componentName));
+ removeActivityPolicyExemption(new ActivityPolicyExemption.Builder()
+ .setComponentName(componentName)
+ .build());
}
/**
- * Specifies a package name to be exempt from the current activity launch policy.
+ * Specifies an exemption from the current activity launch policy.
*
* <p>If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} allows activity
* launches by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_DEFAULT}),
- * then all activities from the specified package will be blocked from launching.
+ * then all exempt activities be blocked from launching.
* If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} blocks activity launches
* by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_CUSTOM}), then all
- * activities from the specified package will be allowed to launch.</p>
- *
- * <p>Package level exemptions are independent of component level exemptions added via
- * {@link #addActivityPolicyExemption(String)}, i.e. removing a package exemption will not
- * remove any existing component exemptions, even if the component belongs to that package.
- * </p>
+ * exempt activities will be allowed to launch.</p>
*
* <p>Note that changing the activity launch policy will clear current set of exempt
* packages.</p>
+ * <p>Any change to the exemptions will only be applied for new activity launches.</p>
*
- * @see #removeActivityPolicyExemption(String)
+ * @see #removeActivityPolicyExemption(ActivityPolicyExemption)
* @see #setDevicePolicy
*/
@FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ACTIVITY_CONTROL_API)
@RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
- public void addActivityPolicyExemption(@NonNull String packageName) {
- mVirtualDeviceInternal.addActivityPolicyPackageExemption(
- Objects.requireNonNull(packageName));
+ public void addActivityPolicyExemption(@NonNull ActivityPolicyExemption exemption) {
+ mVirtualDeviceInternal.addActivityPolicyExemption(Objects.requireNonNull(exemption));
}
/**
- * Makes the specified package name adhere to the default activity launch policy.
- *
- * <p>If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} allows activity
- * launches by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_DEFAULT}),
- * then all activities from the specified package will be allowed to launch.
- * If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} blocks activity launches
- * by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_CUSTOM}), then all
- * activities from the specified package will be blocked from launching.</p>
- *
- * <p>Package level exemptions are independent of component level exemptions added via
- * {@link #addActivityPolicyExemption(String)}, i.e. removing a package exemption will not
- * remove any existing component exemptions, even if the component belongs to that package.
- * </p>
+ * Removes an exemption from the current activity launch policy.
*
* <p>Note that changing the activity launch policy will clear current set of exempt
* packages.</p>
+ * <p>Any change to the exemptions will only be applied for new activity launches.</p>
*
- * @see #addActivityPolicyExemption(String)
+ * @see #addActivityPolicyExemption(ActivityPolicyExemption)
* @see #setDevicePolicy
*/
@FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ACTIVITY_CONTROL_API)
@RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
- public void removeActivityPolicyExemption(@NonNull String packageName) {
- mVirtualDeviceInternal.removeActivityPolicyPackageExemption(
- Objects.requireNonNull(packageName));
+ public void removeActivityPolicyExemption(@NonNull ActivityPolicyExemption exemption) {
+ mVirtualDeviceInternal.removeActivityPolicyExemption(Objects.requireNonNull(exemption));
}
/**
@@ -881,142 +866,6 @@
}
/**
- * Specifies a component name to be exempt from the given display's activity launch policy.
- *
- * <p>If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} allows activity
- * launches by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_DEFAULT}),
- * then the specified component will be blocked from launching.
- * If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} blocks activity launches
- * by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_CUSTOM}), then the
- * specified component will be allowed to launch.</p>
- *
- * <p>Note that changing the activity launch policy will clear current set of exempt
- * components.</p>
- * <p>Any change to the exemptions will only be applied for new activity launches.</p>
- *
- * @param componentName the component name to be exempt from the activity launch policy.
- * @param displayId the ID of the display, for which to apply the exemption. The display
- * must belong to the virtual device.
- * @throws IllegalArgumentException if the specified display does not belong to the virtual
- * device.
- *
- * @see #removeActivityPolicyExemption
- * @see #setDevicePolicy
- * @see Display#getDisplayId
- */
- @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ACTIVITY_CONTROL_API)
- @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
- public void addActivityPolicyExemption(
- @NonNull ComponentName componentName, int displayId) {
- mVirtualDeviceInternal.addActivityPolicyExemptionForDisplay(
- displayId, Objects.requireNonNull(componentName));
- }
-
- /**
- * Makes the specified component name adhere to the given display's activity launch policy.
- *
- * <p>If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} allows activity
- * launches by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_DEFAULT}),
- * then the specified component will be allowed to launch.
- * If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} blocks activity launches
- * by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_CUSTOM}), then the
- * specified component will be blocked from launching.</p>
- *
- * <p>Note that changing the activity launch policy will clear current set of exempt
- * components.</p>
- *
- * @param componentName the component name to be removed from the exemption list.
- * @param displayId the ID of the display, for which to apply the exemption. The display
- * must belong to the virtual device.
- * @throws IllegalArgumentException if the specified display does not belong to the virtual
- * device.
- *
- * @see #addActivityPolicyExemption
- * @see #setDevicePolicy
- * @see Display#getDisplayId
- */
- @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ACTIVITY_CONTROL_API)
- @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
- public void removeActivityPolicyExemption(
- @NonNull ComponentName componentName, int displayId) {
- mVirtualDeviceInternal.removeActivityPolicyExemptionForDisplay(
- displayId, Objects.requireNonNull(componentName));
- }
-
- /**
- * Specifies a package name to be exempt from the given display's activity launch policy.
- *
- * <p>If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} allows activity
- * launches by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_DEFAULT}),
- * then all activities from the specified package will be blocked from launching.
- * If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} blocks activity launches
- * by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_CUSTOM}), then all
- * activities from the specified package will be allowed to launch.</p>
- *
- * <p>Note that changing the activity launch policy will clear current set of exempt
- * packages.</p>
- * <p>Any change to the exemptions will only be applied for new activity launches.</p>
- *
- * <p>Package level exemptions are independent of component level exemptions added via
- * {@link #addActivityPolicyExemption(String, int)}, i.e. removing a package exemption will
- * not remove any existing component exemptions, even if the component belongs to that
- * package.</p>
- *
- * @param packageName the package name to be exempt from the activity launch policy. All
- * activities from that package will be exempt.
- * @param displayId the ID of the display, for which to apply the exemption. The display
- * must belong to the virtual device.
- * @throws IllegalArgumentException if the specified display does not belong to the virtual
- * device.
- *
- * @see #removeActivityPolicyExemption(String, int)
- * @see #setDevicePolicy
- * @see Display#getDisplayId
- */
- @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ACTIVITY_CONTROL_API)
- @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
- public void addActivityPolicyExemption(@NonNull String packageName, int displayId) {
- mVirtualDeviceInternal.addActivityPolicyPackageExemptionForDisplay(
- displayId, Objects.requireNonNull(packageName));
- }
-
- /**
- * Makes the specified package name adhere to the given display's activity launch policy.
- *
- * <p>If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} allows activity
- * launches by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_DEFAULT}),
- * then all activities from the specified package will be allowed to launch.
- * If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} blocks activity launches
- * by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_CUSTOM}), then all
- * activities from the specified package will be blocked from launching.</p>
- *
- * <p>Note that changing the activity launch policy will clear current set of exempt
- * packages.</p>
- *
- * <p>Package level exemptions are independent of component level exemptions added via
- * {@link #addActivityPolicyExemption(String, int)}, i.e. removing a package exemption will
- * not remove any existing component exemptions, even if the component belongs to that
- * package.</p>
- *
- * @param packageName the package name to be removed from the exemption list. All activities
- * from that package stop being exempt from the activity launch policy.
- * @param displayId the ID of the display, for which to apply the exemption. The display
- * must belong to the virtual device.
- * @throws IllegalArgumentException if the specified display does not belong to the virtual
- * device.
- *
- * @see #addActivityPolicyExemption(String, int)
- * @see #setDevicePolicy
- * @see Display#getDisplayId
- */
- @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ACTIVITY_CONTROL_API)
- @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
- public void removeActivityPolicyExemption(@NonNull String packageName, int displayId) {
- mVirtualDeviceInternal.removeActivityPolicyPackageExemptionForDisplay(
- displayId, Objects.requireNonNull(packageName));
- }
-
- /**
* Creates a virtual dpad.
*
* @param config the configurations of the virtual dpad.
@@ -1401,7 +1250,7 @@
* activity to a different display.
*
* @see VirtualDeviceParams#POLICY_TYPE_ACTIVITY
- * @see VirtualDevice#addActivityPolicyExemption(ComponentName)
+ * @see VirtualDevice#addActivityPolicyExemption(ActivityPolicyExemption)
*/
@FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ACTIVITY_CONTROL_API)
default void onActivityLaunchBlocked(int displayId, @NonNull ComponentName componentName,
diff --git a/core/java/android/content/AbstractThreadedSyncAdapter.java b/core/java/android/content/AbstractThreadedSyncAdapter.java
index da4ecdd..9649cab 100644
--- a/core/java/android/content/AbstractThreadedSyncAdapter.java
+++ b/core/java/android/content/AbstractThreadedSyncAdapter.java
@@ -42,7 +42,7 @@
* will be invoked on that thread.
* <p>
* Syncs can be cancelled at any time by the framework. For example a sync that was not
- * user-initiated and lasts longer than 30 minutes will be considered timed-out and cancelled.
+ * user-initiated and lasts longer than 10 minutes will be considered timed-out and cancelled.
* Similarly the framework will attempt to determine whether or not an adapter is making progress
* by monitoring its network activity over the course of a minute. If the network traffic over this
* window is close enough to zero the sync will be cancelled. You can also request the sync be
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index f929c1f..d6620d1 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -28,6 +28,7 @@
import android.os.Build.VERSION_CODES;
import android.os.Parcel;
import android.os.Parcelable;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
import android.util.DisplayMetrics;
import android.util.MergedConfiguration;
import android.view.InsetsSourceControl;
@@ -42,6 +43,7 @@
*
* {@hide}
*/
+@RavenwoodKeepWholeClass
public class CompatibilityInfo implements Parcelable {
/** default compatibility info object for compatible applications */
@UnsupportedAppUsage
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 982224b..ef200c3 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -58,6 +58,7 @@
import android.os.LocaleList;
import android.os.Parcel;
import android.os.Parcelable;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Slog;
@@ -89,6 +90,7 @@
* with {@link android.app.Activity#getResources}:</p>
* <pre>Configuration config = getResources().getConfiguration();</pre>
*/
+@RavenwoodKeepWholeClass
public final class Configuration implements Parcelable, Comparable<Configuration> {
/** @hide */
public static final Configuration EMPTY = new Configuration();
diff --git a/core/java/android/content/res/ConfigurationBoundResourceCache.java b/core/java/android/content/res/ConfigurationBoundResourceCache.java
index 5e10a57..9dc097a 100644
--- a/core/java/android/content/res/ConfigurationBoundResourceCache.java
+++ b/core/java/android/content/res/ConfigurationBoundResourceCache.java
@@ -18,6 +18,7 @@
import android.compat.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
/**
* A Cache class which can be used to cache resource objects that are easy to clone but more
@@ -25,6 +26,7 @@
*
* @hide For internal use only.
*/
+@RavenwoodKeepWholeClass
public class ConfigurationBoundResourceCache<T> extends ThemedResourceCache<ConstantState<T>> {
@UnsupportedAppUsage
diff --git a/core/java/android/content/res/ConstantState.java b/core/java/android/content/res/ConstantState.java
index 09d4a59..cedfe02 100644
--- a/core/java/android/content/res/ConstantState.java
+++ b/core/java/android/content/res/ConstantState.java
@@ -16,6 +16,7 @@
package android.content.res;
import android.content.pm.ActivityInfo.Config;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
/**
* A cache class that can provide new instances of a particular resource which may change
@@ -29,6 +30,7 @@
* changing configurations of each Animator in the set)
* @hide
*/
+@RavenwoodKeepWholeClass
abstract public class ConstantState<T> {
/**
diff --git a/core/java/android/content/res/FontResourcesParser.java b/core/java/android/content/res/FontResourcesParser.java
index 24ae31e..8aef45b 100644
--- a/core/java/android/content/res/FontResourcesParser.java
+++ b/core/java/android/content/res/FontResourcesParser.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.Typeface;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Xml;
@@ -36,6 +37,7 @@
* Parser for xml type font resources.
* @hide
*/
+@RavenwoodKeepWholeClass
public class FontResourcesParser {
private static final String TAG = "FontResourcesParser";
diff --git a/core/java/android/content/res/FontScaleConverter.java b/core/java/android/content/res/FontScaleConverter.java
index f4312a9..b2c5afa 100644
--- a/core/java/android/content/res/FontScaleConverter.java
+++ b/core/java/android/content/res/FontScaleConverter.java
@@ -20,6 +20,7 @@
import android.annotation.AnyThread;
import android.annotation.FlaggedApi;
import android.annotation.Nullable;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
/**
* A converter for non-linear font scaling. Converts font sizes given in "sp" dimensions to a
@@ -32,6 +33,7 @@
* scale them slightly to preserve the visual hierarchy when compared to smaller fonts.
*/
@FlaggedApi(Flags.FLAG_FONT_SCALE_CONVERTER_PUBLIC)
+@RavenwoodKeepWholeClass
public interface FontScaleConverter {
/**
* Converts a dimension in "sp" to "dp".
diff --git a/core/java/android/content/res/FontScaleConverterFactory.java b/core/java/android/content/res/FontScaleConverterFactory.java
index c7237ea..9087a9a 100644
--- a/core/java/android/content/res/FontScaleConverterFactory.java
+++ b/core/java/android/content/res/FontScaleConverterFactory.java
@@ -19,6 +19,7 @@
import android.annotation.AnyThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
import android.util.MathUtils;
import android.util.SparseArray;
@@ -34,6 +35,7 @@
*
* @hide
*/
+@RavenwoodKeepWholeClass
public class FontScaleConverterFactory {
private static final float SCALE_KEY_MULTIPLIER = 100f;
diff --git a/core/java/android/content/res/FontScaleConverterImpl.java b/core/java/android/content/res/FontScaleConverterImpl.java
index 1968c4e..508507a 100644
--- a/core/java/android/content/res/FontScaleConverterImpl.java
+++ b/core/java/android/content/res/FontScaleConverterImpl.java
@@ -17,6 +17,7 @@
package android.content.res;
import android.annotation.NonNull;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
import android.util.MathUtils;
import com.android.internal.annotations.VisibleForTesting;
@@ -33,6 +34,7 @@
*/
// Needs to be public so the Kotlin test can see it
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+@RavenwoodKeepWholeClass
public class FontScaleConverterImpl implements FontScaleConverter {
/** @hide */
diff --git a/core/java/android/content/res/ThemedResourceCache.java b/core/java/android/content/res/ThemedResourceCache.java
index 690dfcf..c7fcc1a 100644
--- a/core/java/android/content/res/ThemedResourceCache.java
+++ b/core/java/android/content/res/ThemedResourceCache.java
@@ -22,6 +22,7 @@
import android.content.pm.ActivityInfo.Config;
import android.content.res.Resources.Theme;
import android.content.res.Resources.ThemeKey;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
import android.util.ArrayMap;
import android.util.LongSparseArray;
@@ -32,6 +33,7 @@
*
* @param <T> type of data to cache
*/
+@RavenwoodKeepWholeClass
abstract class ThemedResourceCache<T> {
public static final int UNDEFINED_GENERATION = -1;
@UnsupportedAppUsage
diff --git a/core/java/android/view/DisplayAdjustments.java b/core/java/android/view/DisplayAdjustments.java
index bb50849..149d992 100644
--- a/core/java/android/view/DisplayAdjustments.java
+++ b/core/java/android/view/DisplayAdjustments.java
@@ -21,10 +21,12 @@
import android.compat.annotation.UnsupportedAppUsage;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
import java.util.Objects;
/** @hide */
+@RavenwoodKeepWholeClass
public class DisplayAdjustments {
public static final DisplayAdjustments DEFAULT_DISPLAY_ADJUSTMENTS = new DisplayAdjustments();
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
index 61ee13a..be744fd 100644
--- a/core/java/android/window/flags/windowing_frontend.aconfig
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -228,6 +228,16 @@
}
flag {
+ name: "ensure_wallpaper_in_wear_transitions"
+ namespace: "windowing_frontend"
+ description: "Ensure that wallpaper window tokens are always present/available for collection in transitions on Wear"
+ bug: "355596979"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "custom_animations_behind_translucent"
namespace: "windowing_frontend"
description: "A change can use its own layer parameters to animate behind a translucent activity"
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index 2bbaf9c..e86515f 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -164,6 +164,7 @@
"org.apache.http.legacy",
],
sdk_version: "core_platform",
+ resource_zips: [":FrameworksCoreTests_apks_as_resources"],
}
// Rules to copy all the test apks to the intermediate raw resource directory
@@ -237,6 +238,7 @@
static_libs: [
"core-test-rules", // for libcore.dalvik.system.CloseGuardSupport
"androidx.core_core",
+ "androidx.core_core-ktx",
"androidx.annotation_annotation",
"androidx.test.rules",
"androidx.test.ext.junit",
@@ -255,8 +257,11 @@
"src/android/content/pm/UserInfoTest.java",
"src/android/database/CursorWindowTest.java",
"src/android/os/**/*.java",
+ "src/android/content/res/*.java",
+ "src/android/content/res/*.kt",
"src/android/telephony/PinResultTest.java",
"src/android/util/**/*.java",
+ "src/android/view/DisplayAdjustmentsTests.java",
"src/android/view/DisplayTest.java",
"src/android/view/DisplayInfoTest.java",
"src/com/android/internal/logging/**/*.java",
@@ -274,6 +279,10 @@
":FrameworksCoreTests-helpers",
":FrameworksCoreTestDoubles-sources",
],
+ exclude_srcs: [
+ "src/android/content/res/FontScaleConverterActivityTest.java",
+ ],
+ resource_apk: "FrameworksCoreTests-resonly",
aidl: {
generate_get_transaction_name: true,
local_include_dirs: ["aidl"],
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index fc3c2f3..0dcb1ce 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -1672,14 +1672,6 @@
</intent-filter>
</activity>
- <activity android:name="android.content.res.ResourceCacheActivity"
- android:exported="true">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
- </intent-filter>
- </activity>
-
<activity
android:name="android.print.test.PrintDocumentActivity"
android:theme="@style/Theme" />
diff --git a/core/tests/coretests/src/android/content/res/ConfigurationBoundResourceCacheTest.java b/core/tests/coretests/src/android/content/res/ConfigurationBoundResourceCacheTest.java
index 6ffdee1..68882eb 100644
--- a/core/tests/coretests/src/android/content/res/ConfigurationBoundResourceCacheTest.java
+++ b/core/tests/coretests/src/android/content/res/ConfigurationBoundResourceCacheTest.java
@@ -16,80 +16,94 @@
package android.content.res;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+
+import android.content.Context;
import android.platform.test.annotations.Presubmit;
-import android.test.ActivityInstrumentationTestCase2;
+import android.platform.test.ravenwood.RavenwoodRule;
import android.util.TypedValue;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
import com.android.frameworks.coretests.R;
-import java.lang.reflect.InvocationTargetException;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
@Presubmit
-public class ConfigurationBoundResourceCacheTest
- extends ActivityInstrumentationTestCase2<ResourceCacheActivity> {
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ConfigurationBoundResourceCacheTest {
- ConfigurationBoundResourceCache<Float> mCache;
+ @Rule
+ public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder().build();
- public ConfigurationBoundResourceCacheTest() {
- super(ResourceCacheActivity.class);
+ private ConfigurationBoundResourceCache<Float> mCache;
+ private Context mContext;
+
+ private void assertEquals(float expected, float actual) {
+ Assert.assertEquals(expected, actual, 0);
}
- @Override
- protected void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setUp() throws Exception {
mCache = new ConfigurationBoundResourceCache<>();
+ mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
}
- @SmallTest
+ @Test
public void testGetEmpty() {
- final Resources res = getActivity().getResources();
+ final Resources res = mContext.getResources();
assertNull(mCache.getInstance(-1, res, null));
}
- @SmallTest
+ @Test
public void testSetGet() {
mCache.put(1, null, new DummyFloatConstantState(5f),
ThemedResourceCache.UNDEFINED_GENERATION);
- final Resources res = getActivity().getResources();
+ final Resources res = mContext.getResources();
assertEquals(5f, mCache.getInstance(1, res, null));
assertNotSame(5f, mCache.getInstance(1, res, null));
- assertEquals(null, mCache.getInstance(1, res, getActivity().getTheme()));
+ assertNull(mCache.getInstance(1, res, mContext.getTheme()));
}
- @SmallTest
+ @Test
public void testSetGetThemed() {
- mCache.put(1, getActivity().getTheme(), new DummyFloatConstantState(5f),
+ mCache.put(1, mContext.getTheme(), new DummyFloatConstantState(5f),
ThemedResourceCache.UNDEFINED_GENERATION);
- final Resources res = getActivity().getResources();
- assertEquals(null, mCache.getInstance(1, res, null));
- assertEquals(5f, mCache.getInstance(1, res, getActivity().getTheme()));
- assertNotSame(5f, mCache.getInstance(1, res, getActivity().getTheme()));
+ final Resources res = mContext.getResources();
+ assertNull(mCache.getInstance(1, res, null));
+ assertEquals(5f, mCache.getInstance(1, res, mContext.getTheme()));
+ assertNotSame(5f, mCache.getInstance(1, res, mContext.getTheme()));
}
- @SmallTest
+ @Test
public void testMultiThreadPutGet() {
- mCache.put(1, getActivity().getTheme(), new DummyFloatConstantState(5f),
+ mCache.put(1, mContext.getTheme(), new DummyFloatConstantState(5f),
ThemedResourceCache.UNDEFINED_GENERATION);
mCache.put(1, null, new DummyFloatConstantState(10f),
ThemedResourceCache.UNDEFINED_GENERATION);
- final Resources res = getActivity().getResources();
+ final Resources res = mContext.getResources();
assertEquals(10f, mCache.getInstance(1, res, null));
assertNotSame(10f, mCache.getInstance(1, res, null));
- assertEquals(5f, mCache.getInstance(1, res, getActivity().getTheme()));
- assertNotSame(5f, mCache.getInstance(1, res, getActivity().getTheme()));
+ assertEquals(5f, mCache.getInstance(1, res, mContext.getTheme()));
+ assertNotSame(5f, mCache.getInstance(1, res, mContext.getTheme()));
}
- @SmallTest
- public void testVoidConfigChange()
- throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+ @Test
+ public void testVoidConfigChange() {
TypedValue staticValue = new TypedValue();
long key = 3L;
- final Resources res = getActivity().getResources();
+ final Resources res = mContext.getResources();
res.getValue(R.dimen.resource_cache_test_generic, staticValue, true);
float staticDim = TypedValue.complexToDimension(staticValue.data, res.getDisplayMetrics());
- mCache.put(key, getActivity().getTheme(),
+ mCache.put(key, mContext.getTheme(),
new DummyFloatConstantState(staticDim, staticValue.changingConfigurations),
ThemedResourceCache.UNDEFINED_GENERATION);
final Configuration cfg = res.getConfiguration();
@@ -98,21 +112,20 @@
Configuration.ORIENTATION_PORTRAIT
: Configuration.ORIENTATION_LANDSCAPE;
int changes = calcConfigChanges(res, newCnf);
- assertEquals(staticDim, mCache.getInstance(key, res, getActivity().getTheme()));
+ assertEquals(staticDim, mCache.getInstance(key, res, mContext.getTheme()));
mCache.onConfigurationChange(changes);
- assertEquals(staticDim, mCache.getInstance(key, res, getActivity().getTheme()));
+ assertEquals(staticDim, mCache.getInstance(key, res, mContext.getTheme()));
}
- @SmallTest
- public void testEffectiveConfigChange()
- throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+ @Test
+ public void testEffectiveConfigChange() {
TypedValue changingValue = new TypedValue();
long key = 4L;
- final Resources res = getActivity().getResources();
+ final Resources res = mContext.getResources();
res.getValue(R.dimen.resource_cache_test_orientation_dependent, changingValue, true);
float changingDim = TypedValue.complexToDimension(changingValue.data,
res.getDisplayMetrics());
- mCache.put(key, getActivity().getTheme(),
+ mCache.put(key, mContext.getTheme(),
new DummyFloatConstantState(changingDim, changingValue.changingConfigurations),
ThemedResourceCache.UNDEFINED_GENERATION);
@@ -123,26 +136,25 @@
: Configuration.ORIENTATION_LANDSCAPE;
int changes = calcConfigChanges(res, newCnf);
assertEquals(changingDim,
- mCache.getInstance(key, res, getActivity().getTheme()));
+ mCache.getInstance(key, res, mContext.getTheme()));
mCache.onConfigurationChange(changes);
- assertNull(mCache.get(key, getActivity().getTheme()));
+ assertNull(mCache.get(key, mContext.getTheme()));
}
- @SmallTest
- public void testConfigChangeMultipleResources()
- throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+ @Test
+ public void testConfigChangeMultipleResources() {
TypedValue staticValue = new TypedValue();
TypedValue changingValue = new TypedValue();
- final Resources res = getActivity().getResources();
+ final Resources res = mContext.getResources();
res.getValue(R.dimen.resource_cache_test_generic, staticValue, true);
res.getValue(R.dimen.resource_cache_test_orientation_dependent, changingValue, true);
float staticDim = TypedValue.complexToDimension(staticValue.data, res.getDisplayMetrics());
float changingDim = TypedValue.complexToDimension(changingValue.data,
res.getDisplayMetrics());
- mCache.put(R.dimen.resource_cache_test_generic, getActivity().getTheme(),
+ mCache.put(R.dimen.resource_cache_test_generic, mContext.getTheme(),
new DummyFloatConstantState(staticDim, staticValue.changingConfigurations),
ThemedResourceCache.UNDEFINED_GENERATION);
- mCache.put(R.dimen.resource_cache_test_orientation_dependent, getActivity().getTheme(),
+ mCache.put(R.dimen.resource_cache_test_orientation_dependent, mContext.getTheme(),
new DummyFloatConstantState(changingDim, changingValue.changingConfigurations),
ThemedResourceCache.UNDEFINED_GENERATION);
final Configuration cfg = res.getConfiguration();
@@ -152,25 +164,24 @@
: Configuration.ORIENTATION_LANDSCAPE;
int changes = calcConfigChanges(res, newCnf);
assertEquals(staticDim, mCache.getInstance(R.dimen.resource_cache_test_generic, res,
- getActivity().getTheme()));
+ mContext.getTheme()));
assertEquals(changingDim,
mCache.getInstance(R.dimen.resource_cache_test_orientation_dependent, res,
- getActivity().getTheme()));
+ mContext.getTheme()));
mCache.onConfigurationChange(changes);
assertEquals(staticDim, mCache.getInstance(R.dimen.resource_cache_test_generic, res,
- getActivity().getTheme()));
+ mContext.getTheme()));
assertNull(mCache.getInstance(R.dimen.resource_cache_test_orientation_dependent, res,
- getActivity().getTheme()));
+ mContext.getTheme()));
}
- @SmallTest
- public void testConfigChangeMultipleThemes()
- throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+ @Test
+ public void testConfigChangeMultipleThemes() {
TypedValue[] staticValues = new TypedValue[]{new TypedValue(), new TypedValue()};
TypedValue[] changingValues = new TypedValue[]{new TypedValue(), new TypedValue()};
float staticDim = 0;
float changingDim = 0;
- final Resources res = getActivity().getResources();
+ final Resources res = mContext.getResources();
for (int i = 0; i < 2; i++) {
res.getValue(R.dimen.resource_cache_test_generic, staticValues[i], true);
staticDim = TypedValue
@@ -180,7 +191,7 @@
true);
changingDim = TypedValue.complexToDimension(changingValues[i].data,
res.getDisplayMetrics());
- final Resources.Theme theme = i == 0 ? getActivity().getTheme() : null;
+ final Resources.Theme theme = i == 0 ? mContext.getTheme() : null;
mCache.put(R.dimen.resource_cache_test_generic, theme,
new DummyFloatConstantState(staticDim, staticValues[i].changingConfigurations),
ThemedResourceCache.UNDEFINED_GENERATION);
@@ -196,7 +207,7 @@
: Configuration.ORIENTATION_LANDSCAPE;
int changes = calcConfigChanges(res, newCnf);
for (int i = 0; i < 2; i++) {
- final Resources.Theme theme = i == 0 ? getActivity().getTheme() : null;
+ final Resources.Theme theme = i == 0 ? mContext.getTheme() : null;
assertEquals(staticDim,
mCache.getInstance(R.dimen.resource_cache_test_generic, res, theme));
assertEquals(changingDim,
@@ -205,7 +216,7 @@
}
mCache.onConfigurationChange(changes);
for (int i = 0; i < 2; i++) {
- final Resources.Theme theme = i == 0 ? getActivity().getTheme() : null;
+ final Resources.Theme theme = i == 0 ? mContext.getTheme() : null;
assertEquals(staticDim,
mCache.getInstance(R.dimen.resource_cache_test_generic, res, theme));
assertNull(mCache.getInstance(R.dimen.resource_cache_test_orientation_dependent, res,
diff --git a/core/tests/coretests/src/android/content/res/ConfigurationTest.java b/core/tests/coretests/src/android/content/res/ConfigurationTest.java
index 0d5cd72..83c7484 100644
--- a/core/tests/coretests/src/android/content/res/ConfigurationTest.java
+++ b/core/tests/coretests/src/android/content/res/ConfigurationTest.java
@@ -28,23 +28,27 @@
import static android.content.res.Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
import static android.view.Surface.ROTATION_90;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
import android.content.Context;
import android.os.LocaleList;
import android.platform.test.annotations.Presubmit;
+import android.platform.test.ravenwood.RavenwoodRule;
import android.util.AtomicFile;
import android.util.proto.ProtoInputStream;
import android.util.proto.ProtoOutputStream;
-import androidx.test.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
import com.android.server.usage.IntervalStatsProto;
-import junit.framework.TestCase;
-
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
import java.io.File;
import java.io.FileInputStream;
@@ -54,10 +58,14 @@
/**
* Build/install/run: bit FrameworksCoreTests:android.content.res.ConfigurationTest
*/
-@RunWith(JUnit4.class)
+@RunWith(AndroidJUnit4.class)
@SmallTest
@Presubmit
-public class ConfigurationTest extends TestCase {
+public class ConfigurationTest {
+
+ @Rule
+ public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder().build();
+
@Test
public void testUpdateFromPreservesRoundBit() {
Configuration config = new Configuration();
@@ -82,7 +90,7 @@
@Test
public void testReadWriteProto() throws Exception {
- final Context context = InstrumentationRegistry.getTargetContext();
+ final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
final File testDir = new File(context.getFilesDir(), "ConfigurationTest");
testDir.mkdirs();
final File proto = new File(testDir, "configs");
diff --git a/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java b/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java
index 85f5d69..3fcd372 100644
--- a/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java
+++ b/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java
@@ -26,16 +26,17 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
-import android.app.Instrumentation;
import android.platform.test.annotations.Presubmit;
+import android.platform.test.ravenwood.RavenwoodRule;
-import androidx.test.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
import com.android.frameworks.coretests.R;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.xmlpull.v1.XmlPullParserException;
@@ -51,13 +52,14 @@
@RunWith(AndroidJUnit4.class)
public class FontResourcesParserTest {
- private Instrumentation mInstrumentation;
+ @Rule
+ public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder().build();
+
private Resources mResources;
@Before
public void setup() {
- mInstrumentation = InstrumentationRegistry.getInstrumentation();
- mResources = mInstrumentation.getContext().getResources();
+ mResources = InstrumentationRegistry.getInstrumentation().getContext().getResources();
}
@Test
diff --git a/core/tests/coretests/src/android/content/res/FontScaleConverterFactoryTest.kt b/core/tests/coretests/src/android/content/res/FontScaleConverterFactoryTest.kt
index c7d5825..c0a9bc2 100644
--- a/core/tests/coretests/src/android/content/res/FontScaleConverterFactoryTest.kt
+++ b/core/tests/coretests/src/android/content/res/FontScaleConverterFactoryTest.kt
@@ -20,6 +20,8 @@
import android.platform.test.annotations.RequiresFlagsEnabled
import android.platform.test.flag.junit.CheckFlagsRule
import android.platform.test.flag.junit.DeviceFlagsValueProvider
+import android.platform.test.flag.junit.RavenwoodFlagsValueProvider
+import android.platform.test.ravenwood.RavenwoodRule
import android.util.SparseArray
import androidx.core.util.forEach
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -27,15 +29,14 @@
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
+import kotlin.math.ceil
+import kotlin.math.floor
+import kotlin.random.Random.Default.nextFloat
import org.junit.After
import org.junit.Before
import org.junit.Rule
-import kotlin.math.ceil
-import kotlin.math.floor
import org.junit.Test
import org.junit.runner.RunWith
-import java.lang.IllegalStateException
-import kotlin.random.Random.Default.nextFloat
/**
* Unit tests for FontScaleConverterFactory. Note that some similar tests are in
@@ -46,7 +47,15 @@
class FontScaleConverterFactoryTest {
@get:Rule
- val checkFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()
+ val ravenwoodRule: RavenwoodRule = RavenwoodRule.Builder().build()
+
+ @get:Rule
+ val checkFlagsRule: CheckFlagsRule =
+ if (RavenwoodRule.isOnRavenwood()) {
+ RavenwoodFlagsValueProvider.createAllOnCheckFlagsRule()
+ } else {
+ DeviceFlagsValueProvider.createCheckFlagsRule()
+ }
private var defaultLookupTables: SparseArray<FontScaleConverter>? = null
diff --git a/core/tests/coretests/src/android/content/res/FontScaleConverterTest.kt b/core/tests/coretests/src/android/content/res/FontScaleConverterTest.kt
index 2c61442..0e5d926 100644
--- a/core/tests/coretests/src/android/content/res/FontScaleConverterTest.kt
+++ b/core/tests/coretests/src/android/content/res/FontScaleConverterTest.kt
@@ -17,8 +17,10 @@
package android.content.res
import android.platform.test.annotations.Presubmit
+import android.platform.test.ravenwood.RavenwoodRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertWithMessage
+import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -26,6 +28,9 @@
@RunWith(AndroidJUnit4::class)
class FontScaleConverterTest {
+ @get:Rule
+ val ravenwoodRule: RavenwoodRule = RavenwoodRule.Builder().build()
+
@Test
fun straightInterpolation() {
val table = createTable(8f to 8f, 10f to 10f, 20f to 20f)
diff --git a/core/tests/coretests/src/android/content/res/ResourceCacheActivity.java b/core/tests/coretests/src/android/content/res/ResourceCacheActivity.java
deleted file mode 100644
index f37e549..0000000
--- a/core/tests/coretests/src/android/content/res/ResourceCacheActivity.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-* Copyright (C) 2014 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.content.res;
-
-import android.annotation.Nullable;
-import android.app.Activity;
-import android.os.Bundle;
-
-import java.lang.ref.WeakReference;
-
-public class ResourceCacheActivity extends Activity {
- static WeakReference<ResourceCacheActivity> lastCreatedInstance;
-
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- lastCreatedInstance = new WeakReference<ResourceCacheActivity>(this);
- }
-
- public static ResourceCacheActivity getLastCreatedInstance() {
- return lastCreatedInstance == null ? null : lastCreatedInstance.get();
- }
-}
diff --git a/core/tests/coretests/src/android/content/res/ResourcesDrawableTest.java b/core/tests/coretests/src/android/content/res/ResourcesDrawableTest.java
index ac69a0f..6a09848 100644
--- a/core/tests/coretests/src/android/content/res/ResourcesDrawableTest.java
+++ b/core/tests/coretests/src/android/content/res/ResourcesDrawableTest.java
@@ -24,22 +24,29 @@
import android.graphics.drawable.ColorStateListDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
+import android.platform.test.annotations.DisabledOnRavenwood;
import android.platform.test.annotations.Presubmit;
+import android.platform.test.ravenwood.RavenwoodRule;
-import androidx.test.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
import com.android.frameworks.coretests.R;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@Presubmit
@SmallTest
+@DisabledOnRavenwood(blockedBy = Drawable.class)
@RunWith(AndroidJUnit4.class)
public class ResourcesDrawableTest {
+ @Rule
+ public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder().build();
+
@Test
public void testLoadColorAsDrawable() {
Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
diff --git a/core/tests/coretests/src/android/content/res/ResourcesLocaleTest.java b/core/tests/coretests/src/android/content/res/ResourcesLocaleTest.java
index 26e4349..fdfddc8 100644
--- a/core/tests/coretests/src/android/content/res/ResourcesLocaleTest.java
+++ b/core/tests/coretests/src/android/content/res/ResourcesLocaleTest.java
@@ -16,29 +16,52 @@
package android.content.res;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
import android.content.Context;
import android.os.FileUtils;
import android.os.LocaleList;
import android.platform.test.annotations.Presubmit;
-import android.test.AndroidTestCase;
+import android.platform.test.ravenwood.RavenwoodRule;
import android.util.DisplayMetrics;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
import com.android.frameworks.coretests.R;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
import java.io.File;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Locale;
@Presubmit
-public class ResourcesLocaleTest extends AndroidTestCase {
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ResourcesLocaleTest {
+
+ @Rule
+ public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder().build();
+
+ private Context mContext;
+
+ @Before
+ public void setup() {
+ mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ }
private String extractApkAndGetPath(int id) throws Exception {
- final Resources resources = getContext().getResources();
+ final Resources resources = mContext.getResources();
try (InputStream is = resources.openRawResource(id)) {
- File path = new File(getContext().getFilesDir(), resources.getResourceEntryName(id));
+ File path = new File(mContext.getFilesDir(), resources.getResourceEntryName(id));
FileUtils.copyToFileOrThrow(is, path);
return path.getAbsolutePath();
}
@@ -53,6 +76,15 @@
return new Resources(assets, dm, new Configuration());
}
+ private Resources createResourcesWithSelfApk() {
+ final AssetManager assets = new AssetManager();
+ assertTrue(assets.addAssetPath(mContext.getPackageResourcePath()) != 0);
+
+ final DisplayMetrics dm = new DisplayMetrics();
+ dm.setToDefaults();
+ return new Resources(assets, dm, new Configuration());
+ }
+
private static void ensureNoLanguage(Resources resources, String language) {
final String[] supportedLocales = resources.getAssets().getNonSystemLocales();
for (String languageTag : supportedLocales) {
@@ -65,7 +97,7 @@
}
}
- @SmallTest
+ @Test
public void testEnglishIsAlwaysConsideredSupported() throws Exception {
final Resources resources = createResourcesWithApk(R.raw.locales);
ensureNoLanguage(resources, "en");
@@ -82,7 +114,7 @@
resources.getConfiguration().getLocales().get(0));
}
- @SmallTest
+ @Test
public void testSelectFirstSupportedLanguage() throws Exception {
final Resources resources = createResourcesWithApk(R.raw.locales);
ensureNoLanguage(resources, "fr");
@@ -99,7 +131,7 @@
resources.getConfiguration().getLocales().get(0));
}
- @SmallTest
+ @Test
public void testDeprecatedISOLanguageCode() {
assertResGetString(Locale.US, R.string.locale_test_res_1, "Testing ID");
assertResGetString(Locale.forLanguageTag("id"), R.string.locale_test_res_2, "Pengujian IN");
@@ -115,7 +147,8 @@
LocaleList locales = new LocaleList(locale);
final Configuration config = new Configuration();
config.setLocales(locales);
- Context newContext = getContext().createConfigurationContext(config);
- assertEquals(expectedString, newContext.getResources().getString(resId));
+ final Resources resources = createResourcesWithSelfApk();
+ resources.updateConfiguration(config, null);
+ assertEquals(expectedString, resources.getString(resId));
}
}
diff --git a/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java b/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
index ee1b658..3eefe04 100644
--- a/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
+++ b/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
@@ -16,27 +16,34 @@
package android.content.res;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
import android.annotation.NonNull;
import android.app.ResourcesManager;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.LocaleList;
+import android.platform.test.annotations.DisabledOnRavenwood;
import android.platform.test.annotations.Postsubmit;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
+import android.platform.test.flag.junit.RavenwoodFlagsValueProvider;
+import android.platform.test.ravenwood.RavenwoodRule;
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Display;
import android.view.DisplayAdjustments;
-import androidx.test.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
-
-import junit.framework.TestCase;
+import androidx.test.platform.app.InstrumentationRegistry;
import org.junit.Before;
import org.junit.Rule;
@@ -49,7 +56,7 @@
@Postsubmit
@RunWith(AndroidJUnit4.class)
-public class ResourcesManagerTest extends TestCase {
+public class ResourcesManagerTest {
private static final int SECONDARY_DISPLAY_ID = 1;
private static final String APP_ONE_RES_DIR = "app_one.apk";
private static final String APP_ONE_RES_SPLIT_DIR = "app_one_split.apk";
@@ -57,14 +64,20 @@
private static final String LIB_RES_DIR = "lib.apk";
private static final String TEST_LIB = "com.android.frameworks.coretests.bdr_helper_app1";
+ @Rule
+ public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder().build();
+
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule =
+ RavenwoodRule.isOnRavenwood()
+ ? RavenwoodFlagsValueProvider.createAllOnCheckFlagsRule()
+ : DeviceFlagsValueProvider.createCheckFlagsRule();
+
private ResourcesManager mResourcesManager;
private Map<Integer, DisplayMetrics> mDisplayMetricsMap;
- private PackageManager mPackageManager;
@Before
public void setUp() throws Exception {
- super.setUp();
-
mDisplayMetricsMap = new HashMap<>();
DisplayMetrics defaultDisplayMetrics = new DisplayMetrics();
@@ -110,12 +123,11 @@
return mDisplayMetricsMap.get(displayId);
}
};
-
- mPackageManager = InstrumentationRegistry.getContext().getPackageManager();
}
- @Rule
- public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+ private PackageManager getPackageManager() {
+ return InstrumentationRegistry.getInstrumentation().getContext().getPackageManager();
+ }
@Test
@SmallTest
@@ -356,6 +368,7 @@
@Test
@SmallTest
@RequiresFlagsEnabled(Flags.FLAG_REGISTER_RESOURCE_PATHS)
+ @DisabledOnRavenwood(blockedBy = PackageManager.class)
public void testExistingResourcesAfterResourcePathsRegistration()
throws PackageManager.NameNotFoundException {
// Inject ResourcesManager instance from this test to the ResourcesManager class so that all
@@ -370,7 +383,7 @@
assertNotNull(resources);
ResourcesImpl oriResImpl = resources.getImpl();
- ApplicationInfo appInfo = mPackageManager.getApplicationInfo(TEST_LIB, 0);
+ ApplicationInfo appInfo = getPackageManager().getApplicationInfo(TEST_LIB, 0);
Resources.registerResourcePaths(TEST_LIB, appInfo);
assertNotSame(oriResImpl, resources.getImpl());
@@ -390,6 +403,7 @@
@Test
@SmallTest
@RequiresFlagsEnabled(Flags.FLAG_REGISTER_RESOURCE_PATHS)
+ @DisabledOnRavenwood(blockedBy = PackageManager.class)
public void testNewResourcesAfterResourcePathsRegistration()
throws PackageManager.NameNotFoundException {
// Inject ResourcesManager instance from this test to the ResourcesManager class so that all
@@ -397,7 +411,7 @@
ResourcesManager oriResourcesManager = ResourcesManager.getInstance();
ResourcesManager.setInstance(mResourcesManager);
- ApplicationInfo appInfo = mPackageManager.getApplicationInfo(TEST_LIB, 0);
+ ApplicationInfo appInfo = getPackageManager().getApplicationInfo(TEST_LIB, 0);
Resources.registerResourcePaths(TEST_LIB, appInfo);
// Create a Resources after register resources' paths for a package.
@@ -420,6 +434,7 @@
@Test
@SmallTest
@RequiresFlagsEnabled(Flags.FLAG_REGISTER_RESOURCE_PATHS)
+ @DisabledOnRavenwood(blockedBy = PackageManager.class)
public void testExistingResourcesCreatedByConstructorAfterResourcePathsRegistration()
throws PackageManager.NameNotFoundException {
// Inject ResourcesManager instance from this test to the ResourcesManager class so that all
@@ -437,7 +452,7 @@
ResourcesImpl oriResImpl = resources.getImpl();
- ApplicationInfo appInfo = mPackageManager.getApplicationInfo(TEST_LIB, 0);
+ ApplicationInfo appInfo = getPackageManager().getApplicationInfo(TEST_LIB, 0);
Resources.registerResourcePaths(TEST_LIB, appInfo);
assertNotSame(oriResImpl, resources.getImpl());
@@ -456,6 +471,7 @@
@Test
@SmallTest
@RequiresFlagsEnabled(Flags.FLAG_REGISTER_RESOURCE_PATHS)
+ @DisabledOnRavenwood(blockedBy = PackageManager.class)
public void testNewResourcesWithOutdatedImplAfterResourcePathsRegistration()
throws PackageManager.NameNotFoundException {
ResourcesManager oriResourcesManager = ResourcesManager.getInstance();
@@ -467,7 +483,7 @@
assertNotNull(old_resources);
ResourcesImpl oldImpl = old_resources.getImpl();
- ApplicationInfo appInfo = mPackageManager.getApplicationInfo(TEST_LIB, 0);
+ ApplicationInfo appInfo = getPackageManager().getApplicationInfo(TEST_LIB, 0);
Resources.registerResourcePaths(TEST_LIB, appInfo);
// Create another resources with identical parameters.
diff --git a/core/tests/coretests/src/android/view/DisplayAdjustmentsTests.java b/core/tests/coretests/src/android/view/DisplayAdjustmentsTests.java
index afbf8db..b86029b 100644
--- a/core/tests/coretests/src/android/view/DisplayAdjustmentsTests.java
+++ b/core/tests/coretests/src/android/view/DisplayAdjustmentsTests.java
@@ -19,9 +19,11 @@
import static org.junit.Assert.assertEquals;
import android.content.res.Configuration;
+import android.platform.test.ravenwood.RavenwoodRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -34,6 +36,9 @@
@RunWith(AndroidJUnit4.class)
public class DisplayAdjustmentsTests {
+ @Rule
+ public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder().build();
+
@Test
public void testDefaultConstructor_hasEmptyConfiguration() {
DisplayAdjustments emptyAdjustments = new DisplayAdjustments();
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapperTest.kt
index c44836a..620e90d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapperTest.kt
@@ -117,7 +117,11 @@
label,
activationState,
secondaryLabel,
- setOf(QSTileState.UserAction.CLICK, QSTileState.UserAction.LONG_CLICK),
+ setOf(
+ QSTileState.UserAction.CLICK,
+ QSTileState.UserAction.TOGGLE_CLICK,
+ QSTileState.UserAction.LONG_CLICK
+ ),
contentDescription,
null,
QSTileState.SideViewIcon.Chevron,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractorTest.kt
index e1f3d97..52c476e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractorTest.kt
@@ -27,6 +27,7 @@
import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject
import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
import com.android.systemui.qs.tiles.dialog.InternetDialogManager
+import com.android.systemui.qs.tiles.dialog.WifiStateWorker
import com.android.systemui.qs.tiles.impl.internet.domain.model.InternetTileModel
import com.android.systemui.statusbar.connectivity.AccessPointController
import com.android.systemui.util.mockito.mock
@@ -40,6 +41,8 @@
import org.mockito.ArgumentMatchers.eq
import org.mockito.Mock
import org.mockito.Mockito.verify
+import org.mockito.kotlin.times
+import org.mockito.kotlin.whenever
@SmallTest
@EnabledOnRavenwood
@@ -51,17 +54,20 @@
private lateinit var underTest: InternetTileUserActionInteractor
@Mock private lateinit var internetDialogManager: InternetDialogManager
+ @Mock private lateinit var wifiStateWorker: WifiStateWorker
@Mock private lateinit var controller: AccessPointController
@Before
fun setup() {
internetDialogManager = mock<InternetDialogManager>()
+ wifiStateWorker = mock<WifiStateWorker>()
controller = mock<AccessPointController>()
underTest =
InternetTileUserActionInteractor(
kosmos.testScope.coroutineContext,
internetDialogManager,
+ wifiStateWorker,
controller,
inputHandler,
)
@@ -110,4 +116,24 @@
Truth.assertThat(it.intent.action).isEqualTo(Settings.ACTION_WIFI_SETTINGS)
}
}
+
+ @Test
+ fun handleSecondaryClickWhenWifiOn() =
+ kosmos.testScope.runTest {
+ whenever(wifiStateWorker.isWifiEnabled).thenReturn(true)
+
+ underTest.handleInput(QSTileInputTestKtx.toggleClick(InternetTileModel.Active()))
+
+ verify(wifiStateWorker, times(1)).isWifiEnabled = eq(false)
+ }
+
+ @Test
+ fun handleSecondaryClickWhenWifiOff() =
+ kosmos.testScope.runTest {
+ whenever(wifiStateWorker.isWifiEnabled).thenReturn(false)
+
+ underTest.handleInput(QSTileInputTestKtx.toggleClick(InternetTileModel.Inactive()))
+
+ verify(wifiStateWorker, times(1)).isWifiEnabled = eq(true)
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
index 355669b..f72a2e8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
@@ -43,6 +43,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.scene.data.repository.Idle
import com.android.systemui.scene.data.repository.setTransition
+import com.android.systemui.scene.domain.interactor.sceneBackInteractor
import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.model.Scenes
@@ -112,6 +113,7 @@
{ kosmos.sceneInteractor },
{ kosmos.sceneContainerOcclusionInteractor },
{ kosmos.keyguardClockInteractor },
+ { kosmos.sceneBackInteractor },
) {
override fun createDarkAnimator(): ObjectAnimator {
return mockDarkAnimator
@@ -320,12 +322,23 @@
assertThat(deviceUnlockStatus!!.isUnlocked).isTrue()
- kosmos.sceneInteractor.changeScene(toScene = Scenes.Gone, loggingReason = "reason")
+ kosmos.sceneInteractor.changeScene(
+ toScene = Scenes.Lockscreen,
+ loggingReason = "reason"
+ )
runCurrent()
- assertThat(currentScene).isEqualTo(Scenes.Gone)
+ assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
// Call start to begin hydrating based on the scene framework:
underTest.start()
+ runCurrent()
+
+ assertThat(statusBarState).isEqualTo(StatusBarState.KEYGUARD)
+
+ kosmos.sceneInteractor.changeScene(toScene = Scenes.Gone, loggingReason = "reason")
+ runCurrent()
+ assertThat(currentScene).isEqualTo(Scenes.Gone)
+ assertThat(statusBarState).isEqualTo(StatusBarState.SHADE)
kosmos.sceneInteractor.changeScene(toScene = Scenes.Shade, loggingReason = "reason")
runCurrent()
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
index d13c750..be44dee 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
@@ -169,6 +169,7 @@
public boolean isTransient = false;
public String expandedAccessibilityClassName;
public boolean handlesLongClick = true;
+ public boolean handlesSecondaryClick = false;
@Nullable
public Drawable sideViewCustomDrawable;
public String spec;
@@ -212,6 +213,7 @@
|| !Objects.equals(other.isTransient, isTransient)
|| !Objects.equals(other.dualTarget, dualTarget)
|| !Objects.equals(other.handlesLongClick, handlesLongClick)
+ || !Objects.equals(other.handlesSecondaryClick, handlesSecondaryClick)
|| !Objects.equals(other.sideViewCustomDrawable, sideViewCustomDrawable);
other.spec = spec;
other.icon = icon;
@@ -227,6 +229,7 @@
other.dualTarget = dualTarget;
other.isTransient = isTransient;
other.handlesLongClick = handlesLongClick;
+ other.handlesSecondaryClick = handlesSecondaryClick;
other.sideViewCustomDrawable = sideViewCustomDrawable;
return changed;
}
@@ -252,6 +255,7 @@
sb.append(",disabledByPolicy=").append(disabledByPolicy);
sb.append(",dualTarget=").append(dualTarget);
sb.append(",isTransient=").append(isTransient);
+ sb.append(",handlesSecondaryClick=").append(handlesSecondaryClick);
sb.append(",state=").append(state);
sb.append(",sideViewCustomDrawable=").append(sideViewCustomDrawable);
return sb.append(']');
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/data/model/UserDeviceConnectionStatus.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/data/model/UserDeviceConnectionStatus.kt
new file mode 100644
index 0000000..1a22d3c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/data/model/UserDeviceConnectionStatus.kt
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2024 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.systemui.inputdevice.data.model
+
+data class UserDeviceConnectionStatus(val isConnected: Boolean, val userId: Int)
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/data/repository/UserInputDeviceRepository.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/data/repository/UserInputDeviceRepository.kt
new file mode 100644
index 0000000..b8e73a3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/data/repository/UserInputDeviceRepository.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2024 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.systemui.inputdevice.data.repository
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.inputdevice.data.model.UserDeviceConnectionStatus
+import com.android.systemui.keyboard.data.repository.KeyboardRepository
+import com.android.systemui.touchpad.data.repository.TouchpadRepository
+import com.android.systemui.user.data.model.SelectionStatus
+import com.android.systemui.user.data.repository.UserRepository
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.map
+
+/**
+ * Allow listening keyboard and touchpad device connection changes for current user. It emits new
+ * value when user is changed.
+ */
+@SysUISingleton
+class UserInputDeviceRepository
+@Inject
+constructor(
+ @Background private val backgroundDispatcher: CoroutineDispatcher,
+ keyboardRepository: KeyboardRepository,
+ touchpadRepository: TouchpadRepository,
+ userRepository: UserRepository,
+) {
+ private val selectedUserId =
+ userRepository.selectedUser
+ .filter { it.selectionStatus == SelectionStatus.SELECTION_COMPLETE }
+ .map { it.userInfo.id }
+
+ val isAnyKeyboardConnectedForUser =
+ keyboardRepository.isAnyKeyboardConnected
+ .combine(selectedUserId) { isAnyKeyboardConnected, userId ->
+ UserDeviceConnectionStatus(isAnyKeyboardConnected, userId)
+ }
+ .flowOn(backgroundDispatcher)
+
+ val isAnyTouchpadConnectedForUser =
+ touchpadRepository.isAnyTouchpadConnected
+ .combine(selectedUserId) { isAnyTouchpadConnected, userId ->
+ UserDeviceConnectionStatus(isAnyTouchpadConnected, userId)
+ }
+ .flowOn(backgroundDispatcher)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModel.kt
index 19b46e3..04aa04d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModel.kt
@@ -63,7 +63,11 @@
if (categories.isEmpty()) {
ShortcutsUiState.Inactive
} else {
- val filteredCategories = filterCategoriesBySearchQuery(query, categories)
+ /* temporarily hiding launcher shortcut categories until b/327141011
+ * is completed. */
+ val categoriesWithLauncherExcluded = excludeLauncherApp(categories)
+ val filteredCategories =
+ filterCategoriesBySearchQuery(query, categoriesWithLauncherExcluded)
ShortcutsUiState.Active(
searchQuery = query,
shortcutCategories = filteredCategories,
@@ -77,15 +81,27 @@
initialValue = ShortcutsUiState.Inactive
)
+ private suspend fun excludeLauncherApp(
+ categories: List<ShortcutCategory>
+ ): List<ShortcutCategory> {
+ val launcherAppCategory =
+ categories.firstOrNull { it.type is CurrentApp && isLauncherApp(it.type.packageName) }
+ return if (launcherAppCategory != null) {
+ categories - launcherAppCategory
+ } else {
+ categories
+ }
+ }
+
private suspend fun getDefaultSelectedCategory(
categories: List<ShortcutCategory>
): ShortcutCategoryType? {
val currentAppShortcuts =
- categories.firstOrNull { it.type is CurrentApp && !isAppLauncher(it.type.packageName) }
+ categories.firstOrNull { it.type is CurrentApp && !isLauncherApp(it.type.packageName) }
return currentAppShortcuts?.type ?: categories.firstOrNull()?.type
}
- private suspend fun isAppLauncher(packageName: String): Boolean {
+ private suspend fun isLauncherApp(packageName: String): Boolean {
return withContext(backgroundDispatcher) {
roleManager
.getRoleHoldersAsUser(RoleManager.ROLE_HOME, userTracker.userHandle)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt
index c06d6d2..6eacb2e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt
@@ -109,6 +109,7 @@
import com.android.systemui.qs.panels.ui.model.SpacerGridCell
import com.android.systemui.qs.panels.ui.model.TileGridCell
import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.TileUiState
import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel
import com.android.systemui.qs.panels.ui.viewmodel.toUiState
import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor
@@ -129,7 +130,7 @@
) {
val state by tile.state.collectAsStateWithLifecycle(tile.currentState)
val uiState = remember(state) { state.toUiState() }
- val colors = TileDefaults.getColorForState(uiState.state)
+ val colors = TileDefaults.getColorForState(uiState)
TileContainer(
colors = colors,
@@ -150,9 +151,13 @@
secondaryLabel = uiState.secondaryLabel,
icon = icon,
colors = colors,
- clickEnabled = true,
- onClick = tile::onSecondaryClick,
- onLongClick = tile::onLongClick,
+ toggleClickSupported = state.handlesSecondaryClick,
+ onClick = {
+ if (state.handlesSecondaryClick) {
+ tile.onSecondaryClick()
+ }
+ },
+ onLongClick = { tile.onLongClick(it) },
)
}
}
@@ -168,7 +173,7 @@
onClick: (Expandable) -> Unit = {},
onLongClick: (Expandable) -> Unit = {},
modifier: Modifier = Modifier,
- content: @Composable BoxScope.() -> Unit,
+ content: @Composable BoxScope.(Expandable) -> Unit,
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
@@ -200,7 +205,7 @@
}
.tilePadding(),
) {
- content()
+ content(it)
}
}
@@ -222,36 +227,27 @@
secondaryLabel: String?,
icon: Icon,
colors: TileColors,
- clickEnabled: Boolean = false,
- onClick: (Expandable) -> Unit = {},
- onLongClick: (Expandable) -> Unit = {},
+ toggleClickSupported: Boolean = false,
+ onClick: () -> Unit = {},
+ onLongClick: () -> Unit = {},
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = tileHorizontalArrangement()
) {
- Expandable(
- color = colors.iconBackground,
- shape = TileDefaults.TileShape,
- modifier = Modifier.fillMaxHeight().aspectRatio(1f)
+ // Icon
+ Box(
+ modifier =
+ Modifier.fillMaxHeight().aspectRatio(1f).thenIf(toggleClickSupported) {
+ Modifier.clip(TileDefaults.TileShape)
+ .background(colors.iconBackground, { 1f })
+ .combinedClickable(onClick = onClick, onLongClick = onLongClick)
+ }
) {
- Box(
- modifier =
- Modifier.fillMaxSize().clip(TileDefaults.TileShape).thenIf(clickEnabled) {
- Modifier.combinedClickable(
- onClick = { onClick(it) },
- onLongClick = { onLongClick(it) }
- )
- }
- ) {
- TileIcon(
- icon = icon,
- color = colors.icon,
- modifier = Modifier.align(Alignment.Center)
- )
- }
+ TileIcon(icon = icon, color = colors.icon, modifier = Modifier.align(Alignment.Center))
}
+ // Labels
Column(verticalArrangement = Arrangement.Center, modifier = Modifier.fillMaxHeight()) {
Text(
label,
@@ -743,9 +739,21 @@
val TileShape = CircleShape
val IconTileWithLabelHeight = 140.dp
+ /** An active tile without dual target uses the active color as background */
@Composable
fun activeTileColors(): TileColors =
TileColors(
+ background = MaterialTheme.colorScheme.primary,
+ iconBackground = MaterialTheme.colorScheme.primary,
+ label = MaterialTheme.colorScheme.onPrimary,
+ secondaryLabel = MaterialTheme.colorScheme.onPrimary,
+ icon = MaterialTheme.colorScheme.onPrimary,
+ )
+
+ /** An active tile with dual target only show the active color on the icon */
+ @Composable
+ fun activeDualTargetTileColors(): TileColors =
+ TileColors(
background = MaterialTheme.colorScheme.surfaceVariant,
iconBackground = MaterialTheme.colorScheme.primary,
label = MaterialTheme.colorScheme.onSurfaceVariant,
@@ -774,9 +782,15 @@
)
@Composable
- fun getColorForState(state: Int): TileColors {
- return when (state) {
- STATE_ACTIVE -> activeTileColors()
+ fun getColorForState(uiState: TileUiState): TileColors {
+ return when (uiState.state) {
+ STATE_ACTIVE -> {
+ if (uiState.handlesSecondaryClick) {
+ activeDualTargetTileColors()
+ } else {
+ activeTileColors()
+ }
+ }
STATE_INACTIVE -> inactiveTileColors()
else -> unavailableTileColors()
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileUiState.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileUiState.kt
index c83e3b2..45051fe 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileUiState.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileUiState.kt
@@ -25,6 +25,7 @@
val label: String,
val secondaryLabel: String,
val state: Int,
+ val handlesSecondaryClick: Boolean,
val icon: Supplier<QSTile.Icon?>,
)
@@ -33,6 +34,7 @@
label?.toString() ?: "",
secondaryLabel?.toString() ?: "",
state,
+ handlesSecondaryClick,
icon?.let { Supplier { icon } } ?: iconSupplier ?: Supplier { null },
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileViewModel.kt
index 8578bb0..44dd801 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileViewModel.kt
@@ -50,8 +50,8 @@
tile.longClick(expandable)
}
- fun onSecondaryClick(expandable: Expandable?) {
- tile.secondaryClick(expandable)
+ fun onSecondaryClick() {
+ tile.secondaryClick(null)
}
fun startListening(token: Any) = tile.setListening(token, true)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index 9f41d98..7ceb786 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -114,7 +114,9 @@
@Override
public BooleanState newTileState() {
- return new BooleanState();
+ BooleanState s = new BooleanState();
+ s.handlesSecondaryClick = true;
+ return s;
}
@Override
@@ -141,10 +143,7 @@
mDialogViewModel.showDialog(expandable);
} else {
// Secondary clicks are header clicks, just toggle.
- final boolean isEnabled = mState.value;
- // Immediately enter transient enabling state when turning bluetooth on.
- refreshState(isEnabled ? null : ARG_SHOW_TRANSIENT_ENABLING);
- mController.setBluetoothEnabled(!isEnabled);
+ toggleBluetooth();
}
}
@@ -160,9 +159,7 @@
new Intent(Settings.ACTION_BLUETOOTH_SETTINGS), 0);
return;
}
- if (!mState.value) {
- mController.setBluetoothEnabled(true);
- }
+ toggleBluetooth();
}
@Override
@@ -228,6 +225,13 @@
state.forceExpandIcon = mFeatureFlags.isEnabled(Flags.BLUETOOTH_QS_TILE_DIALOG);
}
+ private void toggleBluetooth() {
+ final boolean isEnabled = mState.value;
+ // Immediately enter transient enabling state when turning bluetooth on.
+ refreshState(isEnabled ? null : ARG_SHOW_TRANSIENT_ENABLING);
+ mController.setBluetoothEnabled(!isEnabled);
+ }
+
/**
* Returns the secondary label to use for the given bluetooth connection in the form of the
* battery level or bluetooth profile name. If the bluetooth is disabled, there's no connected
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
index 6d98da4..02f6f80 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
@@ -52,6 +52,7 @@
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.qs.tiles.dialog.InternetDialogManager;
+import com.android.systemui.qs.tiles.dialog.WifiStateWorker;
import com.android.systemui.res.R;
import com.android.systemui.statusbar.connectivity.AccessPointController;
import com.android.systemui.statusbar.connectivity.IconState;
@@ -84,6 +85,7 @@
protected final InternetSignalCallback mSignalCallback = new InternetSignalCallback();
private final InternetDialogManager mInternetDialogManager;
+ private final WifiStateWorker mWifiStateWorker;
final Handler mHandler;
@Inject
@@ -99,11 +101,13 @@
QSLogger qsLogger,
NetworkController networkController,
AccessPointController accessPointController,
- InternetDialogManager internetDialogManager
+ InternetDialogManager internetDialogManager,
+ WifiStateWorker wifiStateWorker
) {
super(host, uiEventLogger, backgroundLooper, mainHandler, falsingManager, metricsLogger,
statusBarStateController, activityStarter, qsLogger);
mInternetDialogManager = internetDialogManager;
+ mWifiStateWorker = wifiStateWorker;
mHandler = mainHandler;
mController = networkController;
mAccessPointController = accessPointController;
@@ -115,6 +119,7 @@
public BooleanState newTileState() {
BooleanState s = new BooleanState();
s.forceExpandIcon = true;
+ s.handlesSecondaryClick = true;
return s;
}
@@ -131,6 +136,13 @@
}
@Override
+ public void secondaryClick(@Nullable Expandable expandable) {
+ // TODO(b/358352265): Figure out the correct action for the secondary click
+ // Toggle Wifi
+ mWifiStateWorker.setWifiEnabled(!mWifiStateWorker.isWifiEnabled());
+ }
+
+ @Override
public CharSequence getTileLabel() {
return mContext.getString(R.string.quick_settings_internet_label);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTileNewImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTileNewImpl.kt
index 932dec5..42ef0cd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTileNewImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTileNewImpl.kt
@@ -34,6 +34,7 @@
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.qs.tiles.dialog.InternetDialogManager
+import com.android.systemui.qs.tiles.dialog.WifiStateWorker
import com.android.systemui.res.R
import com.android.systemui.statusbar.connectivity.AccessPointController
import com.android.systemui.statusbar.pipeline.shared.ui.binder.InternetTileBinder
@@ -55,6 +56,7 @@
qsLogger: QSLogger,
viewModel: InternetTileViewModel,
private val internetDialogManager: InternetDialogManager,
+ private val wifiStateWorker: WifiStateWorker,
private val accessPointController: AccessPointController,
) :
QSTileImpl<QSTile.BooleanState>(
@@ -81,7 +83,10 @@
mContext.getString(R.string.quick_settings_internet_label)
override fun newTileState(): QSTile.BooleanState {
- return QSTile.BooleanState().also { it.forceExpandIcon = true }
+ return QSTile.BooleanState().also {
+ it.forceExpandIcon = true
+ it.handlesSecondaryClick = true
+ }
}
override fun handleClick(expandable: Expandable?) {
@@ -95,6 +100,12 @@
}
}
+ override fun secondaryClick(expandable: Expandable?) {
+ // TODO(b/358352265): Figure out the correct action for the secondary click
+ // Toggle wifi
+ wifiStateWorker.isWifiEnabled = !wifiStateWorker.isWifiEnabled
+ }
+
override fun handleUpdateState(state: QSTile.BooleanState, arg: Any?) {
state.label = mContext.resources.getString(R.string.quick_settings_internet_label)
state.expandedAccessibilityClassName = Switch::class.java.name
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalytics.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalytics.kt
index 0d15a5b..1d42777 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalytics.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalytics.kt
@@ -47,6 +47,7 @@
private fun QSTileUserAction.getQSEvent(): QSEvent =
when (this) {
is QSTileUserAction.Click -> QSEvent.QS_ACTION_CLICK
+ is QSTileUserAction.ToggleClick -> QSEvent.QS_ACTION_SECONDARY_CLICK
is QSTileUserAction.LongClick -> QSEvent.QS_ACTION_LONG_PRESS
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/logging/QSTileLogger.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/logging/QSTileLogger.kt
index f0d7206..8ec8a6d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/logging/QSTileLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/logging/QSTileLogger.kt
@@ -222,6 +222,7 @@
private fun QSTileUserAction.toLogString(): String =
when (this) {
is QSTileUserAction.Click -> "click"
+ is QSTileUserAction.ToggleClick -> "toggle click"
is QSTileUserAction.LongClick -> "long click"
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImpl.kt
index 9e84f01..d8c5af2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImpl.kt
@@ -229,7 +229,8 @@
filter { action ->
val isFalseAction =
when (action) {
- is QSTileUserAction.Click ->
+ is QSTileUserAction.Click,
+ is QSTileUserAction.ToggleClick ->
falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)
is QSTileUserAction.LongClick ->
falsingManager.isFalseLongTap(FalsingManager.LOW_PENALTY)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileUserActionInteractor.kt
index bf0f8f6..5053291 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileUserActionInteractor.kt
@@ -57,6 +57,7 @@
Intent(Settings.ACTION_AIRPLANE_MODE_SETTINGS)
)
}
+ is QSTileUserAction.ToggleClick -> {}
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileUserActionInteractor.kt
index 14fc57c..79fcd37 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileUserActionInteractor.kt
@@ -49,6 +49,7 @@
}
}
is QSTileUserAction.LongClick -> {}
+ is QSTileUserAction.ToggleClick -> {}
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/domain/interactor/BatterySaverTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/domain/interactor/BatterySaverTileUserActionInteractor.kt
index d4b4fe0..3bbb9aa 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/domain/interactor/BatterySaverTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/domain/interactor/BatterySaverTileUserActionInteractor.kt
@@ -48,6 +48,7 @@
Intent(Settings.ACTION_BATTERY_SAVER_SETTINGS)
)
}
+ is QSTileUserAction.ToggleClick -> {}
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionUserActionInteractor.kt
index 534bd73..dfdec3b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionUserActionInteractor.kt
@@ -49,6 +49,7 @@
Intent(Settings.ACTION_COLOR_CORRECTION_SETTINGS)
)
}
+ is QSTileUserAction.ToggleClick -> {}
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileUserActionInteractor.kt
index 9bdf631..af2bb9d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileUserActionInteractor.kt
@@ -74,6 +74,7 @@
click(action.expandable, data.tile.activityLaunchForClick)
is QSTileUserAction.LongClick ->
longClick(user, action.expandable, data.componentName, data.tile.state)
+ is QSTileUserAction.ToggleClick -> {}
}
qsTileLogger.logCustomTileUserActionDelivered(tileSpec)
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileUserActionInteractor.kt
index bedd65e..13afc15 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileUserActionInteractor.kt
@@ -42,6 +42,7 @@
flashlightController.setFlashlight(!input.data.isEnabled)
}
}
+ is QSTileUserAction.ToggleClick -> {}
else -> {}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileUserActionInteractor.kt
index d308ec8..6ab5796 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileUserActionInteractor.kt
@@ -66,8 +66,7 @@
INTERACTION_JANK_TAG
)
)
- ?.let { dialogTransitionAnimator.show(dialog, it) }
- ?: dialog.show()
+ ?.let { dialogTransitionAnimator.show(dialog, it) } ?: dialog.show()
} else {
dialog.show()
}
@@ -89,8 +88,10 @@
Intent(Settings.ACTION_TEXT_READING_SETTINGS)
)
}
+ is QSTileUserAction.ToggleClick -> {}
}
}
+
companion object {
private const val INTERACTION_JANK_TAG = "font_scaling"
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapper.kt
index e543e4b..8965ef2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapper.kt
@@ -72,6 +72,10 @@
else QSTileState.ActivationState.INACTIVE
supportedActions =
- setOf(QSTileState.UserAction.CLICK, QSTileState.UserAction.LONG_CLICK)
+ setOf(
+ QSTileState.UserAction.CLICK,
+ QSTileState.UserAction.TOGGLE_CLICK,
+ QSTileState.UserAction.LONG_CLICK
+ )
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractor.kt
index c0b089d..a963b28 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractor.kt
@@ -23,6 +23,7 @@
import com.android.systemui.qs.tiles.base.interactor.QSTileInput
import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
import com.android.systemui.qs.tiles.dialog.InternetDialogManager
+import com.android.systemui.qs.tiles.dialog.WifiStateWorker
import com.android.systemui.qs.tiles.impl.internet.domain.model.InternetTileModel
import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
import com.android.systemui.statusbar.connectivity.AccessPointController
@@ -36,6 +37,7 @@
constructor(
@Main private val mainContext: CoroutineContext,
private val internetDialogManager: InternetDialogManager,
+ private val wifiStateWorker: WifiStateWorker,
private val accessPointController: AccessPointController,
private val qsTileIntentUserActionHandler: QSTileIntentUserInputHandler,
) : QSTileUserActionInteractor<InternetTileModel> {
@@ -53,6 +55,11 @@
)
}
}
+ is QSTileUserAction.ToggleClick -> {
+ // TODO(b/358352265): Figure out the correct action for the secondary click
+ // Toggle Wifi
+ wifiStateWorker.isWifiEnabled = !wifiStateWorker.isWifiEnabled
+ }
is QSTileUserAction.LongClick -> {
qsTileIntentUserActionHandler.handle(
action.expandable,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionUserActionInteractor.kt
index d643273..aa83877 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionUserActionInteractor.kt
@@ -49,6 +49,7 @@
Intent(Settings.ACTION_COLOR_INVERSION_SETTINGS)
)
}
+ is QSTileUserAction.ToggleClick -> {}
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileUserActionInteractor.kt
index 77404aa..cca947f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileUserActionInteractor.kt
@@ -68,6 +68,7 @@
Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
)
}
+ is QSTileUserAction.ToggleClick -> {}
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractor.kt
index 083bf05..eb8b23c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractor.kt
@@ -41,7 +41,8 @@
override suspend fun handleInput(input: QSTileInput<ModesTileModel>) {
with(input) {
when (action) {
- is QSTileUserAction.Click -> {
+ is QSTileUserAction.Click,
+ is QSTileUserAction.ToggleClick -> {
handleClick(action.expandable)
}
is QSTileUserAction.LongClick -> {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileUserActionInteractor.kt
index 5cee8c4..7076a8f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileUserActionInteractor.kt
@@ -55,6 +55,7 @@
Intent(Settings.ACTION_NIGHT_DISPLAY_SETTINGS)
)
}
+ is QSTileUserAction.ToggleClick -> {}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/domain/OneHandedModeTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/domain/OneHandedModeTileUserActionInteractor.kt
index 5cb0e18..0a0f0a6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/domain/OneHandedModeTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/domain/OneHandedModeTileUserActionInteractor.kt
@@ -49,6 +49,7 @@
Intent(Settings.ACTION_ONE_HANDED_SETTINGS)
)
}
+ is QSTileUserAction.ToggleClick -> {}
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileUserActionInteractor.kt
index 7c0c41e..bb5df02 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileUserActionInteractor.kt
@@ -45,6 +45,7 @@
}
}
is QSTileUserAction.LongClick -> {} // no-op
+ is QSTileUserAction.ToggleClick -> {}
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractor.kt
index ed5e4fe..de49e70 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractor.kt
@@ -71,6 +71,7 @@
Intent(Settings.ACTION_REDUCE_BRIGHT_COLORS_SETTINGS)
)
}
+ is QSTileUserAction.ToggleClick -> {}
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileUserActionInteractor.kt
index 34385ea..65712c7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileUserActionInteractor.kt
@@ -46,6 +46,7 @@
Intent(Settings.ACTION_AUTO_ROTATE_SETTINGS)
)
}
+ is QSTileUserAction.ToggleClick -> {}
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileUserActionInteractor.kt
index a5dc66c..252e3f8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileUserActionInteractor.kt
@@ -94,8 +94,7 @@
)
?.let { controller ->
dialogTransitionAnimator.show(dialog, controller)
- }
- ?: dialog.show()
+ } ?: dialog.show()
}
}
is QSTileUserAction.LongClick -> {
@@ -104,6 +103,7 @@
Intent(Settings.ACTION_DATA_SAVER_SETTINGS)
)
}
+ is QSTileUserAction.ToggleClick -> {}
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractor.kt
index 5637115..48b39ed 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractor.kt
@@ -75,6 +75,7 @@
}
}
is QSTileUserAction.LongClick -> {} // no-op
+ is QSTileUserAction.ToggleClick -> {}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/SensorPrivacyToggleTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/SensorPrivacyToggleTileUserActionInteractor.kt
index f22a426..d7f64d1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/SensorPrivacyToggleTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/SensorPrivacyToggleTileUserActionInteractor.kt
@@ -82,6 +82,7 @@
}
qsTileIntentUserActionHandler.handle(action.expandable, longClickIntent)
}
+ is QSTileUserAction.ToggleClick -> {}
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileUserActionInteractor.kt
index f8dd1730..8897828 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileUserActionInteractor.kt
@@ -54,6 +54,7 @@
Intent(Settings.ACTION_DARK_THEME_SETTINGS)
)
}
+ is QSTileUserAction.ToggleClick -> {}
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileUserActionInteractor.kt
index 031e4d9..45ae09e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileUserActionInteractor.kt
@@ -49,6 +49,7 @@
)
}
}
+ is QSTileUserAction.ToggleClick -> {}
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt
index 30247c4..549f0a7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt
@@ -105,6 +105,7 @@
enum class UserAction {
CLICK,
+ TOGGLE_CLICK,
LONG_CLICK,
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileUserAction.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileUserAction.kt
index acb2936..bf3bc73 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileUserAction.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileUserAction.kt
@@ -23,5 +23,8 @@
val expandable: Expandable?
class Click(override val expandable: Expandable?) : QSTileUserAction
+
+ class ToggleClick(override val expandable: Expandable?) : QSTileUserAction
+
class LongClick(override val expandable: Expandable?) : QSTileUserAction
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt
index 9bcf927..8077c67 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt
@@ -131,8 +131,8 @@
}
override fun secondaryClick(expandable: Expandable?) {
- if (isActionSupported(QSTileState.UserAction.CLICK)) {
- qsTileViewModel.onActionPerformed(QSTileUserAction.Click(expandable))
+ if (isActionSupported(QSTileState.UserAction.TOGGLE_CLICK)) {
+ qsTileViewModel.onActionPerformed(QSTileUserAction.ToggleClick(expandable))
}
}
@@ -184,8 +184,7 @@
}
}
- override fun isListening(): Boolean =
- listeningClients.isNotEmpty()
+ override fun isListening(): Boolean = listeningClients.isNotEmpty()
override fun setDetailListening(show: Boolean) {
// do nothing like QSTileImpl
@@ -238,6 +237,8 @@
secondaryLabel = viewModelState.secondaryLabel
handlesLongClick =
viewModelState.supportedActions.contains(QSTileState.UserAction.LONG_CLICK)
+ handlesSecondaryClick =
+ viewModelState.supportedActions.contains(QSTileState.UserAction.TOGGLE_CLICK)
icon =
when (val stateIcon = viewModelState.icon()) {
diff --git a/packages/SystemUI/src/com/android/systemui/scene/data/model/SceneStack.kt b/packages/SystemUI/src/com/android/systemui/scene/data/model/SceneStack.kt
index d3e529c..323bb3d 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/data/model/SceneStack.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/data/model/SceneStack.kt
@@ -55,6 +55,9 @@
}
}
+/** Does this stack contain the given [sceneKey]? O(N) */
+fun SceneStack.contains(sceneKey: SceneKey): Boolean = asIterable().any { it == sceneKey }
+
/**
* Returns a new [SceneStack] containing the given [scenes], ordered such that the first argument is
* the head returned from [peek], then the second, and so forth.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
index 0957e5a..3422c67 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
@@ -54,6 +54,9 @@
import com.android.systemui.keyguard.shared.model.KeyguardState;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.res.R;
+import com.android.systemui.scene.data.model.SceneStack;
+import com.android.systemui.scene.data.model.SceneStackKt;
+import com.android.systemui.scene.domain.interactor.SceneBackInteractor;
import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor;
import com.android.systemui.scene.domain.interactor.SceneInteractor;
import com.android.systemui.scene.shared.flag.SceneContainerFlag;
@@ -118,6 +121,7 @@
private final Lazy<SceneInteractor> mSceneInteractorLazy;
private final Lazy<SceneContainerOcclusionInteractor> mSceneContainerOcclusionInteractorLazy;
private final Lazy<KeyguardClockInteractor> mKeyguardClockInteractorLazy;
+ private final Lazy<SceneBackInteractor> mSceneBackInteractorLazy;
private int mState;
private int mLastState;
private int mUpcomingState;
@@ -186,7 +190,8 @@
Lazy<DeviceUnlockedInteractor> deviceUnlockedInteractorLazy,
Lazy<SceneInteractor> sceneInteractorLazy,
Lazy<SceneContainerOcclusionInteractor> sceneContainerOcclusionInteractor,
- Lazy<KeyguardClockInteractor> keyguardClockInteractorLazy) {
+ Lazy<KeyguardClockInteractor> keyguardClockInteractorLazy,
+ Lazy<SceneBackInteractor> sceneBackInteractorLazy) {
mUiEventLogger = uiEventLogger;
mInteractionJankMonitorLazy = interactionJankMonitorLazy;
mJavaAdapter = javaAdapter;
@@ -196,6 +201,7 @@
mSceneInteractorLazy = sceneInteractorLazy;
mSceneContainerOcclusionInteractorLazy = sceneContainerOcclusionInteractor;
mKeyguardClockInteractorLazy = keyguardClockInteractorLazy;
+ mSceneBackInteractorLazy = sceneBackInteractorLazy;
for (int i = 0; i < HISTORY_SIZE; i++) {
mHistoricalRecords[i] = new HistoricalState();
}
@@ -221,6 +227,7 @@
combineFlows(
mDeviceUnlockedInteractorLazy.get().getDeviceUnlockStatus(),
mSceneInteractorLazy.get().getCurrentScene(),
+ mSceneBackInteractorLazy.get().getBackStack(),
mSceneContainerOcclusionInteractorLazy.get().getInvisibleDueToOcclusion(),
this::calculateStateFromSceneFramework),
this::onStatusBarStateChanged);
@@ -677,10 +684,15 @@
private int calculateStateFromSceneFramework(
DeviceUnlockStatus deviceUnlockStatus,
SceneKey currentScene,
+ SceneStack backStack,
boolean isOccluded) {
SceneContainerFlag.isUnexpectedlyInLegacyMode();
-
- if (deviceUnlockStatus.isUnlocked() || isOccluded) {
+ if (currentScene.equals(Scenes.Lockscreen)) {
+ return StatusBarState.KEYGUARD;
+ } else if (currentScene.equals(Scenes.Shade)
+ && SceneStackKt.contains(backStack, Scenes.Lockscreen)) {
+ return StatusBarState.SHADE_LOCKED;
+ } else if (deviceUnlockStatus.isUnlocked() || isOccluded) {
return StatusBarState.SHADE;
} else {
return Preconditions.checkNotNull(sStatusBarStateByLockedSceneKey.get(currentScene));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 0e4be8e..8f187f0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -1487,7 +1487,14 @@
private float updateStackEndHeight() {
if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return 0f;
- float height = Math.max(0f, mAmbientState.getStackCutoff() - mAmbientState.getStackTop());
+ final float height;
+ if (mMaxDisplayedNotifications != -1) {
+ // The stack intrinsic height already contains the correct value when there is a limit
+ // in the max number of notifications (e.g. as in keyguard).
+ height = mIntrinsicContentHeight;
+ } else {
+ height = Math.max(0f, mAmbientState.getStackCutoff() - mAmbientState.getStackTop());
+ }
mAmbientState.setStackEndHeight(height);
return height;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/inputdevice/data/repository/UserInputDeviceRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/inputdevice/data/repository/UserInputDeviceRepositoryTest.kt
new file mode 100644
index 0000000..f2e43fc
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/inputdevice/data/repository/UserInputDeviceRepositoryTest.kt
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2024 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.systemui.inputdevice.data.repository
+
+import android.content.pm.UserInfo
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectValues
+import com.android.systemui.inputdevice.data.model.UserDeviceConnectionStatus
+import com.android.systemui.keyboard.data.repository.keyboardRepository
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.touchpad.data.repository.touchpadRepository
+import com.android.systemui.user.data.repository.fakeUserRepository
+import com.android.systemui.user.data.repository.userRepository
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
+class UserInputDeviceRepositoryTest : SysuiTestCase() {
+
+ private lateinit var underTest: UserInputDeviceRepository
+ private val kosmos = Kosmos()
+ private val testScope = kosmos.testScope
+ private val keyboardRepository = kosmos.keyboardRepository
+ private val touchpadRepository = kosmos.touchpadRepository
+ private val userRepository = kosmos.fakeUserRepository
+
+ @Before
+ fun setup() {
+ underTest =
+ UserInputDeviceRepository(
+ kosmos.testDispatcher,
+ keyboardRepository,
+ touchpadRepository,
+ kosmos.userRepository
+ )
+ userRepository.setUserInfos(USER_INFOS)
+ }
+
+ @Test
+ fun emitsNewKeyboardConnectedValueOnUserChanged() =
+ testScope.runTest {
+ val isAnyKeyboardConnected by collectValues(underTest.isAnyKeyboardConnectedForUser)
+ userRepository.setSelectedUserInfo(USER_INFOS[0])
+ keyboardRepository.setIsAnyKeyboardConnected(true)
+ runCurrent()
+
+ userRepository.setSelectedUserInfo(USER_INFOS[1])
+
+ assertThat(isAnyKeyboardConnected)
+ .containsExactly(
+ UserDeviceConnectionStatus(isConnected = true, USER_INFOS[0].id),
+ UserDeviceConnectionStatus(isConnected = true, USER_INFOS[1].id)
+ )
+ .inOrder()
+ }
+
+ @Test
+ fun emitsNewTouchpadConnectedValueOnUserChanged() =
+ testScope.runTest {
+ val isAnyTouchpadConnected by collectValues(underTest.isAnyTouchpadConnectedForUser)
+ userRepository.setSelectedUserInfo(USER_INFOS[0])
+ touchpadRepository.setIsAnyTouchpadConnected(true)
+ runCurrent()
+
+ userRepository.setSelectedUserInfo(USER_INFOS[1])
+
+ assertThat(isAnyTouchpadConnected)
+ .containsExactly(
+ UserDeviceConnectionStatus(isConnected = true, USER_INFOS[0].id),
+ UserDeviceConnectionStatus(isConnected = true, USER_INFOS[1].id)
+ )
+ .inOrder()
+ }
+
+ companion object {
+ private val USER_INFOS =
+ listOf(
+ UserInfo(100, "First User", 0),
+ UserInfo(101, "Second User", 0),
+ )
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt
index 79cb51a..828c7b2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt
@@ -23,7 +23,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.logging.MetricsLogger
-import com.android.systemui.res.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.classifier.FalsingManagerFake
import com.android.systemui.plugins.ActivityStarter
@@ -32,6 +31,8 @@
import com.android.systemui.qs.QsEventLogger
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.qs.tiles.dialog.InternetDialogManager
+import com.android.systemui.qs.tiles.dialog.WifiStateWorker
+import com.android.systemui.res.R
import com.android.systemui.statusbar.connectivity.AccessPointController
import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository
import com.android.systemui.statusbar.pipeline.ethernet.domain.EthernetInteractor
@@ -46,7 +47,6 @@
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiScanEntry
import com.android.systemui.util.mockito.mock
-import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.StandardTestDispatcher
@@ -58,6 +58,10 @@
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@@ -87,6 +91,7 @@
@Mock private lateinit var activityStarter: ActivityStarter
@Mock private lateinit var logger: QSLogger
@Mock private lateinit var dialogManager: InternetDialogManager
+ @Mock private lateinit var wifiStateWorker: WifiStateWorker
@Mock private lateinit var accessPointController: AccessPointController
@Before
@@ -122,6 +127,7 @@
logger,
viewModel,
dialogManager,
+ wifiStateWorker,
accessPointController
)
@@ -231,6 +237,24 @@
assertThat(underTest.state.secondaryLabel).isEqualTo(WIFI_SSID)
}
+ @Test
+ fun secondaryClick_turnsWifiOff() {
+ whenever(wifiStateWorker.isWifiEnabled).thenReturn(true)
+
+ underTest.secondaryClick(null)
+
+ verify(wifiStateWorker, times(1)).isWifiEnabled = eq(false)
+ }
+
+ @Test
+ fun secondaryClick_turnsWifiOn() {
+ whenever(wifiStateWorker.isWifiEnabled).thenReturn(false)
+
+ underTest.secondaryClick(null)
+
+ verify(wifiStateWorker, times(1)).isWifiEnabled = eq(true)
+ }
+
companion object {
const val WIFI_SSID = "test ssid"
val ACTIVE_WIFI =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileTest.java
index 8ea79d7..0cf9604 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileTest.java
@@ -18,7 +18,10 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.os.Handler;
@@ -38,6 +41,7 @@
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.qs.tiles.dialog.InternetDialogManager;
+import com.android.systemui.qs.tiles.dialog.WifiStateWorker;
import com.android.systemui.res.R;
import com.android.systemui.statusbar.connectivity.AccessPointController;
import com.android.systemui.statusbar.connectivity.IconState;
@@ -65,6 +69,8 @@
@Mock
private InternetDialogManager mInternetDialogManager;
@Mock
+ private WifiStateWorker mWifiStateWorker;
+ @Mock
private QsEventLogger mUiEventLogger;
private TestableLooper mTestableLooper;
@@ -89,7 +95,8 @@
mock(QSLogger.class),
mNetworkController,
mAccessPointController,
- mInternetDialogManager
+ mInternetDialogManager,
+ mWifiStateWorker
);
mTile.initialize();
@@ -167,4 +174,22 @@
assertThat(mTile.getState().icon).isEqualTo(
QSTileImpl.ResourceIcon.get(R.drawable.ic_qs_no_internet_unavailable));
}
+
+ @Test
+ public void secondaryClick_turnsWifiOff() {
+ when(mWifiStateWorker.isWifiEnabled()).thenReturn(true);
+
+ mTile.secondaryClick(null);
+
+ verify(mWifiStateWorker, times(1)).setWifiEnabled(eq(false));
+ }
+
+ @Test
+ public void secondaryClick_turnsWifiOn() {
+ when(mWifiStateWorker.isWifiEnabled()).thenReturn(false);
+
+ mTile.secondaryClick(null);
+
+ verify(mWifiStateWorker, times(1)).setWifiEnabled(eq(true));
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
index 8125ef5..523d15c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -468,7 +468,8 @@
() -> mKosmos.getDeviceUnlockedInteractor(),
() -> mKosmos.getSceneInteractor(),
() -> mKosmos.getSceneContainerOcclusionInteractor(),
- () -> mKosmos.getKeyguardClockInteractor());
+ () -> mKosmos.getKeyguardClockInteractor(),
+ () -> mKosmos.getSceneBackInteractor());
KeyguardStatusView keyguardStatusView = new KeyguardStatusView(mContext);
keyguardStatusView.setId(R.id.keyguard_status_view);
@@ -625,7 +626,8 @@
() -> mKosmos.getDeviceUnlockedInteractor(),
() -> mKosmos.getSceneInteractor(),
() -> mKosmos.getSceneContainerOcclusionInteractor(),
- () -> mKosmos.getKeyguardClockInteractor()),
+ () -> mKosmos.getKeyguardClockInteractor(),
+ () -> mKosmos.getSceneBackInteractor()),
mKeyguardBypassController,
mDozeParameters,
mScreenOffAnimationController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 22b9887..1717f4c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -354,6 +354,20 @@
}
@Test
+ @EnableSceneContainer
+ public void updateStackEndHeightAndStackHeight_maxNotificationsSet_withSceneContainer() {
+ float stackHeight = 300f;
+ when(mStackSizeCalculator.computeHeight(eq(mStackScroller), anyInt(), anyFloat()))
+ .thenReturn(stackHeight);
+ mStackScroller.setMaxDisplayedNotifications(3); // any non-zero amount
+
+ clearInvocations(mAmbientState);
+ mStackScroller.updateStackEndHeightAndStackHeight(1f);
+
+ verify(mAmbientState).setStackHeight(eq(300f));
+ }
+
+ @Test
public void updateStackEndHeightAndStackHeight_onlyUpdatesStackHeightDuringSwipeUp() {
final float expansionFraction = 0.5f;
mAmbientState.setStatusBarState(StatusBarState.KEYGUARD);
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
index e6bd24b..9fe66eb 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
@@ -50,6 +50,7 @@
import com.android.systemui.plugins.statusbar.statusBarStateController
import com.android.systemui.power.data.repository.fakePowerRepository
import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.scene.domain.interactor.sceneBackInteractor
import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.domain.startable.scrimStartable
@@ -115,6 +116,7 @@
val interactionJankMonitor by lazy { kosmos.interactionJankMonitor }
val fakeSceneContainerConfig by lazy { kosmos.sceneContainerConfig }
val sceneInteractor by lazy { kosmos.sceneInteractor }
+ val sceneBackInteractor by lazy { kosmos.sceneBackInteractor }
val falsingCollector by lazy { kosmos.falsingCollector }
val powerInteractor by lazy { kosmos.powerInteractor }
val deviceEntryInteractor by lazy { kosmos.deviceEntryInteractor }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/statusbar/StatusBarStateControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/statusbar/StatusBarStateControllerKosmos.kt
index f9f8d23..2deeb25 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/statusbar/StatusBarStateControllerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/statusbar/StatusBarStateControllerKosmos.kt
@@ -22,6 +22,7 @@
import com.android.systemui.keyguard.domain.interactor.keyguardClockInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.scene.domain.interactor.sceneBackInteractor
import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.shade.domain.interactor.shadeInteractor
@@ -41,5 +42,6 @@
{ sceneInteractor },
{ sceneContainerOcclusionInteractor },
{ keyguardClockInteractor },
+ { sceneBackInteractor },
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/QSTileInputTestKtx.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/QSTileInputTestKtx.kt
index 9cb76bb..3943d1d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/QSTileInputTestKtx.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/QSTileInputTestKtx.kt
@@ -28,6 +28,12 @@
expandable: Expandable? = null,
): QSTileInput<T> = QSTileInput(user, QSTileUserAction.Click(expandable), data)
+ fun <T> toggleClick(
+ data: T,
+ user: UserHandle = UserHandle.CURRENT,
+ expandable: Expandable? = null,
+ ): QSTileInput<T> = QSTileInput(user, QSTileUserAction.ToggleClick(expandable), data)
+
fun <T> longClick(
data: T,
user: UserHandle = UserHandle.CURRENT,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/touchpad/data/repository/TouchpadRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/touchpad/data/repository/TouchpadRepositoryKosmos.kt
new file mode 100644
index 0000000..91e2396
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/touchpad/data/repository/TouchpadRepositoryKosmos.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2024 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.systemui.touchpad.data.repository
+
+import com.android.systemui.kosmos.Kosmos
+
+val Kosmos.touchpadRepository by Kosmos.Fixture { FakeTouchpadRepository() }
diff --git a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
index 231179b..5cffdec 100644
--- a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
+++ b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
@@ -222,8 +222,16 @@
android.content.res.AssetFileDescriptor
android.content.res.AssetManager
android.content.res.AssetManager$Builder
+android.content.res.ConfigurationBoundResourceCache
+android.content.res.Configuration
+android.content.res.CompatibilityInfo
+android.content.res.ConstantState
android.content.res.DrawableCache
android.content.res.Element
+android.content.res.FontResourcesParser
+android.content.res.FontScaleConverter
+android.content.res.FontScaleConverterImpl
+android.content.res.FontScaleConverterFactory
android.content.res.Resources
android.content.res.Resources$Theme
android.content.res.ResourceId
@@ -231,6 +239,7 @@
android.content.res.ResourcesKey
android.content.res.StringBlock
android.content.res.TagCounter
+android.content.res.ThemedResourceCache
android.content.res.TypedArray
android.content.res.Validator
android.content.res.XmlBlock
@@ -275,6 +284,7 @@
android.app.ActivityManager
android.app.ActivityOptions
+android.app.ApplicationPackageManager
android.app.BroadcastOptions
android.app.ComponentOptions
android.app.Instrumentation
@@ -288,6 +298,7 @@
android.view.Display
android.view.Display$HdrCapabilities
android.view.Display$Mode
+android.view.DisplayAdjustments
android.view.DisplayInfo
android.view.inputmethod.InputBinding
diff --git a/ravenwood/texts/ravenwood-framework-policies.txt b/ravenwood/texts/ravenwood-framework-policies.txt
index 3062863..2d49128 100644
--- a/ravenwood/texts/ravenwood-framework-policies.txt
+++ b/ravenwood/texts/ravenwood-framework-policies.txt
@@ -69,20 +69,3 @@
# Just enough to allow ResourcesManager to run
class android.hardware.display.DisplayManagerGlobal keep
method getInstance ()Landroid/hardware/display/DisplayManagerGlobal; ignore
-
-# These classes will be properly enabled in follow-up CLs
-
-class android.content.res.FontResourcesParser keepclass
-class android.content.res.FontResourcesParser.FamilyResourceEntry keepclass
-class android.content.res.FontResourcesParser.ProviderResourceEntry keepclass
-class android.content.res.FontResourcesParser.FontFamilyFilesResourceEntry keepclass
-class android.content.res.FontResourcesParser.FontFileResourceEntry keepclass
-class android.content.res.FontScaleConverter keepclass
-class android.content.res.FontScaleConverterImpl keepclass
-class android.content.res.FontScaleConverterFactory keepclass
-class android.content.res.ThemedResourceCache keepclass
-class android.content.res.ConfigurationBoundResourceCache keepclass
-class android.content.res.Configuration keepclass
-class android.content.res.CompatibilityInfo keepclass
-class android.content.res.ConstantState keepclass
-class android.view.DisplayAdjustments keepclass
diff --git a/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java
index 191ec69..6b8e8c7 100644
--- a/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java
+++ b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java
@@ -23,10 +23,6 @@
import android.app.appfunctions.IAppFunctionService;
import android.app.appfunctions.IExecuteAppFunctionCallback;
import android.app.appfunctions.SafeOneTimeExecuteAppFunctionCallback;
-import android.app.appfunctions.ServiceCallHelper;
-import android.app.appfunctions.ServiceCallHelper.RunServiceCallCallback;
-import android.app.appfunctions.ServiceCallHelper.ServiceUsageCompleteListener;
-import android.app.appfunctions.ServiceCallHelperImpl;
import android.content.Context;
import android.content.Intent;
import android.os.UserHandle;
@@ -34,6 +30,8 @@
import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.appfunctions.RemoteServiceCaller.RunServiceCallCallback;
+import com.android.server.appfunctions.RemoteServiceCaller.ServiceUsageCompleteListener;
import java.util.Objects;
import java.util.concurrent.LinkedBlockingQueue;
@@ -45,12 +43,12 @@
*/
public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub {
private static final String TAG = AppFunctionManagerServiceImpl.class.getSimpleName();
- private final ServiceCallHelper<IAppFunctionService> mExternalServiceCallHelper;
+ private final RemoteServiceCaller<IAppFunctionService> mRemoteServiceCaller;
private final CallerValidator mCallerValidator;
private final ServiceHelper mInternalServiceHelper;
public AppFunctionManagerServiceImpl(@NonNull Context context) {
- this(new ServiceCallHelperImpl<>(
+ this(new RemoteServiceCallerImpl<>(
context,
IAppFunctionService.Stub::asInterface, new ThreadPoolExecutor(
/*corePoolSize=*/ Runtime.getRuntime().availableProcessors(),
@@ -63,11 +61,11 @@
}
@VisibleForTesting
- AppFunctionManagerServiceImpl(ServiceCallHelper<IAppFunctionService> serviceCallHelper,
- CallerValidator apiValidator,
+ AppFunctionManagerServiceImpl(RemoteServiceCaller<IAppFunctionService> remoteServiceCaller,
+ CallerValidator callerValidator,
ServiceHelper appFunctionInternalServiceHelper) {
- mExternalServiceCallHelper = Objects.requireNonNull(serviceCallHelper);
- mCallerValidator = Objects.requireNonNull(apiValidator);
+ mRemoteServiceCaller = Objects.requireNonNull(remoteServiceCaller);
+ mCallerValidator = Objects.requireNonNull(callerValidator);
mInternalServiceHelper =
Objects.requireNonNull(appFunctionInternalServiceHelper);
}
@@ -134,7 +132,6 @@
return;
}
- // TODO(b/357551503): Offload call to async executor.
bindAppFunctionServiceUnchecked(requestInternal, serviceIntent, targetUser,
safeExecuteAppFunctionCallback,
/*bindFlags=*/ Context.BIND_AUTO_CREATE,
@@ -148,12 +145,12 @@
@NonNull SafeOneTimeExecuteAppFunctionCallback
safeExecuteAppFunctionCallback,
int bindFlags, long timeoutInMillis) {
- boolean bindServiceResult = mExternalServiceCallHelper.runServiceCall(
+ boolean bindServiceResult = mRemoteServiceCaller.runServiceCall(
serviceIntent,
bindFlags,
timeoutInMillis,
targetUser,
- /*timeOutCallback=*/ new RunServiceCallCallback<IAppFunctionService>() {
+ new RunServiceCallCallback<IAppFunctionService>() {
@Override
public void onServiceConnected(@NonNull IAppFunctionService service,
@NonNull ServiceUsageCompleteListener
diff --git a/core/java/android/app/appfunctions/ServiceCallHelper.java b/services/appfunctions/java/com/android/server/appfunctions/RemoteServiceCaller.java
similarity index 96%
rename from core/java/android/app/appfunctions/ServiceCallHelper.java
rename to services/appfunctions/java/com/android/server/appfunctions/RemoteServiceCaller.java
index cc882bd..98903ae 100644
--- a/core/java/android/app/appfunctions/ServiceCallHelper.java
+++ b/services/appfunctions/java/com/android/server/appfunctions/RemoteServiceCaller.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.app.appfunctions;
+package com.android.server.appfunctions;
import android.annotation.NonNull;
import android.content.Intent;
@@ -27,7 +27,7 @@
* @param <T> Class of wrapped service.
* @hide
*/
-public interface ServiceCallHelper<T> {
+public interface RemoteServiceCaller<T> {
/**
* Initiates service binding and executes a provided method when the service connects. Unbinds
diff --git a/core/java/android/app/appfunctions/ServiceCallHelperImpl.java b/services/appfunctions/java/com/android/server/appfunctions/RemoteServiceCallerImpl.java
similarity index 89%
rename from core/java/android/app/appfunctions/ServiceCallHelperImpl.java
rename to services/appfunctions/java/com/android/server/appfunctions/RemoteServiceCallerImpl.java
index 2e58546..c19a027 100644
--- a/core/java/android/app/appfunctions/ServiceCallHelperImpl.java
+++ b/services/appfunctions/java/com/android/server/appfunctions/RemoteServiceCallerImpl.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.app.appfunctions;
+package com.android.server.appfunctions;
import android.annotation.NonNull;
import android.content.ComponentName;
@@ -30,27 +30,29 @@
import java.util.function.Function;
/**
- * An implementation of {@link android.app.appfunctions.ServiceCallHelper} that that is based on
+ * An implementation of {@link RemoteServiceCaller} that that is based on
* {@link Context#bindService}.
*
* @param <T> Class of wrapped service.
* @hide
*/
-public class ServiceCallHelperImpl<T> implements ServiceCallHelper<T> {
+public class RemoteServiceCallerImpl<T> implements RemoteServiceCaller<T> {
private static final String TAG = "AppFunctionsServiceCall";
- @NonNull private final Context mContext;
- @NonNull private final Function<IBinder, T> mInterfaceConverter;
+ @NonNull
+ private final Context mContext;
+ @NonNull
+ private final Function<IBinder, T> mInterfaceConverter;
private final Handler mHandler = new Handler(Looper.getMainLooper());
private final Executor mExecutor;
/**
* @param interfaceConverter A function responsible for converting an IBinder object into the
- * desired service interface.
- * @param executor An Executor instance to dispatch callback.
- * @param context The system context.
+ * desired service interface.
+ * @param executor An Executor instance to dispatch callback.
+ * @param context The system context.
*/
- public ServiceCallHelperImpl(
+ public RemoteServiceCallerImpl(
@NonNull Context context,
@NonNull Function<IBinder, T> interfaceConverter,
@NonNull Executor executor) {
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
index f332ed9..4eb50a9 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
@@ -41,6 +41,7 @@
import android.app.PendingIntent;
import android.app.admin.DevicePolicyManager;
import android.companion.AssociationInfo;
+import android.companion.virtual.ActivityPolicyExemption;
import android.companion.virtual.IVirtualDevice;
import android.companion.virtual.IVirtualDeviceActivityListener;
import android.companion.virtual.IVirtualDeviceIntentInterceptor;
@@ -522,13 +523,37 @@
@Override // Binder call
@EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
- public void addActivityPolicyExemption(@NonNull ComponentName componentName) {
+ public void addActivityPolicyExemption(@NonNull ActivityPolicyExemption exemption) {
super.addActivityPolicyExemption_enforcePermission();
+ final int displayId = exemption.getDisplayId();
+ if (exemption.getComponentName() == null || displayId != Display.INVALID_DISPLAY) {
+ if (!android.companion.virtualdevice.flags.Flags.activityControlApi()) {
+ return;
+ }
+ }
synchronized (mVirtualDeviceLock) {
- if (mActivityPolicyExemptions.add(componentName)) {
- for (int i = 0; i < mVirtualDisplays.size(); i++) {
- mVirtualDisplays.valueAt(i).getWindowPolicyController()
- .addActivityPolicyExemption(componentName);
+ if (displayId != Display.INVALID_DISPLAY) {
+ checkDisplayOwnedByVirtualDeviceLocked(displayId);
+ if (exemption.getComponentName() != null) {
+ mVirtualDisplays.get(displayId).getWindowPolicyController()
+ .addActivityPolicyExemption(exemption.getComponentName());
+ } else if (exemption.getPackageName() != null) {
+ mVirtualDisplays.get(displayId).getWindowPolicyController()
+ .addActivityPolicyExemption(exemption.getPackageName());
+ }
+ } else {
+ if (exemption.getComponentName() != null
+ && mActivityPolicyExemptions.add(exemption.getComponentName())) {
+ for (int i = 0; i < mVirtualDisplays.size(); i++) {
+ mVirtualDisplays.valueAt(i).getWindowPolicyController()
+ .addActivityPolicyExemption(exemption.getComponentName());
+ }
+ } else if (exemption.getPackageName() != null
+ && mActivityPolicyPackageExemptions.add(exemption.getPackageName())) {
+ for (int i = 0; i < mVirtualDisplays.size(); i++) {
+ mVirtualDisplays.valueAt(i).getWindowPolicyController()
+ .addActivityPolicyExemption(exemption.getPackageName());
+ }
}
}
}
@@ -536,112 +561,42 @@
@Override // Binder call
@EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
- public void removeActivityPolicyExemption(@NonNull ComponentName componentName) {
+ public void removeActivityPolicyExemption(@NonNull ActivityPolicyExemption exemption) {
super.removeActivityPolicyExemption_enforcePermission();
- synchronized (mVirtualDeviceLock) {
- if (mActivityPolicyExemptions.remove(componentName)) {
- for (int i = 0; i < mVirtualDisplays.size(); i++) {
- mVirtualDisplays.valueAt(i).getWindowPolicyController()
- .removeActivityPolicyExemption(componentName);
- }
+ final int displayId = exemption.getDisplayId();
+ if (exemption.getComponentName() == null || displayId != Display.INVALID_DISPLAY) {
+ if (!android.companion.virtualdevice.flags.Flags.activityControlApi()) {
+ return;
}
}
- }
-
- @Override // Binder call
- @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
- public void addActivityPolicyPackageExemption(@NonNull String packageName) {
- super.addActivityPolicyPackageExemption_enforcePermission();
- if (!android.companion.virtualdevice.flags.Flags.activityControlApi()) {
- return;
- }
synchronized (mVirtualDeviceLock) {
- if (mActivityPolicyPackageExemptions.add(packageName)) {
- for (int i = 0; i < mVirtualDisplays.size(); i++) {
- mVirtualDisplays.valueAt(i).getWindowPolicyController()
- .addActivityPolicyExemption(packageName);
+ if (displayId != Display.INVALID_DISPLAY) {
+ checkDisplayOwnedByVirtualDeviceLocked(displayId);
+ if (exemption.getComponentName() != null) {
+ mVirtualDisplays.get(displayId).getWindowPolicyController()
+ .removeActivityPolicyExemption(exemption.getComponentName());
+ } else if (exemption.getPackageName() != null) {
+ mVirtualDisplays.get(displayId).getWindowPolicyController()
+ .removeActivityPolicyExemption(exemption.getPackageName());
+ }
+ } else {
+ if (exemption.getComponentName() != null
+ && mActivityPolicyExemptions.remove(exemption.getComponentName())) {
+ for (int i = 0; i < mVirtualDisplays.size(); i++) {
+ mVirtualDisplays.valueAt(i).getWindowPolicyController()
+ .removeActivityPolicyExemption(exemption.getComponentName());
+ }
+ } else if (exemption.getPackageName() != null
+ && mActivityPolicyPackageExemptions.remove(exemption.getPackageName())) {
+ for (int i = 0; i < mVirtualDisplays.size(); i++) {
+ mVirtualDisplays.valueAt(i).getWindowPolicyController()
+ .removeActivityPolicyExemption(exemption.getPackageName());
+ }
}
}
}
}
- @Override // Binder call
- @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
- public void removeActivityPolicyPackageExemption(@NonNull String packageName) {
- super.removeActivityPolicyPackageExemption_enforcePermission();
- if (!android.companion.virtualdevice.flags.Flags.activityControlApi()) {
- return;
- }
- synchronized (mVirtualDeviceLock) {
- if (mActivityPolicyPackageExemptions.remove(packageName)) {
- for (int i = 0; i < mVirtualDisplays.size(); i++) {
- mVirtualDisplays.valueAt(i).getWindowPolicyController()
- .removeActivityPolicyExemption(packageName);
- }
- }
- }
- }
-
- @Override // Binder call
- @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
- public void addActivityPolicyExemptionForDisplay(
- int displayId, @NonNull ComponentName componentName) {
- super.addActivityPolicyExemptionForDisplay_enforcePermission();
- if (!android.companion.virtualdevice.flags.Flags.activityControlApi()) {
- return;
- }
- synchronized (mVirtualDeviceLock) {
- checkDisplayOwnedByVirtualDeviceLocked(displayId);
- mVirtualDisplays.get(displayId).getWindowPolicyController()
- .addActivityPolicyExemption(componentName);
- }
- }
-
- @Override // Binder call
- @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
- public void removeActivityPolicyExemptionForDisplay(
- int displayId, @NonNull ComponentName componentName) {
- super.removeActivityPolicyExemptionForDisplay_enforcePermission();
- if (!android.companion.virtualdevice.flags.Flags.activityControlApi()) {
- return;
- }
- synchronized (mVirtualDeviceLock) {
- checkDisplayOwnedByVirtualDeviceLocked(displayId);
- mVirtualDisplays.get(displayId).getWindowPolicyController()
- .removeActivityPolicyExemption(componentName);
- }
- }
-
- @Override // Binder call
- @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
- public void addActivityPolicyPackageExemptionForDisplay(
- int displayId, @NonNull String packageName) {
- super.addActivityPolicyPackageExemptionForDisplay_enforcePermission();
- if (!android.companion.virtualdevice.flags.Flags.activityControlApi()) {
- return;
- }
- synchronized (mVirtualDeviceLock) {
- checkDisplayOwnedByVirtualDeviceLocked(displayId);
- mVirtualDisplays.get(displayId).getWindowPolicyController()
- .addActivityPolicyExemption(packageName);
- }
- }
-
- @Override // Binder call
- @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
- public void removeActivityPolicyPackageExemptionForDisplay(
- int displayId, @NonNull String packageName) {
- super.removeActivityPolicyPackageExemptionForDisplay_enforcePermission();
- if (!android.companion.virtualdevice.flags.Flags.activityControlApi()) {
- return;
- }
- synchronized (mVirtualDeviceLock) {
- checkDisplayOwnedByVirtualDeviceLocked(displayId);
- mVirtualDisplays.get(displayId).getWindowPolicyController()
- .removeActivityPolicyExemption(packageName);
- }
- }
-
private void sendPendingIntent(int displayId, PendingIntent pendingIntent)
throws PendingIntent.CanceledException {
final ActivityOptions options = ActivityOptions.makeBasic().setLaunchDisplayId(displayId);
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 27024a7..a27360d 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -125,9 +125,9 @@
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.LatencyTracker;
import com.android.internal.util.Preconditions;
+import com.android.server.crashrecovery.CrashRecoveryHelper;
import com.android.server.EventLogTags;
import com.android.server.LockGuard;
-import com.android.server.RescueParty;
import com.android.server.ServiceThread;
import com.android.server.SystemService;
import com.android.server.UiThread;
@@ -4031,7 +4031,7 @@
}
}
if (mHandler == null || !mSystemReady) {
- if (RescueParty.isRecoveryTriggeredReboot()) {
+ if (CrashRecoveryHelper.isRecoveryTriggeredReboot()) {
// If we're stuck in a really low-level reboot loop, and a
// rescue party is trying to prompt the user for a factory data
// reset, we must GET TO DA CHOPPA!
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index 4b4e442..d209ea9 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -59,8 +59,8 @@
import android.view.WindowManager;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.crashrecovery.CrashRecoveryHelper;
import com.android.server.LocalServices;
-import com.android.server.RescueParty;
import com.android.server.statusbar.StatusBarManagerInternal;
import java.io.File;
@@ -339,7 +339,7 @@
com.android.internal.R.string.reboot_to_update_reboot));
}
} else if (mReason != null && mReason.equals(PowerManager.REBOOT_RECOVERY)) {
- if (RescueParty.isRecoveryTriggeredReboot()) {
+ if (CrashRecoveryHelper.isRecoveryTriggeredReboot()) {
// We're not actually doing a factory reset yet; we're rebooting
// to ask the user if they'd like to reset, so give them a less
// scary dialog message.
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index b768bb1..e76e94d 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -1804,7 +1804,7 @@
// If on a rotation leash, the wallpaper token surface needs to be shown explicitly
// because shell only gets the leash and the wallpaper token surface is not allowed
// to be changed by non-transition logic until the transition is finished.
- if (Flags.ensureWallpaperInTransitions() && wp.isVisibleRequested()
+ if (wp.mWmService.mFlags.mEnsureWallpaperInTransitions && wp.isVisibleRequested()
&& wp.getFixedRotationLeash() != null) {
transaction.show(wp.mSurfaceControl);
}
@@ -2216,7 +2216,8 @@
if (wallpaper != null) {
if (!wallpaper.isVisible() && wallpaper.isVisibleRequested()) {
wallpaper.commitVisibility(showWallpaper);
- } else if (Flags.ensureWallpaperInTransitions() && wallpaper.isVisible()
+ } else if (wallpaper.mWmService.mFlags.mEnsureWallpaperInTransitions
+ && wallpaper.isVisible()
&& !showWallpaper && !wallpaper.getDisplayContent().isKeyguardLocked()
&& !wallpaperIsOwnTarget(wallpaper)) {
wallpaper.setVisibleRequested(false);
@@ -2934,7 +2935,7 @@
// Use parent rotation because shell doesn't know the surface is rotated.
endRotation = parent.getWindowConfiguration().getRotation();
}
- } else if (isWallpaper(target) && Flags.ensureWallpaperInTransitions()
+ } else if (isWallpaper(target) && target.mWmService.mFlags.mEnsureWallpaperInTransitions
&& target.getRelativeDisplayRotation() != 0
&& !target.mTransitionController.useShellTransitionsRotation()) {
// If the wallpaper is "fixed-rotated", shell is unaware of this, so use the
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index db95d96..4536f24 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -59,7 +59,6 @@
import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.ToBooleanFunction;
import com.android.server.wallpaper.WallpaperCropper.WallpaperCropUtils;
-import com.android.window.flags.Flags;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -759,7 +758,7 @@
void collectTopWallpapers(Transition transition) {
if (mFindResults.hasTopShowWhenLockedWallpaper()) {
- if (Flags.ensureWallpaperInTransitions()) {
+ if (mService.mFlags.mEnsureWallpaperInTransitions) {
transition.collect(mFindResults.mTopWallpaper.mTopShowWhenLockedWallpaper.mToken);
} else {
transition.collect(mFindResults.mTopWallpaper.mTopShowWhenLockedWallpaper);
@@ -767,7 +766,7 @@
}
if (mFindResults.hasTopHideWhenLockedWallpaper()) {
- if (Flags.ensureWallpaperInTransitions()) {
+ if (mService.mFlags.mEnsureWallpaperInTransitions) {
transition.collect(mFindResults.mTopWallpaper.mTopHideWhenLockedWallpaper.mToken);
} else {
transition.collect(mFindResults.mTopWallpaper.mTopHideWhenLockedWallpaper);
diff --git a/services/core/java/com/android/server/wm/WallpaperWindowToken.java b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
index 31156de..384d111 100644
--- a/services/core/java/com/android/server/wm/WallpaperWindowToken.java
+++ b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
@@ -32,7 +32,6 @@
import android.util.SparseArray;
import com.android.internal.protolog.ProtoLog;
-import com.android.window.flags.Flags;
import java.util.function.Consumer;
@@ -85,7 +84,7 @@
public void prepareSurfaces() {
super.prepareSurfaces();
- if (Flags.ensureWallpaperInTransitions()) {
+ if (mWmService.mFlags.mEnsureWallpaperInTransitions) {
// Similar to Task.prepareSurfaces, outside of transitions we need to apply visibility
// changes directly. In transitions the transition player will take care of applying the
// visibility change.
diff --git a/services/core/java/com/android/server/wm/WindowManagerFlags.java b/services/core/java/com/android/server/wm/WindowManagerFlags.java
index f3e6a18..7ef8d8d 100644
--- a/services/core/java/com/android/server/wm/WindowManagerFlags.java
+++ b/services/core/java/com/android/server/wm/WindowManagerFlags.java
@@ -16,6 +16,9 @@
package com.android.server.wm;
+import android.app.AppGlobals;
+import android.content.pm.PackageManager;
+
import com.android.window.flags.Flags;
/**
@@ -53,5 +56,26 @@
final boolean mRespectNonTopVisibleFixedOrientation =
Flags.respectNonTopVisibleFixedOrientation();
+ final boolean mEnsureWallpaperInTransitions;
+
/* End Available Flags */
+
+ WindowManagerFlags() {
+ boolean isWatch;
+ try {
+ isWatch = AppGlobals.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_WATCH, 0 /* version */);
+ } catch (Throwable e) {
+ isWatch = false;
+ }
+ /*
+ * Wallpaper enablement is separated on Wear vs Phone as the latter appears to still exhibit
+ * regressions when enabled (for example b/353870983). These don't exist on Wear likely
+ * due to differences in SysUI/transition implementations. Wear enablement is required for
+ * 25Q2 while phone doesn't have as pressing a constraint and will wait to resolve any
+ * outstanding issues prior to roll-out.
+ */
+ mEnsureWallpaperInTransitions = (isWatch && Flags.ensureWallpaperInWearTransitions())
+ || Flags.ensureWallpaperInTransitions();
+ }
}
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 24a2a62..b40cf56 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -67,9 +67,8 @@
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
-import com.android.internal.protolog.common.LogLevel;
import com.android.internal.protolog.ProtoLog;
-import com.android.window.flags.Flags;
+import com.android.internal.protolog.common.LogLevel;
import com.android.server.policy.WindowManagerPolicy;
import java.io.PrintWriter;
@@ -413,7 +412,7 @@
ProtoLog.i(WM_SHOW_SURFACE_ALLOC, "SURFACE DESTROY: %s. %s",
mWin, new RuntimeException().fillInStackTrace());
destroySurface(t);
- if (Flags.ensureWallpaperInTransitions()) {
+ if (mService.mFlags.mEnsureWallpaperInTransitions) {
if (mWallpaperControllerLocked.isWallpaperTarget(mWin)) {
mWin.requestUpdateWallpaperIfNeeded();
}
@@ -464,7 +463,7 @@
if (!w.isOnScreen()) {
hide(t, "prepareSurfaceLocked");
- if (!w.mIsWallpaper || !Flags.ensureWallpaperInTransitions()) {
+ if (!w.mIsWallpaper || !mService.mFlags.mEnsureWallpaperInTransitions) {
mWallpaperControllerLocked.hideWallpapers(w);
}