Merge "fix(non linear font scaling)!: add ComplexDimensionUnit annotation to setLineHeight()" into udc-dev
diff --git a/apex/jobscheduler/framework/java/android/app/JobSchedulerImpl.java b/apex/jobscheduler/framework/java/android/app/JobSchedulerImpl.java
index 776d913..3cfddc6 100644
--- a/apex/jobscheduler/framework/java/android/app/JobSchedulerImpl.java
+++ b/apex/jobscheduler/framework/java/android/app/JobSchedulerImpl.java
@@ -65,8 +65,12 @@
@NonNull
@Override
public JobScheduler forNamespace(@NonNull String namespace) {
+ namespace = sanitizeNamespace(namespace);
if (namespace == null) {
- throw new IllegalArgumentException("namespace cannot be null");
+ throw new NullPointerException("namespace cannot be null");
+ }
+ if (namespace.isEmpty()) {
+ throw new IllegalArgumentException("namespace cannot be empty");
}
return new JobSchedulerImpl(this, namespace);
}
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobScheduler.java b/apex/jobscheduler/framework/java/android/app/job/JobScheduler.java
index b8847ad..d59d430 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobScheduler.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobScheduler.java
@@ -270,6 +270,9 @@
* otherwise. Attempting to update a job scheduled in another namespace will not be possible
* but will instead create or update the job inside the current namespace. A JobScheduler
* instance dedicated to a namespace must be used to schedule or update jobs in that namespace.
+ *
+ * <p class="note">Since leading and trailing whitespace can lead to hard-to-debug issues,
+ * they will be {@link String#trim() trimmed}. An empty String (after trimming) is not allowed.
* @see #getNamespace()
*/
@NonNull
@@ -287,6 +290,15 @@
throw new RuntimeException("Not implemented. Must override in a subclass.");
}
+ /** @hide */
+ @Nullable
+ public static String sanitizeNamespace(@Nullable String namespace) {
+ if (namespace == null) {
+ return null;
+ }
+ return namespace.trim().intern();
+ }
+
/**
* Schedule a job to be executed. Will replace any currently scheduled job with the same
* ID with the new information in the {@link JobInfo}. If a job with the given ID is currently
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index 3fe83a6..70b06cb 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -233,7 +233,7 @@
}
}
- @VisibleForTesting
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public static Clock sUptimeMillisClock = new MySimpleClock(ZoneOffset.UTC) {
@Override
public long millis() {
@@ -241,7 +241,6 @@
}
};
- @VisibleForTesting
public static Clock sElapsedRealtimeClock = new MySimpleClock(ZoneOffset.UTC) {
@Override
public long millis() {
@@ -4024,6 +4023,18 @@
return JobScheduler.RESULT_SUCCESS;
}
+ /** Returns a sanitized namespace if valid, or throws an exception if not. */
+ private String validateNamespace(@Nullable String namespace) {
+ namespace = JobScheduler.sanitizeNamespace(namespace);
+ if (namespace != null) {
+ if (namespace.isEmpty()) {
+ throw new IllegalArgumentException("namespace cannot be empty");
+ }
+ namespace = namespace.intern();
+ }
+ return namespace;
+ }
+
private int validateRunUserInitiatedJobsPermission(int uid, String packageName) {
final int state = getRunUserInitiatedJobsPermissionState(uid, packageName);
if (state == PermissionChecker.PERMISSION_HARD_DENIED) {
@@ -4071,9 +4082,7 @@
return result;
}
- if (namespace != null) {
- namespace = namespace.intern();
- }
+ namespace = validateNamespace(namespace);
final long ident = Binder.clearCallingIdentity();
try {
@@ -4104,9 +4113,7 @@
return result;
}
- if (namespace != null) {
- namespace = namespace.intern();
- }
+ namespace = validateNamespace(namespace);
final long ident = Binder.clearCallingIdentity();
try {
@@ -4145,9 +4152,7 @@
return result;
}
- if (namespace != null) {
- namespace = namespace.intern();
- }
+ namespace = validateNamespace(namespace);
final long ident = Binder.clearCallingIdentity();
try {
@@ -4184,7 +4189,8 @@
final long ident = Binder.clearCallingIdentity();
try {
return new ParceledListSlice<>(
- JobSchedulerService.this.getPendingJobsInNamespace(uid, namespace));
+ JobSchedulerService.this.getPendingJobsInNamespace(uid,
+ validateNamespace(namespace)));
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -4196,7 +4202,8 @@
final long ident = Binder.clearCallingIdentity();
try {
- return JobSchedulerService.this.getPendingJob(uid, namespace, jobId);
+ return JobSchedulerService.this.getPendingJob(
+ uid, validateNamespace(namespace), jobId);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -4208,7 +4215,8 @@
final long ident = Binder.clearCallingIdentity();
try {
- return JobSchedulerService.this.getPendingJobReason(uid, namespace, jobId);
+ return JobSchedulerService.this.getPendingJobReason(
+ uid, validateNamespace(namespace), jobId);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -4238,7 +4246,7 @@
JobSchedulerService.this.cancelJobsForUid(uid,
// Documentation says only jobs scheduled BY the app will be cancelled
/* includeSourceApp */ false,
- /* namespaceOnly */ true, namespace,
+ /* namespaceOnly */ true, validateNamespace(namespace),
JobParameters.STOP_REASON_CANCELLED_BY_APP,
JobParameters.INTERNAL_STOP_REASON_CANCELED,
"cancelAllInNamespace() called by app, callingUid=" + uid);
@@ -4253,7 +4261,7 @@
final long ident = Binder.clearCallingIdentity();
try {
- JobSchedulerService.this.cancelJob(uid, namespace, jobId, uid,
+ JobSchedulerService.this.cancelJob(uid, validateNamespace(namespace), jobId, uid,
JobParameters.STOP_REASON_CANCELLED_BY_APP);
} finally {
Binder.restoreCallingIdentity(ident);
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java
index 234a93c..5d2c926 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java
@@ -33,7 +33,9 @@
import android.app.job.JobInfo;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.os.Handler;
import android.os.Looper;
+import android.os.Message;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.util.ArraySet;
@@ -66,6 +68,11 @@
| CONSTRAINT_CHARGING
| CONSTRAINT_IDLE;
+ /** List of flexible constraints a job can opt into. */
+ static final int OPTIONAL_FLEXIBLE_CONSTRAINTS = CONSTRAINT_BATTERY_NOT_LOW
+ | CONSTRAINT_CHARGING
+ | CONSTRAINT_IDLE;
+
/** List of all job flexible constraints whose satisfaction is job specific. */
private static final int JOB_SPECIFIC_FLEXIBLE_CONSTRAINTS = CONSTRAINT_CONNECTIVITY;
@@ -76,6 +83,9 @@
private static final int NUM_JOB_SPECIFIC_FLEXIBLE_CONSTRAINTS =
Integer.bitCount(JOB_SPECIFIC_FLEXIBLE_CONSTRAINTS);
+ static final int NUM_OPTIONAL_FLEXIBLE_CONSTRAINTS =
+ Integer.bitCount(OPTIONAL_FLEXIBLE_CONSTRAINTS);
+
static final int NUM_SYSTEM_WIDE_FLEXIBLE_CONSTRAINTS =
Integer.bitCount(SYSTEM_WIDE_FLEXIBLE_CONSTRAINTS);
@@ -130,6 +140,7 @@
final FlexibilityAlarmQueue mFlexibilityAlarmQueue;
@VisibleForTesting
final FcConfig mFcConfig;
+ private final FcHandler mHandler;
@VisibleForTesting
final PrefetchController mPrefetchController;
@@ -174,9 +185,12 @@
}
};
+ private static final int MSG_UPDATE_JOBS = 0;
+
public FlexibilityController(
JobSchedulerService service, PrefetchController prefetchController) {
super(service);
+ mHandler = new FcHandler(AppSchedulingModuleThread.get().getLooper());
mDeviceSupportsFlexConstraints = !mContext.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_AUTOMOTIVE);
mFlexibilityEnabled &= mDeviceSupportsFlexConstraints;
@@ -238,15 +252,16 @@
boolean isFlexibilitySatisfiedLocked(JobStatus js) {
return !mFlexibilityEnabled
|| mService.getUidBias(js.getSourceUid()) == JobInfo.BIAS_TOP_APP
- || mService.isCurrentlyRunningLocked(js)
|| getNumSatisfiedFlexibleConstraintsLocked(js)
- >= js.getNumRequiredFlexibleConstraints();
+ >= js.getNumRequiredFlexibleConstraints()
+ || mService.isCurrentlyRunningLocked(js);
}
@VisibleForTesting
@GuardedBy("mLock")
int getNumSatisfiedFlexibleConstraintsLocked(JobStatus js) {
return Integer.bitCount(mSatisfiedFlexibleConstraints & js.getPreferredConstraintFlags())
+ // Connectivity is job-specific, so must be handled separately.
+ (js.getHasAccessToUnmetered() ? 1 : 0);
}
@@ -267,33 +282,11 @@
+ " constraint: " + constraint + " state: " + state);
}
- final int prevSatisfied = Integer.bitCount(mSatisfiedFlexibleConstraints);
mSatisfiedFlexibleConstraints =
(mSatisfiedFlexibleConstraints & ~constraint) | (state ? constraint : 0);
- final int curSatisfied = Integer.bitCount(mSatisfiedFlexibleConstraints);
-
- // Only the max of the number of required flexible constraints will need to be updated
- // The rest did not have a change in state and are still satisfied or unsatisfied.
- final int numConstraintsToUpdate = Math.max(curSatisfied, prevSatisfied);
-
- // In order to get the range of all potentially satisfied jobs, we start at the number
- // of satisfied system-wide constraints and iterate to the max number of potentially
- // satisfied constraints, determined by how many job-specific constraints exist.
- for (int j = 0; j <= NUM_JOB_SPECIFIC_FLEXIBLE_CONSTRAINTS; j++) {
- final ArraySet<JobStatus> jobsByNumConstraints = mFlexibilityTracker
- .getJobsByNumRequiredConstraints(numConstraintsToUpdate + j);
-
- if (jobsByNumConstraints == null) {
- // If there are no more jobs to iterate through we can just return.
- return;
- }
-
- for (int i = 0; i < jobsByNumConstraints.size(); i++) {
- JobStatus js = jobsByNumConstraints.valueAt(i);
- js.setFlexibilityConstraintSatisfied(
- nowElapsed, isFlexibilitySatisfiedLocked(js));
- }
- }
+ // Push the job update to the handler to avoid blocking other controllers and
+ // potentially batch back-to-back controller state updates together.
+ mHandler.obtainMessage(MSG_UPDATE_JOBS).sendToTarget();
}
}
@@ -630,6 +623,44 @@
}
}
+ private class FcHandler extends Handler {
+ FcHandler(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_UPDATE_JOBS:
+ removeMessages(MSG_UPDATE_JOBS);
+
+ synchronized (mLock) {
+ final long nowElapsed = sElapsedRealtimeClock.millis();
+ final ArraySet<JobStatus> changedJobs = new ArraySet<>();
+
+ for (int o = 0; o <= NUM_OPTIONAL_FLEXIBLE_CONSTRAINTS; ++o) {
+ final ArraySet<JobStatus> jobsByNumConstraints = mFlexibilityTracker
+ .getJobsByNumRequiredConstraints(o);
+
+ if (jobsByNumConstraints != null) {
+ for (int i = 0; i < jobsByNumConstraints.size(); i++) {
+ final JobStatus js = jobsByNumConstraints.valueAt(i);
+ if (js.setFlexibilityConstraintSatisfied(
+ nowElapsed, isFlexibilitySatisfiedLocked(js))) {
+ changedJobs.add(js);
+ }
+ }
+ }
+ }
+ if (changedJobs.size() > 0) {
+ mStateChangedListener.onControllerStateChanged(changedJobs);
+ }
+ }
+ break;
+ }
+ }
+ }
+
@VisibleForTesting
class FcConfig {
private boolean mShouldReevaluateConstraints = false;
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 0e4c3c0..e908ced 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -41,9 +41,12 @@
* <p>The properties describing a
* {@link CameraDevice CameraDevice}.</p>
*
- * <p>These properties are fixed for a given CameraDevice, and can be queried
+ * <p>These properties are primarily fixed for a given CameraDevice, and can be queried
* through the {@link CameraManager CameraManager}
- * interface with {@link CameraManager#getCameraCharacteristics}.</p>
+ * interface with {@link CameraManager#getCameraCharacteristics}. Beginning with API level 32, some
+ * properties such as {@link #SENSOR_ORIENTATION} may change dynamically based on the state of the
+ * device. For information on whether a specific value is fixed, see the documentation for its key.
+ * </p>
*
* <p>When obtained by a client that does not hold the CAMERA permission, some metadata values are
* not included. The list of keys that require the permission is given by
@@ -281,9 +284,6 @@
* <p>The field definitions can be
* found in {@link CameraCharacteristics}.</p>
*
- * <p>Querying the value for the same key more than once will return a value
- * which is equal to the previous queried value.</p>
- *
* @throws IllegalArgumentException if the key was not valid
*
* @param key The characteristics field to read.
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index a7e28e2..4950373 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -41,9 +41,10 @@
* </p>
*
* <p>
- * All instances of CameraMetadata are immutable. The list of keys with {@link #getKeys()}
- * never changes, nor do the values returned by any key with {@code #get} throughout
- * the lifetime of the object.
+ * All instances of CameraMetadata are immutable. Beginning with API level 32, the list of keys
+ * returned by {@link #getKeys()} may change depending on the state of the device, as may the
+ * values returned by any key with {@code #get} throughout the lifetime of the object. For
+ * information on whether a specific value is fixed, see the documentation for its key.
* </p>
*
* @see CameraDevice
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index e7385b6..9cacfff 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -39,6 +39,7 @@
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.Vibrator;
+import android.sysprop.InputProperties;
import android.util.Log;
import android.view.Display;
import android.view.InputDevice;
@@ -1123,7 +1124,8 @@
public boolean isStylusPointerIconEnabled() {
if (mIsStylusPointerIconEnabled == null) {
mIsStylusPointerIconEnabled = getContext().getResources()
- .getBoolean(com.android.internal.R.bool.config_enableStylusPointerIcon);
+ .getBoolean(com.android.internal.R.bool.config_enableStylusPointerIcon)
+ || InputProperties.force_enable_stylus_pointer_icon().orElse(false);
}
return mIsStylusPointerIconEnabled;
}
diff --git a/core/java/android/net/vcn/VcnCellUnderlyingNetworkTemplate.java b/core/java/android/net/vcn/VcnCellUnderlyingNetworkTemplate.java
index 38b3174..46cf016 100644
--- a/core/java/android/net/vcn/VcnCellUnderlyingNetworkTemplate.java
+++ b/core/java/android/net/vcn/VcnCellUnderlyingNetworkTemplate.java
@@ -354,6 +354,7 @@
}
/** @hide */
+ @Override
public Map<Integer, Integer> getCapabilitiesMatchCriteria() {
return Collections.unmodifiableMap(new HashMap<>(mCapabilitiesMatchCriteria));
}
diff --git a/core/java/android/net/vcn/VcnUnderlyingNetworkTemplate.java b/core/java/android/net/vcn/VcnUnderlyingNetworkTemplate.java
index 9235d09..edf2c09 100644
--- a/core/java/android/net/vcn/VcnUnderlyingNetworkTemplate.java
+++ b/core/java/android/net/vcn/VcnUnderlyingNetworkTemplate.java
@@ -29,6 +29,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Map;
import java.util.Objects;
/**
@@ -307,4 +308,7 @@
public int getMinExitDownstreamBandwidthKbps() {
return mMinExitDownstreamBandwidthKbps;
}
+
+ /** @hide */
+ public abstract Map<Integer, Integer> getCapabilitiesMatchCriteria();
}
diff --git a/core/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplate.java b/core/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplate.java
index 2544a6d..2e6b09f 100644
--- a/core/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplate.java
+++ b/core/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplate.java
@@ -15,6 +15,9 @@
*/
package android.net.vcn;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
+import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_ANY;
+
import static com.android.internal.annotations.VisibleForTesting.Visibility;
import static com.android.server.vcn.util.PersistableBundleUtils.STRING_DESERIALIZER;
import static com.android.server.vcn.util.PersistableBundleUtils.STRING_SERIALIZER;
@@ -23,6 +26,7 @@
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.net.NetworkCapabilities;
+import android.net.vcn.VcnUnderlyingNetworkTemplate.MatchCriteria;
import android.os.PersistableBundle;
import android.util.ArraySet;
@@ -32,6 +36,7 @@
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Map;
import java.util.Objects;
import java.util.Set;
@@ -162,6 +167,12 @@
return Collections.unmodifiableSet(mSsids);
}
+ /** @hide */
+ @Override
+ public Map<Integer, Integer> getCapabilitiesMatchCriteria() {
+ return Collections.singletonMap(NET_CAPABILITY_INTERNET, MATCH_REQUIRED);
+ }
+
/** This class is used to incrementally build VcnWifiUnderlyingNetworkTemplate objects. */
public static final class Builder {
private int mMeteredMatchCriteria = MATCH_ANY;
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index bfc5afe..4bfff16 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -8434,7 +8434,7 @@
extras.putString(KEY_ACCOUNT_NAME, accountName);
extras.putString(KEY_ACCOUNT_TYPE, accountType);
- contentResolver.call(ContactsContract.AUTHORITY_URI,
+ nullSafeCall(contentResolver, ContactsContract.AUTHORITY_URI,
ContactsContract.SimContacts.ADD_SIM_ACCOUNT_METHOD,
null, extras);
}
@@ -8457,7 +8457,7 @@
Bundle extras = new Bundle();
extras.putInt(KEY_SIM_SLOT_INDEX, simSlotIndex);
- contentResolver.call(ContactsContract.AUTHORITY_URI,
+ nullSafeCall(contentResolver, ContactsContract.AUTHORITY_URI,
ContactsContract.SimContacts.REMOVE_SIM_ACCOUNT_METHOD,
null, extras);
}
@@ -8469,7 +8469,7 @@
*/
public static @NonNull List<SimAccount> getSimAccounts(
@NonNull ContentResolver contentResolver) {
- Bundle response = contentResolver.call(ContactsContract.AUTHORITY_URI,
+ Bundle response = nullSafeCall(contentResolver, ContactsContract.AUTHORITY_URI,
ContactsContract.SimContacts.QUERY_SIM_ACCOUNTS_METHOD,
null, null);
List<SimAccount> result = response.getParcelableArrayList(KEY_SIM_ACCOUNTS, android.provider.ContactsContract.SimAccount.class);
@@ -9088,7 +9088,8 @@
* @param contactId the id of the contact to undemote.
*/
public static void undemote(ContentResolver contentResolver, long contactId) {
- contentResolver.call(ContactsContract.AUTHORITY_URI, PinnedPositions.UNDEMOTE_METHOD,
+ nullSafeCall(contentResolver, ContactsContract.AUTHORITY_URI,
+ PinnedPositions.UNDEMOTE_METHOD,
String.valueOf(contactId), null);
}
@@ -10300,4 +10301,13 @@
public static final String CONTENT_ITEM_TYPE =
"vnd.android.cursor.item/contact_metadata_sync_state";
}
+
+ private static Bundle nullSafeCall(@NonNull ContentResolver resolver, @NonNull Uri uri,
+ @NonNull String method, @Nullable String arg, @Nullable Bundle extras) {
+ try (ContentProviderClient client = resolver.acquireContentProviderClient(uri)) {
+ return client.call(method, arg, extras);
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
+ }
}
diff --git a/core/java/android/view/inputmethod/RemoteInputConnectionImpl.java b/core/java/android/view/inputmethod/RemoteInputConnectionImpl.java
index eb91d08..ec50c69 100644
--- a/core/java/android/view/inputmethod/RemoteInputConnectionImpl.java
+++ b/core/java/android/view/inputmethod/RemoteInputConnectionImpl.java
@@ -405,21 +405,15 @@
}
if (handler.getLooper().isCurrentThread()) {
servedView.onInputConnectionClosedInternal();
- final ViewRootImpl viewRoot = servedView.getViewRootImpl();
- if (viewRoot != null) {
- viewRoot.getHandwritingInitiator().onInputConnectionClosed(servedView);
- }
} else {
handler.post(servedView::onInputConnectionClosedInternal);
- handler.post(() -> {
- final ViewRootImpl viewRoot = servedView.getViewRootImpl();
- if (viewRoot != null) {
- viewRoot.getHandwritingInitiator()
- .onInputConnectionClosed(servedView);
- }
- });
}
}
+
+ final ViewRootImpl viewRoot = servedView.getViewRootImpl();
+ if (viewRoot != null) {
+ viewRoot.getHandwritingInitiator().onInputConnectionClosed(servedView);
+ }
}
});
}
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 774899d..ef19fc1 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -6379,4 +6379,6 @@
<!-- Whether we should persist the brightness value in nits for the default display even if
the underlying display device changes. -->
<bool name="config_persistBrightnessNitsForDefaultDisplay">false</bool>
+ <!-- Whether to request the approval before commit sessions. -->
+ <bool name="config_isPreApprovalRequestAvailable">true</bool>
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 79f3dcd..8855d5b 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2238,6 +2238,7 @@
<java-symbol type="array" name="config_nonPreemptibleInputMethods" />
<java-symbol type="bool" name="config_enhancedConfirmationModeEnabled" />
<java-symbol type="bool" name="config_persistBrightnessNitsForDefaultDisplay" />
+ <java-symbol type="bool" name="config_isPreApprovalRequestAvailable" />
<java-symbol type="layout" name="resolver_list" />
<java-symbol type="id" name="resolver_list" />
diff --git a/libs/WindowManager/Shell/res/drawable/caption_desktop_button.xml b/libs/WindowManager/Shell/res/drawable/caption_desktop_button.xml
deleted file mode 100644
index 8779cc0..0000000
--- a/libs/WindowManager/Shell/res/drawable/caption_desktop_button.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2022 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="32.0dp"
- android:height="32.0dp"
- android:viewportWidth="32.0"
- android:viewportHeight="32.0"
->
- <group android:scaleX="0.5"
- android:scaleY="0.5"
- android:translateX="6.0"
- android:translateY="6.0">
- <path
- android:fillColor="@android:color/black"
- android:pathData="M5.958,37.708Q4.458,37.708 3.354,36.604Q2.25,35.5 2.25,34V18.292Q2.25,16.792 3.354,15.688Q4.458,14.583 5.958,14.583H9.5V5.958Q9.5,4.458 10.625,3.354Q11.75,2.25 13.208,2.25H34Q35.542,2.25 36.646,3.354Q37.75,4.458 37.75,5.958V21.667Q37.75,23.167 36.646,24.271Q35.542,25.375 34,25.375H30.5V34Q30.5,35.5 29.396,36.604Q28.292,37.708 26.792,37.708ZM5.958,34H26.792Q26.792,34 26.792,34Q26.792,34 26.792,34V21.542H5.958V34Q5.958,34 5.958,34Q5.958,34 5.958,34ZM30.5,21.667H34Q34,21.667 34,21.667Q34,21.667 34,21.667V9.208H13.208V14.583H26.833Q28.375,14.583 29.438,15.667Q30.5,16.75 30.5,18.25Z"/>
- </group>
-</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/caption_floating_button.xml b/libs/WindowManager/Shell/res/drawable/caption_floating_button.xml
deleted file mode 100644
index ea0fbb0..0000000
--- a/libs/WindowManager/Shell/res/drawable/caption_floating_button.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2022 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="32.0dp"
- android:height="32.0dp"
- android:viewportWidth="32.0"
- android:viewportHeight="32.0"
->
- <group android:scaleX="0.5"
- android:scaleY="0.5"
- android:translateX="6.0"
- android:translateY="6.0">
- <path
- android:fillColor="@android:color/black"
- android:pathData="M18.167,21.875H29.833V10.208H18.167ZM7.875,35.833Q6.375,35.833 5.271,34.729Q4.167,33.625 4.167,32.125V7.875Q4.167,6.375 5.271,5.271Q6.375,4.167 7.875,4.167H32.125Q33.625,4.167 34.729,5.271Q35.833,6.375 35.833,7.875V32.125Q35.833,33.625 34.729,34.729Q33.625,35.833 32.125,35.833ZM7.875,32.125H32.125Q32.125,32.125 32.125,32.125Q32.125,32.125 32.125,32.125V7.875Q32.125,7.875 32.125,7.875Q32.125,7.875 32.125,7.875H7.875Q7.875,7.875 7.875,7.875Q7.875,7.875 7.875,7.875V32.125Q7.875,32.125 7.875,32.125Q7.875,32.125 7.875,32.125ZM7.875,7.875Q7.875,7.875 7.875,7.875Q7.875,7.875 7.875,7.875V32.125Q7.875,32.125 7.875,32.125Q7.875,32.125 7.875,32.125Q7.875,32.125 7.875,32.125Q7.875,32.125 7.875,32.125V7.875Q7.875,7.875 7.875,7.875Q7.875,7.875 7.875,7.875Z"/>
- </group>
-</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/caption_fullscreen_button.xml b/libs/WindowManager/Shell/res/drawable/caption_fullscreen_button.xml
deleted file mode 100644
index c55cbe2..0000000
--- a/libs/WindowManager/Shell/res/drawable/caption_fullscreen_button.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2022 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="32.0dp"
- android:height="32.0dp"
- android:viewportWidth="32.0"
- android:viewportHeight="32.0"
->
- <group android:scaleX="0.5"
- android:scaleY="0.5"
- android:translateX="6.0"
- android:translateY="6.0">
- <path
- android:fillColor="@android:color/black"
- android:pathData="M34.042,14.625V9.333Q34.042,9.333 34.042,9.333Q34.042,9.333 34.042,9.333H28.708V5.708H33.917Q35.458,5.708 36.562,6.833Q37.667,7.958 37.667,9.458V14.625ZM2.375,14.625V9.458Q2.375,7.958 3.479,6.833Q4.583,5.708 6.125,5.708H11.292V9.333H6Q6,9.333 6,9.333Q6,9.333 6,9.333V14.625ZM28.708,34.25V30.667H34.042Q34.042,30.667 34.042,30.667Q34.042,30.667 34.042,30.667V25.333H37.667V30.542Q37.667,32 36.562,33.125Q35.458,34.25 33.917,34.25ZM6.125,34.25Q4.583,34.25 3.479,33.125Q2.375,32 2.375,30.542V25.333H6V30.667Q6,30.667 6,30.667Q6,30.667 6,30.667H11.292V34.25ZM9.333,27.292V12.667H30.708V27.292ZM12.917,23.708H27.125V16.25H12.917ZM12.917,23.708V16.25V23.708Z"/>
- </group>
-</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/caption_more_button.xml b/libs/WindowManager/Shell/res/drawable/caption_more_button.xml
deleted file mode 100644
index 447df43..0000000
--- a/libs/WindowManager/Shell/res/drawable/caption_more_button.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2022 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="32.0dp"
- android:height="32.0dp"
- android:viewportWidth="32.0"
- android:viewportHeight="32.0"
->
- <group android:scaleX="0.5"
- android:scaleY="0.5"
- android:translateX="6.0"
- android:translateY="6.0">
- <path
- android:fillColor="@android:color/black"
- android:pathData="M8.083,22.833Q6.917,22.833 6.104,22Q5.292,21.167 5.292,20Q5.292,18.833 6.125,18Q6.958,17.167 8.125,17.167Q9.292,17.167 10.125,18Q10.958,18.833 10.958,20Q10.958,21.167 10.125,22Q9.292,22.833 8.083,22.833ZM20,22.833Q18.833,22.833 18,22Q17.167,21.167 17.167,20Q17.167,18.833 18,18Q18.833,17.167 20,17.167Q21.167,17.167 22,18Q22.833,18.833 22.833,20Q22.833,21.167 22,22Q21.167,22.833 20,22.833ZM31.875,22.833Q30.708,22.833 29.875,22Q29.042,21.167 29.042,20Q29.042,18.833 29.875,18Q30.708,17.167 31.917,17.167Q33.083,17.167 33.896,18Q34.708,18.833 34.708,20Q34.708,21.167 33.875,22Q33.042,22.833 31.875,22.833Z"/>
- </group>
-</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/caption_screenshot_button.xml b/libs/WindowManager/Shell/res/drawable/caption_screenshot_button.xml
deleted file mode 100644
index 7c86888..0000000
--- a/libs/WindowManager/Shell/res/drawable/caption_screenshot_button.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2023 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="32.0dp"
- android:height="32.0dp"
- android:viewportWidth="32.0"
- android:viewportHeight="32.0"
->
- <group android:scaleX="0.5"
- android:scaleY="0.5"
- android:translateY="4.0">
- <path
- android:fillColor="@android:color/black"
- android:pathData="M10,38V28.35H13V35H19.65V38ZM10,19.65V10H19.65V13H13V19.65ZM28.35,38V35H35V28.35H38V38ZM35,19.65V13H28.35V10H38V19.65Z"/>
- </group>
-</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/caption_select_button.xml b/libs/WindowManager/Shell/res/drawable/caption_select_button.xml
deleted file mode 100644
index 8c60c84..0000000
--- a/libs/WindowManager/Shell/res/drawable/caption_select_button.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2023 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="32.0dp"
- android:height="32.0dp"
- android:viewportWidth="32.0"
- android:viewportHeight="32.0"
->
- <group
- android:translateX="4.0"
- android:translateY="6.0">
- <path
- android:fillColor="@android:color/black"
- android:pathData="M13.7021 12.5833L16.5676 15.5L15.426 16.7333L12.526 13.8333L10.4426 15.9167V10.5H15.9176L13.7021 12.5833ZM13.8343 3.83333H15.501V5.5H13.8343V3.83333ZM15.501 2.16667H13.8343V0.566667C14.751 0.566667 15.501 1.33333 15.501 2.16667ZM10.501 0.5H12.1676V2.16667H10.501V0.5ZM13.8343 7.16667H15.501V8.83333H13.8343V7.16667ZM5.50098 15.5H3.83431V13.8333H5.50098V15.5ZM2.16764 5.5H0.500977V3.83333H2.16764V5.5ZM2.16764 0.566667V2.16667H0.500977C0.500977 1.33333 1.33431 0.566667 2.16764 0.566667ZM2.16764 12.1667H0.500977V10.5H2.16764V12.1667ZM5.50098 2.16667H3.83431V0.5H5.50098V2.16667ZM8.83431 2.16667H7.16764V0.5H8.83431V2.16667ZM8.83431 15.5H7.16764V13.8333H8.83431V15.5ZM2.16764 8.83333H0.500977V7.16667H2.16764V8.83333ZM2.16764 15.5667C1.25098 15.5667 0.500977 14.6667 0.500977 13.8333H2.16764V15.5667Z"/>
- </group>
-</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/caption_split_screen_button.xml b/libs/WindowManager/Shell/res/drawable/caption_split_screen_button.xml
deleted file mode 100644
index c334a54..0000000
--- a/libs/WindowManager/Shell/res/drawable/caption_split_screen_button.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2022 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="32.0dp"
- android:height="32.0dp"
- android:viewportWidth="32.0"
- android:viewportHeight="32.0"
->
- <group android:translateX="6.0"
- android:translateY="8.0">
- <path
- android:fillColor="@android:color/black"
- android:pathData="M18 14L13 14L13 2L18 2L18 14ZM20 14L20 2C20 0.9 19.1 -3.93402e-08 18 -8.74228e-08L13 -3.0598e-07C11.9 -3.54062e-07 11 0.9 11 2L11 14C11 15.1 11.9 16 13 16L18 16C19.1 16 20 15.1 20 14ZM7 14L2 14L2 2L7 2L7 14ZM9 14L9 2C9 0.9 8.1 -5.20166e-07 7 -5.68248e-07L2 -7.86805e-07C0.9 -8.34888e-07 -3.93403e-08 0.9 -8.74228e-08 2L-6.11959e-07 14C-6.60042e-07 15.1 0.9 16 2 16L7 16C8.1 16 9 15.1 9 14Z"/> </group>
-</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_menu_background.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_menu_background.xml
index c6e634c..4ee10f4 100644
--- a/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_menu_background.xml
+++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_menu_background.xml
@@ -17,6 +17,5 @@
<shape android:shape="rectangle"
xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@android:color/white" />
- <corners android:radius="@dimen/caption_menu_corner_radius" />
- <stroke android:width="1dp" android:color="#b3b3b3"/>
+ <corners android:radius="@dimen/desktop_mode_handle_menu_corner_radius" />
</shape>
diff --git a/libs/WindowManager/Shell/res/drawable/caption_collapse_menu_button.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_close.xml
similarity index 62%
rename from libs/WindowManager/Shell/res/drawable/caption_collapse_menu_button.xml
rename to libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_close.xml
index 166552d..b7521d4 100644
--- a/libs/WindowManager/Shell/res/drawable/caption_collapse_menu_button.xml
+++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_close.xml
@@ -15,16 +15,12 @@
~ limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24.0dp"
- android:height="24.0dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0"
->
- <group android:scaleX="1.25"
- android:scaleY="1.75"
- android:translateY="6.0">
- <path
- android:fillColor="@android:color/black"
- android:pathData="M10.3937 6.93935L11.3337 5.99935L6.00033 0.666016L0.666992 5.99935L1.60699 6.93935L6.00033 2.55268"/>
- </group>
+ android:height="20dp"
+ android:tint="#000000"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="20dp">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/caption_close_button.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_desktop.xml
similarity index 60%
copy from libs/WindowManager/Shell/res/drawable/caption_close_button.xml
copy to libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_desktop.xml
index e258564..e2b724b 100644
--- a/libs/WindowManager/Shell/res/drawable/caption_close_button.xml
+++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_desktop.xml
@@ -15,16 +15,12 @@
~ limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="32.0dp"
- android:height="32.0dp"
- android:viewportWidth="32.0"
- android:viewportHeight="32.0"
->
- <group android:scaleX="0.5"
- android:scaleY="0.5"
- android:translateY="4.0">
- <path
- android:fillColor="#FFFF0000"
- android:pathData="M12.45,38.35 L9.65,35.55 21.2,24 9.65,12.45 12.45,9.65 24,21.2 35.55,9.65 38.35,12.45 26.8,24 38.35,35.55 35.55,38.35 24,26.8Z"/>
- </group>
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20"
+ android:viewportHeight="20">
+ <path
+ android:pathData="M16.667,15H3.333V5H16.667V15ZM16.667,16.667C17.583,16.667 18.333,15.917 18.333,15V5C18.333,4.083 17.583,3.333 16.667,3.333H3.333C2.417,3.333 1.667,4.083 1.667,5V15C1.667,15.917 2.417,16.667 3.333,16.667H16.667ZM15,6.667H9.167V8.333H13.333V10H15V6.667ZM5,9.167H12.5V13.333H5V9.167Z"
+ android:fillColor="#1C1C14"
+ android:fillType="evenOdd"/>
</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/caption_collapse_menu_button.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_floating.xml
similarity index 62%
copy from libs/WindowManager/Shell/res/drawable/caption_collapse_menu_button.xml
copy to libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_floating.xml
index 166552d..b0ea98e 100644
--- a/libs/WindowManager/Shell/res/drawable/caption_collapse_menu_button.xml
+++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_floating.xml
@@ -15,16 +15,12 @@
~ limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24.0dp"
- android:height="24.0dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0"
->
- <group android:scaleX="1.25"
- android:scaleY="1.75"
- android:translateY="6.0">
- <path
- android:fillColor="@android:color/black"
- android:pathData="M10.3937 6.93935L11.3337 5.99935L6.00033 0.666016L0.666992 5.99935L1.60699 6.93935L6.00033 2.55268"/>
- </group>
+ android:width="21dp"
+ android:height="20dp"
+ android:viewportWidth="21"
+ android:viewportHeight="20">
+ <path
+ android:pathData="M3.667,15H17V5H3.667V15ZM18.667,15C18.667,15.917 17.917,16.667 17,16.667H3.667C2.75,16.667 2,15.917 2,15V5C2,4.083 2.75,3.333 3.667,3.333H17C17.917,3.333 18.667,4.083 18.667,5V15ZM11.167,6.667H15.333V11.667H11.167V6.667Z"
+ android:fillColor="#1C1C14"
+ android:fillType="evenOdd"/>
</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/caption_collapse_menu_button.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_fullscreen.xml
similarity index 62%
copy from libs/WindowManager/Shell/res/drawable/caption_collapse_menu_button.xml
copy to libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_fullscreen.xml
index 166552d..99e1d26 100644
--- a/libs/WindowManager/Shell/res/drawable/caption_collapse_menu_button.xml
+++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_fullscreen.xml
@@ -15,16 +15,12 @@
~ limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24.0dp"
- android:height="24.0dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0"
->
- <group android:scaleX="1.25"
- android:scaleY="1.75"
- android:translateY="6.0">
- <path
- android:fillColor="@android:color/black"
- android:pathData="M10.3937 6.93935L11.3337 5.99935L6.00033 0.666016L0.666992 5.99935L1.60699 6.93935L6.00033 2.55268"/>
- </group>
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20"
+ android:viewportHeight="20">
+ <path
+ android:pathData="M3.333,15H16.667V5H3.333V15ZM18.333,15C18.333,15.917 17.583,16.667 16.667,16.667H3.333C2.417,16.667 1.667,15.917 1.667,15V5C1.667,4.083 2.417,3.333 3.333,3.333H16.667C17.583,3.333 18.333,4.083 18.333,5V15ZM5,6.667H15V13.333H5V6.667Z"
+ android:fillColor="#1C1C14"
+ android:fillType="evenOdd"/>
</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_screenshot.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_screenshot.xml
new file mode 100644
index 0000000..79a9125
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_screenshot.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20"
+ android:viewportHeight="20">
+ <path
+ android:pathData="M18.333,5.833L18.333,8.333L16.667,8.333L16.667,5.833L13.333,5.833L13.333,4.167L16.667,4.167C17.587,4.167 18.333,4.913 18.333,5.833Z"
+ android:fillColor="#1C1C14"/>
+ <path
+ android:pathData="M6.667,4.167L3.333,4.167C2.413,4.167 1.667,4.913 1.667,5.833L1.667,8.333L3.333,8.333L3.333,5.833L6.667,5.833L6.667,4.167Z"
+ android:fillColor="#1C1C14"/>
+ <path
+ android:pathData="M6.667,14.167L3.333,14.167L3.333,11.667L1.667,11.667L1.667,14.167C1.667,15.087 2.413,15.833 3.333,15.833L6.667,15.833L6.667,14.167Z"
+ android:fillColor="#1C1C14"/>
+ <path
+ android:pathData="M13.333,15.833L16.667,15.833C17.587,15.833 18.333,15.087 18.333,14.167L18.333,11.667L16.667,11.667L16.667,14.167L13.333,14.167L13.333,15.833Z"
+ android:fillColor="#1C1C14"/>
+</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_select.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_select.xml
new file mode 100644
index 0000000..7c4f499
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_select.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20"
+ android:viewportHeight="20">
+ <path
+ android:pathData="M15.701,14.583L18.567,17.5L17.425,18.733L14.525,15.833L12.442,17.917V12.5H17.917L15.701,14.583ZM15.833,5.833H17.5V7.5H15.833V5.833ZM17.5,4.167H15.833V2.567C16.75,2.567 17.5,3.333 17.5,4.167ZM12.5,2.5H14.167V4.167H12.5V2.5ZM15.833,9.167H17.5V10.833H15.833V9.167ZM7.5,17.5H5.833V15.833H7.5V17.5ZM4.167,7.5H2.5V5.833H4.167V7.5ZM4.167,2.567V4.167H2.5C2.5,3.333 3.333,2.567 4.167,2.567ZM4.167,14.167H2.5V12.5H4.167V14.167ZM7.5,4.167H5.833V2.5H7.5V4.167ZM10.833,4.167H9.167V2.5H10.833V4.167ZM10.833,17.5H9.167V15.833H10.833V17.5ZM4.167,10.833H2.5V9.167H4.167V10.833ZM4.167,17.567C3.25,17.567 2.5,16.667 2.5,15.833H4.167V17.567Z"
+ android:fillColor="#1C1C14"/>
+</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/caption_close_button.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_splitscreen.xml
similarity index 61%
rename from libs/WindowManager/Shell/res/drawable/caption_close_button.xml
rename to libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_splitscreen.xml
index e258564..853ab60 100644
--- a/libs/WindowManager/Shell/res/drawable/caption_close_button.xml
+++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_splitscreen.xml
@@ -15,16 +15,12 @@
~ limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="32.0dp"
- android:height="32.0dp"
- android:viewportWidth="32.0"
- android:viewportHeight="32.0"
->
- <group android:scaleX="0.5"
- android:scaleY="0.5"
- android:translateY="4.0">
- <path
- android:fillColor="#FFFF0000"
- android:pathData="M12.45,38.35 L9.65,35.55 21.2,24 9.65,12.45 12.45,9.65 24,21.2 35.55,9.65 38.35,12.45 26.8,24 38.35,35.55 35.55,38.35 24,26.8Z"/>
- </group>
+ android:width="21dp"
+ android:height="20dp"
+ android:viewportWidth="21"
+ android:viewportHeight="20">
+ <path
+ android:pathData="M17.333,15H4V5H17.333V15ZM17.333,16.667C18.25,16.667 19,15.917 19,15V5C19,4.083 18.25,3.333 17.333,3.333H4C3.083,3.333 2.333,4.083 2.333,5V15C2.333,15.917 3.083,16.667 4,16.667H17.333ZM9.833,6.667H5.667V13.333H9.833V6.667ZM11.5,6.667H15.667V13.333H11.5V6.667Z"
+ android:fillColor="#1C1C14"
+ android:fillType="evenOdd"/>
</vector>
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_app_controls_window_decor.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_app_controls_window_decor.xml
index 35562b6..f6b21ba 100644
--- a/libs/WindowManager/Shell/res/layout/desktop_mode_app_controls_window_decor.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_app_controls_window_decor.xml
@@ -61,7 +61,7 @@
android:layout_width="32dp"
android:layout_height="32dp"
android:padding="4dp"
- android:contentDescription="@string/collapse_menu_text"
+ android:contentDescription="@string/expand_menu_text"
android:src="@drawable/ic_baseline_expand_more_24"
android:tint="@color/desktop_mode_caption_expand_button_dark"
android:background="@null"
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_decor_handle_menu.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_decor_handle_menu.xml
deleted file mode 100644
index ac13eae..0000000
--- a/libs/WindowManager/Shell/res/layout/desktop_mode_decor_handle_menu.xml
+++ /dev/null
@@ -1,136 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2022 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<com.android.wm.shell.windowdecor.WindowDecorLinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/handle_menu"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:background="@drawable/desktop_mode_decor_menu_background"
- android:divider="?android:attr/dividerHorizontal"
- android:showDividers="middle"
- android:dividerPadding="18dip">
- <RelativeLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
- <ImageView
- android:id="@+id/application_icon"
- android:layout_width="24dp"
- android:layout_height="24dp"
- android:layout_margin="12dp"
- android:contentDescription="@string/app_icon_text"
- android:layout_alignParentStart="true"
- android:layout_centerVertical="true"/>
- <TextView
- android:id="@+id/application_name"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_toEndOf="@+id/application_icon"
- android:layout_toStartOf="@+id/collapse_menu_button"
- android:textColor="#FF000000"
- android:layout_centerVertical="true"/>
- <Button
- android:id="@+id/collapse_menu_button"
- android:layout_width="24dp"
- android:layout_height="24dp"
- android:layout_marginEnd="10dp"
- android:contentDescription="@string/collapse_menu_text"
- android:layout_alignParentEnd="true"
- android:background="@drawable/ic_baseline_expand_more_24"
- android:layout_centerVertical="true"/>
- </RelativeLayout>
- <LinearLayout
- android:id="@+id/windowing_mode_buttons"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center_horizontal">
- <Space
- android:layout_width="0dp"
- android:layout_height="1dp"
- android:layout_weight="0.5" />
- <ImageButton
- style="@style/CaptionWindowingButtonStyle"
- android:id="@+id/fullscreen_button"
- android:contentDescription="@string/fullscreen_text"
- android:src="@drawable/caption_fullscreen_button"
- android:scaleType="fitCenter"
- android:background="?android:selectableItemBackgroundBorderless"/>
- <Space
- android:layout_width="0dp"
- android:layout_height="1dp"
- android:layout_weight="1" />
- <ImageButton
- style="@style/CaptionWindowingButtonStyle"
- android:id="@+id/split_screen_button"
- android:contentDescription="@string/split_screen_text"
- android:src="@drawable/caption_split_screen_button"
- android:scaleType="fitCenter"
- android:background="?android:selectableItemBackgroundBorderless"/>
- <Space
- android:layout_width="0dp"
- android:layout_height="1dp"
- android:layout_weight="1" />
- <ImageButton
- style="@style/CaptionWindowingButtonStyle"
- android:id="@+id/floating_button"
- android:contentDescription="@string/float_button_text"
- android:src="@drawable/caption_floating_button"
- android:scaleType="fitCenter"
- android:background="?android:selectableItemBackgroundBorderless"/>
- <Space
- android:layout_width="0dp"
- android:layout_height="1dp"
- android:layout_weight="1" />
- <ImageButton
- style="@style/CaptionWindowingButtonStyle"
- android:id="@+id/desktop_button"
- android:contentDescription="@string/desktop_text"
- android:src="@drawable/caption_desktop_button"
- android:scaleType="fitCenter"
- android:background="?android:selectableItemBackgroundBorderless"/>
- <Space
- android:layout_width="0dp"
- android:layout_height="1dp"
- android:layout_weight="0.5" />
-
- </LinearLayout>
- <LinearLayout
- android:id="@+id/menu_buttons_misc"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
- <Button
- style="@style/CaptionMenuButtonStyle"
- android:id="@+id/screenshot_button"
- android:contentDescription="@string/screenshot_text"
- android:text="@string/screenshot_text"
- android:drawableStart="@drawable/caption_screenshot_button"/>
- <Button
- style="@style/CaptionMenuButtonStyle"
- android:id="@+id/select_button"
- android:contentDescription="@string/select_text"
- android:text="@string/select_text"
- android:drawableStart="@drawable/caption_select_button"/>
- <Button
- style="@style/CaptionMenuButtonStyle"
- android:id="@+id/close_button"
- android:contentDescription="@string/close_text"
- android:text="@string/close_text"
- android:drawableStart="@drawable/caption_close_button"
- android:textColor="#FFFF0000"/>
- </LinearLayout>
-</com.android.wm.shell.windowdecor.WindowDecorLinearLayout>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_focused_window_decor.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_focused_window_decor.xml
index 5ab159c..1d6864c 100644
--- a/libs/WindowManager/Shell/res/layout/desktop_mode_focused_window_decor.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_focused_window_decor.xml
@@ -25,8 +25,9 @@
<ImageButton
android:id="@+id/caption_handle"
- android:layout_width="128dp"
+ android:layout_width="176dp"
android:layout_height="42dp"
+ android:paddingHorizontal="24dp"
android:contentDescription="@string/handle_text"
android:src="@drawable/decor_handle_dark"
tools:tint="@color/desktop_mode_caption_handle_bar_dark"
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_app_info_pill.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_app_info_pill.xml
new file mode 100644
index 0000000..167a003
--- /dev/null
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_app_info_pill.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="@dimen/desktop_mode_handle_menu_width"
+ android:layout_height="@dimen/desktop_mode_handle_menu_app_info_pill_height"
+ android:orientation="horizontal"
+ android:background="@drawable/desktop_mode_decor_menu_background"
+ android:gravity="center_vertical">
+
+ <ImageView
+ android:id="@+id/application_icon"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:layout_marginStart="14dp"
+ android:layout_marginEnd="14dp"
+ android:contentDescription="@string/app_icon_text"/>
+
+ <TextView
+ android:id="@+id/application_name"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ tools:text="Gmail"
+ android:textColor="@color/desktop_mode_caption_menu_text_color"
+ android:textSize="14sp"
+ android:textFontWeight="500"
+ android:lineHeight="20dp"
+ android:textStyle="normal"
+ android:layout_weight="1"/>
+
+ <ImageButton
+ android:id="@+id/collapse_menu_button"
+ android:layout_width="32dp"
+ android:layout_height="32dp"
+ android:padding="4dp"
+ android:layout_marginEnd="14dp"
+ android:layout_marginStart="14dp"
+ android:contentDescription="@string/collapse_menu_text"
+ android:src="@drawable/ic_baseline_expand_more_24"
+ android:rotation="180"
+ android:tint="@color/desktop_mode_caption_menu_buttons_color_inactive"
+ android:background="?android:selectableItemBackgroundBorderless"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_more_actions_pill.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_more_actions_pill.xml
new file mode 100644
index 0000000..40a4b53
--- /dev/null
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_more_actions_pill.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="@dimen/desktop_mode_handle_menu_width"
+ android:layout_height="@dimen/desktop_mode_handle_menu_more_actions_pill_height"
+ android:orientation="vertical"
+ android:background="@drawable/desktop_mode_decor_menu_background">
+
+ <Button
+ android:id="@+id/screenshot_button"
+ android:contentDescription="@string/screenshot_text"
+ android:text="@string/screenshot_text"
+ android:drawableStart="@drawable/desktop_mode_ic_handle_menu_screenshot"
+ android:drawableTint="@color/desktop_mode_caption_menu_buttons_color_inactive"
+ style="@style/DesktopModeHandleMenuActionButton"/>
+
+ <Button
+ android:id="@+id/select_button"
+ android:contentDescription="@string/select_text"
+ android:text="@string/select_text"
+ android:drawableStart="@drawable/desktop_mode_ic_handle_menu_select"
+ android:drawableTint="@color/desktop_mode_caption_menu_buttons_color_inactive"
+ style="@style/DesktopModeHandleMenuActionButton"/>
+
+ <Button
+ android:id="@+id/close_button"
+ android:contentDescription="@string/close_text"
+ android:text="@string/close_text"
+ android:drawableStart="@drawable/desktop_mode_ic_handle_menu_close"
+ android:drawableTint="@color/desktop_mode_caption_menu_buttons_color_inactive"
+ style="@style/DesktopModeHandleMenuActionButton"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_windowing_pill.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_windowing_pill.xml
new file mode 100644
index 0000000..95283b9
--- /dev/null
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_windowing_pill.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="@dimen/desktop_mode_handle_menu_width"
+ android:layout_height="@dimen/desktop_mode_handle_menu_windowing_pill_height"
+ android:orientation="horizontal"
+ android:background="@drawable/desktop_mode_decor_menu_background"
+ android:gravity="center_vertical">
+
+ <ImageButton
+ android:id="@+id/fullscreen_button"
+ android:layout_marginEnd="4dp"
+ android:contentDescription="@string/fullscreen_text"
+ android:src="@drawable/desktop_mode_ic_handle_menu_fullscreen"
+ android:tint="@color/desktop_mode_caption_menu_buttons_color_inactive"
+ android:layout_weight="1"
+ style="@style/DesktopModeHandleMenuWindowingButton"/>
+
+ <ImageButton
+ android:id="@+id/split_screen_button"
+ android:layout_marginStart="4dp"
+ android:layout_marginEnd="4dp"
+ android:contentDescription="@string/split_screen_text"
+ android:src="@drawable/desktop_mode_ic_handle_menu_splitscreen"
+ android:tint="@color/desktop_mode_caption_menu_buttons_color_inactive"
+ android:layout_weight="1"
+ style="@style/DesktopModeHandleMenuWindowingButton"/>
+
+ <ImageButton
+ android:id="@+id/floating_button"
+ android:layout_marginStart="4dp"
+ android:layout_marginEnd="4dp"
+ android:contentDescription="@string/float_button_text"
+ android:src="@drawable/desktop_mode_ic_handle_menu_floating"
+ android:tint="@color/desktop_mode_caption_menu_buttons_color_inactive"
+ android:layout_weight="1"
+ style="@style/DesktopModeHandleMenuWindowingButton"/>
+
+ <ImageButton
+ android:id="@+id/desktop_button"
+ android:layout_marginStart="4dp"
+ android:contentDescription="@string/desktop_text"
+ android:src="@drawable/desktop_mode_ic_handle_menu_desktop"
+ android:tint="@color/desktop_mode_caption_menu_buttons_color_active"
+ android:layout_weight="1"
+ style="@style/DesktopModeHandleMenuWindowingButton"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/values/colors.xml b/libs/WindowManager/Shell/res/values/colors.xml
index 4a1635d..4b885c2 100644
--- a/libs/WindowManager/Shell/res/values/colors.xml
+++ b/libs/WindowManager/Shell/res/values/colors.xml
@@ -67,4 +67,7 @@
<color name="desktop_mode_caption_close_button_dark">#1C1C17</color>
<color name="desktop_mode_caption_app_name_light">#EFF1F2</color>
<color name="desktop_mode_caption_app_name_dark">#1C1C17</color>
+ <color name="desktop_mode_caption_menu_text_color">#191C1D</color>
+ <color name="desktop_mode_caption_menu_buttons_color_inactive">#191C1D</color>
+ <color name="desktop_mode_caption_menu_buttons_color_active">#00677E</color>
</resources>
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 3a8614a..9049ed5 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -372,20 +372,34 @@
<!-- Height of button (32dp) + 2 * margin (5dp each). -->
<dimen name="freeform_decor_caption_height">42dp</dimen>
- <!-- Width of buttons (32dp each) + padding (128dp total). -->
- <dimen name="freeform_decor_caption_menu_width">256dp</dimen>
+ <!-- The width of the handle menu in desktop mode. -->
+ <dimen name="desktop_mode_handle_menu_width">216dp</dimen>
- <dimen name="freeform_decor_caption_menu_height">250dp</dimen>
- <dimen name="freeform_decor_caption_menu_height_no_windowing_controls">210dp</dimen>
+ <!-- The height of the handle menu's "App Info" pill in desktop mode. -->
+ <dimen name="desktop_mode_handle_menu_app_info_pill_height">52dp</dimen>
+
+ <!-- The height of the handle menu's "Windowing" pill in desktop mode. -->
+ <dimen name="desktop_mode_handle_menu_windowing_pill_height">52dp</dimen>
+
+ <!-- The height of the handle menu's "More Actions" pill in desktop mode. -->
+ <dimen name="desktop_mode_handle_menu_more_actions_pill_height">156dp</dimen>
+
+ <!-- The top margin of the handle menu in desktop mode. -->
+ <dimen name="desktop_mode_handle_menu_margin_top">4dp</dimen>
+
+ <!-- The start margin of the handle menu in desktop mode. -->
+ <dimen name="desktop_mode_handle_menu_margin_start">6dp</dimen>
+
+ <!-- The margin between pills of the handle menu in desktop mode. -->
+ <dimen name="desktop_mode_handle_menu_pill_spacing_margin">2dp</dimen>
+
+ <!-- The radius of the caption menu corners. -->
+ <dimen name="desktop_mode_handle_menu_corner_radius">26dp</dimen>
+
+ <!-- The radius of the caption menu shadow. -->
+ <dimen name="desktop_mode_handle_menu_shadow_radius">2dp</dimen>
<dimen name="freeform_resize_handle">30dp</dimen>
<dimen name="freeform_resize_corner">44dp</dimen>
-
- <!-- The radius of the caption menu shadow. -->
- <dimen name="caption_menu_shadow_radius">4dp</dimen>
-
- <!-- The radius of the caption menu corners. -->
- <dimen name="caption_menu_corner_radius">20dp</dimen>
-
</resources>
diff --git a/libs/WindowManager/Shell/res/values/strings.xml b/libs/WindowManager/Shell/res/values/strings.xml
index 395fdd1..563fb4d 100644
--- a/libs/WindowManager/Shell/res/values/strings.xml
+++ b/libs/WindowManager/Shell/res/values/strings.xml
@@ -263,4 +263,6 @@
<string name="close_text">Close</string>
<!-- Accessibility text for the handle menu close menu button [CHAR LIMIT=NONE] -->
<string name="collapse_menu_text">Close Menu</string>
+ <!-- Accessibility text for the handle menu open menu button [CHAR LIMIT=NONE] -->
+ <string name="expand_menu_text">Open Menu</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values/styles.xml b/libs/WindowManager/Shell/res/values/styles.xml
index d0782ad..8cad385 100644
--- a/libs/WindowManager/Shell/res/values/styles.xml
+++ b/libs/WindowManager/Shell/res/values/styles.xml
@@ -30,6 +30,26 @@
<item name="android:activityCloseExitAnimation">@anim/forced_resizable_exit</item>
</style>
+ <style name="DesktopModeHandleMenuActionButton">
+ <item name="android:layout_width">match_parent</item>
+ <item name="android:layout_height">52dp</item>
+ <item name="android:gravity">start|center_vertical</item>
+ <item name="android:padding">16dp</item>
+ <item name="android:textSize">14sp</item>
+ <item name="android:textFontWeight">500</item>
+ <item name="android:textColor">@color/desktop_mode_caption_menu_text_color</item>
+ <item name="android:drawablePadding">16dp</item>
+ <item name="android:background">?android:selectableItemBackground</item>
+ </style>
+
+ <style name="DesktopModeHandleMenuWindowingButton">
+ <item name="android:layout_width">48dp</item>
+ <item name="android:layout_height">48dp</item>
+ <item name="android:padding">14dp</item>
+ <item name="android:scaleType">fitCenter</item>
+ <item name="android:background">?android:selectableItemBackgroundBorderless</item>
+ </style>
+
<style name="CaptionButtonStyle">
<item name="android:layout_width">32dp</item>
<item name="android:layout_height">32dp</item>
@@ -37,20 +57,6 @@
<item name="android:padding">4dp</item>
</style>
- <style name="CaptionWindowingButtonStyle">
- <item name="android:layout_width">40dp</item>
- <item name="android:layout_height">40dp</item>
- <item name="android:padding">4dp</item>
- </style>
-
- <style name="CaptionMenuButtonStyle" parent="@style/Widget.AppCompat.Button.Borderless">
- <item name="android:layout_width">match_parent</item>
- <item name="android:layout_height">52dp</item>
- <item name="android:layout_marginStart">10dp</item>
- <item name="android:padding">4dp</item>
- <item name="android:gravity">start|center_vertical</item>
- </style>
-
<style name="DockedDividerBackground">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">@dimen/split_divider_bar_width</item>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
index 5459094..9eba5ec 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
@@ -1120,7 +1120,7 @@
setDividerInteractive(!mImeShown || !mHasImeFocus || isFloating, true,
"onImeStartPositioning");
- return needOffset ? IME_ANIMATION_NO_ALPHA : 0;
+ return mTargetYOffset != mLastYOffset ? IME_ANIMATION_NO_ALPHA : 0;
}
@Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
index 32abd73..22800ad 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
@@ -66,13 +66,11 @@
private final Transitions mTransitions;
private final Runnable mOnFinish;
- DismissTransition mPendingDismiss = null;
+ DismissSession mPendingDismiss = null;
TransitSession mPendingEnter = null;
- TransitSession mPendingRecent = null;
TransitSession mPendingResize = null;
private IBinder mAnimatingTransition = null;
- OneShotRemoteHandler mPendingRemoteHandler = null;
private OneShotRemoteHandler mActiveRemoteHandler = null;
private final Transitions.TransitionFinishCallback mRemoteFinishCB = this::onFinish;
@@ -101,27 +99,30 @@
mFinishCallback = finishCallback;
mAnimatingTransition = transition;
mFinishTransaction = finishTransaction;
- if (mPendingRemoteHandler != null) {
- mPendingRemoteHandler.startAnimation(transition, info, startTransaction,
- finishTransaction, mRemoteFinishCB);
- mActiveRemoteHandler = mPendingRemoteHandler;
- mPendingRemoteHandler = null;
- return;
+
+ final TransitSession pendingTransition = getPendingTransition(transition);
+ if (pendingTransition != null) {
+ if (pendingTransition.mCanceled) {
+ // The pending transition was canceled, so skip playing animation.
+ startTransaction.apply();
+ onFinish(null /* wct */, null /* wctCB */);
+ return;
+ }
+
+ if (pendingTransition.mRemoteHandler != null) {
+ pendingTransition.mRemoteHandler.startAnimation(transition, info, startTransaction,
+ finishTransaction, mRemoteFinishCB);
+ mActiveRemoteHandler = pendingTransition.mRemoteHandler;
+ return;
+ }
}
+
playInternalAnimation(transition, info, startTransaction, mainRoot, sideRoot, topRoot);
}
private void playInternalAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction t, @NonNull WindowContainerToken mainRoot,
@NonNull WindowContainerToken sideRoot, @NonNull WindowContainerToken topRoot) {
- final TransitSession pendingTransition = getPendingTransition(transition);
- if (pendingTransition != null && pendingTransition.mCanceled) {
- // The pending transition was canceled, so skip playing animation.
- t.apply();
- onFinish(null /* wct */, null /* wctCB */);
- return;
- }
-
// Play some place-holder fade animations
for (int i = info.getChanges().size() - 1; i >= 0; --i) {
final TransitionInfo.Change change = info.getChanges().get(i);
@@ -260,10 +261,6 @@
return mPendingEnter != null && mPendingEnter.mTransition == transition;
}
- boolean isPendingRecent(IBinder transition) {
- return mPendingRecent != null && mPendingRecent.mTransition == transition;
- }
-
boolean isPendingDismiss(IBinder transition) {
return mPendingDismiss != null && mPendingDismiss.mTransition == transition;
}
@@ -276,8 +273,6 @@
private TransitSession getPendingTransition(IBinder transition) {
if (isPendingEnter(transition)) {
return mPendingEnter;
- } else if (isPendingRecent(transition)) {
- return mPendingRecent;
} else if (isPendingDismiss(transition)) {
return mPendingDismiss;
} else if (isPendingResize(transition)) {
@@ -311,14 +306,8 @@
@Nullable RemoteTransition remoteTransition,
@Nullable TransitionConsumedCallback consumedCallback,
@Nullable TransitionFinishedCallback finishedCallback) {
- mPendingEnter = new TransitSession(transition, consumedCallback, finishedCallback);
-
- if (remoteTransition != null) {
- // Wrapping it for ease-of-use (OneShot handles all the binder linking/death stuff)
- mPendingRemoteHandler = new OneShotRemoteHandler(
- mTransitions.getMainExecutor(), remoteTransition);
- mPendingRemoteHandler.setTransition(transition);
- }
+ mPendingEnter = new TransitSession(
+ transition, consumedCallback, finishedCallback, remoteTransition);
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " splitTransition "
+ " deduced Enter split screen");
@@ -344,7 +333,7 @@
/** Sets a transition to dismiss split. */
void setDismissTransition(@NonNull IBinder transition, @SplitScreen.StageType int dismissTop,
@SplitScreenController.ExitReason int reason) {
- mPendingDismiss = new DismissTransition(transition, reason, dismissTop);
+ mPendingDismiss = new DismissSession(transition, reason, dismissTop);
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " splitTransition "
+ " deduced Dismiss due to %s. toTop=%s",
@@ -372,32 +361,10 @@
+ " deduced Resize split screen");
}
- void setRecentTransition(@NonNull IBinder transition,
- @Nullable RemoteTransition remoteTransition,
- @Nullable TransitionFinishedCallback finishCallback) {
- mPendingRecent = new TransitSession(transition, null /* consumedCb */, finishCallback);
-
- if (remoteTransition != null) {
- // Wrapping it for ease-of-use (OneShot handles all the binder linking/death stuff)
- mPendingRemoteHandler = new OneShotRemoteHandler(
- mTransitions.getMainExecutor(), remoteTransition);
- mPendingRemoteHandler.setTransition(transition);
- }
-
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " splitTransition "
- + " deduced Enter recent panel");
- }
-
void mergeAnimation(IBinder transition, TransitionInfo info, SurfaceControl.Transaction t,
IBinder mergeTarget, Transitions.TransitionFinishCallback finishCallback) {
if (mergeTarget != mAnimatingTransition) return;
- if (isPendingEnter(transition) && isPendingRecent(mergeTarget)) {
- // Since there's an entering transition merged, recent transition no longer
- // need to handle entering split screen after the transition finished.
- mPendingRecent.setFinishedCallback(null);
- }
-
if (mActiveRemoteHandler != null) {
mActiveRemoteHandler.mergeAnimation(transition, info, t, mergeTarget, finishCallback);
} else {
@@ -425,19 +392,13 @@
// An entering transition got merged, appends the rest operations to finish entering
// split screen.
mStageCoordinator.finishEnterSplitScreen(finishT);
- mPendingRemoteHandler = null;
}
mPendingEnter.onConsumed(aborted);
mPendingEnter = null;
- mPendingRemoteHandler = null;
} else if (isPendingDismiss(transition)) {
mPendingDismiss.onConsumed(aborted);
mPendingDismiss = null;
- } else if (isPendingRecent(transition)) {
- mPendingRecent.onConsumed(aborted);
- mPendingRecent = null;
- mPendingRemoteHandler = null;
} else if (isPendingResize(transition)) {
mPendingResize.onConsumed(aborted);
mPendingResize = null;
@@ -451,9 +412,6 @@
if (isPendingEnter(mAnimatingTransition)) {
mPendingEnter.onFinished(wct, mFinishTransaction);
mPendingEnter = null;
- } else if (isPendingRecent(mAnimatingTransition)) {
- mPendingRecent.onFinished(wct, mFinishTransaction);
- mPendingRecent = null;
} else if (isPendingDismiss(mAnimatingTransition)) {
mPendingDismiss.onFinished(wct, mFinishTransaction);
mPendingDismiss = null;
@@ -462,7 +420,6 @@
mPendingResize = null;
}
- mPendingRemoteHandler = null;
mActiveRemoteHandler = null;
mAnimatingTransition = null;
@@ -568,10 +525,11 @@
}
/** Session for a transition and its clean-up callback. */
- static class TransitSession {
+ class TransitSession {
final IBinder mTransition;
TransitionConsumedCallback mConsumedCallback;
TransitionFinishedCallback mFinishedCallback;
+ OneShotRemoteHandler mRemoteHandler;
/** Whether the transition was canceled. */
boolean mCanceled;
@@ -579,10 +537,24 @@
TransitSession(IBinder transition,
@Nullable TransitionConsumedCallback consumedCallback,
@Nullable TransitionFinishedCallback finishedCallback) {
+ this(transition, consumedCallback, finishedCallback, null /* remoteTransition */);
+ }
+
+ TransitSession(IBinder transition,
+ @Nullable TransitionConsumedCallback consumedCallback,
+ @Nullable TransitionFinishedCallback finishedCallback,
+ @Nullable RemoteTransition remoteTransition) {
mTransition = transition;
mConsumedCallback = consumedCallback;
mFinishedCallback = finishedCallback;
+ if (remoteTransition != null) {
+ // Wrapping the remote transition for ease-of-use. (OneShot handles all the binder
+ // linking/death stuff)
+ mRemoteHandler = new OneShotRemoteHandler(
+ mTransitions.getMainExecutor(), remoteTransition);
+ mRemoteHandler.setTransition(transition);
+ }
}
/** Sets transition consumed callback. */
@@ -621,11 +593,11 @@
}
/** Bundled information of dismiss transition. */
- static class DismissTransition extends TransitSession {
+ class DismissSession extends TransitSession {
final int mReason;
final @SplitScreen.StageType int mDismissTop;
- DismissTransition(IBinder transition, int reason, int dismissTop) {
+ DismissSession(IBinder transition, int reason, int dismissTop) {
super(transition, null /* consumedCallback */, null /* finishedCallback */);
this.mReason = reason;
this.mDismissTop = dismissTop;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index c616587..dd91a37 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -2226,15 +2226,9 @@
} else if (isOpening && inFullscreen) {
final int activityType = triggerTask.getActivityType();
if (activityType == ACTIVITY_TYPE_HOME || activityType == ACTIVITY_TYPE_RECENTS) {
- if (request.getRemoteTransition() != null) {
- // starting recents/home, so don't handle this and let it fall-through to
- // the remote handler.
- return null;
- }
- // Need to use the old stuff for non-remote animations, otherwise we don't
- // exit split-screen.
- mSplitTransitions.setRecentTransition(transition, null /* remote */,
- this::onRecentsInSplitAnimationFinish);
+ // starting recents/home, so don't handle this and let it fall-through to
+ // the remote handler.
+ return null;
}
}
} else {
@@ -2363,8 +2357,6 @@
if (mSplitTransitions.isPendingEnter(transition)) {
shouldAnimate = startPendingEnterAnimation(
transition, info, startTransaction, finishTransaction);
- } else if (mSplitTransitions.isPendingRecent(transition)) {
- onRecentsInSplitAnimationStart(startTransaction);
} else if (mSplitTransitions.isPendingDismiss(transition)) {
shouldAnimate = startPendingDismissAnimation(
mSplitTransitions.mPendingDismiss, info, startTransaction, finishTransaction);
@@ -2589,7 +2581,7 @@
}
private boolean startPendingDismissAnimation(
- @NonNull SplitScreenTransitions.DismissTransition dismissTransition,
+ @NonNull SplitScreenTransitions.DismissSession dismissTransition,
@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction t,
@NonNull SurfaceControl.Transaction finishT) {
prepareDismissAnimation(dismissTransition.mDismissTop, dismissTransition.mReason, info,
@@ -2626,7 +2618,7 @@
/** Call this when the recents animation during split-screen finishes. */
public void onRecentsInSplitAnimationFinish(WindowContainerTransaction finishWct,
- SurfaceControl.Transaction finishT) {
+ SurfaceControl.Transaction finishT, TransitionInfo info) {
// Check if the recent transition is finished by returning to the current
// split, so we can restore the divider bar.
for (int i = 0; i < finishWct.getHierarchyOps().size(); ++i) {
@@ -2643,8 +2635,14 @@
}
}
+ // TODO(b/275664132): Remove dismissing split screen here to fit in back-to-split support.
// Dismiss the split screen if it's not returning to split.
prepareExitSplitScreen(STAGE_TYPE_UNDEFINED, finishWct);
+ for (TransitionInfo.Change change : info.getChanges()) {
+ if (change.getTaskInfo() != null && TransitionUtil.isClosingType(change.getMode())) {
+ finishT.setCrop(change.getLeash(), null).hide(change.getLeash());
+ }
+ }
setSplitsVisible(false);
setDividerVisibility(false, finishT);
logExit(EXIT_REASON_UNKNOWN);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
index 646d55e..36c9077 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
@@ -387,8 +387,15 @@
return;
}
// Sync Transactions can't operate simultaneously with shell transition collection.
- // The transition animation (upon showing) will sync the location itself.
- if (isUsingShellTransitions() && mTaskViewTransitions.hasPending()) return;
+ if (isUsingShellTransitions()) {
+ if (mTaskViewTransitions.hasPending()) {
+ // There is already a transition in-flight. The window bounds will be synced
+ // once it is complete.
+ return;
+ }
+ mTaskViewTransitions.setTaskBounds(this, boundsOnScreen);
+ return;
+ }
WindowContainerTransaction wct = new WindowContainerTransaction();
wct.setBounds(mTaskToken, boundsOnScreen);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java
index 9b995c5..3b1ce49 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java
@@ -16,6 +16,7 @@
package com.android.wm.shell.taskview;
+import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
@@ -23,6 +24,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
+import android.graphics.Rect;
import android.os.IBinder;
import android.util.Slog;
import android.view.SurfaceControl;
@@ -40,7 +42,7 @@
* Handles Shell Transitions that involve TaskView tasks.
*/
public class TaskViewTransitions implements Transitions.TransitionHandler {
- private static final String TAG = "TaskViewTransitions";
+ static final String TAG = "TaskViewTransitions";
private final ArrayList<TaskViewTaskController> mTaskViews = new ArrayList<>();
private final ArrayList<PendingTransition> mPending = new ArrayList<>();
@@ -197,6 +199,13 @@
// visibility is reported in transition.
}
+ void setTaskBounds(TaskViewTaskController taskView, Rect boundsOnScreen) {
+ WindowContainerTransaction wct = new WindowContainerTransaction();
+ wct.setBounds(taskView.getTaskInfo().token, boundsOnScreen);
+ mPending.add(new PendingTransition(TRANSIT_CHANGE, wct, taskView, null /* cookie */));
+ startNextTransition();
+ }
+
private void startNextTransition() {
if (mPending.isEmpty()) return;
final PendingTransition pending = mPending.get(0);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
index 586cab0..d52abf7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
@@ -187,17 +187,18 @@
&& isOpeningType(request.getType())
&& request.getTriggerTask() != null
&& request.getTriggerTask().getWindowingMode() == WINDOWING_MODE_FULLSCREEN
- && (request.getTriggerTask().getActivityType() == ACTIVITY_TYPE_HOME
- || request.getTriggerTask().getActivityType() == ACTIVITY_TYPE_RECENTS)
- && request.getRemoteTransition() != null) {
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Got a recents request while "
+ && request.getTriggerTask().getActivityType() == ACTIVITY_TYPE_HOME) {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Got a going-home request while "
+ "Split-Screen is active, so treat it as Mixed.");
Pair<Transitions.TransitionHandler, WindowContainerTransaction> handler =
mPlayer.dispatchRequest(transition, request, this);
if (handler == null) {
- android.util.Log.e(Transitions.TAG, " No handler for remote? This is unexpected"
- + ", there should at-least be RemoteHandler.");
- return null;
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
+ " Lean on the remote transition handler to fetch a proper remote via"
+ + " TransitionFilter");
+ handler = new Pair<>(
+ mPlayer.getRemoteTransitionHandler(),
+ new WindowContainerTransaction());
}
final MixedTransition mixed = new MixedTransition(
MixedTransition.TYPE_RECENTS_DURING_SPLIT, transition);
@@ -515,7 +516,7 @@
// If pair-to-pair switching, the post-recents clean-up isn't needed.
if (mixed.mAnimType != MixedTransition.ANIM_TYPE_PAIR_TO_PAIR) {
wct = wct != null ? wct : new WindowContainerTransaction();
- mSplitHandler.onRecentsInSplitAnimationFinish(wct, finishTransaction);
+ mSplitHandler.onRecentsInSplitAnimationFinish(wct, finishTransaction, info);
}
mSplitHandler.onTransitionAnimationComplete();
finishCallback.onTransitionFinished(wct, wctCB);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
index beabf18..4284993 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
@@ -324,6 +324,10 @@
mRemoteTransitionHandler.removeFiltered(remoteTransition);
}
+ RemoteTransitionHandler getRemoteTransitionHandler() {
+ return mRemoteTransitionHandler;
+ }
+
/** Registers an observer on the lifecycle of transitions. */
public void registerObserver(@NonNull TransitionObserver observer) {
mObservers.add(observer);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index c45e3fc..e08d40d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -17,11 +17,15 @@
package com.android.wm.shell.windowdecor;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
+import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Point;
@@ -34,7 +38,8 @@
import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewConfiguration;
-import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.window.WindowContainerTransaction;
@@ -71,17 +76,17 @@
private DragDetector mDragDetector;
private RelayoutParams mRelayoutParams = new RelayoutParams();
- private final int mCaptionMenuHeightId = R.dimen.freeform_decor_caption_menu_height;
- private final int mCaptionMenuHeightWithoutWindowingControlsId =
- R.dimen.freeform_decor_caption_menu_height_no_windowing_controls;
private final WindowDecoration.RelayoutResult<WindowDecorLinearLayout> mResult =
new WindowDecoration.RelayoutResult<>();
- private AdditionalWindow mHandleMenu;
- private final int mHandleMenuWidthId = R.dimen.freeform_decor_caption_menu_width;
- private final int mHandleMenuShadowRadiusId = R.dimen.caption_menu_shadow_radius;
- private final int mHandleMenuCornerRadiusId = R.dimen.caption_menu_corner_radius;
- private PointF mHandleMenuPosition = new PointF();
+ private final PointF mHandleMenuAppInfoPillPosition = new PointF();
+ private final PointF mHandleMenuWindowingPillPosition = new PointF();
+ private final PointF mHandleMenuMoreActionsPillPosition = new PointF();
+
+ // Collection of additional windows that comprise the handle menu.
+ private AdditionalWindow mHandleMenuAppInfoPill;
+ private AdditionalWindow mHandleMenuWindowingPill;
+ private AdditionalWindow mHandleMenuMoreActionsPill;
private Drawable mAppIcon;
private CharSequence mAppName;
@@ -234,30 +239,8 @@
mResult.mWidth, mResult.mHeight, resize_handle, resize_corner, touchSlop);
}
- private void setupHandleMenu() {
- final View menu = mHandleMenu.mWindowViewHost.getView();
- final View fullscreen = menu.findViewById(R.id.fullscreen_button);
- fullscreen.setOnClickListener(mOnCaptionButtonClickListener);
- final View desktop = menu.findViewById(R.id.desktop_button);
- desktop.setOnClickListener(mOnCaptionButtonClickListener);
- final ViewGroup windowingBtns = menu.findViewById(R.id.windowing_mode_buttons);
- windowingBtns.setVisibility(DesktopModeStatus.isProto1Enabled() ? View.GONE : View.VISIBLE);
- final View split = menu.findViewById(R.id.split_screen_button);
- split.setOnClickListener(mOnCaptionButtonClickListener);
- final View close = menu.findViewById(R.id.close_button);
- close.setOnClickListener(mOnCaptionButtonClickListener);
- final View collapse = menu.findViewById(R.id.collapse_menu_button);
- collapse.setOnClickListener(mOnCaptionButtonClickListener);
- menu.setOnTouchListener(mOnCaptionTouchListener);
-
- final ImageView appIcon = menu.findViewById(R.id.application_icon);
- final TextView appName = menu.findViewById(R.id.application_name);
- appIcon.setImageDrawable(mAppIcon);
- appName.setText(mAppName);
- }
-
boolean isHandleMenuActive() {
- return mHandleMenu != null;
+ return mHandleMenuAppInfoPill != null;
}
private void loadAppInfo() {
@@ -291,34 +274,142 @@
final Resources resources = mDecorWindowContext.getResources();
final int captionWidth = mTaskInfo.getConfiguration()
.windowConfiguration.getBounds().width();
- final int menuWidth = loadDimensionPixelSize(resources, mHandleMenuWidthId);
- // The windowing controls are disabled in proto1.
- final int menuHeight = loadDimensionPixelSize(resources, DesktopModeStatus.isProto1Enabled()
- ? mCaptionMenuHeightWithoutWindowingControlsId : mCaptionMenuHeightId);
- final int shadowRadius = loadDimensionPixelSize(resources, mHandleMenuShadowRadiusId);
- final int cornerRadius = loadDimensionPixelSize(resources, mHandleMenuCornerRadiusId);
+ final int menuWidth = loadDimensionPixelSize(resources,
+ R.dimen.desktop_mode_handle_menu_width);
+ final int shadowRadius = loadDimensionPixelSize(resources,
+ R.dimen.desktop_mode_handle_menu_shadow_radius);
+ final int cornerRadius = loadDimensionPixelSize(resources,
+ R.dimen.desktop_mode_handle_menu_corner_radius);
+ final int marginMenuTop = loadDimensionPixelSize(resources,
+ R.dimen.desktop_mode_handle_menu_margin_top);
+ final int marginMenuStart = loadDimensionPixelSize(resources,
+ R.dimen.desktop_mode_handle_menu_margin_start);
+ final int marginMenuSpacing = loadDimensionPixelSize(resources,
+ R.dimen.desktop_mode_handle_menu_pill_spacing_margin);
+ final int appInfoPillHeight = loadDimensionPixelSize(resources,
+ R.dimen.desktop_mode_handle_menu_app_info_pill_height);
+ final int windowingPillHeight = loadDimensionPixelSize(resources,
+ R.dimen.desktop_mode_handle_menu_windowing_pill_height);
+ final int moreActionsPillHeight = loadDimensionPixelSize(resources,
+ R.dimen.desktop_mode_handle_menu_more_actions_pill_height);
- final int x, y;
+ final int menuX, menuY;
if (mRelayoutParams.mLayoutResId
== R.layout.desktop_mode_app_controls_window_decor) {
// Align the handle menu to the left of the caption.
- x = mRelayoutParams.mCaptionX - mResult.mDecorContainerOffsetX;
- y = mRelayoutParams.mCaptionY - mResult.mDecorContainerOffsetY;
+ menuX = mRelayoutParams.mCaptionX - mResult.mDecorContainerOffsetX + marginMenuStart;
+ menuY = mRelayoutParams.mCaptionY - mResult.mDecorContainerOffsetY + marginMenuTop;
} else {
// Position the handle menu at the center of the caption.
- x = mRelayoutParams.mCaptionX + (captionWidth / 2) - (menuWidth / 2)
+ menuX = mRelayoutParams.mCaptionX + (captionWidth / 2) - (menuWidth / 2)
- mResult.mDecorContainerOffsetX;
- y = mRelayoutParams.mCaptionY - mResult.mDecorContainerOffsetY;
+ menuY = mRelayoutParams.mCaptionY - mResult.mDecorContainerOffsetY + marginMenuStart;
}
- mHandleMenuPosition.set(x, y);
- final String namePrefix = "Caption Menu";
- mHandleMenu = addWindow(R.layout.desktop_mode_decor_handle_menu, namePrefix, t, x, y,
- menuWidth, menuHeight, shadowRadius, cornerRadius);
+
+ final int appInfoPillY = menuY;
+ createAppInfoPill(t, menuX, appInfoPillY, menuWidth, appInfoPillHeight, shadowRadius,
+ cornerRadius);
+
+ // Only show windowing buttons in proto2. Proto1 uses a system-level mode only.
+ final boolean shouldShowWindowingPill = DesktopModeStatus.isProto2Enabled();
+ final int windowingPillY = appInfoPillY + appInfoPillHeight + marginMenuSpacing;
+ if (shouldShowWindowingPill) {
+ createWindowingPill(t, menuX, windowingPillY, menuWidth, windowingPillHeight,
+ shadowRadius,
+ cornerRadius);
+ }
+
+ final int moreActionsPillY;
+ if (shouldShowWindowingPill) {
+ // Take into account the windowing pill height and margins.
+ moreActionsPillY = windowingPillY + windowingPillHeight + marginMenuSpacing;
+ } else {
+ // Just start after the end of the app info pill + margins.
+ moreActionsPillY = appInfoPillY + appInfoPillHeight + marginMenuSpacing;
+ }
+ createMoreActionsPill(t, menuX, moreActionsPillY, menuWidth, moreActionsPillHeight,
+ shadowRadius, cornerRadius);
+
mSyncQueue.runInSync(transaction -> {
transaction.merge(t);
t.close();
});
- setupHandleMenu();
+ setupHandleMenu(shouldShowWindowingPill);
+ }
+
+ private void createAppInfoPill(SurfaceControl.Transaction t, int x, int y, int width,
+ int height, int shadowRadius, int cornerRadius) {
+ mHandleMenuAppInfoPillPosition.set(x, y);
+ mHandleMenuAppInfoPill = addWindow(
+ R.layout.desktop_mode_window_decor_handle_menu_app_info_pill,
+ "Menu's app info pill",
+ t, x, y, width, height, shadowRadius, cornerRadius);
+ }
+
+ private void createWindowingPill(SurfaceControl.Transaction t, int x, int y, int width,
+ int height, int shadowRadius, int cornerRadius) {
+ mHandleMenuWindowingPillPosition.set(x, y);
+ mHandleMenuWindowingPill = addWindow(
+ R.layout.desktop_mode_window_decor_handle_menu_windowing_pill,
+ "Menu's windowing pill",
+ t, x, y, width, height, shadowRadius, cornerRadius);
+ }
+
+ private void createMoreActionsPill(SurfaceControl.Transaction t, int x, int y, int width,
+ int height, int shadowRadius, int cornerRadius) {
+ mHandleMenuMoreActionsPillPosition.set(x, y);
+ mHandleMenuMoreActionsPill = addWindow(
+ R.layout.desktop_mode_window_decor_handle_menu_more_actions_pill,
+ "Menu's more actions pill",
+ t, x, y, width, height, shadowRadius, cornerRadius);
+ }
+
+ private void setupHandleMenu(boolean windowingPillShown) {
+ // App Info pill setup.
+ final View appInfoPillView = mHandleMenuAppInfoPill.mWindowViewHost.getView();
+ final ImageButton collapseBtn = appInfoPillView.findViewById(R.id.collapse_menu_button);
+ final ImageView appIcon = appInfoPillView.findViewById(R.id.application_icon);
+ final TextView appName = appInfoPillView.findViewById(R.id.application_name);
+ collapseBtn.setOnClickListener(mOnCaptionButtonClickListener);
+ appInfoPillView.setOnTouchListener(mOnCaptionTouchListener);
+ appIcon.setImageDrawable(mAppIcon);
+ appName.setText(mAppName);
+
+ // Windowing pill setup.
+ if (windowingPillShown) {
+ final View windowingPillView = mHandleMenuWindowingPill.mWindowViewHost.getView();
+ final ImageButton fullscreenBtn = windowingPillView.findViewById(
+ R.id.fullscreen_button);
+ final ImageButton splitscreenBtn = windowingPillView.findViewById(
+ R.id.split_screen_button);
+ final ImageButton floatingBtn = windowingPillView.findViewById(R.id.floating_button);
+ final ImageButton desktopBtn = windowingPillView.findViewById(R.id.desktop_button);
+ fullscreenBtn.setOnClickListener(mOnCaptionButtonClickListener);
+ splitscreenBtn.setOnClickListener(mOnCaptionButtonClickListener);
+ floatingBtn.setOnClickListener(mOnCaptionButtonClickListener);
+ desktopBtn.setOnClickListener(mOnCaptionButtonClickListener);
+ // The button corresponding to the windowing mode that the task is currently in uses a
+ // different color than the others.
+ final ColorStateList activeColorStateList = ColorStateList.valueOf(
+ mContext.getColor(R.color.desktop_mode_caption_menu_buttons_color_active));
+ final ColorStateList inActiveColorStateList = ColorStateList.valueOf(
+ mContext.getColor(R.color.desktop_mode_caption_menu_buttons_color_inactive));
+ fullscreenBtn.setImageTintList(
+ mTaskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
+ ? activeColorStateList : inActiveColorStateList);
+ splitscreenBtn.setImageTintList(
+ mTaskInfo.getWindowingMode() == WINDOWING_MODE_MULTI_WINDOW
+ ? activeColorStateList : inActiveColorStateList);
+ floatingBtn.setImageTintList(mTaskInfo.getWindowingMode() == WINDOWING_MODE_PINNED
+ ? activeColorStateList : inActiveColorStateList);
+ desktopBtn.setImageTintList(mTaskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM
+ ? activeColorStateList : inActiveColorStateList);
+ }
+
+ // More Actions pill setup.
+ final View moreActionsPillView = mHandleMenuMoreActionsPill.mWindowViewHost.getView();
+ final Button closeBtn = moreActionsPillView.findViewById(R.id.close_button);
+ closeBtn.setOnClickListener(mOnCaptionButtonClickListener);
}
/**
@@ -326,8 +417,14 @@
*/
void closeHandleMenu() {
if (!isHandleMenuActive()) return;
- mHandleMenu.releaseView();
- mHandleMenu = null;
+ mHandleMenuAppInfoPill.releaseView();
+ mHandleMenuAppInfoPill = null;
+ if (mHandleMenuWindowingPill != null) {
+ mHandleMenuWindowingPill.releaseView();
+ mHandleMenuWindowingPill = null;
+ }
+ mHandleMenuMoreActionsPill.releaseView();
+ mHandleMenuMoreActionsPill = null;
}
@Override
@@ -346,12 +443,29 @@
// When this is called before the layout is fully inflated, width will be 0.
// Menu is not visible in this scenario, so skip the check if that is the case.
- if (mHandleMenu.mWindowViewHost.getView().getWidth() == 0) return;
+ if (mHandleMenuAppInfoPill.mWindowViewHost.getView().getWidth() == 0) return;
PointF inputPoint = offsetCaptionLocation(ev);
- if (!pointInView(mHandleMenu.mWindowViewHost.getView(),
- inputPoint.x - mHandleMenuPosition.x - mResult.mDecorContainerOffsetX,
- inputPoint.y - mHandleMenuPosition.y - mResult.mDecorContainerOffsetY)) {
+ final boolean pointInAppInfoPill = pointInView(
+ mHandleMenuAppInfoPill.mWindowViewHost.getView(),
+ inputPoint.x - mHandleMenuAppInfoPillPosition.x - mResult.mDecorContainerOffsetX,
+ inputPoint.y - mHandleMenuAppInfoPillPosition.y
+ - mResult.mDecorContainerOffsetY);
+ boolean pointInWindowingPill = false;
+ if (mHandleMenuWindowingPill != null) {
+ pointInWindowingPill = pointInView(mHandleMenuWindowingPill.mWindowViewHost.getView(),
+ inputPoint.x - mHandleMenuWindowingPillPosition.x
+ - mResult.mDecorContainerOffsetX,
+ inputPoint.y - mHandleMenuWindowingPillPosition.y
+ - mResult.mDecorContainerOffsetY);
+ }
+ final boolean pointInMoreActionsPill = pointInView(
+ mHandleMenuMoreActionsPill.mWindowViewHost.getView(),
+ inputPoint.x - mHandleMenuMoreActionsPillPosition.x
+ - mResult.mDecorContainerOffsetX,
+ inputPoint.y - mHandleMenuMoreActionsPillPosition.y
+ - mResult.mDecorContainerOffsetY);
+ if (!pointInAppInfoPill && !pointInWindowingPill && !pointInMoreActionsPill) {
closeHandleMenu();
}
}
@@ -408,14 +522,13 @@
final View handle = caption.findViewById(R.id.caption_handle);
clickIfPointInView(new PointF(ev.getX(), ev.getY()), handle);
} else {
- final View menu = mHandleMenu.mWindowViewHost.getView();
- final int captionWidth = mTaskInfo.getConfiguration().windowConfiguration
- .getBounds().width();
- final int menuX = mRelayoutParams.mCaptionX + (captionWidth / 2)
- - (menu.getWidth() / 2);
- final PointF inputPoint = new PointF(ev.getX() - menuX, ev.getY());
- final View collapse = menu.findViewById(R.id.collapse_menu_button);
- if (clickIfPointInView(inputPoint, collapse)) return;
+ final View appInfoPill = mHandleMenuAppInfoPill.mWindowViewHost.getView();
+ final ImageButton collapse = appInfoPill.findViewById(R.id.collapse_menu_button);
+ // Translate the input point from display coordinates to the same space as the collapse
+ // button, meaning its parent (app info pill view).
+ final PointF inputPoint = new PointF(ev.getX() - mHandleMenuAppInfoPillPosition.x,
+ ev.getY() - mHandleMenuAppInfoPillPosition.y);
+ clickIfPointInView(inputPoint, collapse);
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
index bd2ffc1..2e81b30 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
@@ -71,7 +71,7 @@
// TODO(b/245472831): Move back to presubmit after shell transitions landing.
@FlakyTest(bugId = 245472831)
@Test
- fun secondaryAppLayerBecomesInvisible() = flicker.layerBecomesInvisible(primaryApp)
+ fun secondaryAppLayerBecomesInvisible() = flicker.layerBecomesInvisible(secondaryApp)
// TODO(b/245472831): Move back to presubmit after shell transitions landing.
@FlakyTest(bugId = 245472831)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
index df78d92..1b29146 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
@@ -278,7 +278,7 @@
// Make sure it cleans-up if recents doesn't restore
WindowContainerTransaction commitWCT = new WindowContainerTransaction();
mStageCoordinator.onRecentsInSplitAnimationFinish(commitWCT,
- mock(SurfaceControl.Transaction.class));
+ mock(SurfaceControl.Transaction.class), mock(TransitionInfo.class));
assertFalse(mStageCoordinator.isSplitScreenVisible());
}
@@ -317,7 +317,7 @@
mMainStage.onTaskAppeared(mMainChild, mock(SurfaceControl.class));
mSideStage.onTaskAppeared(mSideChild, mock(SurfaceControl.class));
mStageCoordinator.onRecentsInSplitAnimationFinish(restoreWCT,
- mock(SurfaceControl.Transaction.class));
+ mock(SurfaceControl.Transaction.class), mock(TransitionInfo.class));
assertTrue(mStageCoordinator.isSplitScreenVisible());
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
index c92d2f3..dfa3c10 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
@@ -583,7 +583,7 @@
int cornerRadius = loadDimensionPixelSize(resources, mCaptionMenuCornerRadiusId);
String name = "Test Window";
WindowDecoration.AdditionalWindow additionalWindow =
- addWindow(R.layout.desktop_mode_decor_handle_menu, name,
+ addWindow(R.layout.desktop_mode_window_decor_handle_menu_app_info_pill, name,
mMockSurfaceControlAddWindowT,
x - mRelayoutResult.mDecorContainerOffsetX,
y - mRelayoutResult.mDecorContainerOffsetY,
diff --git a/location/java/android/location/Location.java b/location/java/android/location/Location.java
index f5a9850..9be7728 100644
--- a/location/java/android/location/Location.java
+++ b/location/java/android/location/Location.java
@@ -831,7 +831,9 @@
* will be present for any location.
*
* <ul>
- * <li> satellites - the number of satellites used to derive a GNSS fix
+ * <li> satellites - the number of satellites used to derive a GNSS fix. This key was deprecated
+ * in API 34 because the information can be obtained through more accurate means, such as by
+ * referencing {@link GnssStatus#usedInFix}.
* </ul>
*/
public @Nullable Bundle getExtras() {
diff --git a/packages/CompanionDeviceManager/res/values/strings.xml b/packages/CompanionDeviceManager/res/values/strings.xml
index 82e5a7f..c898fe5 100644
--- a/packages/CompanionDeviceManager/res/values/strings.xml
+++ b/packages/CompanionDeviceManager/res/values/strings.xml
@@ -31,10 +31,10 @@
<string name="chooser_title">Choose a <xliff:g id="profile_name" example="watch">%1$s</xliff:g> to be managed by <strong><xliff:g id="app_name" example="Android Wear">%2$s</xliff:g></strong></string>
<!-- Description of the privileges the application will get if associated with the companion device of WATCH profile (type) [CHAR LIMIT=NONE] -->
- <string name="summary_watch">The app is needed to manage your <xliff:g id="device_name" example="My Watch">%1$s</xliff:g>. <xliff:g id="app_name" example="Android Wear">%2$s</xliff:g> will be allowed to sync info, like the name of someone calling, interact with your notifications and access your Phone, SMS, Contacts, Calendar, Call logs and Nearby devices permissions.</string>
+ <string name="summary_watch">This app is needed to manage your <xliff:g id="device_name" example="My Watch">%1$s</xliff:g>. <xliff:g id="app_name" example="Android Wear">%2$s</xliff:g> will be allowed to sync info, like the name of someone calling, interact with your notifications and access your Phone, SMS, Contacts, Calendar, Call logs and Nearby devices permissions.</string>
<!-- Description of the privileges the application will get if associated with the companion device of WATCH profile for singleDevice(type) [CHAR LIMIT=NONE] -->
- <string name="summary_watch_single_device">The app is needed to manage your <xliff:g id="device_name" example="My Watch">%1$s</xliff:g>. <xliff:g id="app_name" example="Android Wear">%2$s</xliff:g> will be allowed to sync info, like the name of someone calling, and access these permissions:</string>
+ <string name="summary_watch_single_device">This app will be allowed to sync info, like the name of someone calling, and access these permissions</string>
<!-- ================= DEVICE_PROFILE_GLASSES ================= -->
@@ -48,7 +48,7 @@
<string name="summary_glasses_multi_device">This app is needed to manage <xliff:g id="device_name" example="My Glasses">%1$s</xliff:g>. <xliff:g id="app_name" example="Glasses">%2$s</xliff:g> will be allowed to interact with your notifications and access your Phone, SMS, Contacts, Microphone and Nearby devices permissions.</string>
<!-- Description of the privileges the application will get if associated with the companion device of GLASSES profile for singleDevice(type) [CHAR LIMIT=NONE] -->
- <string name="summary_glasses_single_device">This app will be allowed to access these permissions on your phone:</string>
+ <string name="summary_glasses_single_device">This app will be allowed to access these permissions on your phone</string>
<!-- ================= DEVICE_PROFILE_APP_STREAMING ================= -->
@@ -97,10 +97,10 @@
<string name="profile_name_generic">device</string>
<!-- Description of the privileges the application will get if associated with the companion device of unspecified profile (type) [CHAR LIMIT=NONE] -->
- <string name="summary_generic_single_device">This app will be able to sync info, like the name of someone calling, between your phone and <xliff:g id="device_name" example="My Watch">%1$s</xliff:g>.</string>
+ <string name="summary_generic_single_device">This app will be able to sync info, like the name of someone calling, between your phone and <xliff:g id="device_name" example="My Watch">%1$s</xliff:g></string>
<!-- Description of the privileges the application will get if associated with the companion device of unspecified profile (type) [CHAR LIMIT=NONE] -->
- <string name="summary_generic">This app will be able to sync info, like the name of someone calling, between your phone and the chosen device.</string>
+ <string name="summary_generic">This app will be able to sync info, like the name of someone calling, between your phone and the chosen device</string>
<!-- ================= Buttons ================= -->
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
index 71ae578..ae08823 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
@@ -551,8 +551,7 @@
summary = getHtmlFromResources(this, SUMMARIES.get(null), deviceName);
mConstraintList.setVisibility(View.GONE);
} else {
- summary = getHtmlFromResources(this, SUMMARIES.get(deviceProfile),
- getString(PROFILES_NAME.get(deviceProfile)), appLabel);
+ summary = getHtmlFromResources(this, SUMMARIES.get(deviceProfile));
mPermissionTypes.addAll(PERMISSION_TYPES.get(deviceProfile));
setupPermissionList();
}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
index 7b98049..ed4cc95 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
@@ -296,7 +296,11 @@
}
item { Divider(thickness = 24.dp, color = Color.Transparent) }
- item { BodyMediumText(text = stringResource(R.string.choose_provider_body)) }
+ item {
+ Row(modifier = Modifier.fillMaxWidth().wrapContentHeight()) {
+ BodyMediumText(text = stringResource(R.string.choose_provider_body))
+ }
+ }
item { Divider(thickness = 16.dp, color = Color.Transparent) }
item {
CredentialContainerCard {
@@ -444,8 +448,10 @@
}
item { Divider(thickness = 24.dp, color = Color.Transparent) }
item {
- BodyMediumText(text = stringResource(
- R.string.use_provider_for_all_description, entryInfo.userProviderDisplayName))
+ Row(modifier = Modifier.fillMaxWidth().wrapContentHeight()) {
+ BodyMediumText(text = stringResource(
+ R.string.use_provider_for_all_description, entryInfo.userProviderDisplayName))
+ }
}
item { Divider(thickness = 24.dp, color = Color.Transparent) }
item {
@@ -626,25 +632,33 @@
MoreAboutPasskeySectionHeader(
text = stringResource(R.string.passwordless_technology_title)
)
- BodyMediumText(text = stringResource(R.string.passwordless_technology_detail))
+ Row(modifier = Modifier.fillMaxWidth().wrapContentHeight()) {
+ BodyMediumText(text = stringResource(R.string.passwordless_technology_detail))
+ }
}
item {
MoreAboutPasskeySectionHeader(
text = stringResource(R.string.public_key_cryptography_title)
)
- BodyMediumText(text = stringResource(R.string.public_key_cryptography_detail))
+ Row(modifier = Modifier.fillMaxWidth().wrapContentHeight()) {
+ BodyMediumText(text = stringResource(R.string.public_key_cryptography_detail))
+ }
}
item {
MoreAboutPasskeySectionHeader(
text = stringResource(R.string.improved_account_security_title)
)
- BodyMediumText(text = stringResource(R.string.improved_account_security_detail))
+ Row(modifier = Modifier.fillMaxWidth().wrapContentHeight()) {
+ BodyMediumText(text = stringResource(R.string.improved_account_security_detail))
+ }
}
item {
MoreAboutPasskeySectionHeader(
text = stringResource(R.string.seamless_transition_title)
)
- BodyMediumText(text = stringResource(R.string.seamless_transition_detail))
+ Row(modifier = Modifier.fillMaxWidth().wrapContentHeight()) {
+ BodyMediumText(text = stringResource(R.string.seamless_transition_detail))
+ }
}
}
onLog(CreateCredentialEvent.CREDMAN_CREATE_CRED_MORE_ABOUT_PASSKEYS_INTRO)
diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml
index 11b4d79..2143fc4 100644
--- a/packages/SystemUI/res-keyguard/values/strings.xml
+++ b/packages/SystemUI/res-keyguard/values/strings.xml
@@ -21,12 +21,21 @@
<!-- Instructions telling the user to enter their PIN password to unlock the keyguard [CHAR LIMIT=30] -->
<string name="keyguard_enter_your_pin">Enter your PIN</string>
+ <!-- Instructions telling the user to enter their PIN password to unlock the keyguard [CHAR LIMIT=26] -->
+ <string name="keyguard_enter_pin">Enter PIN</string>
+
<!-- Instructions telling the user to enter their pattern to unlock the keyguard [CHAR LIMIT=30] -->
<string name="keyguard_enter_your_pattern">Enter your pattern</string>
+ <!-- Instructions telling the user to enter their pattern to unlock the keyguard [CHAR LIMIT=26] -->
+ <string name="keyguard_enter_pattern">Draw pattern</string>
+
<!-- Instructions telling the user to enter their text password to unlock the keyguard [CHAR LIMIT=30] -->
<string name="keyguard_enter_your_password">Enter your password</string>
+ <!-- Instructions telling the user to enter their text password to unlock the keyguard [CHAR LIMIT=26] -->
+ <string name="keyguard_enter_password">Enter password</string>
+
<!-- Shown in the lock screen when there is SIM card IO error. -->
<string name="keyguard_sim_error_message_short">Invalid Card.</string>
@@ -118,11 +127,104 @@
<!-- Message shown when user enters wrong pattern -->
<string name="kg_wrong_pattern">Wrong pattern</string>
+
+ <!-- Message shown when user enters wrong pattern [CHAR LIMIT=26] -->
+ <string name="kg_wrong_pattern_try_again">Wrong pattern. Try again.</string>
+
<!-- Message shown when user enters wrong password -->
<string name="kg_wrong_password">Wrong password</string>
+
+ <!-- Message shown when user enters wrong pattern [CHAR LIMIT=26] -->
+ <string name="kg_wrong_password_try_again">Wrong password. Try again.</string>
+
<!-- Message shown when user enters wrong PIN -->
<string name="kg_wrong_pin">Wrong PIN</string>
- <!-- Countdown message shown after too many failed unlock attempts -->
+
+ <!-- Message shown when user enters wrong PIN [CHAR LIMIT=26] -->
+ <string name="kg_wrong_pin_try_again">Wrong PIN. Try again.</string>
+
+ <!-- Message shown when user enters wrong PIN/password/pattern below the main message, for ex: "Wrong PIN. Try again" in line 1 and the following text in line 2. [CHAR LIMIT=52] -->
+ <string name="kg_wrong_input_try_fp_suggestion">Or unlock with fingerprint</string>
+
+ <!-- Message shown when user fingerprint is not recognized [CHAR LIMIT=26] -->
+ <string name="kg_fp_not_recognized">Fingerprint not recognized</string>
+
+ <!-- Message shown when we want the users to try biometric auth again or use pin/pattern/password [CHAR LIMIT=26] -->
+ <string name="bouncer_face_not_recognized">Face not recognized</string>
+
+ <!-- Message shown when we want the users to try biometric auth again or use pin/pattern/password [CHAR LIMIT=52] -->
+ <string name="kg_bio_try_again_or_pin">Try again or enter PIN</string>
+
+ <!-- Message shown when we want the users to try biometric auth again or use pin/pattern/password [CHAR LIMIT=52] -->
+ <string name="kg_bio_try_again_or_password">Try again or enter password</string>
+
+ <!-- Message shown when we want the users to try biometric auth again or use pin/pattern/password [CHAR LIMIT=52] -->
+ <string name="kg_bio_try_again_or_pattern">Try again or draw pattern</string>
+
+ <!-- Message shown when we are on bouncer after temporary lockout of either face or fingerprint [CHAR LIMIT=52] -->
+ <string name="kg_bio_too_many_attempts_pin">PIN is required after too many attempts</string>
+
+ <!-- Message shown when we are on bouncer after temporary lockout of either face or fingerprint [CHAR LIMIT=52] -->
+ <string name="kg_bio_too_many_attempts_password">Password is required after too many attempts</string>
+
+ <!-- Message shown when we are on bouncer after temporary lockout of either face or fingerprint [CHAR LIMIT=52] -->
+ <string name="kg_bio_too_many_attempts_pattern">Pattern is required after too many attempts</string>
+
+ <!-- Instructions when the user can unlock with PIN/password/pattern or fingerprint from bouncer. [CHAR LIMIT=26] -->
+ <string name="kg_unlock_with_pin_or_fp">Unlock with PIN or fingerprint</string>
+
+ <!-- Instructions when the user can unlock with PIN/password/pattern or fingerprint from bouncer. [CHAR LIMIT=26] -->
+ <string name="kg_unlock_with_password_or_fp">Unlock with password or fingerprint</string>
+
+ <!-- Instructions when the user can unlock with PIN/password/pattern or fingerprint from bouncer. [CHAR LIMIT=26] -->
+ <string name="kg_unlock_with_pattern_or_fp">Unlock with pattern or fingerprint</string>
+
+ <!-- Message shown when we are on bouncer after Device admin requested lockdown. [CHAR LIMIT=52] -->
+ <string name="kg_prompt_after_dpm_lock">For added security, device was locked by work policy</string>
+
+ <!-- Message shown for pin/pattern/password when we are on bouncer after user triggered lockdown. [CHAR LIMIT=52] -->
+ <string name="kg_prompt_after_user_lockdown_pin">PIN is required after lockdown</string>
+
+ <!-- Message shown for pin/pattern/password when we are on bouncer after user triggered lockdown. [CHAR LIMIT=52] -->
+ <string name="kg_prompt_after_user_lockdown_password">Password is required after lockdown</string>
+
+ <!-- Message shown for pin/pattern/password when we are on bouncer after user triggered lockdown. [CHAR LIMIT=52] -->
+ <string name="kg_prompt_after_user_lockdown_pattern">Pattern is required after lockdown</string>
+
+ <!-- Message shown to prepare for an unattended update (OTA). Also known as an over-the-air (OTA) update. [CHAR LIMIT=52] -->
+ <string name="kg_prompt_unattended_update">Update will install during inactive hours</string>
+
+ <!-- Message shown when primary authentication hasn't been used for some time. [CHAR LIMIT=52] -->
+ <string name="kg_prompt_pin_auth_timeout">Added security required. PIN not used for a while.</string>
+
+ <!-- Message shown when primary authentication hasn't been used for some time. [CHAR LIMIT=52] -->
+ <string name="kg_prompt_password_auth_timeout">Added security required. Password not used for a while.</string>
+
+ <!-- Message shown when primary authentication hasn't been used for some time. [CHAR LIMIT=52] -->
+ <string name="kg_prompt_pattern_auth_timeout">Added security required. Pattern not used for a while.</string>
+
+ <!-- Message shown when device hasn't been unlocked for a while. [CHAR LIMIT=52] -->
+ <string name="kg_prompt_auth_timeout">Added security required. Device wasn\u2019t unlocked for a while.</string>
+
+ <!-- Message shown when face unlock is not available after too many failed face authentication attempts. [CHAR LIMIT=52] -->
+ <string name="kg_face_locked_out">Can\u2019t unlock with face. Too many attempts.</string>
+
+ <!-- Message shown when fingerprint unlock isn't available after too many failed fingerprint authentication attempts. [CHAR LIMIT=52] -->
+ <string name="kg_fp_locked_out">Can\u2019t unlock with fingerprint. Too many attempts.</string>
+
+ <!-- Message shown when Trust Agent is disabled. [CHAR LIMIT=52] -->
+ <string name="kg_trust_agent_disabled">Trust agent is unavailable</string>
+
+ <!-- Message shown when primary auth is locked out after too many attempts [CHAR LIMIT=52] -->
+ <string name="kg_primary_auth_locked_out_pin">Too many attempts with incorrect PIN</string>
+
+ <!-- Message shown when primary auth is locked out after too many attempts [CHAR LIMIT=52] -->
+ <string name="kg_primary_auth_locked_out_pattern">Too many attempts with incorrect pattern</string>
+
+ <!-- Message shown when primary auth is locked out after too many attempts [CHAR LIMIT=52] -->
+ <string name="kg_primary_auth_locked_out_password">Too many attempts with incorrect password</string>
+
+ <!-- Countdown message shown after too many failed unlock attempts [CHAR LIMIT=26]-->
<string name="kg_too_many_failed_attempts_countdown">{count, plural,
=1 {Try again in # second.}
other {Try again in # seconds.}
@@ -194,14 +296,14 @@
<!-- Description of airplane mode -->
<string name="airplane_mode">Airplane mode</string>
- <!-- An explanation text that the pattern needs to be solved since the device has just been restarted. [CHAR LIMIT=80] -->
- <string name="kg_prompt_reason_restart_pattern">Pattern required after device restarts</string>
+ <!-- An explanation text that the pattern needs to be solved since the device has just been restarted. [CHAR LIMIT=52] -->
+ <string name="kg_prompt_reason_restart_pattern">Pattern is required after device restarts</string>
- <!-- An explanation text that the pin needs to be entered since the device has just been restarted. [CHAR LIMIT=80] -->
- <string name="kg_prompt_reason_restart_pin">PIN required after device restarts</string>
+ <!-- An explanation text that the pin needs to be entered since the device has just been restarted. [CHAR LIMIT=52] -->
+ <string name="kg_prompt_reason_restart_pin">PIN is required after device restarts</string>
- <!-- An explanation text that the password needs to be entered since the device has just been restarted. [CHAR LIMIT=80] -->
- <string name="kg_prompt_reason_restart_password">Password required after device restarts</string>
+ <!-- An explanation text that the password needs to be entered since the device has just been restarted. [CHAR LIMIT=52] -->
+ <string name="kg_prompt_reason_restart_password">Password is required after device restarts</string>
<!-- An explanation text that the pattern needs to be solved since the user hasn't used strong authentication since quite some time. [CHAR LIMIT=80] -->
<string name="kg_prompt_reason_timeout_pattern">For additional security, use pattern instead</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 082ede3..2663ffb 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1553,6 +1553,9 @@
<dimen name="status_bar_user_chip_end_margin">12dp</dimen>
<dimen name="status_bar_user_chip_text_size">12sp</dimen>
+ <!-- System UI Dialog -->
+ <dimen name="dialog_title_text_size">24sp</dimen>
+
<!-- Internet panel related dimensions -->
<dimen name="internet_dialog_list_max_height">662dp</dimen>
<!-- The height of the WiFi network in Internet panel. -->
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index a3655c31..8a86fd5 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -1041,7 +1041,7 @@
<style name="TextAppearance.Dialog.Title" parent="@android:style/TextAppearance.DeviceDefault.Large">
<item name="android:textColor">?android:attr/textColorPrimary</item>
- <item name="android:textSize">24sp</item>
+ <item name="android:textSize">@dimen/dialog_title_text_size</item>
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
<item name="android:lineHeight">32sp</item>
<item name="android:gravity">center</item>
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/fontscaling/FontScalingDialog.kt b/packages/SystemUI/src/com/android/systemui/accessibility/fontscaling/FontScalingDialog.kt
index 1836ce8..c9579d5 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/fontscaling/FontScalingDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/fontscaling/FontScalingDialog.kt
@@ -21,6 +21,7 @@
import android.content.res.Configuration
import android.os.Bundle
import android.provider.Settings
+import android.util.TypedValue
import android.view.LayoutInflater
import android.widget.Button
import android.widget.SeekBar
@@ -49,8 +50,7 @@
private lateinit var seekBarWithIconButtonsView: SeekBarWithIconButtonsView
private var lastProgress: Int = -1
- private val configuration: Configuration =
- Configuration(context.getResources().getConfiguration())
+ private val configuration: Configuration = Configuration(context.resources.configuration)
override fun onCreate(savedInstanceState: Bundle?) {
setTitle(R.string.font_scaling_dialog_title)
@@ -84,31 +84,45 @@
seekBarWithIconButtonsView.setOnSeekBarChangeListener(
object : OnSeekBarChangeListener {
+ var isTrackingTouch = false
+
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
- if (progress != lastProgress) {
- if (!fontSizeHasBeenChangedFromTile) {
- backgroundExecutor.execute { updateSecureSettingsIfNeeded() }
- fontSizeHasBeenChangedFromTile = true
- }
-
- backgroundExecutor.execute { updateFontScale(strEntryValues[progress]) }
-
- lastProgress = progress
+ if (!isTrackingTouch) {
+ // The seekbar progress is changed by icon buttons
+ changeFontSize(progress)
+ } else {
+ // Provide preview configuration for text instead of changing the system
+ // font scale before users release their finger from the seekbar.
+ createTextPreview(progress)
}
}
override fun onStartTrackingTouch(seekBar: SeekBar) {
- // Do nothing
+ isTrackingTouch = true
}
override fun onStopTrackingTouch(seekBar: SeekBar) {
- // Do nothing
+ isTrackingTouch = false
+ changeFontSize(seekBar.progress)
}
}
)
doneButton.setOnClickListener { dismiss() }
}
+ private fun changeFontSize(progress: Int) {
+ if (progress != lastProgress) {
+ if (!fontSizeHasBeenChangedFromTile) {
+ backgroundExecutor.execute { updateSecureSettingsIfNeeded() }
+ fontSizeHasBeenChangedFromTile = true
+ }
+
+ backgroundExecutor.execute { updateFontScale(strEntryValues[progress]) }
+
+ lastProgress = progress
+ }
+ }
+
private fun fontSizeValueToIndex(value: Float): Int {
var lastValue = strEntryValues[0].toFloat()
for (i in 1 until strEntryValues.size) {
@@ -153,6 +167,20 @@
}
}
+ /** Provides font size preview for text before putting the final settings to the system. */
+ fun createTextPreview(index: Int) {
+ val previewConfig = Configuration(configuration)
+ previewConfig.fontScale = strEntryValues[index].toFloat()
+
+ val previewConfigContext = context.createConfigurationContext(previewConfig)
+ previewConfigContext.theme.setTo(context.theme)
+
+ title.setTextSize(
+ TypedValue.COMPLEX_UNIT_PX,
+ previewConfigContext.resources.getDimension(R.dimen.dialog_title_text_size)
+ )
+ }
+
companion object {
private const val ON = "1"
private const val OFF = "0"
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.kt
index 3e7d81a..063b41e 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.kt
@@ -390,11 +390,14 @@
return true
}
- // Only pause auth if we're not on the keyguard AND we're not transitioning to doze
- // (ie: dozeAmount = 0f). For the UnlockedScreenOffAnimation, the statusBarState is
+ // Only pause auth if we're not on the keyguard AND we're not transitioning to doze.
+ // For the UnlockedScreenOffAnimation, the statusBarState is
// delayed. However, we still animate in the UDFPS affordance with the
- // mUnlockedScreenOffDozeAnimator.
- if (statusBarState != StatusBarState.KEYGUARD && lastDozeAmount == 0f) {
+ // unlockedScreenOffDozeAnimator.
+ if (
+ statusBarState != StatusBarState.KEYGUARD &&
+ !unlockedScreenOffAnimationController.isAnimationPlaying()
+ ) {
return true
}
if (isBouncerExpansionGreaterThan(.5f)) {
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index ff4a252..27f35db 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -285,7 +285,7 @@
/** Enables Font Scaling Quick Settings tile */
// TODO(b/269341316): Tracking Bug
@JvmField
- val ENABLE_FONT_SCALING_TILE = unreleasedFlag(509, "enable_font_scaling_tile", teamfood = false)
+ val ENABLE_FONT_SCALING_TILE = unreleasedFlag(509, "enable_font_scaling_tile", teamfood = true)
/** Enables new QS Edit Mode visual refresh */
// TODO(b/269787742): Tracking Bug
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
index 0318fa5..2f4cc14 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
@@ -283,11 +283,15 @@
}
mLockIconViewController.onTouchEvent(
ev,
- () -> mService.wakeUpIfDozing(
- mClock.uptimeMillis(),
- mView,
- "LOCK_ICON_TOUCH",
- PowerManager.WAKE_REASON_GESTURE)
+ /* onGestureDetectedRunnable */
+ () -> {
+ mService.userActivity();
+ mService.wakeUpIfDozing(
+ mClock.uptimeMillis(),
+ mView,
+ "LOCK_ICON_TOUCH",
+ PowerManager.WAKE_REASON_GESTURE);
+ }
);
// In case we start outside of the view bounds (below the status bar), we need to
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
index adfea80..eaa1455 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
@@ -37,6 +37,8 @@
import com.android.systemui.statusbar.pipeline.mobile.ui.MobileUiAdapter
import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxyImpl
+import com.android.systemui.statusbar.pipeline.mobile.util.SubscriptionManagerProxy
+import com.android.systemui.statusbar.pipeline.mobile.util.SubscriptionManagerProxyImpl
import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepository
import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepositoryImpl
import com.android.systemui.statusbar.pipeline.wifi.data.repository.RealWifiRepository
@@ -65,8 +67,7 @@
@Binds abstract fun wifiRepository(impl: WifiRepositorySwitcher): WifiRepository
- @Binds
- abstract fun wifiInteractor(impl: WifiInteractorImpl): WifiInteractor
+ @Binds abstract fun wifiInteractor(impl: WifiInteractorImpl): WifiInteractor
@Binds
abstract fun mobileConnectionsRepository(
@@ -78,6 +79,11 @@
@Binds abstract fun mobileMappingsProxy(impl: MobileMappingsProxyImpl): MobileMappingsProxy
@Binds
+ abstract fun subscriptionManagerProxy(
+ impl: SubscriptionManagerProxyImpl
+ ): SubscriptionManagerProxy
+
+ @Binds
abstract fun mobileIconsInteractor(impl: MobileIconsInteractorImpl): MobileIconsInteractor
@Binds
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
index 8c93bf7..45d50c1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
@@ -44,6 +44,7 @@
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository
import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
+import com.android.systemui.statusbar.pipeline.mobile.util.SubscriptionManagerProxy
import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepository
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
@@ -65,6 +66,7 @@
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.withContext
@@ -76,6 +78,7 @@
constructor(
connectivityRepository: ConnectivityRepository,
private val subscriptionManager: SubscriptionManager,
+ private val subscriptionManagerProxy: SubscriptionManagerProxy,
private val telephonyManager: TelephonyManager,
private val logger: MobileInputLogger,
@MobileSummaryLog private val tableLogger: TableLogBuffer,
@@ -195,7 +198,7 @@
override val defaultDataSubId: StateFlow<Int> =
broadcastDispatcher
.broadcastFlow(
- IntentFilter(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)
+ IntentFilter(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED),
) { intent, _ ->
intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, INVALID_SUBSCRIPTION_ID)
}
@@ -204,14 +207,11 @@
tableLogger,
LOGGING_PREFIX,
columnName = "defaultSubId",
- initialValue = SubscriptionManager.getDefaultDataSubscriptionId(),
+ initialValue = INVALID_SUBSCRIPTION_ID,
)
+ .onStart { emit(subscriptionManagerProxy.getDefaultDataSubscriptionId()) }
.onEach { defaultDataSubIdChangeEvent.tryEmit(Unit) }
- .stateIn(
- scope,
- SharingStarted.WhileSubscribed(),
- SubscriptionManager.getDefaultDataSubscriptionId()
- )
+ .stateIn(scope, SharingStarted.WhileSubscribed(), INVALID_SUBSCRIPTION_ID)
private val carrierConfigChangedEvent =
broadcastDispatcher
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/util/SubscriptionManagerProxy.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/util/SubscriptionManagerProxy.kt
new file mode 100644
index 0000000..22d0483
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/util/SubscriptionManagerProxy.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.mobile.util
+
+import android.telephony.SubscriptionManager
+import javax.inject.Inject
+
+interface SubscriptionManagerProxy {
+ fun getDefaultDataSubscriptionId(): Int
+}
+
+/** Injectable proxy class for [SubscriptionManager]'s static methods */
+class SubscriptionManagerProxyImpl @Inject constructor() : SubscriptionManagerProxy {
+ /** The system default data subscription id, or INVALID_SUBSCRIPTION_ID on error */
+ override fun getDefaultDataSubscriptionId() = SubscriptionManager.getDefaultDataSubscriptionId()
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogTest.kt
index eb82956..353a7c3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogTest.kt
@@ -26,6 +26,8 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView
import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.capture
+import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.settings.FakeSettings
import com.android.systemui.util.settings.SecureSettings
import com.android.systemui.util.settings.SystemSettings
@@ -34,6 +36,10 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.Mockito.spy
+import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
private const val ON: Int = 1
@@ -53,6 +59,9 @@
.getResources()
.getStringArray(com.android.settingslib.R.array.entryvalues_font_size)
+ @Captor
+ private lateinit var seekBarChangeCaptor: ArgumentCaptor<SeekBar.OnSeekBarChangeListener>
+
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
@@ -61,7 +70,7 @@
secureSettings = FakeSettings()
backgroundExecutor = FakeExecutor(FakeSystemClock())
fontScalingDialog =
- FontScalingDialog(mContext, systemSettings, secureSettings, backgroundExecutor)
+ spy(FontScalingDialog(mContext, systemSettings, secureSettings, backgroundExecutor))
}
@Test
@@ -70,7 +79,7 @@
val seekBar: SeekBar = fontScalingDialog.findViewById<SeekBar>(R.id.seekbar)!!
val progress: Int = seekBar.getProgress()
- val currentScale = systemSettings.getFloat(Settings.System.FONT_SCALE, /* def = */ 1.0f)
+ val currentScale = systemSettings.getFloat(Settings.System.FONT_SCALE, /* def= */ 1.0f)
assertThat(currentScale).isEqualTo(fontSizeValueArray[progress].toFloat())
@@ -91,7 +100,7 @@
iconEndFrame.performClick()
backgroundExecutor.runAllReady()
- val currentScale = systemSettings.getFloat(Settings.System.FONT_SCALE, /* def = */ 1.0f)
+ val currentScale = systemSettings.getFloat(Settings.System.FONT_SCALE, /* def= */ 1.0f)
assertThat(seekBar.getProgress()).isEqualTo(1)
assertThat(currentScale).isEqualTo(fontSizeValueArray[1].toFloat())
@@ -112,7 +121,7 @@
iconStartFrame.performClick()
backgroundExecutor.runAllReady()
- val currentScale = systemSettings.getFloat(Settings.System.FONT_SCALE, /* def = */ 1.0f)
+ val currentScale = systemSettings.getFloat(Settings.System.FONT_SCALE, /* def= */ 1.0f)
assertThat(seekBar.getProgress()).isEqualTo(fontSizeValueArray.size - 2)
assertThat(currentScale)
.isEqualTo(fontSizeValueArray[fontSizeValueArray.size - 2].toFloat())
@@ -141,4 +150,64 @@
fontScalingDialog.dismiss()
}
+
+ @Test
+ fun dragSeekbar_systemFontSizeSettingsDoesNotChange() {
+ val slider: SeekBarWithIconButtonsView = spy(SeekBarWithIconButtonsView(mContext))
+ whenever(
+ fontScalingDialog.findViewById<SeekBarWithIconButtonsView>(R.id.font_scaling_slider)
+ )
+ .thenReturn(slider)
+ fontScalingDialog.show()
+ verify(slider).setOnSeekBarChangeListener(capture(seekBarChangeCaptor))
+ val seekBar: SeekBar = slider.findViewById(R.id.seekbar)!!
+
+ // Default seekbar progress for font size is 1, simulate dragging to 0 without
+ // releasing the finger.
+ seekBarChangeCaptor.value.onStartTrackingTouch(seekBar)
+ // Update seekbar progress. This will trigger onProgressChanged in the
+ // OnSeekBarChangeListener and the seekbar could get updated progress value
+ // in onStopTrackingTouch.
+ seekBar.progress = 0
+ backgroundExecutor.runAllReady()
+
+ // Verify that the scale of font size remains the default value 1.0f.
+ var systemScale = systemSettings.getFloat(Settings.System.FONT_SCALE, /* def= */ 1.0f)
+ assertThat(systemScale).isEqualTo(1.0f)
+
+ // Simulate releasing the finger from the seekbar.
+ seekBarChangeCaptor.value.onStopTrackingTouch(seekBar)
+ backgroundExecutor.runAllReady()
+
+ // Verify that the scale of font size has been updated.
+ systemScale = systemSettings.getFloat(Settings.System.FONT_SCALE, /* def= */ 1.0f)
+ assertThat(systemScale).isEqualTo(fontSizeValueArray[0].toFloat())
+
+ fontScalingDialog.dismiss()
+ }
+
+ @Test
+ fun dragSeekBar_createTextPreview() {
+ val slider: SeekBarWithIconButtonsView = spy(SeekBarWithIconButtonsView(mContext))
+ whenever(
+ fontScalingDialog.findViewById<SeekBarWithIconButtonsView>(R.id.font_scaling_slider)
+ )
+ .thenReturn(slider)
+ fontScalingDialog.show()
+ verify(slider).setOnSeekBarChangeListener(capture(seekBarChangeCaptor))
+ val seekBar: SeekBar = slider.findViewById(R.id.seekbar)!!
+
+ // Default seekbar progress for font size is 1, simulate dragging to 0 without
+ // releasing the finger
+ seekBarChangeCaptor.value.onStartTrackingTouch(seekBar)
+ seekBarChangeCaptor.value.onProgressChanged(
+ seekBar,
+ /* progress= */ 0,
+ /* fromUser= */ false
+ )
+ backgroundExecutor.runAllReady()
+
+ verify(fontScalingDialog).createTextPreview(/* index= */ 0)
+ fontScalingDialog.dismiss()
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt
index 0b202853..1fdcf7f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt
@@ -34,6 +34,7 @@
import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.validMobileEvent
import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileConnectionsRepositoryImpl
import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
+import com.android.systemui.statusbar.pipeline.mobile.util.FakeSubscriptionManagerProxy
import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepository
import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository
import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository
@@ -89,6 +90,7 @@
private val fakeNetworkEventsFlow = MutableStateFlow<FakeNetworkEventModel?>(null)
private val mobileMappings = FakeMobileMappingsProxy()
+ private val subscriptionManagerProxy = FakeSubscriptionManagerProxy()
private val scope = CoroutineScope(IMMEDIATE)
@@ -117,6 +119,7 @@
MobileConnectionsRepositoryImpl(
connectivityRepository,
subscriptionManager,
+ subscriptionManagerProxy,
telephonyManager,
logger,
summaryLogger,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
index d65277f..ddff17ae 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
@@ -47,6 +47,7 @@
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Factory.Companion.tableBufferLogName
import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
+import com.android.systemui.statusbar.pipeline.mobile.util.FakeSubscriptionManagerProxy
import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlots
import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepository
import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepositoryImpl
@@ -98,6 +99,7 @@
@Mock private lateinit var logBufferFactory: TableLogBufferFactory
private val mobileMappings = FakeMobileMappingsProxy()
+ private val subscriptionManagerProxy = FakeSubscriptionManagerProxy()
private val scope = CoroutineScope(IMMEDIATE)
@@ -179,6 +181,7 @@
MobileConnectionsRepositoryImpl(
connectivityRepository,
subscriptionManager,
+ subscriptionManagerProxy,
telephonyManager,
logger,
summaryLogger,
@@ -662,6 +665,8 @@
var latest: Int? = null
val job = underTest.defaultDataSubId.onEach { latest = it }.launchIn(this)
+ assertThat(latest).isEqualTo(INVALID_SUBSCRIPTION_ID)
+
fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
receiver.onReceive(
context,
@@ -686,6 +691,42 @@
}
@Test
+ fun defaultDataSubId_fetchesInitialValueOnStart() =
+ runBlocking(IMMEDIATE) {
+ subscriptionManagerProxy.defaultDataSubId = 2
+ var latest: Int? = null
+ val job = underTest.defaultDataSubId.onEach { latest = it }.launchIn(this)
+
+ assertThat(latest).isEqualTo(2)
+
+ job.cancel()
+ }
+
+ @Test
+ fun defaultDataSubId_fetchesCurrentOnRestart() =
+ runBlocking(IMMEDIATE) {
+ subscriptionManagerProxy.defaultDataSubId = 2
+ var latest: Int? = null
+ var job = underTest.defaultDataSubId.onEach { latest = it }.launchIn(this)
+
+ assertThat(latest).isEqualTo(2)
+
+ job.cancel()
+
+ // Collectors go away but come back later
+
+ latest = null
+
+ subscriptionManagerProxy.defaultDataSubId = 1
+
+ job = underTest.defaultDataSubId.onEach { latest = it }.launchIn(this)
+
+ assertThat(latest).isEqualTo(1)
+
+ job.cancel()
+ }
+
+ @Test
fun mobileIsDefault_startsAsFalse() {
assertThat(underTest.mobileIsDefault.value).isFalse()
}
@@ -902,6 +943,7 @@
MobileConnectionsRepositoryImpl(
connectivityRepository,
subscriptionManager,
+ subscriptionManagerProxy,
telephonyManager,
logger,
summaryLogger,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeSubscriptionManagerProxy.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeSubscriptionManagerProxy.kt
new file mode 100644
index 0000000..3dc7de6
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeSubscriptionManagerProxy.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.mobile.util
+
+import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
+
+/** Fake of [SubscriptionManagerProxy] for easy testing */
+class FakeSubscriptionManagerProxy(
+ /** Set the default data subId to be returned in [getDefaultDataSubscriptionId] */
+ var defaultDataSubId: Int = INVALID_SUBSCRIPTION_ID
+) : SubscriptionManagerProxy {
+ override fun getDefaultDataSubscriptionId(): Int = defaultDataSubId
+}
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index e0d1c1e..73dbb86a 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -73,6 +73,9 @@
import android.content.pm.UserInfo;
import android.content.res.ObbInfo;
import android.database.ContentObserver;
+import android.media.MediaCodecList;
+import android.media.MediaCodecInfo;
+import android.media.MediaFormat;
import android.net.Uri;
import android.os.BatteryManager;
import android.os.Binder;
@@ -954,10 +957,27 @@
}
}
+ private boolean isHevcDecoderSupported() {
+ MediaCodecList codecList = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+ MediaCodecInfo[] codecInfos = codecList.getCodecInfos();
+ for (MediaCodecInfo codecInfo : codecInfos) {
+ if (codecInfo.isEncoder()) {
+ continue;
+ }
+ String[] supportedTypes = codecInfo.getSupportedTypes();
+ for (String type : supportedTypes) {
+ if (type.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_HEVC)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
private void configureTranscoding() {
// See MediaProvider TranscodeHelper#getBooleanProperty for more information
boolean transcodeEnabled = false;
- boolean defaultValue = true;
+ boolean defaultValue = isHevcDecoderSupported() ? true : false;
if (SystemProperties.getBoolean("persist.sys.fuse.transcode_user_control", false)) {
transcodeEnabled = SystemProperties.getBoolean("persist.sys.fuse.transcode_enabled",
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 153faa7..a3e5820 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -6984,8 +6984,9 @@
mActivityTaskManager.onScreenAwakeChanged(isAwake);
mOomAdjProfiler.onWakefulnessChanged(wakefulness);
mOomAdjuster.onWakefulnessChanged(wakefulness);
+
+ updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_UI_VISIBILITY);
}
- updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_UI_VISIBILITY);
}
}
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 6758581..43063af 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -1359,6 +1359,9 @@
"LE Audio device addr=" + address + " now available").printLog(TAG));
}
+ // Reset LEA suspend state each time a new sink is connected
+ mAudioSystem.setParameters("LeAudioSuspended=false");
+
mConnectedDevices.put(DeviceInfo.makeDeviceListKey(device, address),
new DeviceInfo(device, name, address, AudioSystem.AUDIO_FORMAT_DEFAULT));
mDeviceBroker.postAccessoryPlugMediaUnmute(device);
@@ -1404,6 +1407,9 @@
@GuardedBy("mDevicesLock")
private void makeLeAudioDeviceUnavailableLater(String address, int device, int delayMs) {
+ // prevent any activity on the LEA output to avoid unwanted
+ // reconnection of the sink.
+ mAudioSystem.setParameters("LeAudioSuspended=true");
// the device will be made unavailable later, so consider it disconnected right away
mConnectedDevices.remove(DeviceInfo.makeDeviceListKey(device, address));
// send the delayed message to make the device unavailable later
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 9886faf7..d43687b 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -929,7 +929,7 @@
// Defines the format for the connection "address" for ALSA devices
public static String makeAlsaAddressString(int card, int device) {
- return "card=" + card + ";device=" + device + ";";
+ return "card=" + card + ";device=" + device;
}
public static final class Lifecycle extends SystemService {
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index 2dcdc54..631d7f5 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -493,6 +493,7 @@
mScoAudioState = SCO_STATE_INACTIVE;
broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
AudioSystem.setParameters("A2dpSuspended=false");
+ AudioSystem.setParameters("LeAudioSuspended=false");
mDeviceBroker.setBluetoothScoOn(false, "resetBluetoothSco");
}
diff --git a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
index e48412a..82b4da3 100644
--- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
@@ -103,6 +103,7 @@
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
+import android.util.Pair;
import android.util.TimeUtils;
import com.android.internal.annotations.GuardedBy;
@@ -1396,11 +1397,14 @@
Log.v(TAG, "SV count: " + gnssStatus.getSatelliteCount());
}
+ Set<Pair<Integer, Integer>> satellites = new HashSet<>();
int usedInFixCount = 0;
int maxCn0 = 0;
int meanCn0 = 0;
for (int i = 0; i < gnssStatus.getSatelliteCount(); i++) {
if (gnssStatus.usedInFix(i)) {
+ satellites.add(
+ new Pair<>(gnssStatus.getConstellationType(i), gnssStatus.getSvid(i)));
++usedInFixCount;
if (gnssStatus.getCn0DbHz(i) > maxCn0) {
maxCn0 = (int) gnssStatus.getCn0DbHz(i);
@@ -1413,7 +1417,7 @@
meanCn0 /= usedInFixCount;
}
// return number of sats used in fix instead of total reported
- mLocationExtras.set(usedInFixCount, meanCn0, maxCn0);
+ mLocationExtras.set(satellites.size(), meanCn0, maxCn0);
mGnssMetrics.logSvStatus(gnssStatus);
}
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 1cfcb4e..c9a6c63 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -545,6 +545,7 @@
pw.println(prefix + "mAdjustments=" + mAdjustments);
pw.println(prefix + "shortcut=" + notification.getShortcutId()
+ " found valid? " + (mShortcutInfo != null));
+ pw.println(prefix + "mUserVisOverride=" + getPackageVisibilityOverride());
}
private void dumpNotification(PrintWriter pw, String prefix, Notification notification,
@@ -574,6 +575,7 @@
} else {
pw.println("null");
}
+ pw.println(prefix + "vis=" + notification.visibility);
pw.println(prefix + "contentView=" + formatRemoteViews(notification.contentView));
pw.println(prefix + "bigContentView=" + formatRemoteViews(notification.bigContentView));
pw.println(prefix + "headsUpContentView="
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 2038e79..6b213b7 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -7208,6 +7208,7 @@
* TODO: In the meantime, can this be moved to a schedule call?
* TODO(b/182523293): This should be removed once we finish migration of permission storage.
*/
+ @SuppressWarnings("GuardedBy")
void writeSettingsLPrTEMP(boolean sync) {
snapshotComputer(false);
mPermissionManager.writeLegacyPermissionsTEMP(mSettings.mPermissions);
@@ -7257,6 +7258,10 @@
static boolean isPreapprovalRequestAvailable() {
final long token = Binder.clearCallingIdentity();
try {
+ if (!Resources.getSystem().getBoolean(
+ com.android.internal.R.bool.config_isPreApprovalRequestAvailable)) {
+ return false;
+ }
return DeviceConfig.getBoolean(NAMESPACE_PACKAGE_MANAGER_SERVICE,
PROPERTY_IS_PRE_APPROVAL_REQUEST_AVAILABLE, true /* defaultValue */);
} finally {
diff --git a/services/core/java/com/android/server/powerstats/PowerStatsService.java b/services/core/java/com/android/server/powerstats/PowerStatsService.java
index 1358417..2638f34 100644
--- a/services/core/java/com/android/server/powerstats/PowerStatsService.java
+++ b/services/core/java/com/android/server/powerstats/PowerStatsService.java
@@ -360,7 +360,7 @@
sb.append("ALL");
}
sb.append("[");
- for (int i = 0; i < expectedLength; i++) {
+ for (int i = 0; i < energyConsumerIds.length; i++) {
final int id = energyConsumerIds[i];
sb.append(id);
sb.append("(type:");
diff --git a/services/core/java/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java b/services/core/java/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java
index 2141eba..7f129ea 100644
--- a/services/core/java/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java
+++ b/services/core/java/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java
@@ -171,6 +171,18 @@
return false;
}
+ for (Map.Entry<Integer, Integer> entry :
+ networkPriority.getCapabilitiesMatchCriteria().entrySet()) {
+ final int cap = entry.getKey();
+ final int matchCriteria = entry.getValue();
+
+ if (matchCriteria == MATCH_REQUIRED && !caps.hasCapability(cap)) {
+ return false;
+ } else if (matchCriteria == MATCH_FORBIDDEN && caps.hasCapability(cap)) {
+ return false;
+ }
+ }
+
if (vcnContext.isInTestMode() && caps.hasTransport(TRANSPORT_TEST)) {
return true;
}
@@ -319,18 +331,6 @@
return false;
}
- for (Map.Entry<Integer, Integer> entry :
- networkPriority.getCapabilitiesMatchCriteria().entrySet()) {
- final int cap = entry.getKey();
- final int matchCriteria = entry.getValue();
-
- if (matchCriteria == MATCH_REQUIRED && !caps.hasCapability(cap)) {
- return false;
- } else if (matchCriteria == MATCH_FORBIDDEN && caps.hasCapability(cap)) {
- return false;
- }
- }
-
return true;
}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 81dabfd..94e041a 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -6046,6 +6046,8 @@
// An activity must be in the {@link PAUSING} state for the system to validate
// the move to {@link PAUSED}.
setState(PAUSING, "makeActiveIfNeeded");
+ EventLogTags.writeWmPauseActivity(mUserId, System.identityHashCode(this),
+ shortComponentName, "userLeaving=false", "make-active");
try {
mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), token,
PauseActivityItem.obtain(finishing, false /* userLeaving */,
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index feaec37..be503fc 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -1562,7 +1562,6 @@
}
private void removePinnedRootTaskInSurfaceTransaction(Task rootTask) {
- rootTask.mTransitionController.requestCloseTransitionIfNeeded(rootTask);
/**
* Workaround: Force-stop all the activities in the root pinned task before we reparent them
* to the fullscreen root task. This is to guarantee that when we are removing a root task,
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 683767e..c6ba600 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -783,7 +783,9 @@
* a chance we won't thus legacy-entry (via pause+userLeaving) will return false.
*/
private boolean checkEnterPipOnFinish(@NonNull ActivityRecord ar) {
- if (!mCanPipOnFinish || !ar.isVisible() || ar.getTask() == null) return false;
+ if (!mCanPipOnFinish || !ar.isVisible() || ar.getTask() == null || !ar.isState(RESUMED)) {
+ return false;
+ }
if (ar.pictureInPictureArgs != null && ar.pictureInPictureArgs.isAutoEnterEnabled()) {
if (didCommitTransientLaunch()) {
@@ -796,18 +798,14 @@
}
// Legacy pip-entry (not via isAutoEnterEnabled).
- boolean canPip = ar.getDeferHidingClient();
- if (!canPip && didCommitTransientLaunch()) {
+ if (didCommitTransientLaunch() && ar.supportsPictureInPicture()) {
// force enable pip-on-task-switch now that we've committed to actually launching to the
// transient activity, and then recalculate whether we can attempt pip.
ar.supportsEnterPipOnTaskSwitch = true;
- canPip = ar.checkEnterPictureInPictureState(
- "finishTransition", true /* beforeStopping */)
- && ar.isState(RESUMED);
}
- if (!canPip) return false;
+
try {
- // Legacy PIP-enter requires pause event with user-leaving.
+ // If not going auto-pip, the activity should be paused with user-leaving.
mController.mAtm.mTaskSupervisor.mUserLeaving = true;
ar.getTaskFragment().startPausing(false /* uiSleeping */,
null /* resuming */, "finishTransition");
@@ -851,6 +849,7 @@
boolean hasParticipatedDisplay = false;
boolean hasVisibleTransientLaunch = false;
+ boolean enterAutoPip = false;
// Commit all going-invisible containers
for (int i = 0; i < mParticipants.size(); ++i) {
final WindowContainer<?> participant = mParticipants.valueAt(i);
@@ -886,6 +885,8 @@
}
ar.commitVisibility(false /* visible */, false /* performLayout */,
true /* fromTransition */);
+ } else {
+ enterAutoPip = true;
}
}
if (mChanges.get(ar).mVisible != visibleAtTransitionEnd) {
@@ -940,8 +941,10 @@
}
if (hasVisibleTransientLaunch) {
- // Notify the change about the transient-below task that becomes invisible.
- mController.mAtm.getTaskChangeNotificationController().notifyTaskStackChanged();
+ // Notify the change about the transient-below task if entering auto-pip.
+ if (enterAutoPip) {
+ mController.mAtm.getTaskChangeNotificationController().notifyTaskStackChanged();
+ }
// Prevent spurious background app switches.
mController.mAtm.stopAppSwitches();
// The end of transient launch may not reorder task, so make sure to compute the latest
diff --git a/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java b/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java
index 629e988..2266041 100644
--- a/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java
+++ b/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java
@@ -95,6 +95,7 @@
private static final NetworkCapabilities WIFI_NETWORK_CAPABILITIES =
new NetworkCapabilities.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.setSignalStrength(WIFI_RSSI)
.setSsid(SSID)
.setLinkUpstreamBandwidthKbps(LINK_UPSTREAM_BANDWIDTH_KBPS)
@@ -509,12 +510,14 @@
VcnCellUnderlyingNetworkTemplate template, boolean expectMatch) {
assertEquals(
expectMatch,
- checkMatchesCellPriorityRule(
+ checkMatchesPriorityRule(
mVcnContext,
template,
mCellNetworkRecord,
SUB_GROUP,
- mSubscriptionSnapshot));
+ mSubscriptionSnapshot,
+ null /* currentlySelected */,
+ null /* carrierConfig */));
}
@Test