summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds/incidentd/src/IncidentService.cpp6
-rw-r--r--cmds/screencap/screencap.cpp12
-rw-r--r--core/java/android/service/credentials/Action.java32
-rw-r--r--core/java/android/service/credentials/CreateCredentialCallback.java64
-rw-r--r--core/java/android/service/credentials/CreateCredentialRequest.java3
-rw-r--r--core/java/android/service/credentials/CreateCredentialResponse.java3
-rw-r--r--core/java/android/service/credentials/Credential.java100
-rw-r--r--core/java/android/service/credentials/CredentialEntry.java48
-rw-r--r--core/java/android/service/credentials/CredentialProviderException.java65
-rw-r--r--core/java/android/service/credentials/CredentialProviderService.java66
-rw-r--r--core/java/android/service/credentials/CredentialsDisplayContent.java3
-rw-r--r--core/java/android/service/credentials/GetCredentialOption.java96
-rw-r--r--core/java/android/service/credentials/GetCredentialsCallback.java65
-rw-r--r--core/java/android/service/credentials/GetCredentialsRequest.java6
-rw-r--r--core/java/android/service/credentials/GetCredentialsResponse.java19
-rw-r--r--core/java/android/service/credentials/SaveEntry.java34
-rw-r--r--libs/WindowManager/Shell/res/drawable/decor_back_button_dark.xml32
-rw-r--r--libs/WindowManager/Shell/res/drawable/decor_caption_title.xml4
-rw-r--r--libs/WindowManager/Shell/res/drawable/decor_close_button_dark.xml8
-rw-r--r--libs/WindowManager/Shell/res/drawable/decor_handle_dark.xml23
-rw-r--r--libs/WindowManager/Shell/res/layout/caption_window_decoration.xml30
-rw-r--r--libs/WindowManager/Shell/res/values/strings.xml4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java73
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java104
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java165
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskPositioner.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java21
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java5
-rw-r--r--libs/hwui/Rect.h9
-rw-r--r--media/java/android/media/MediaMuxer.java23
-rw-r--r--media/jni/android_media_MediaMuxer.cpp6
-rw-r--r--packages/SettingsLib/res/values-ar/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-as/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-eu/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-nb/strings.xml28
-rw-r--r--packages/SettingsLib/res/values-sv/strings.xml2
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/applications/PermissionsSummaryHelper.java34
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java59
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java15
-rw-r--r--services/core/java/com/android/server/am/BroadcastQueueImpl.java4
-rw-r--r--services/core/java/com/android/server/am/BroadcastQueueModernImpl.java2
-rw-r--r--services/core/java/com/android/server/input/PersistentDataStore.java5
44 files changed, 625 insertions, 684 deletions
diff --git a/cmds/incidentd/src/IncidentService.cpp b/cmds/incidentd/src/IncidentService.cpp
index 836801deaa08..5af02f405ed9 100644
--- a/cmds/incidentd/src/IncidentService.cpp
+++ b/cmds/incidentd/src/IncidentService.cpp
@@ -52,11 +52,7 @@ enum {
#define SKIPPED_DUMPSTATE_SECTIONS { \
1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, /* Logs */ \
1200, 1201, 1202, /* Native, hal, java traces */ \
- 3000, 3001, 3002, 3003, 3004, 3005, 3006, 3007, 3008, 3009, 3010, 3011, 3012, 3013, \
- 3014, 3015, 3016, 3017, 3018, 3019, 3020, 3021, 3022, 3023, 3024, 3027, 3028, 3029, \
- 3030, 3031, 3032, 3033, 3034, 3035, 3036, 3037, 3038, 3039, 3040, 3041, 3042, 3043, \
- 3044, 3045, 3046, 3047, 3048, 3049, 3050, 3051, 3052, 3053, 3054, 3055, 3056, 4000, \
- 4001, /* Dumpsys */ }
+ 3018, /* dumpsys meminfo*/ }
namespace android {
namespace os {
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index 44fb6b320102..d7222d248911 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -159,12 +159,14 @@ int main(int argc, char** argv)
}
if (!displayId) { // no diplsay id is specified
- if (ids.size() == 1) {
- displayId = ids.front();
- } else {
- fprintf(stderr, "Please specify a display ID (-d display-id) for multi-display device.\n");
+ displayId = ids.front();
+ if (ids.size() > 1) {
+ fprintf(stderr,
+ "[Warning] Multiple displays were found, but no display id was specified! "
+ "Defaulting to the first display found, however this default is not guaranteed "
+ "to be consistent across captures. A display id should be specified.\n");
+ fprintf(stderr, "A display ID can be specified with the [-d display-id] option.\n");
fprintf(stderr, "See \"dumpsys SurfaceFlinger --display-id\" for valid display IDs.\n");
- return 1;
}
}
diff --git a/core/java/android/service/credentials/Action.java b/core/java/android/service/credentials/Action.java
index 186b2a60c430..e2c11fbac008 100644
--- a/core/java/android/service/credentials/Action.java
+++ b/core/java/android/service/credentials/Action.java
@@ -16,13 +16,12 @@
package android.service.credentials;
+import android.annotation.NonNull;
import android.app.PendingIntent;
import android.app.slice.Slice;
import android.os.Parcel;
import android.os.Parcelable;
-import androidx.annotation.NonNull;
-
import java.util.Objects;
/**
@@ -32,29 +31,26 @@ import java.util.Objects;
* @hide
*/
public final class Action implements Parcelable {
- /** Info to be displayed with this action on the UI. */
- private final @NonNull Slice mInfo;
- /**
- * The pending intent to be invoked when the user selects this action.
- */
+ /** Slice object containing display content to be displayed with this action on the UI. */
+ private final @NonNull Slice mSlice;
+ /** The pending intent to be invoked when the user selects this action. */
private final @NonNull PendingIntent mPendingIntent;
/**
* Constructs an action to be displayed on the UI.
*
- * @param actionInfo The info to be displayed along with this action.
- * @param pendingIntent The intent to be invoked when the user selects this action.
- * @throws NullPointerException If {@code actionInfo}, or {@code pendingIntent} is null.
+ * @param slice the display content to be displayed on the UI, along with this action
+ * @param pendingIntent the intent to be invoked when the user selects this action
*/
- public Action(@NonNull Slice actionInfo, @NonNull PendingIntent pendingIntent) {
- Objects.requireNonNull(actionInfo, "actionInfo must not be null");
+ public Action(@NonNull Slice slice, @NonNull PendingIntent pendingIntent) {
+ Objects.requireNonNull(slice, "slice must not be null");
Objects.requireNonNull(pendingIntent, "pendingIntent must not be null");
- mInfo = actionInfo;
+ mSlice = slice;
mPendingIntent = pendingIntent;
}
private Action(@NonNull Parcel in) {
- mInfo = in.readParcelable(Slice.class.getClassLoader(), Slice.class);
+ mSlice = in.readParcelable(Slice.class.getClassLoader(), Slice.class);
mPendingIntent = in.readParcelable(PendingIntent.class.getClassLoader(),
PendingIntent.class);
}
@@ -78,15 +74,15 @@ public final class Action implements Parcelable {
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
- mInfo.writeToParcel(dest, flags);
+ mSlice.writeToParcel(dest, flags);
mPendingIntent.writeToParcel(dest, flags);
}
/**
- * Returns the action info as a {@link Slice} object, to be displayed on the UI.
+ * Returns a {@code Slice} object containing the display content to be displayed on the UI.
*/
- public @NonNull Slice getActionInfo() {
- return mInfo;
+ public @NonNull Slice getSlice() {
+ return mSlice;
}
/**
diff --git a/core/java/android/service/credentials/CreateCredentialCallback.java b/core/java/android/service/credentials/CreateCredentialCallback.java
deleted file mode 100644
index 6108eea5bea1..000000000000
--- a/core/java/android/service/credentials/CreateCredentialCallback.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.service.credentials;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.RemoteException;
-import android.util.Log;
-
-/**
- * Callback to be invoked as a response to {@link CreateCredentialRequest}.
- *
- * @hide
- */
-public final class CreateCredentialCallback {
- private static final String TAG = "CreateCredentialCallback";
-
- private final ICreateCredentialCallback mCallback;
-
- /** @hide */
- public CreateCredentialCallback(@NonNull ICreateCredentialCallback callback) {
- mCallback = callback;
- }
-
- /**
- * Invoked on a successful response for {@link CreateCredentialRequest}
- * @param response The response from the credential provider.
- */
- public void onSuccess(@NonNull CreateCredentialResponse response) {
- try {
- mCallback.onSuccess(response);
- } catch (RemoteException e) {
- e.rethrowAsRuntimeException();
- }
- }
-
- /**
- * Invoked on a failure response for {@link CreateCredentialRequest}
- * @param errorCode The code defining the type of error.
- * @param message The message corresponding to the failure.
- */
- public void onFailure(int errorCode, @Nullable CharSequence message) {
- Log.w(TAG, "onFailure: " + message);
- try {
- mCallback.onFailure(errorCode, message);
- } catch (RemoteException e) {
- e.rethrowAsRuntimeException();
- }
- }
-}
diff --git a/core/java/android/service/credentials/CreateCredentialRequest.java b/core/java/android/service/credentials/CreateCredentialRequest.java
index ac11e04bcb77..6a0bbc0bd917 100644
--- a/core/java/android/service/credentials/CreateCredentialRequest.java
+++ b/core/java/android/service/credentials/CreateCredentialRequest.java
@@ -16,12 +16,11 @@
package android.service.credentials;
+import android.annotation.NonNull;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
-import androidx.annotation.NonNull;
-
import com.android.internal.util.Preconditions;
import java.util.Objects;
diff --git a/core/java/android/service/credentials/CreateCredentialResponse.java b/core/java/android/service/credentials/CreateCredentialResponse.java
index f2ad7272f207..613eba8c9bb2 100644
--- a/core/java/android/service/credentials/CreateCredentialResponse.java
+++ b/core/java/android/service/credentials/CreateCredentialResponse.java
@@ -16,12 +16,11 @@
package android.service.credentials;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
-import androidx.annotation.NonNull;
-
import com.android.internal.util.Preconditions;
import java.util.ArrayList;
diff --git a/core/java/android/service/credentials/Credential.java b/core/java/android/service/credentials/Credential.java
deleted file mode 100644
index 7d5da8a7c4e0..000000000000
--- a/core/java/android/service/credentials/Credential.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.service.credentials;
-
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import androidx.annotation.NonNull;
-
-import static java.util.Objects.requireNonNull;
-
-import com.android.internal.util.Preconditions;
-
-/**
- * A Credential object that contains type specific data that is returned from the credential
- * provider to the framework. Framework then converts it to an app facing representation and
- * returns to the calling app.
- *
- * @hide
- */
-public final class Credential implements Parcelable {
- /** The type of this credential. */
- private final @NonNull String mType;
-
- /** The data associated with this credential. */
- private final @NonNull Bundle mData;
-
- /**
- * Constructs a credential object.
- *
- * @param type The type of the credential.
- * @param data The data of the credential that is passed back to the framework, and eventually
- * to the calling app.
- * @throws NullPointerException If {@code data} is null.
- * @throws IllegalArgumentException If {@code type} is null or empty.
- */
- public Credential(@NonNull String type, @NonNull Bundle data) {
- Preconditions.checkStringNotEmpty(type, "type must not be null, or empty");
- requireNonNull(data, "data must not be null");
- this.mType = type;
- this.mData = data;
- }
-
- private Credential(@NonNull Parcel in) {
- mType = in.readString16NoHelper();
- mData = in.readBundle();
- }
-
- /**
- * Returns the type of the credential.
- */
- public @NonNull String getType() {
- return mType;
- }
-
- /**
- * Returns the data associated with the credential.
- */
- public @NonNull Bundle getData() {
- return mData;
- }
-
- public static final @NonNull Creator<Credential> CREATOR = new Creator<Credential>() {
- @Override
- public Credential createFromParcel(@NonNull Parcel in) {
- return new Credential(in);
- }
-
- @Override
- public Credential[] newArray(int size) {
- return new Credential[size];
- }
- };
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeString8(mType);
- dest.writeBundle(mData);
- }
-}
diff --git a/core/java/android/service/credentials/CredentialEntry.java b/core/java/android/service/credentials/CredentialEntry.java
index b49215a08bfb..49b84359d94a 100644
--- a/core/java/android/service/credentials/CredentialEntry.java
+++ b/core/java/android/service/credentials/CredentialEntry.java
@@ -16,14 +16,14 @@
package android.service.credentials;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.PendingIntent;
import android.app.slice.Slice;
+import android.credentials.Credential;
import android.os.Parcel;
import android.os.Parcelable;
-import androidx.annotation.NonNull;
-
import com.android.internal.util.Preconditions;
import java.util.Objects;
@@ -38,8 +38,9 @@ public final class CredentialEntry implements Parcelable {
/** The type of the credential entry to be shown on the UI. */
private final @NonNull String mType;
- /** The info to be displayed along with this credential entry on the UI. */
- private final @NonNull Slice mInfo;
+ /** The object containing display content to be shown along with this credential entry
+ * on the UI. */
+ private final @NonNull Slice mSlice;
/** The pending intent to be invoked when this credential entry is selected. */
private final @Nullable PendingIntent mPendingIntent;
@@ -53,11 +54,11 @@ public final class CredentialEntry implements Parcelable {
/** A flag denoting whether auto-select is enabled for this entry. */
private final @NonNull boolean mAutoSelectAllowed;
- private CredentialEntry(@NonNull String type, @NonNull Slice entryInfo,
+ private CredentialEntry(@NonNull String type, @NonNull Slice slice,
@Nullable PendingIntent pendingIntent, @Nullable Credential credential,
@NonNull boolean autoSeletAllowed) {
mType = type;
- mInfo = entryInfo;
+ mSlice = slice;
mPendingIntent = pendingIntent;
mCredential = credential;
mAutoSelectAllowed = autoSeletAllowed;
@@ -65,7 +66,7 @@ public final class CredentialEntry implements Parcelable {
private CredentialEntry(@NonNull Parcel in) {
mType = in.readString();
- mInfo = in.readParcelable(Slice.class.getClassLoader(), Slice.class);
+ mSlice = in.readParcelable(Slice.class.getClassLoader(), Slice.class);
mPendingIntent = in.readParcelable(PendingIntent.class.getClassLoader(),
PendingIntent.class);
mCredential = in.readParcelable(Credential.class.getClassLoader(),
@@ -94,7 +95,7 @@ public final class CredentialEntry implements Parcelable {
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeString8(mType);
- mInfo.writeToParcel(dest, flags);
+ mSlice.writeToParcel(dest, flags);
mPendingIntent.writeToParcel(dest, flags);
mCredential.writeToParcel(dest, flags);
dest.writeBoolean(mAutoSelectAllowed);
@@ -108,10 +109,10 @@ public final class CredentialEntry implements Parcelable {
}
/**
- * Returns the UI info to be displayed for this entry.
+ * Returns the {@link Slice} object containing UI display content to be shown for this entry.
*/
- public @NonNull Slice getInfo() {
- return mInfo;
+ public @NonNull Slice getSlice() {
+ return mSlice;
}
/**
@@ -131,7 +132,7 @@ public final class CredentialEntry implements Parcelable {
/**
* Returns whether this entry can be auto selected if it is the only option for the user.
*/
- public @NonNull boolean isAutoSelectAllowed() {
+ public boolean isAutoSelectAllowed() {
return mAutoSelectAllowed;
}
@@ -140,28 +141,35 @@ public final class CredentialEntry implements Parcelable {
*/
public static final class Builder {
private String mType;
- private Slice mInfo;
+ private Slice mSlice;
private PendingIntent mPendingIntent;
private Credential mCredential;
private boolean mAutoSelectAllowed = false;
/**
* Builds the instance.
- * @param type The type of credential underlying this credential entry.
- * @param info The info to be displayed with this entry on the UI.
+ * @param type the type of credential underlying this credential entry
+ * @param slice the content to be displayed with this entry on the UI
*
* @throws IllegalArgumentException If {@code type} is null or empty.
- * @throws NullPointerException If {@code info} is null.
+ * @throws NullPointerException If {@code slice} is null.
*/
- public Builder(@NonNull String type, @NonNull Slice info) {
+ public Builder(@NonNull String type, @NonNull Slice slice) {
mType = Preconditions.checkStringNotEmpty(type, "type must not be "
+ "null, or empty");
- mInfo = Objects.requireNonNull(info, "info must not be null");
+ mSlice = Objects.requireNonNull(slice,
+ "slice must not be null");
}
/**
* Sets the pendingIntent to be invoked if the user selects this entry.
*
+ * The pending intent can be used to launch activities that require some user engagement
+ * before getting the credential corresponding to this entry, e.g. authentication,
+ * confirmation etc.
+ * Once the activity fulfills the required user engagement, a {@link Credential} object
+ * must be returned as an extra on activity finish.
+ *
* @throws IllegalStateException If {@code credential} is already set. Must either set the
* {@code credential}, or the {@code pendingIntent}.
*/
@@ -199,7 +207,7 @@ public final class CredentialEntry implements Parcelable {
/**
* Creates a new {@link CredentialEntry} instance.
*
- * @throws NullPointerException If {@code info} is null.
+ * @throws NullPointerException If {@code slice} is null.
* @throws IllegalArgumentException If {@code type} is null, or empty.
* @throws IllegalStateException If neither {@code pendingIntent} nor {@code credential}
* is set, or if both are set.
@@ -209,7 +217,7 @@ public final class CredentialEntry implements Parcelable {
"Either pendingIntent or credential must be set");
Preconditions.checkState(mPendingIntent != null && mCredential != null,
"Cannot set both the pendingIntent and credential");
- return new CredentialEntry(mType, mInfo, mPendingIntent,
+ return new CredentialEntry(mType, mSlice, mPendingIntent,
mCredential, mAutoSelectAllowed);
}
}
diff --git a/core/java/android/service/credentials/CredentialProviderException.java b/core/java/android/service/credentials/CredentialProviderException.java
new file mode 100644
index 000000000000..b39b4a0cc180
--- /dev/null
+++ b/core/java/android/service/credentials/CredentialProviderException.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.credentials;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Contains custom exceptions to be used by credential providers on failure.
+ *
+ * @hide
+ */
+public class CredentialProviderException extends Exception {
+ public static final int ERROR_UNKNOWN = 0;
+
+ private final int mErrorCode;
+
+ /**
+ * @hide
+ */
+ @IntDef(prefix = {"ERROR_"}, value = {
+ ERROR_UNKNOWN,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface CredentialProviderError { }
+
+
+ public CredentialProviderException(@CredentialProviderError int errorCode,
+ @NonNull String message) {
+ super(message);
+ mErrorCode = errorCode;
+ }
+
+ public CredentialProviderException(@CredentialProviderError int errorCode,
+ @NonNull Throwable cause) {
+ super(cause);
+ mErrorCode = errorCode;
+ }
+
+ public CredentialProviderException(@CredentialProviderError int errorCode) {
+ super();
+ mErrorCode = errorCode;
+ }
+
+ public @CredentialProviderError int getErrorCode() {
+ return mErrorCode;
+ }
+}
diff --git a/core/java/android/service/credentials/CredentialProviderService.java b/core/java/android/service/credentials/CredentialProviderService.java
index 1fe89dffaa0f..1cdf186d898c 100644
--- a/core/java/android/service/credentials/CredentialProviderService.java
+++ b/core/java/android/service/credentials/CredentialProviderService.java
@@ -20,6 +20,7 @@ import static com.android.internal.util.function.pooled.PooledLambda.obtainMessa
import android.annotation.CallSuper;
import android.annotation.NonNull;
+import android.annotation.SdkConstant;
import android.app.Service;
import android.content.Intent;
import android.os.CancellationSignal;
@@ -27,13 +28,14 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.ICancellationSignal;
import android.os.Looper;
+import android.os.OutcomeReceiver;
import android.os.RemoteException;
import android.util.Log;
import java.util.Objects;
/**
- * Main service to be extended by credential providers, in order to return user credentials
+ * Service to be extended by credential providers, in order to return user credentials
* to the framework.
*
* @hide
@@ -42,6 +44,12 @@ public abstract class CredentialProviderService extends Service {
private static final String TAG = "CredProviderService";
private Handler mHandler;
+ /**
+ * The {@link Intent} that must be declared as handled by the service. The service must also
+ * require the {android.Manifest.permission#BIND_CREDENTIAL_PROVIDER_SERVICE} permission
+ * so that only the system can bind to it.
+ */
+ @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
public static final String SERVICE_INTERFACE =
"android.service.credentials.CredentialProviderService";
@@ -64,7 +72,7 @@ public abstract class CredentialProviderService extends Service {
private final ICredentialProviderService mInterface = new ICredentialProviderService.Stub() {
@Override
public void onGetCredentials(GetCredentialsRequest request, ICancellationSignal transport,
- IGetCredentialsCallback callback) throws RemoteException {
+ IGetCredentialsCallback callback) {
Objects.requireNonNull(request);
Objects.requireNonNull(transport);
Objects.requireNonNull(callback);
@@ -73,14 +81,30 @@ public abstract class CredentialProviderService extends Service {
CredentialProviderService::onGetCredentials,
CredentialProviderService.this, request,
CancellationSignal.fromTransport(transport),
- new GetCredentialsCallback(callback)
+ new OutcomeReceiver<GetCredentialsResponse, CredentialProviderException>() {
+ @Override
+ public void onResult(GetCredentialsResponse result) {
+ try {
+ callback.onSuccess(result);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
+ @Override
+ public void onError(CredentialProviderException e) {
+ try {
+ callback.onFailure(e.getErrorCode(), e.getMessage());
+ } catch (RemoteException ex) {
+ ex.rethrowFromSystemServer();
+ }
+ }
+ }
));
}
@Override
public void onCreateCredential(CreateCredentialRequest request,
- ICancellationSignal transport, ICreateCredentialCallback callback)
- throws RemoteException {
+ ICancellationSignal transport, ICreateCredentialCallback callback) {
Objects.requireNonNull(request);
Objects.requireNonNull(transport);
Objects.requireNonNull(callback);
@@ -89,7 +113,24 @@ public abstract class CredentialProviderService extends Service {
CredentialProviderService::onCreateCredential,
CredentialProviderService.this, request,
CancellationSignal.fromTransport(transport),
- new CreateCredentialCallback(callback)
+ new OutcomeReceiver<CreateCredentialResponse, CredentialProviderException>() {
+ @Override
+ public void onResult(CreateCredentialResponse result) {
+ try {
+ callback.onSuccess(result);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
+ @Override
+ public void onError(CredentialProviderException e) {
+ try {
+ callback.onFailure(e.getErrorCode(), e.getMessage());
+ } catch (RemoteException ex) {
+ ex.rethrowFromSystemServer();
+ }
+ }
+ }
));
}
};
@@ -97,14 +138,14 @@ public abstract class CredentialProviderService extends Service {
/**
* Called by the android system to retrieve user credentials from the connected provider
* service.
- * @param request The credential request for the provider to handle.
- * @param cancellationSignal Signal for providers to listen to any cancellation requests from
- * the android system.
- * @param callback Object used to relay the response of the credentials request.
+ * @param request the credential request for the provider to handle
+ * @param cancellationSignal signal for providers to listen to any cancellation requests from
+ * the android system
+ * @param callback object used to relay the response of the credentials request
*/
public abstract void onGetCredentials(@NonNull GetCredentialsRequest request,
@NonNull CancellationSignal cancellationSignal,
- @NonNull GetCredentialsCallback callback);
+ @NonNull OutcomeReceiver<GetCredentialsResponse, CredentialProviderException> callback);
/**
* Called by the android system to create a credential.
@@ -115,5 +156,6 @@ public abstract class CredentialProviderService extends Service {
*/
public abstract void onCreateCredential(@NonNull CreateCredentialRequest request,
@NonNull CancellationSignal cancellationSignal,
- @NonNull CreateCredentialCallback callback);
+ @NonNull OutcomeReceiver<CreateCredentialResponse,
+ CredentialProviderException> callback);
}
diff --git a/core/java/android/service/credentials/CredentialsDisplayContent.java b/core/java/android/service/credentials/CredentialsDisplayContent.java
index 106f322c4ab4..4133ea5955c4 100644
--- a/core/java/android/service/credentials/CredentialsDisplayContent.java
+++ b/core/java/android/service/credentials/CredentialsDisplayContent.java
@@ -16,12 +16,11 @@
package android.service.credentials;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
-import androidx.annotation.NonNull;
-
import com.android.internal.util.Preconditions;
import java.util.ArrayList;
diff --git a/core/java/android/service/credentials/GetCredentialOption.java b/core/java/android/service/credentials/GetCredentialOption.java
deleted file mode 100644
index c6cda1d1abf6..000000000000
--- a/core/java/android/service/credentials/GetCredentialOption.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.service.credentials;
-
-import android.annotation.NonNull;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import com.android.internal.util.Preconditions;
-
-import static java.util.Objects.requireNonNull;
-
-/**
- * A type specific credential request, containing the associated data to be used for
- * retrieving credentials.
- *
- * @hide
- */
-public final class GetCredentialOption implements Parcelable {
- /** The type of credential requested. */
- private final @NonNull String mType;
-
- /** The data associated with the request. */
- private final @NonNull Bundle mData;
-
- /**
- * Constructs a new instance of {@link GetCredentialOption}
- *
- * @throws IllegalArgumentException If {@code type} string is null or empty.
- * @throws NullPointerException If {@code data} is null.
- */
- public GetCredentialOption(@NonNull String type, @NonNull Bundle data) {
- Preconditions.checkStringNotEmpty(type, "type must not be null, or empty");
- requireNonNull(data, "data must not be null");
- mType = type;
- mData = data;
- }
-
- /**
- * Returns the data associated with this credential request option.
- */
- public @NonNull Bundle getData() {
- return mData;
- }
-
- /**
- * Returns the type associated with this credential request option.
- */
- public @NonNull String getType() {
- return mType;
- }
-
- private GetCredentialOption(@NonNull Parcel in) {
- mType = in.readString16NoHelper();
- mData = in.readBundle();
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeString16NoHelper(mType);
- dest.writeBundle(mData);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- public static final @NonNull Creator<GetCredentialOption> CREATOR =
- new Creator<GetCredentialOption>() {
- @Override
- public GetCredentialOption createFromParcel(@NonNull Parcel in) {
- return new GetCredentialOption(in);
- }
-
- @Override
- public GetCredentialOption[] newArray(int size) {
- return new GetCredentialOption[size];
- }
- };
-}
diff --git a/core/java/android/service/credentials/GetCredentialsCallback.java b/core/java/android/service/credentials/GetCredentialsCallback.java
deleted file mode 100644
index 42a73946b5cc..000000000000
--- a/core/java/android/service/credentials/GetCredentialsCallback.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.service.credentials;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.RemoteException;
-import android.util.Log;
-
-/**
- * Callback to be invoked as a response to {@link GetCredentialsRequest}.
- *
- * @hide
- */
-public final class GetCredentialsCallback {
-
- private static final String TAG = "GetCredentialsCallback";
-
- private final IGetCredentialsCallback mCallback;
-
- /** @hide */
- public GetCredentialsCallback(@NonNull IGetCredentialsCallback callback) {
- mCallback = callback;
- }
-
- /**
- * Invoked on a successful response for {@link GetCredentialsRequest}
- * @param response The response from the credential provider.
- */
- public void onSuccess(@NonNull GetCredentialsResponse response) {
- try {
- mCallback.onSuccess(response);
- } catch (RemoteException e) {
- e.rethrowAsRuntimeException();
- }
- }
-
- /**
- * Invoked on a failure response for {@link GetCredentialsRequest}
- * @param errorCode The code defining the kind of error.
- * @param message The message corresponding to the failure.
- */
- public void onFailure(int errorCode, @Nullable CharSequence message) {
- Log.w(TAG, "onFailure: " + message);
- try {
- mCallback.onFailure(errorCode, message);
- } catch (RemoteException e) {
- e.rethrowAsRuntimeException();
- }
- }
-}
diff --git a/core/java/android/service/credentials/GetCredentialsRequest.java b/core/java/android/service/credentials/GetCredentialsRequest.java
index cf7c2834f75f..5b1a1713ee51 100644
--- a/core/java/android/service/credentials/GetCredentialsRequest.java
+++ b/core/java/android/service/credentials/GetCredentialsRequest.java
@@ -16,11 +16,11 @@
package android.service.credentials;
+import android.annotation.NonNull;
+import android.credentials.GetCredentialOption;
import android.os.Parcel;
import android.os.Parcelable;
-import androidx.annotation.NonNull;
-
import com.android.internal.util.Preconditions;
import java.util.ArrayList;
@@ -100,7 +100,7 @@ public final class GetCredentialsRequest implements Parcelable {
/**
* Creates a new builder.
- * @param callingPackage The calling package of the app requesting credentials.
+ * @param callingPackage the calling package of the app requesting credentials
*
* @throws IllegalArgumentException If {@code callingPackag}e is null or empty.
*/
diff --git a/core/java/android/service/credentials/GetCredentialsResponse.java b/core/java/android/service/credentials/GetCredentialsResponse.java
index 293867ba55b2..980d9ae47aa7 100644
--- a/core/java/android/service/credentials/GetCredentialsResponse.java
+++ b/core/java/android/service/credentials/GetCredentialsResponse.java
@@ -16,12 +16,11 @@
package android.service.credentials;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
-import androidx.annotation.NonNull;
-
import java.util.Objects;
/**
@@ -44,6 +43,11 @@ public final class GetCredentialsResponse implements Parcelable {
* Creates a {@link GetCredentialsRequest} instance with an authentication action set.
* Providers must use this method when no content can be shown before authentication.
*
+ * Once the authentication action activity is launched, and the user is authenticated, providers
+ * should create another response with {@link CredentialsDisplayContent} using
+ * {@code createWithDisplayContent}, and add that response to the result of the authentication
+ * activity.
+ *
* @throws NullPointerException If {@code authenticationAction} is null.
*/
public static @NonNull GetCredentialsResponse createWithAuthentication(
@@ -104,17 +108,10 @@ public final class GetCredentialsResponse implements Parcelable {
}
/**
- * Returns whether the response contains a top level authentication action.
- */
- public @NonNull boolean isAuthenticationActionSet() {
- return mAuthenticationAction != null;
- }
-
- /**
* Returns the authentication action to be invoked before any other content
* can be shown to the user.
*/
- public @NonNull Action getAuthenticationAction() {
+ public @Nullable Action getAuthenticationAction() {
return mAuthenticationAction;
}
@@ -122,7 +119,7 @@ public final class GetCredentialsResponse implements Parcelable {
* Returns the credentialDisplayContent that does not require authentication, and
* can be shown to the user on the account selector UI.
*/
- public @NonNull CredentialsDisplayContent getCredentialsDisplayContent() {
+ public @Nullable CredentialsDisplayContent getCredentialsDisplayContent() {
return mCredentialsDisplayContent;
}
}
diff --git a/core/java/android/service/credentials/SaveEntry.java b/core/java/android/service/credentials/SaveEntry.java
index 28fec30caa89..18644f09ecef 100644
--- a/core/java/android/service/credentials/SaveEntry.java
+++ b/core/java/android/service/credentials/SaveEntry.java
@@ -16,14 +16,14 @@
package android.service.credentials;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.PendingIntent;
import android.app.slice.Slice;
+import android.credentials.Credential;
import android.os.Parcel;
import android.os.Parcelable;
-import androidx.annotation.NonNull;
-
import com.android.internal.util.Preconditions;
import java.util.Objects;
@@ -35,12 +35,12 @@ import java.util.Objects;
* @hide
*/
public final class SaveEntry implements Parcelable {
- private final @NonNull Slice mInfo;
+ private final @NonNull Slice mSlice;
private final @Nullable PendingIntent mPendingIntent;
private final @Nullable Credential mCredential;
private SaveEntry(@NonNull Parcel in) {
- mInfo = in.readParcelable(Slice.class.getClassLoader(), Slice.class);
+ mSlice = in.readParcelable(Slice.class.getClassLoader(), Slice.class);
mPendingIntent = in.readParcelable(PendingIntent.class.getClassLoader(),
PendingIntent.class);
mCredential = in.readParcelable(Credential.class.getClassLoader(), Credential.class);
@@ -65,25 +65,25 @@ public final class SaveEntry implements Parcelable {
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
- mInfo.writeToParcel(dest, flags);
+ mSlice.writeToParcel(dest, flags);
mPendingIntent.writeToParcel(dest, flags);
mCredential.writeToParcel(dest, flags);
}
/* package-private */ SaveEntry(
- @NonNull Slice info,
+ @NonNull Slice slice,
@Nullable PendingIntent pendingIntent,
@Nullable Credential credential) {
- this.mInfo = info;
+ this.mSlice = slice;
com.android.internal.util.AnnotationValidations.validate(
- NonNull.class, null, mInfo);
+ NonNull.class, null, mSlice);
this.mPendingIntent = pendingIntent;
this.mCredential = credential;
}
- /** Returns the info to be displayed with this save entry on the UI. */
- public @NonNull Slice getInfo() {
- return mInfo;
+ /** Returns the content to be displayed with this save entry on the UI. */
+ public @NonNull Slice getSlice() {
+ return mSlice;
}
/** Returns the pendingIntent to be invoked when this save entry on the UI is selectcd. */
@@ -101,18 +101,18 @@ public final class SaveEntry implements Parcelable {
*/
public static final class Builder {
- private @NonNull Slice mInfo;
+ private @NonNull Slice mSlice;
private @Nullable PendingIntent mPendingIntent;
private @Nullable Credential mCredential;
/**
* Builds the instance.
- * @param info The info to be displayed with this save entry.
+ * @param slice the content to be displayed with this save entry
*
- * @throws NullPointerException If {@code info} is null.
+ * @throws NullPointerException If {@code slice} is null.
*/
- public Builder(@NonNull Slice info) {
- mInfo = Objects.requireNonNull(info, "info must not be null");
+ public Builder(@NonNull Slice slice) {
+ mSlice = Objects.requireNonNull(slice, "slice must not be null");
}
/**
@@ -154,7 +154,7 @@ public final class SaveEntry implements Parcelable {
"pendingIntent and credential both must not be null. Must set "
+ "either the pendingIntnet or the credential");
return new SaveEntry(
- mInfo,
+ mSlice,
mPendingIntent,
mCredential);
}
diff --git a/libs/WindowManager/Shell/res/drawable/decor_back_button_dark.xml b/libs/WindowManager/Shell/res/drawable/decor_back_button_dark.xml
new file mode 100644
index 000000000000..66e5b43d76af
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/decor_back_button_dark.xml
@@ -0,0 +1,32 @@
+<!--
+ ~ 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="8.0"
+ android:translateY="8.0" >
+ <path
+ android:fillColor="@android:color/black"
+ android:pathData="MM24,40.3 L7.7,24 24,7.7 26.8,10.45 15.3,22H40.3V26H15.3L26.8,37.5Z"/>
+
+ </group>
+</vector> \ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/decor_caption_title.xml b/libs/WindowManager/Shell/res/drawable/decor_caption_title.xml
index 8207365a737d..53a8bb18537c 100644
--- a/libs/WindowManager/Shell/res/drawable/decor_caption_title.xml
+++ b/libs/WindowManager/Shell/res/drawable/decor_caption_title.xml
@@ -15,8 +15,6 @@
~ limitations under the License.
-->
<shape android:shape="rectangle"
- android:tintMode="multiply"
- android:tint="@color/decor_caption_title_color"
xmlns:android="http://schemas.android.com/apk/res/android">
- <solid android:color="?android:attr/colorPrimary" />
+ <solid android:color="@android:color/white" />
</shape>
diff --git a/libs/WindowManager/Shell/res/drawable/decor_close_button_dark.xml b/libs/WindowManager/Shell/res/drawable/decor_close_button_dark.xml
index f2f1a1d55dee..851cbf26afc3 100644
--- a/libs/WindowManager/Shell/res/drawable/decor_close_button_dark.xml
+++ b/libs/WindowManager/Shell/res/drawable/decor_close_button_dark.xml
@@ -18,15 +18,13 @@
android:width="32.0dp"
android:height="32.0dp"
android:viewportWidth="32.0"
- android:viewportHeight="32.0"
- android:tint="@color/decor_button_dark_color"
- >
+ android:viewportHeight="32.0">
<group android:scaleX="0.5"
android:scaleY="0.5"
android:translateX="8.0"
android:translateY="8.0" >
<path
- android:fillColor="@android:color/white"
- android:pathData="M6.9,4.0l-2.9,2.9 9.1,9.1 -9.1,9.200001 2.9,2.799999 9.1,-9.1 9.1,9.1 2.9,-2.799999 -9.1,-9.200001 9.1,-9.1 -2.9,-2.9 -9.1,9.2z"/>
+ android:fillColor="@android:color/black"
+ 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>
</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/decor_handle_dark.xml b/libs/WindowManager/Shell/res/drawable/decor_handle_dark.xml
new file mode 100644
index 000000000000..ee0f4663c940
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/decor_handle_dark.xml
@@ -0,0 +1,23 @@
+<!--
+ ~ 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="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/black" android:pathData="M3,5V3H21V5Z"/>
+</vector>
diff --git a/libs/WindowManager/Shell/res/layout/caption_window_decoration.xml b/libs/WindowManager/Shell/res/layout/caption_window_decoration.xml
index d183e42c173b..38cd5702f134 100644
--- a/libs/WindowManager/Shell/res/layout/caption_window_decoration.xml
+++ b/libs/WindowManager/Shell/res/layout/caption_window_decoration.xml
@@ -17,39 +17,33 @@
<com.android.wm.shell.windowdecor.WindowDecorLinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/caption"
- android:layout_width="match_parent"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:gravity="end"
+ android:gravity="center_horizontal"
android:background="@drawable/decor_caption_title">
<Button
- android:id="@+id/minimize_window"
- android:visibility="gone"
+ android:id="@+id/back_button"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_margin="5dp"
android:padding="4dp"
- android:layout_gravity="top|end"
- android:contentDescription="@string/maximize_button_text"
- android:background="@drawable/decor_minimize_button_dark"
- android:duplicateParentState="true"/>
+ android:contentDescription="@string/back_button_text"
+ android:background="@drawable/decor_back_button_dark"
+ />
<Button
- android:id="@+id/maximize_window"
- android:layout_width="32dp"
+ android:id="@+id/caption_handle"
+ android:layout_width="128dp"
android:layout_height="32dp"
android:layout_margin="5dp"
android:padding="4dp"
- android:layout_gravity="center_vertical|end"
- android:contentDescription="@string/maximize_button_text"
- android:background="@drawable/decor_maximize_button_dark"
- android:duplicateParentState="true"/>
+ android:contentDescription="@string/handle_text"
+ android:background="@drawable/decor_handle_dark"/>
<Button
android:id="@+id/close_window"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_margin="5dp"
android:padding="4dp"
- android:layout_gravity="center_vertical|end"
android:contentDescription="@string/close_button_text"
- android:background="@drawable/decor_close_button_dark"
- android:duplicateParentState="true"/>
-</com.android.wm.shell.windowdecor.WindowDecorLinearLayout>
+ android:background="@drawable/decor_close_button_dark"/>
+</com.android.wm.shell.windowdecor.WindowDecorLinearLayout> \ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/values/strings.xml b/libs/WindowManager/Shell/res/values/strings.xml
index b48a508fddb8..4807f08b4bed 100644
--- a/libs/WindowManager/Shell/res/values/strings.xml
+++ b/libs/WindowManager/Shell/res/values/strings.xml
@@ -198,4 +198,8 @@
<string name="minimize_button_text">Minimize</string>
<!-- Accessibility text for the close window button [CHAR LIMIT=NONE] -->
<string name="close_button_text">Close</string>
+ <!-- Accessibility text for the caption back button [CHAR LIMIT=NONE] -->
+ <string name="back_button_text">Back</string>
+ <!-- Accessibility text for the caption handle [CHAR LIMIT=NONE] -->
+ <string name="handle_text">Handle</string>
</resources>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index 1ec98d3e94f3..f1670cd792cf 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -191,13 +191,13 @@ public abstract class WMShellModule {
SyncTransactionQueue syncQueue,
@DynamicOverride DesktopModeController desktopModeController) {
return new CaptionWindowDecorViewModel(
- context,
- mainHandler,
- mainChoreographer,
- taskOrganizer,
- displayController,
- syncQueue,
- desktopModeController);
+ context,
+ mainHandler,
+ mainChoreographer,
+ taskOrganizer,
+ displayController,
+ syncQueue,
+ desktopModeController);
}
//
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
index 3df33f346e84..dca516a327b0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
@@ -19,15 +19,20 @@ package com.android.wm.shell.windowdecor;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityTaskManager;
import android.content.Context;
+import android.hardware.input.InputManager;
import android.os.Handler;
+import android.os.SystemClock;
+import android.util.Log;
import android.util.SparseArray;
import android.view.Choreographer;
+import android.view.InputDevice;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceControl;
import android.view.View;
@@ -47,7 +52,9 @@ import com.android.wm.shell.transition.Transitions;
* View model for the window decoration with a caption and shadows. Works with
* {@link CaptionWindowDecoration}.
*/
+
public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
+ private static final String TAG = "CaptionViewModel";
private final ActivityTaskManager mActivityTaskManager;
private final ShellTaskOrganizer mTaskOrganizer;
private final Context mContext;
@@ -107,7 +114,6 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
windowDecoration.setCaptionListeners(touchEventListener, touchEventListener);
windowDecoration.setDragResizeCallback(taskPositioner);
setupWindowDecorationForTransition(taskInfo, startT, finishT);
- setupCaptionColor(taskInfo, windowDecoration);
return true;
}
@@ -117,12 +123,6 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
if (decoration == null) return;
decoration.relayout(taskInfo);
- setupCaptionColor(taskInfo, decoration);
- }
-
- private void setupCaptionColor(RunningTaskInfo taskInfo, CaptionWindowDecoration decoration) {
- int statusBarColor = taskInfo.taskDescription.getStatusBarColor();
- decoration.setCaptionColor(statusBarColor);
}
@Override
@@ -153,6 +153,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
private final DragResizeCallback mDragResizeCallback;
private int mDragPointerId = -1;
+ private boolean mDragActive = false;
private CaptionTouchEventListener(
RunningTaskInfo taskInfo,
@@ -173,42 +174,38 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
} else {
mSyncQueue.queue(wct);
}
- } else if (id == R.id.maximize_window) {
- WindowContainerTransaction wct = new WindowContainerTransaction();
- RunningTaskInfo taskInfo = mTaskOrganizer.getRunningTaskInfo(mTaskId);
- int targetWindowingMode = taskInfo.getWindowingMode() != WINDOWING_MODE_FULLSCREEN
- ? WINDOWING_MODE_FULLSCREEN : WINDOWING_MODE_FREEFORM;
- int displayWindowingMode =
- taskInfo.configuration.windowConfiguration.getDisplayWindowingMode();
- wct.setWindowingMode(mTaskToken,
- targetWindowingMode == displayWindowingMode
- ? WINDOWING_MODE_UNDEFINED : targetWindowingMode);
- if (targetWindowingMode == WINDOWING_MODE_FULLSCREEN) {
- wct.setBounds(mTaskToken, null);
- }
- if (Transitions.ENABLE_SHELL_TRANSITIONS) {
- mTransitionStarter.startWindowingModeTransition(targetWindowingMode, wct);
- } else {
- mSyncQueue.queue(wct);
- }
- } else if (id == R.id.minimize_window) {
- WindowContainerTransaction wct = new WindowContainerTransaction();
- wct.reorder(mTaskToken, false);
- if (Transitions.ENABLE_SHELL_TRANSITIONS) {
- mTransitionStarter.startMinimizedModeTransition(wct);
- } else {
- mSyncQueue.queue(wct);
- }
+ } else if (id == R.id.back_button) {
+ injectBackKey();
+ }
+ }
+ private void injectBackKey() {
+ sendBackEvent(KeyEvent.ACTION_DOWN);
+ sendBackEvent(KeyEvent.ACTION_UP);
+ }
+
+ private void sendBackEvent(int action) {
+ final long when = SystemClock.uptimeMillis();
+ final KeyEvent ev = new KeyEvent(when, when, action, KeyEvent.KEYCODE_BACK,
+ 0 /* repeat */, 0 /* metaState */, KeyCharacterMap.VIRTUAL_KEYBOARD,
+ 0 /* scancode */, KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
+ InputDevice.SOURCE_KEYBOARD);
+
+ ev.setDisplayId(mContext.getDisplay().getDisplayId());
+ if (!InputManager.getInstance()
+ .injectInputEvent(ev, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC)) {
+ Log.e(TAG, "Inject input event fail");
}
}
@Override
public boolean onTouch(View v, MotionEvent e) {
- if (v.getId() != R.id.caption) {
+ int id = v.getId();
+ if (id != R.id.caption_handle && id != R.id.caption) {
return false;
}
- handleEventForMove(e);
-
+ if (id == R.id.caption_handle || mDragActive) {
+ handleEventForMove(e);
+ }
if (e.getAction() != MotionEvent.ACTION_DOWN) {
return false;
}
@@ -231,6 +228,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
}
switch (e.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
+ mDragActive = true;
mDragPointerId = e.getPointerId(0);
mDragResizeCallback.onDragResizeStart(
0 /* ctrlType */, e.getRawX(0), e.getRawY(0));
@@ -243,6 +241,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL: {
+ mDragActive = false;
int dragPointerIdx = e.findPointerIndex(mDragPointerId);
int statusBarHeight = mDisplayController.getDisplayLayout(taskInfo.displayId)
.stableInsets().top;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
index 733f6b7d5dbf..beace75d9fca 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
@@ -22,12 +22,12 @@ import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.Rect;
-import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.VectorDrawable;
import android.os.Handler;
import android.view.Choreographer;
import android.view.SurfaceControl;
import android.view.View;
+import android.view.ViewConfiguration;
import android.window.WindowContainerTransaction;
import com.android.wm.shell.R;
@@ -38,11 +38,7 @@ import com.android.wm.shell.desktopmode.DesktopModeStatus;
/**
* Defines visuals and behaviors of a window decoration of a caption bar and shadows. It works with
- * {@link CaptionWindowDecorViewModel}. The caption bar contains maximize and close buttons.
- *
- * {@link CaptionWindowDecorViewModel} can change the color of the caption bar based on the foremost
- * app's request through {@link #setCaptionColor(int)}, in which it changes the foreground color of
- * caption buttons according to the luminance of the background.
+ * {@link CaptionWindowDecorViewModel}. The caption bar contains a handle, back button, and close button.
*
* The shadow's thickness is 20dp when the window is in focus and 5dp when the window isn't.
*/
@@ -54,7 +50,10 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
// Height of button (32dp) + 2 * margin (5dp each)
private static final int DECOR_CAPTION_HEIGHT_IN_DIP = 42;
+ // Width of buttons (64dp) + handle (128dp) + padding (24dp total)
+ private static final int DECOR_CAPTION_WIDTH_IN_DIP = 216;
private static final int RESIZE_HANDLE_IN_DIP = 30;
+ private static final int RESIZE_CORNER_IN_DIP = 44;
private static final Rect EMPTY_OUTSET = new Rect();
private static final Rect RESIZE_HANDLE_OUTSET = new Rect(
@@ -73,6 +72,8 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
private final WindowDecoration.RelayoutResult<WindowDecorLinearLayout> mResult =
new WindowDecoration.RelayoutResult<>();
+ private boolean mDesktopActive;
+
CaptionWindowDecoration(
Context context,
DisplayController displayController,
@@ -87,6 +88,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
mHandler = handler;
mChoreographer = choreographer;
mSyncQueue = syncQueue;
+ mDesktopActive = DesktopModeStatus.isActive(mContext);
}
void setCaptionListeners(
@@ -123,8 +125,8 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
final SurfaceControl oldDecorationSurface = mDecorationContainerSurface;
final WindowContainerTransaction wct = new WindowContainerTransaction();
relayout(taskInfo, R.layout.caption_window_decoration, oldRootView,
- DECOR_CAPTION_HEIGHT_IN_DIP, outset, shadowRadiusDp, startT, finishT, wct, mResult);
- taskInfo = null; // Clear it just in case we use it accidentally
+ DECOR_CAPTION_HEIGHT_IN_DIP, DECOR_CAPTION_WIDTH_IN_DIP, outset, shadowRadiusDp,
+ startT, finishT, wct, mResult);
mTaskOrganizer.applyTransaction(wct);
@@ -137,6 +139,17 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
setupRootView();
}
+ // If this task is not focused, do not show caption.
+ setCaptionVisibility(taskInfo.isFocused);
+
+ // Only handle should show if Desktop Mode is inactive.
+ boolean desktopCurrentStatus = DesktopModeStatus.isActive(mContext);
+ if (mDesktopActive != desktopCurrentStatus && taskInfo.isFocused) {
+ mDesktopActive = desktopCurrentStatus;
+ setButtonVisibility();
+ }
+ taskInfo = null; // Clear it just in case we use it accidentally
+
if (!isDragResizeable) {
closeDragResizeListener();
return;
@@ -145,16 +158,19 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
if (oldDecorationSurface != mDecorationContainerSurface || mDragResizeListener == null) {
closeDragResizeListener();
mDragResizeListener = new DragResizeInputListener(
- mContext,
- mHandler,
- mChoreographer,
- mDisplay.getDisplayId(),
- mDecorationContainerSurface,
- mDragResizeCallback);
+ mContext,
+ mHandler,
+ mChoreographer,
+ mDisplay.getDisplayId(),
+ mDecorationContainerSurface,
+ mDragResizeCallback);
}
+ int touchSlop = ViewConfiguration.get(mResult.mRootView.getContext()).getScaledTouchSlop();
+
mDragResizeListener.setGeometry(
- mResult.mWidth, mResult.mHeight, (int) (mResult.mDensity * RESIZE_HANDLE_IN_DIP));
+ mResult.mWidth, mResult.mHeight, (int) (mResult.mDensity * RESIZE_HANDLE_IN_DIP),
+ (int) (mResult.mDensity * RESIZE_CORNER_IN_DIP), touchSlop);
}
/**
@@ -163,42 +179,46 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
private void setupRootView() {
View caption = mResult.mRootView.findViewById(R.id.caption);
caption.setOnTouchListener(mOnCaptionTouchListener);
- View maximize = caption.findViewById(R.id.maximize_window);
- if (DesktopModeStatus.IS_SUPPORTED) {
- // Hide maximize button when desktop mode is available
- maximize.setVisibility(View.GONE);
- } else {
- maximize.setVisibility(View.VISIBLE);
- maximize.setOnClickListener(mOnCaptionButtonClickListener);
- }
View close = caption.findViewById(R.id.close_window);
close.setOnClickListener(mOnCaptionButtonClickListener);
- View minimize = caption.findViewById(R.id.minimize_window);
- minimize.setOnClickListener(mOnCaptionButtonClickListener);
+ View back = caption.findViewById(R.id.back_button);
+ back.setOnClickListener(mOnCaptionButtonClickListener);
+ View handle = caption.findViewById(R.id.caption_handle);
+ handle.setOnTouchListener(mOnCaptionTouchListener);
+ setButtonVisibility();
}
- void setCaptionColor(int captionColor) {
- if (mResult.mRootView == null) {
- return;
- }
-
+ /**
+ * Sets caption visibility based on task focus.
+ *
+ * @param visible whether or not the caption should be visible
+ */
+ private void setCaptionVisibility(boolean visible) {
+ int v = visible ? View.VISIBLE : View.GONE;
View caption = mResult.mRootView.findViewById(R.id.caption);
- GradientDrawable captionDrawable = (GradientDrawable) caption.getBackground();
- captionDrawable.setColor(captionColor);
+ caption.setVisibility(v);
+ }
+ /**
+ * Sets the visibility of buttons and color of caption based on desktop mode status
+ *
+ */
+ public void setButtonVisibility() {
+ int v = mDesktopActive ? View.VISIBLE : View.GONE;
+ View caption = mResult.mRootView.findViewById(R.id.caption);
+ View back = caption.findViewById(R.id.back_button);
+ View close = caption.findViewById(R.id.close_window);
+ back.setVisibility(v);
+ close.setVisibility(v);
int buttonTintColorRes =
- Color.valueOf(captionColor).luminance() < 0.5
- ? R.color.decor_button_light_color
- : R.color.decor_button_dark_color;
+ mDesktopActive ? R.color.decor_button_dark_color
+ : R.color.decor_button_light_color;
ColorStateList buttonTintColor =
caption.getResources().getColorStateList(buttonTintColorRes, null /* theme */);
- View maximize = caption.findViewById(R.id.maximize_window);
- VectorDrawable maximizeBackground = (VectorDrawable) maximize.getBackground();
- maximizeBackground.setTintList(buttonTintColor);
-
- View close = caption.findViewById(R.id.close_window);
- VectorDrawable closeBackground = (VectorDrawable) close.getBackground();
- closeBackground.setTintList(buttonTintColor);
+ View handle = caption.findViewById(R.id.caption_handle);
+ VectorDrawable handleBackground = (VectorDrawable) handle.getBackground();
+ handleBackground.setTintList(buttonTintColor);
+ caption.setBackgroundColor(v == View.VISIBLE ? Color.WHITE : Color.TRANSPARENT);
}
private void closeDragResizeListener() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
index 3d014959a952..b9f16b63de48 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
@@ -16,11 +16,13 @@
package com.android.wm.shell.windowdecor;
+import static android.view.InputDevice.SOURCE_TOUCHSCREEN;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import android.content.Context;
+import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.Region;
import android.hardware.input.InputManager;
@@ -42,8 +44,11 @@ import com.android.internal.view.BaseIWindow;
/**
* An input event listener registered to InputDispatcher to receive input events on task edges and
- * convert them to drag resize requests.
+ * and corners. Converts them to drag resize requests.
+ * Task edges are for resizing with a mouse.
+ * Task corners are for resizing with touch input.
*/
+// TODO(b/251270585): investigate how to pass taps in corners to the tasks
class DragResizeInputListener implements AutoCloseable {
private static final String TAG = "DragResizeInputListener";
@@ -63,8 +68,15 @@ class DragResizeInputListener implements AutoCloseable {
private int mWidth;
private int mHeight;
private int mResizeHandleThickness;
+ private int mCornerSize;
+
+ private Rect mLeftTopCornerBounds;
+ private Rect mRightTopCornerBounds;
+ private Rect mLeftBottomCornerBounds;
+ private Rect mRightBottomCornerBounds;
private int mDragPointerId = -1;
+ private int mTouchSlop;
DragResizeInputListener(
Context context,
@@ -118,16 +130,23 @@ class DragResizeInputListener implements AutoCloseable {
* @param height The height of the drag resize handler in pixels, including resize handle
* thickness. That is task height + 2 * resize handle thickness.
* @param resizeHandleThickness The thickness of the resize handle in pixels.
+ * @param cornerSize The size of the resize handle centered in each corner.
+ * @param touchSlop The distance in pixels user has to drag with touch for it to register as
+ * a resize action.
*/
- void setGeometry(int width, int height, int resizeHandleThickness) {
+ void setGeometry(int width, int height, int resizeHandleThickness, int cornerSize,
+ int touchSlop) {
if (mWidth == width && mHeight == height
- && mResizeHandleThickness == resizeHandleThickness) {
+ && mResizeHandleThickness == resizeHandleThickness
+ && mCornerSize == cornerSize) {
return;
}
mWidth = width;
mHeight = height;
mResizeHandleThickness = resizeHandleThickness;
+ mCornerSize = cornerSize;
+ mTouchSlop = touchSlop;
Region touchRegion = new Region();
final Rect topInputBounds = new Rect(0, 0, mWidth, mResizeHandleThickness);
@@ -146,6 +165,40 @@ class DragResizeInputListener implements AutoCloseable {
mWidth, mHeight);
touchRegion.union(bottomInputBounds);
+ // Set up touch areas in each corner.
+ int cornerRadius = mCornerSize / 2;
+ mLeftTopCornerBounds = new Rect(
+ mResizeHandleThickness - cornerRadius,
+ mResizeHandleThickness - cornerRadius,
+ mResizeHandleThickness + cornerRadius,
+ mResizeHandleThickness + cornerRadius
+ );
+ touchRegion.union(mLeftTopCornerBounds);
+
+ mRightTopCornerBounds = new Rect(
+ mWidth - mResizeHandleThickness - cornerRadius,
+ mResizeHandleThickness - cornerRadius,
+ mWidth - mResizeHandleThickness + cornerRadius,
+ mResizeHandleThickness + cornerRadius
+ );
+ touchRegion.union(mRightTopCornerBounds);
+
+ mLeftBottomCornerBounds = new Rect(
+ mResizeHandleThickness - cornerRadius,
+ mHeight - mResizeHandleThickness - cornerRadius,
+ mResizeHandleThickness + cornerRadius,
+ mHeight - mResizeHandleThickness + cornerRadius
+ );
+ touchRegion.union(mLeftBottomCornerBounds);
+
+ mRightBottomCornerBounds = new Rect(
+ mWidth - mResizeHandleThickness - cornerRadius,
+ mHeight - mResizeHandleThickness - cornerRadius,
+ mWidth - mResizeHandleThickness + cornerRadius,
+ mHeight - mResizeHandleThickness + cornerRadius
+ );
+ touchRegion.union(mRightBottomCornerBounds);
+
try {
mWindowSession.updateInputChannel(
mInputChannel.getToken(),
@@ -173,6 +226,9 @@ class DragResizeInputListener implements AutoCloseable {
private final Choreographer mChoreographer;
private final Runnable mConsumeBatchEventRunnable;
private boolean mConsumeBatchEventScheduled;
+ private boolean mShouldHandleEvents;
+ private boolean mDragging;
+ private final PointF mActionDownPoint = new PointF();
private TaskResizeInputEventReceiver(
InputChannel inputChannel, Handler handler, Choreographer choreographer) {
@@ -216,41 +272,101 @@ class DragResizeInputListener implements AutoCloseable {
}
MotionEvent e = (MotionEvent) inputEvent;
+ boolean result = false;
+ // Check if this is a touch event vs mouse event.
+ // Touch events are tracked in four corners. Other events are tracked in resize edges.
+ boolean isTouch = (e.getSource() & SOURCE_TOUCHSCREEN) == SOURCE_TOUCHSCREEN;
+
switch (e.getActionMasked()) {
case MotionEvent.ACTION_DOWN: {
- mDragPointerId = e.getPointerId(0);
- mCallback.onDragResizeStart(
- calculateCtrlType(e.getX(0), e.getY(0)), e.getRawX(0), e.getRawY(0));
+ float x = e.getX(0);
+ float y = e.getY(0);
+ if (isTouch) {
+ mShouldHandleEvents = isInCornerBounds(x, y);
+ } else {
+ mShouldHandleEvents = isInResizeHandleBounds(x, y);
+ }
+ if (mShouldHandleEvents) {
+ mDragPointerId = e.getPointerId(0);
+ float rawX = e.getRawX(0);
+ float rawY = e.getRawY(0);
+ mActionDownPoint.set(rawX, rawY);
+ int ctrlType = calculateCtrlType(isTouch, x, y);
+ mCallback.onDragResizeStart(ctrlType, rawX, rawY);
+ result = true;
+ }
break;
}
case MotionEvent.ACTION_MOVE: {
+ if (!mShouldHandleEvents) {
+ break;
+ }
int dragPointerIndex = e.findPointerIndex(mDragPointerId);
- mCallback.onDragResizeMove(
- e.getRawX(dragPointerIndex), e.getRawY(dragPointerIndex));
+ float rawX = e.getRawX(dragPointerIndex);
+ float rawY = e.getRawY(dragPointerIndex);
+ if (isTouch) {
+ // Check for touch slop for touch events
+ float dx = rawX - mActionDownPoint.x;
+ float dy = rawY - mActionDownPoint.y;
+ if (!mDragging && Math.hypot(dx, dy) > mTouchSlop) {
+ mDragging = true;
+ }
+ } else {
+ // For all other types allow immediate dragging.
+ mDragging = true;
+ }
+ if (mDragging) {
+ mCallback.onDragResizeMove(rawX, rawY);
+ result = true;
+ }
break;
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL: {
- int dragPointerIndex = e.findPointerIndex(mDragPointerId);
- mCallback.onDragResizeEnd(
- e.getRawX(dragPointerIndex), e.getRawY(dragPointerIndex));
+ if (mDragging) {
+ int dragPointerIndex = e.findPointerIndex(mDragPointerId);
+ mCallback.onDragResizeEnd(
+ e.getRawX(dragPointerIndex), e.getRawY(dragPointerIndex));
+ }
+ mDragging = false;
+ mShouldHandleEvents = false;
+ mActionDownPoint.set(0, 0);
mDragPointerId = -1;
+ result = true;
break;
}
case MotionEvent.ACTION_HOVER_ENTER:
case MotionEvent.ACTION_HOVER_MOVE: {
updateCursorType(e.getXCursorPosition(), e.getYCursorPosition());
+ result = true;
break;
}
case MotionEvent.ACTION_HOVER_EXIT:
mInputManager.setPointerIconType(PointerIcon.TYPE_DEFAULT);
+ result = true;
break;
}
- return true;
+ return result;
+ }
+
+ private boolean isInCornerBounds(float xf, float yf) {
+ return calculateCornersCtrlType(xf, yf) != 0;
+ }
+
+ private boolean isInResizeHandleBounds(float x, float y) {
+ return calculateResizeHandlesCtrlType(x, y) != 0;
+ }
+
+ @TaskPositioner.CtrlType
+ private int calculateCtrlType(boolean isTouch, float x, float y) {
+ if (isTouch) {
+ return calculateCornersCtrlType(x, y);
+ }
+ return calculateResizeHandlesCtrlType(x, y);
}
@TaskPositioner.CtrlType
- private int calculateCtrlType(float x, float y) {
+ private int calculateResizeHandlesCtrlType(float x, float y) {
int ctrlType = 0;
if (x < mResizeHandleThickness) {
ctrlType |= TaskPositioner.CTRL_TYPE_LEFT;
@@ -267,8 +383,27 @@ class DragResizeInputListener implements AutoCloseable {
return ctrlType;
}
+ @TaskPositioner.CtrlType
+ private int calculateCornersCtrlType(float x, float y) {
+ int xi = (int) x;
+ int yi = (int) y;
+ if (mLeftTopCornerBounds.contains(xi, yi)) {
+ return TaskPositioner.CTRL_TYPE_LEFT | TaskPositioner.CTRL_TYPE_TOP;
+ }
+ if (mLeftBottomCornerBounds.contains(xi, yi)) {
+ return TaskPositioner.CTRL_TYPE_LEFT | TaskPositioner.CTRL_TYPE_BOTTOM;
+ }
+ if (mRightTopCornerBounds.contains(xi, yi)) {
+ return TaskPositioner.CTRL_TYPE_RIGHT | TaskPositioner.CTRL_TYPE_TOP;
+ }
+ if (mRightBottomCornerBounds.contains(xi, yi)) {
+ return TaskPositioner.CTRL_TYPE_RIGHT | TaskPositioner.CTRL_TYPE_BOTTOM;
+ }
+ return 0;
+ }
+
private void updateCursorType(float x, float y) {
- @TaskPositioner.CtrlType int ctrlType = calculateCtrlType(x, y);
+ @TaskPositioner.CtrlType int ctrlType = calculateResizeHandlesCtrlType(x, y);
int cursorType = PointerIcon.TYPE_DEFAULT;
switch (ctrlType) {
@@ -292,4 +427,4 @@ class DragResizeInputListener implements AutoCloseable {
mInputManager.setPointerIconType(cursorType);
}
}
-}
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskPositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskPositioner.java
index 280569b05d87..27c10114ac0e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskPositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskPositioner.java
@@ -25,9 +25,10 @@ import com.android.wm.shell.ShellTaskOrganizer;
class TaskPositioner implements DragResizeCallback {
- @IntDef({CTRL_TYPE_LEFT, CTRL_TYPE_RIGHT, CTRL_TYPE_TOP, CTRL_TYPE_BOTTOM})
+ @IntDef({CTRL_TYPE_UNDEFINED, CTRL_TYPE_LEFT, CTRL_TYPE_RIGHT, CTRL_TYPE_TOP, CTRL_TYPE_BOTTOM})
@interface CtrlType {}
+ static final int CTRL_TYPE_UNDEFINED = 0;
static final int CTRL_TYPE_LEFT = 1;
static final int CTRL_TYPE_RIGHT = 2;
static final int CTRL_TYPE_TOP = 4;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
index 3e3a864f48c7..bf863ea2c7ab 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
@@ -143,9 +143,9 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
abstract void relayout(RunningTaskInfo taskInfo);
void relayout(RunningTaskInfo taskInfo, int layoutResId, T rootView, float captionHeightDp,
- Rect outsetsDp, float shadowRadiusDp, SurfaceControl.Transaction startT,
- SurfaceControl.Transaction finishT, WindowContainerTransaction wct,
- RelayoutResult<T> outResult) {
+ float captionWidthDp, Rect outsetsDp, float shadowRadiusDp,
+ SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
+ WindowContainerTransaction wct, RelayoutResult<T> outResult) {
outResult.reset();
final Configuration oldTaskConfig = mTaskInfo.getConfiguration();
@@ -249,8 +249,15 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
}
final int captionHeight = (int) Math.ceil(captionHeightDp * outResult.mDensity);
+ final int captionWidth = (int) Math.ceil(captionWidthDp * outResult.mDensity);
+
+ //Prevent caption from going offscreen if task is too high up
+ final int captionYPos = taskBounds.top <= captionHeight / 2 ? 0 : captionHeight / 2;
+
startT.setPosition(
- mCaptionContainerSurface, -decorContainerOffsetX, -decorContainerOffsetY)
+ mCaptionContainerSurface, -decorContainerOffsetX
+ + taskBounds.width() / 2 - captionWidth / 2,
+ -decorContainerOffsetY - captionYPos)
.setWindowCrop(mCaptionContainerSurface, taskBounds.width(), captionHeight)
.show(mCaptionContainerSurface);
@@ -264,7 +271,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
// Caption view
mCaptionWindowManager.setConfiguration(taskConfig);
final WindowManager.LayoutParams lp =
- new WindowManager.LayoutParams(taskBounds.width(), captionHeight,
+ new WindowManager.LayoutParams(captionWidth, captionHeight,
WindowManager.LayoutParams.TYPE_APPLICATION,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT);
lp.setTitle("Caption of Task=" + mTaskInfo.taskId);
@@ -282,7 +289,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
// Caption insets
mCaptionInsetsRect.set(taskBounds);
- mCaptionInsetsRect.bottom = mCaptionInsetsRect.top + captionHeight;
+ mCaptionInsetsRect.bottom = mCaptionInsetsRect.top + captionHeight - captionYPos;
wct.addRectInsetsProvider(mTaskInfo.token, mCaptionInsetsRect, CAPTION_INSETS_TYPES);
} else {
startT.hide(mCaptionContainerSurface);
@@ -388,4 +395,4 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
return new SurfaceControlViewHost(c, d, wmm);
}
}
-}
+} \ No newline at end of file
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 ab6ac949d4a3..fa62b9c00fc7 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
@@ -77,6 +77,7 @@ import java.util.function.Supplier;
@RunWith(AndroidTestingRunner.class)
public class WindowDecorationTests extends ShellTestCase {
private static final int CAPTION_HEIGHT_DP = 32;
+ private static final int CAPTION_WIDTH_DP = 216;
private static final int SHADOW_RADIUS_DP = 5;
private static final Rect TASK_BOUNDS = new Rect(100, 300, 400, 400);
private static final Point TASK_POSITION_IN_PARENT = new Point(40, 60);
@@ -220,7 +221,7 @@ public class WindowDecorationTests extends ShellTestCase {
verify(captionContainerSurfaceBuilder).setParent(decorContainerSurface);
verify(captionContainerSurfaceBuilder).setContainerLayer();
- verify(mMockSurfaceControlStartT).setPosition(captionContainerSurface, 20, 40);
+ verify(mMockSurfaceControlStartT).setPosition(captionContainerSurface, -46, 8);
verify(mMockSurfaceControlStartT).setWindowCrop(captionContainerSurface, 300, 64);
verify(mMockSurfaceControlStartT).show(captionContainerSurface);
@@ -410,7 +411,7 @@ public class WindowDecorationTests extends ShellTestCase {
@Override
void relayout(ActivityManager.RunningTaskInfo taskInfo) {
relayout(null /* taskInfo */, 0 /* layoutResId */, mMockView, CAPTION_HEIGHT_DP,
- mOutsetsDp, SHADOW_RADIUS_DP, mMockSurfaceControlStartT,
+ CAPTION_WIDTH_DP, mOutsetsDp, SHADOW_RADIUS_DP, mMockSurfaceControlStartT,
mMockSurfaceControlFinishT, mMockWindowContainerTransaction, mRelayoutResult);
}
}
diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h
index 24443c8c9836..7170226037f9 100644
--- a/libs/hwui/Rect.h
+++ b/libs/hwui/Rect.h
@@ -71,9 +71,14 @@ public:
, right(rect.fRight)
, bottom(rect.fBottom) {}
- friend int operator==(const Rect& a, const Rect& b) { return !memcmp(&a, &b, sizeof(a)); }
+ friend int operator==(const Rect& a, const Rect& b) {
+ return a.left == b.left &&
+ a.top == b.top &&
+ a.right == b.right &&
+ a.bottom == b.bottom;
+ }
- friend int operator!=(const Rect& a, const Rect& b) { return memcmp(&a, &b, sizeof(a)); }
+ friend int operator!=(const Rect& a, const Rect& b) { return !(a == b); }
inline void clear() { left = top = right = bottom = 0.0f; }
diff --git a/media/java/android/media/MediaMuxer.java b/media/java/android/media/MediaMuxer.java
index c63a5d8d36a2..30f4562bbf28 100644
--- a/media/java/android/media/MediaMuxer.java
+++ b/media/java/android/media/MediaMuxer.java
@@ -335,13 +335,13 @@ final public class MediaMuxer {
}
/**
- * Constructor.
* Creates a media muxer that writes to the specified path.
+ * <p>The caller must not use the file {@code path} before calling {@link #stop}.
* @param path The path of the output media file.
* @param format The format of the output media file.
* @see android.media.MediaMuxer.OutputFormat
* @throws IllegalArgumentException if path is invalid or format is not supported.
- * @throws IOException if failed to open the file for write.
+ * @throws IOException if an error occurs while opening or creating the output file.
*/
public MediaMuxer(@NonNull String path, @Format int format) throws IOException {
if (path == null) {
@@ -363,16 +363,19 @@ final public class MediaMuxer {
}
/**
- * Constructor.
- * Creates a media muxer that writes to the specified FileDescriptor. File descriptor
- * must be seekable and writable. Application should not use the file referenced
- * by this file descriptor until {@link #stop}. It is the application's responsibility
- * to close the file descriptor. It is safe to do so as soon as this call returns.
- * @param fd The FileDescriptor of the output media file.
+ * Creates a media muxer that writes to the specified FileDescriptor.
+ * <p>The caller must not use the file referenced by the specified {@code fd} before calling
+ * {@link #stop}.
+ * <p>It is the caller's responsibility to close the file descriptor, which is safe to do so
+ * as soon as this call returns.
+ * @param fd The FileDescriptor of the output media file. If {@code format} is
+ * {@link OutputFormat#MUXER_OUTPUT_WEBM}, {@code fd} must be open in read-write mode.
+ * Otherwise, write mode is sufficient, but read-write is also accepted.
* @param format The format of the output media file.
* @see android.media.MediaMuxer.OutputFormat
- * @throws IllegalArgumentException if fd is invalid or format is not supported.
- * @throws IOException if failed to open the file for write.
+ * @throws IllegalArgumentException if {@code format} is not supported, or if {@code fd} is
+ * not open in the expected mode.
+ * @throws IOException if an error occurs while performing an IO operation.
*/
public MediaMuxer(@NonNull FileDescriptor fd, @Format int format) throws IOException {
setUpMediaMuxer(fd, format);
diff --git a/media/jni/android_media_MediaMuxer.cpp b/media/jni/android_media_MediaMuxer.cpp
index 267917653efb..b664325ab0d1 100644
--- a/media/jni/android_media_MediaMuxer.cpp
+++ b/media/jni/android_media_MediaMuxer.cpp
@@ -165,7 +165,11 @@ static jlong android_media_MediaMuxer_native_setup(
MediaMuxer::OutputFormat fileFormat =
static_cast<MediaMuxer::OutputFormat>(format);
- sp<MediaMuxer> muxer = new MediaMuxer(fd, fileFormat);
+ sp<MediaMuxer> muxer = MediaMuxer::create(fd, fileFormat);
+ if (muxer == nullptr) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", "Muxer creation failed");
+ return 0;
+ }
muxer->incStrong(clazz);
return reinterpret_cast<jlong>(muxer.get());
}
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 705cccbbd0d7..3b00d26fe793 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -106,7 +106,7 @@
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"المكالمات الهاتفية"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"نقل الملف"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"جهاز الإرسال"</string>
- <string name="bluetooth_profile_pan" msgid="1006235139308318188">"استخدام الإنترنت"</string>
+ <string name="bluetooth_profile_pan" msgid="1006235139308318188">"الوصول إلى الإنترنت"</string>
<string name="bluetooth_profile_pbap" msgid="4262303387989406171">"مشاركة جهات الاتصال وسجل المكالمات"</string>
<string name="bluetooth_profile_pbap_summary" msgid="6466456791354759132">"استخدام إعدادات بلوتوث لمشاركة جهات الاتصال وسجل المكالمات"</string>
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"مشاركة اتصال الإنترنت"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index ba0d30283443..e13ffce7cdd5 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -70,7 +70,7 @@
<string name="wifi_limited_connection" msgid="1184778285475204682">"ইণ্টাৰনেট সংযোগ সীমিত"</string>
<string name="wifi_status_no_internet" msgid="3799933875988829048">"ইণ্টাৰনেট সংযোগ নাই"</string>
<string name="wifi_status_sign_in_required" msgid="2236267500459526855">"ছাইন ইন কৰা দৰকাৰী"</string>
- <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"একচেছ পইণ্ট কিছু সময়ৰ বাবে পূৰ্ণ হৈ আছে"</string>
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"এক্সেছ পইণ্ট সাময়িকভাৱে পূৰ্ণ হৈ আছে"</string>
<string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> খুলি থকা হৈছে"</string>
<string name="osu_connect_failed" msgid="9107873364807159193">"সংযোগ কৰিব পৰা নগ’ল"</string>
<string name="osu_completing_sign_up" msgid="8412636665040390901">"ছাইন আপ সম্পূৰ্ণ কৰি থকা হৈছে…"</string>
@@ -129,7 +129,7 @@
<string name="bluetooth_pan_nap_profile_summary_connected" msgid="3744773111299503493">"ডিভাইচৰ সৈতে স্থানীয় ইণ্টাৰনেট সংযোগ শ্বেয়াৰ কৰা হৈছে"</string>
<string name="bluetooth_pan_profile_summary_use_for" msgid="7422039765025340313">"ইণ্টাৰনেট চলাবলৈ ব্যৱহাৰ কৰক"</string>
<string name="bluetooth_map_profile_summary_use_for" msgid="4453622103977592583">"মেপৰ বাবে ব্যৱহাৰ কৰক"</string>
- <string name="bluetooth_sap_profile_summary_use_for" msgid="6204902866176714046">"ছিমত প্ৰৱেশৰ বাবে ব্যৱহাৰ কৰক"</string>
+ <string name="bluetooth_sap_profile_summary_use_for" msgid="6204902866176714046">"ছিমৰ এক্সেছৰ বাবে ব্যৱহাৰ কৰক"</string>
<string name="bluetooth_a2dp_profile_summary_use_for" msgid="7324694226276491807">"মিডিয়া অডিঅ\'ৰ বাবে ব্যৱহাৰ কৰক"</string>
<string name="bluetooth_headset_profile_summary_use_for" msgid="808970643123744170">"ফ\'ন অডিঅ\'ৰ বাবে ব্যৱহাৰ কৰক"</string>
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"ফাইল স্থানান্তৰ কৰিবলৈ ব্যৱহাৰ কৰক"</string>
@@ -139,7 +139,7 @@
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"পেয়াৰ কৰক"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"পেয়াৰ কৰক"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"বাতিল কৰক"</string>
- <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"যোৰা লগালে ইয়ে সংযোজিত কৰাৰ সময়ত আপোনাৰ সম্পৰ্কসমূহ আৰু কলৰ ইতিহাস চাবলৈ অনুমতি দিব।"</string>
+ <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"পেয়াৰিঙে সংযোজিত হ\'লে আপোনাৰ সম্পৰ্ক আৰু কলৰ ইতিহাসৰ এক্সেছ প্ৰদান কৰে।"</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>ৰ সৈতে পেয়াৰ কৰিব পৰা নগ’ল।"</string>
<string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"এটা ভুল পিন বা পাছকীৰ কাৰণে <xliff:g id="DEVICE_NAME">%1$s</xliff:g>ৰ সৈতে পেয়াৰ কৰিব পৰা নাই।"</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>ৰ সৈতে যোগাযোগ কৰিব পৰা নগ\'ল"</string>
@@ -332,7 +332,7 @@
<string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"ব্লুটুথ Gabeldorche সুবিধাৰ সমষ্টিটো সক্ষম কৰে।"</string>
<string name="enhanced_connectivity_summary" msgid="1576414159820676330">"উন্নত সংযোগ সুবিধাটো সক্ষম কৰে।"</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"স্থানীয় টাৰ্মিনেল"</string>
- <string name="enable_terminal_summary" msgid="2481074834856064500">"স্থানীয় শ্বেল প্ৰৱেশাধিকাৰ দিয়া টাৰ্মিনেল এপ্ সক্ষম কৰক"</string>
+ <string name="enable_terminal_summary" msgid="2481074834856064500">"স্থানীয় শ্বেলৰ এক্সেছ দিয়া টাৰ্মিনেল এপ্ সক্ষম কৰক"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP পৰীক্ষণ"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP পৰীক্ষণ আচৰণ ছেট কৰক"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"ডিবাগিং"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 8e8150cf5a24..29d7d95350e5 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -258,7 +258,7 @@
<string name="keep_screen_on" msgid="1187161672348797558">"Mantendu aktibo"</string>
<string name="keep_screen_on_summary" msgid="1510731514101925829">"Pantaila ez da ezarriko inoiz inaktibo kargatu bitartean"</string>
<string name="bt_hci_snoop_log" msgid="7291287955649081448">"Gaitu Bluetooth HCI miatze-erregistroa"</string>
- <string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"Hauteman Bluetooth paketeak (aktibatu edo desaktibatu Bluetooth-a ezarpena aldatu ostean)"</string>
+ <string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"Hauteman Bluetooth paketeak (aktibatu edo desaktibatu Bluetootha ezarpena aldatu ostean)"</string>
<string name="oem_unlock_enable" msgid="5334869171871566731">"OEM desblokeoa"</string>
<string name="oem_unlock_enable_summary" msgid="5857388174390953829">"Onartu abiarazlea desblokeatzea"</string>
<string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"OEM desblokeoa onartu nahi duzu?"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 3d1e98d101d7..c292e8817c69 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -151,12 +151,12 @@
<string name="bluetooth_talkback_headphone" msgid="8613073829180337091">"Øretelefoner"</string>
<string name="bluetooth_talkback_input_peripheral" msgid="5133944817800149942">"Inndata fra ytre utstyrsenheter"</string>
<string name="bluetooth_talkback_bluetooth" msgid="1143241359781999989">"Bluetooth"</string>
- <string name="accessibility_wifi_off" msgid="1195445715254137155">"Wi-Fi er av."</string>
- <string name="accessibility_no_wifi" msgid="5297119459491085771">"Wi-Fi er frakoblet."</string>
- <string name="accessibility_wifi_one_bar" msgid="6025652717281815212">"Wi-Fi-signal med én stolpe."</string>
- <string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi-signal med to stolper."</string>
- <string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi-signal med tre stolper."</string>
- <string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wi-Fi-signalet er ved full styrke."</string>
+ <string name="accessibility_wifi_off" msgid="1195445715254137155">"Wifi er av."</string>
+ <string name="accessibility_no_wifi" msgid="5297119459491085771">"Wifi er frakoblet."</string>
+ <string name="accessibility_wifi_one_bar" msgid="6025652717281815212">"Wifi-signal med én stolpe."</string>
+ <string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wifi-signal med to stolper."</string>
+ <string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wifi-signal med tre stolper."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wifi-signalet er ved full styrke."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Åpent nettverk"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Sikkert nettverk"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android-operativsystem"</string>
@@ -226,7 +226,7 @@
<string name="enable_adb_summary" msgid="3711526030096574316">"Feilsøkingsmodus når USB kobles til"</string>
<string name="clear_adb_keys" msgid="3010148733140369917">"USB-feilsøking – opphev autorisasjon"</string>
<string name="enable_adb_wireless" msgid="6973226350963971018">"Trådløs feilsøking"</string>
- <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Feilsøkingsmodus når Wi-Fi er tilkoblet"</string>
+ <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Feilsøkingsmodus når Wifi er tilkoblet"</string>
<string name="adb_wireless_error" msgid="721958772149779856">"Feil"</string>
<string name="adb_wireless_settings" msgid="2295017847215680229">"Trådløs feilsøking"</string>
<string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"For å se og bruke tilgjengelige enheter, slå på trådløs feilsøking"</string>
@@ -245,13 +245,13 @@
<string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Wi‑Fi-tilkoblingskode"</string>
<string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"Tilkoblingen mislyktes"</string>
<string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"Sørg for at enheten er koblet til samme nettverk."</string>
- <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Koble til enheten via Wi-Fi ved å skanne en QR-kode"</string>
+ <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Koble til enheten via Wifi ved å skanne en QR-kode"</string>
<string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Kobler til enheten …"</string>
<string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Kunne ikke koble til enheten. Enten var QR-koden feil, eller enheten er ikke koblet til samme nettverk."</string>
<string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP-adresse og port"</string>
<string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Skann QR-koden"</string>
- <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Koble til enheten via Wi-Fi ved å skanne en QR-kode"</string>
- <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Koble til et Wi-Fi-nettverk"</string>
+ <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Koble til enheten via Wifi ved å skanne en QR-kode"</string>
+ <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Koble til et Wifi-nettverk"</string>
<string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, feilsøking, utvikler"</string>
<string name="bugreport_in_power" msgid="8664089072534638709">"Snarvei til feilrapport"</string>
<string name="bugreport_in_power_summary" msgid="1885529649381831775">"Vis en knapp for generering av feilrapport i batterimenyen"</string>
@@ -268,7 +268,7 @@
<string name="mock_location_app_set" msgid="4706722469342913843">"App for fiktiv posisjon: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="debug_networking_category" msgid="6829757985772659599">"Nettverk"</string>
<string name="wifi_display_certification" msgid="1805579519992520381">"Trådløs skjerm-sertifisering"</string>
- <string name="wifi_verbose_logging" msgid="1785910450009679371">"Slå på detaljert Wi-Fi-loggføring"</string>
+ <string name="wifi_verbose_logging" msgid="1785910450009679371">"Slå på detaljert Wifi-loggføring"</string>
<string name="wifi_scan_throttling" msgid="2985624788509913617">"Begrensning av Wi‑Fi-skanning"</string>
<string name="wifi_non_persistent_mac_randomization" msgid="7482769677894247316">"Ikke-vedvarende tilfeldiggjøring av MAC-adresse for Wi‑Fi"</string>
<string name="mobile_data_always_on" msgid="8275958101875563572">"Mobildata er alltid aktiv"</string>
@@ -300,7 +300,7 @@
<string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"Skriv inn DNS-leverandørens vertsnavn"</string>
<string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"Kunne ikke koble til"</string>
<string name="wifi_display_certification_summary" msgid="8111151348106907513">"Vis alternativer for sertifisering av trådløs skjerm"</string>
- <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Øk nivået av Wi-Fi-logging – vis per SSID RSSI i Wi-Fi-velgeren"</string>
+ <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Øk nivået av Wifi-logging – vis per SSID RSSI i Wifi-velgeren"</string>
<string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Reduserer batteriforbruket og forbedrer nettverksytelsen"</string>
<string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"Når denne modusen er slått på, kan MAC-adressen til denne enheten endres hver gang den kobler seg til et nettverk som har tilfeldiggjøring av MAC-adresse slått på."</string>
<string name="wifi_metered_label" msgid="8737187690304098638">"Med datamåling"</string>
@@ -316,7 +316,7 @@
<string name="allow_mock_location" msgid="2102650981552527884">"Tillat simulert posisjon"</string>
<string name="allow_mock_location_summary" msgid="179780881081354579">"Tillat bruk av simulerte GPS-koordinater"</string>
<string name="debug_view_attributes" msgid="3539609843984208216">"Slå på inspeksjon av visningsattributt"</string>
- <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"Ha alltid mobildata slått på, selv når Wi-Fi er aktiv (for hurtig nettverksbytting)."</string>
+ <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"Ha alltid mobildata slått på, selv når Wifi er aktiv (for hurtig nettverksbytting)."</string>
<string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Bruk maskinvareakselerasjon for internettdeling hvis det er tilgjengelig"</string>
<string name="adb_warning_title" msgid="7708653449506485728">"Tillate USB-feilsøking?"</string>
<string name="adb_warning_message" msgid="8145270656419669221">"USB-feilsøking er bare ment for utviklingsformål. Bruk det til å kopiere data mellom datamaskinen og enheten, installere apper på enheten uten varsel og lese loggdata."</string>
@@ -561,7 +561,7 @@
<string name="user_add_user_item_title" msgid="2394272381086965029">"Bruker"</string>
<string name="user_add_profile_item_title" msgid="3111051717414643029">"Begrenset profil"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"Vil du legge til en ny bruker?"</string>
- <string name="user_add_user_message_long" msgid="1527434966294733380">"Du kan dele denne enheten med andre folk ved å opprette flere brukere. Hver bruker har sin egen plass de kan tilpasse med apper, bakgrunner og annet. Brukere kan også justere enhetsinnstillinger, for eksempel Wi-Fi, som påvirker alle.\n\nNår du legger til en ny bruker, må vedkommende angi innstillinger for plassen sin.\n\nAlle brukere kan oppdatere apper for alle andre brukere. Innstillinger og tjenester for tilgjengelighet overføres kanskje ikke til den nye brukeren."</string>
+ <string name="user_add_user_message_long" msgid="1527434966294733380">"Du kan dele denne enheten med andre folk ved å opprette flere brukere. Hver bruker har sin egen plass de kan tilpasse med apper, bakgrunner og annet. Brukere kan også justere enhetsinnstillinger, for eksempel Wifi, som påvirker alle.\n\nNår du legger til en ny bruker, må vedkommende angi innstillinger for plassen sin.\n\nAlle brukere kan oppdatere apper for alle andre brukere. Innstillinger og tjenester for tilgjengelighet overføres kanskje ikke til den nye brukeren."</string>
<string name="user_add_user_message_short" msgid="3295959985795716166">"Når du legger til en ny bruker, må hen konfigurere sitt eget område.\n\nAlle brukere kan oppdatere apper for alle andre brukere."</string>
<string name="user_setup_dialog_title" msgid="8037342066381939995">"Konfigurere brukeren nå?"</string>
<string name="user_setup_dialog_message" msgid="269931619868102841">"Sørg for at brukeren er tilgjengelig for å konfigurere området sitt på enheten"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 8c12372ff7d1..17a06c21d4fa 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -86,7 +86,7 @@
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"Kopplar ifrån…"</string>
<string name="bluetooth_connecting" msgid="5871702668260192755">"Ansluter…"</string>
<string name="bluetooth_connected" msgid="8065345572198502293">"Ansluten<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
- <string name="bluetooth_pairing" msgid="4269046942588193600">"Parkoppling…"</string>
+ <string name="bluetooth_pairing" msgid="4269046942588193600">"Parkopplar…"</string>
<string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Ansluten (ingen mobil)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
<string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Ansluten (inga medier)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
<string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Ansluten (ingen mobil och inga medier) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/PermissionsSummaryHelper.java b/packages/SettingsLib/src/com/android/settingslib/applications/PermissionsSummaryHelper.java
index 5e5c22a403d2..b7ef7664b2e5 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/PermissionsSummaryHelper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/PermissionsSummaryHelper.java
@@ -21,30 +21,28 @@ import android.permission.RuntimePermissionPresentationInfo;
import java.text.Collator;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
-public class PermissionsSummaryHelper {
+/**
+ * Helper to get the runtime permissions for an app.
+ */
+public class PermissionsSummaryHelper {
public static void getPermissionSummary(Context context, String pkg,
final PermissionsResultCallback callback) {
final PermissionControllerManager permController =
context.getSystemService(PermissionControllerManager.class);
permController.getAppPermissions(pkg, permissions -> {
- final int permissionCount = permissions.size();
- int grantedStandardCount = 0;
int grantedAdditionalCount = 0;
int requestedCount = 0;
List<CharSequence> grantedStandardLabels = new ArrayList<>();
- for (int i = 0; i < permissionCount; i++) {
- RuntimePermissionPresentationInfo permission = permissions.get(i);
+ for (RuntimePermissionPresentationInfo permission : permissions) {
requestedCount++;
if (permission.isGranted()) {
if (permission.isStandard()) {
grantedStandardLabels.add(permission.getLabel());
- grantedStandardCount++;
} else {
grantedAdditionalCount++;
}
@@ -53,23 +51,21 @@ public class PermissionsSummaryHelper {
Collator collator = Collator.getInstance();
collator.setStrength(Collator.PRIMARY);
- Collections.sort(grantedStandardLabels, collator);
+ grantedStandardLabels.sort(collator);
- callback.onPermissionSummaryResult(grantedStandardCount, requestedCount,
- grantedAdditionalCount, grantedStandardLabels);
+ callback.onPermissionSummaryResult(
+ requestedCount, grantedAdditionalCount, grantedStandardLabels);
}, null);
}
- public static abstract class PermissionsResultCallback {
- public void onAppWithPermissionsCountsResult(int standardGrantedPermissionAppCount,
- int standardUsedPermissionAppCount) {
- /* do nothing - stub */
- }
+ /**
+ * Callback for the runtime permissions result for an app.
+ */
+ public interface PermissionsResultCallback {
- public void onPermissionSummaryResult(int standardGrantedPermissionCount,
+ /** The runtime permission summary result for an app. */
+ void onPermissionSummaryResult(
int requestedPermissionCount, int additionalGrantedPermissionCount,
- List<CharSequence> grantedGroupLabels) {
- /* do nothing - stub */
- }
+ List<CharSequence> grantedGroupLabels);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index 2cca086571c0..19ffa30324b8 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -485,45 +485,18 @@ public class AuthContainerView extends LinearLayout
mContainerState = STATE_SHOWING;
} else {
mContainerState = STATE_ANIMATING_IN;
- // The background panel and content are different views since we need to be able to
- // animate them separately in other places.
- mPanelView.setY(mTranslationY);
- mBiometricScrollView.setY(mTranslationY);
-
+ setY(mTranslationY);
setAlpha(0f);
final long animateDuration = mConfig.mSkipAnimation ? 0 : ANIMATION_DURATION_SHOW_MS;
postOnAnimation(() -> {
- mPanelView.animate()
- .translationY(0)
- .setDuration(animateDuration)
- .setInterpolator(mLinearOutSlowIn)
- .setListener(getJankListener(mPanelView, SHOW, animateDuration))
- .withLayer()
- .withEndAction(this::onDialogAnimatedIn)
- .start();
- mBiometricScrollView.animate()
- .translationY(0)
- .setDuration(animateDuration)
- .setInterpolator(mLinearOutSlowIn)
- .setListener(getJankListener(mBiometricScrollView, SHOW, animateDuration))
- .withLayer()
- .start();
- if (mCredentialView != null && mCredentialView.isAttachedToWindow()) {
- mCredentialView.setY(mTranslationY);
- mCredentialView.animate()
- .translationY(0)
- .setDuration(animateDuration)
- .setInterpolator(mLinearOutSlowIn)
- .setListener(getJankListener(mCredentialView, SHOW, animateDuration))
- .withLayer()
- .start();
- }
animate()
.alpha(1f)
+ .translationY(0)
.setDuration(animateDuration)
.setInterpolator(mLinearOutSlowIn)
.withLayer()
.setListener(getJankListener(this, SHOW, animateDuration))
+ .withEndAction(this::onDialogAnimatedIn)
.start();
});
}
@@ -794,32 +767,9 @@ public class AuthContainerView extends LinearLayout
final long animateDuration = mConfig.mSkipAnimation ? 0 : ANIMATION_DURATION_AWAY_MS;
postOnAnimation(() -> {
- mPanelView.animate()
- .translationY(mTranslationY)
- .setDuration(animateDuration)
- .setInterpolator(mLinearOutSlowIn)
- .setListener(getJankListener(mPanelView, DISMISS, animateDuration))
- .withLayer()
- .withEndAction(endActionRunnable)
- .start();
- mBiometricScrollView.animate()
- .translationY(mTranslationY)
- .setDuration(animateDuration)
- .setInterpolator(mLinearOutSlowIn)
- .setListener(getJankListener(mBiometricScrollView, DISMISS, animateDuration))
- .withLayer()
- .start();
- if (mCredentialView != null && mCredentialView.isAttachedToWindow()) {
- mCredentialView.animate()
- .translationY(mTranslationY)
- .setDuration(animateDuration)
- .setInterpolator(mLinearOutSlowIn)
- .setListener(getJankListener(mCredentialView, DISMISS, animateDuration))
- .withLayer()
- .start();
- }
animate()
.alpha(0f)
+ .translationY(mTranslationY)
.setDuration(animateDuration)
.setInterpolator(mLinearOutSlowIn)
.setListener(getJankListener(this, DISMISS, animateDuration))
@@ -834,6 +784,7 @@ public class AuthContainerView extends LinearLayout
mWindowManager.updateViewLayout(this, lp);
})
.withLayer()
+ .withEndAction(endActionRunnable)
.start();
});
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index 3b8b8c8d13f0..cc15c827963d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -3308,7 +3308,7 @@ public class CentralSurfacesImpl extends CoreStartable implements
@Override
public boolean onBackPressed() {
if (mStatusBarKeyguardViewManager.canHandleBackPressed()) {
- mStatusBarKeyguardViewManager.onBackPressed(false /* unused */);
+ mStatusBarKeyguardViewManager.onBackPressed();
return true;
}
if (mNotificationPanelViewController.isQsCustomizing()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 65584e69099d..d4d510feb216 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -203,7 +203,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
if (DEBUG) {
Log.d(TAG, "onBackInvokedCallback() called, invoking onBackPressed()");
}
- onBackPressed(false /* unused */);
+ onBackPressed();
};
private boolean mIsBackCallbackRegistered = false;
@@ -1099,16 +1099,9 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
/**
* Notifies this manager that the back button has been pressed.
*/
- // TODO(b/244635782): This "accept boolean and ignore it, and always return false" was done
- // to make it possible to check this in *and* allow merging to master,
- // where ArcStatusBarKeyguardViewManager inherits this class, and its
- // build will break if we change this interface.
- // So, overall, while this function refactors the behavior of onBackPressed,
- // (it now handles the back press, and no longer returns *whether* it did so)
- // its interface is not changing right now (but will, in a follow-up CL).
- public boolean onBackPressed(boolean ignored) {
+ public void onBackPressed() {
if (!canHandleBackPressed()) {
- return false;
+ return;
}
mCentralSurfaces.endAffordanceLaunch();
@@ -1129,7 +1122,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
mNotificationPanelViewController.expandWithoutQs();
}
}
- return false;
+ return;
}
@Override
diff --git a/services/core/java/com/android/server/am/BroadcastQueueImpl.java b/services/core/java/com/android/server/am/BroadcastQueueImpl.java
index 77300f7cf228..d7a075b3b966 100644
--- a/services/core/java/com/android/server/am/BroadcastQueueImpl.java
+++ b/services/core/java/com/android/server/am/BroadcastQueueImpl.java
@@ -579,7 +579,7 @@ public class BroadcastQueueImpl extends BroadcastQueue {
final Object curReceiver = r.receivers.get(curIndex);
FrameworkStatsLog.write(BROADCAST_DELIVERY_EVENT_REPORTED, r.curApp.uid,
r.callingUid == -1 ? Process.SYSTEM_UID : r.callingUid,
- ActivityManagerService.getShortAction(r.intent.getAction()),
+ r.intent.getAction(),
curReceiver instanceof BroadcastFilter
? BROADCAST_DELIVERY_EVENT_REPORTED__RECEIVER_TYPE__RUNTIME
: BROADCAST_DELIVERY_EVENT_REPORTED__RECEIVER_TYPE__MANIFEST,
@@ -757,7 +757,7 @@ public class BroadcastQueueImpl extends BroadcastQueue {
FrameworkStatsLog.write(BROADCAST_DELIVERY_EVENT_REPORTED,
receiverUid == -1 ? Process.SYSTEM_UID : receiverUid,
callingUid == -1 ? Process.SYSTEM_UID : callingUid,
- ActivityManagerService.getShortAction(intent.getAction()),
+ intent.getAction(),
BROADCAST_DELIVERY_EVENT_REPORTED__RECEIVER_TYPE__RUNTIME,
BROADCAST_DELIVERY_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM,
dispatchDelay, receiveDelay, 0 /* finish_delay */);
diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
index fe8d84feb557..89a0283a4264 100644
--- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
+++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
@@ -1298,7 +1298,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
// Report statistics for each individual receiver
final int uid = getReceiverUid(receiver);
final int senderUid = (r.callingUid == -1) ? Process.SYSTEM_UID : r.callingUid;
- final String actionName = ActivityManagerService.getShortAction(r.intent.getAction());
+ final String actionName = r.intent.getAction();
final int receiverType = (receiver instanceof BroadcastFilter)
? BROADCAST_DELIVERY_EVENT_REPORTED__RECEIVER_TYPE__RUNTIME
: BROADCAST_DELIVERY_EVENT_REPORTED__RECEIVER_TYPE__MANIFEST;
diff --git a/services/core/java/com/android/server/input/PersistentDataStore.java b/services/core/java/com/android/server/input/PersistentDataStore.java
index 7dce28c91072..5513cd62a5c5 100644
--- a/services/core/java/com/android/server/input/PersistentDataStore.java
+++ b/services/core/java/com/android/server/input/PersistentDataStore.java
@@ -556,11 +556,10 @@ final class PersistentDataStore {
}
for (int i = 0; i < mKeyboardBacklightBrightnessMap.size(); i++) {
- int lightId = mKeyboardBacklightBrightnessMap.valueAt(i);
serializer.startTag(null, "light-info");
- serializer.attributeInt(null, "light-id", lightId);
+ serializer.attributeInt(null, "light-id", mKeyboardBacklightBrightnessMap.keyAt(i));
serializer.attributeInt(null, "light-brightness",
- mKeyboardBacklightBrightnessMap.get(lightId));
+ mKeyboardBacklightBrightnessMap.valueAt(i));
serializer.endTag(null, "light-info");
}