Merge "Fix #155437855: "dumpsys activity" package filtering doesn't filter everything" into rvc-dev
diff --git a/apex/media/framework/Android.bp b/apex/media/framework/Android.bp
index 34fe228..48e7ec7 100644
--- a/apex/media/framework/Android.bp
+++ b/apex/media/framework/Android.bp
@@ -92,6 +92,7 @@
// TODO(b/135922046) remove this
include_dirs: ["frameworks/base/core/java"],
},
+ dist: { dest: "framework-media.txt" },
}
droidstubs {
@@ -130,18 +131,21 @@
name: "framework-media-stubs-publicapi",
srcs: [":framework-media-stubs-srcs-publicapi"],
defaults: ["framework-module-stubs-lib-defaults-publicapi"],
+ dist: { dest: "framework-media.jar" },
}
java_library {
name: "framework-media-stubs-systemapi",
srcs: [":framework-media-stubs-srcs-systemapi"],
defaults: ["framework-module-stubs-lib-defaults-systemapi"],
+ dist: { dest: "framework-media.jar" },
}
java_library {
name: "framework-media-stubs-module_libs_api",
srcs: [":framework-media-stubs-srcs-module_libs_api"],
defaults: ["framework-module-stubs-lib-defaults-module_libs_api"],
+ dist: { dest: "framework-media.jar" },
}
java_library {
diff --git a/apex/media/framework/java/android/media/MediaParser.java b/apex/media/framework/java/android/media/MediaParser.java
index d22e998..a9ed6d8 100644
--- a/apex/media/framework/java/android/media/MediaParser.java
+++ b/apex/media/framework/java/android/media/MediaParser.java
@@ -1288,7 +1288,11 @@
}
@Override
- public int sampleData(DataReader input, int length, boolean allowEndOfInput)
+ public int sampleData(
+ DataReader input,
+ int length,
+ boolean allowEndOfInput,
+ @SampleDataPart int sampleDataPart)
throws IOException {
mScratchDataReaderAdapter.setDataReader(input, length);
long positionBeforeReading = mScratchDataReaderAdapter.getPosition();
@@ -1297,7 +1301,8 @@
}
@Override
- public void sampleData(ParsableByteArray data, int length) {
+ public void sampleData(
+ ParsableByteArray data, int length, @SampleDataPart int sampleDataPart) {
mScratchParsableByteArrayAdapter.resetWithByteArray(data, length);
try {
mOutputConsumer.onSampleDataFound(mTrackIndex, mScratchParsableByteArrayAdapter);
diff --git a/apex/permission/framework/Android.bp b/apex/permission/framework/Android.bp
index fc9052e..3119b7d 100644
--- a/apex/permission/framework/Android.bp
+++ b/apex/permission/framework/Android.bp
@@ -46,6 +46,7 @@
name: "framework-permission-stubs-defaults",
srcs: [ ":framework-permission-sources" ],
libs: [ "framework-annotations-lib" ],
+ dist: { dest: "framework-permission.txt" },
}
droidstubs {
@@ -84,16 +85,19 @@
name: "framework-permission-stubs-publicapi",
srcs: [ ":framework-permission-stubs-srcs-publicapi" ],
defaults: ["framework-module-stubs-lib-defaults-publicapi"],
+ dist: { dest: "framework-permission.jar" },
}
java_library {
name: "framework-permission-stubs-systemapi",
srcs: [ ":framework-permission-stubs-srcs-systemapi" ],
defaults: ["framework-module-stubs-lib-defaults-systemapi"],
+ dist: { dest: "framework-permission.jar" },
}
java_library {
name: "framework-permission-stubs-module_libs_api",
srcs: [ ":framework-permission-stubs-srcs-module_libs_api" ],
defaults: ["framework-module-stubs-lib-defaults-module_libs_api"],
+ dist: { dest: "framework-permission.jar" },
}
diff --git a/apex/permission/service/Android.bp b/apex/permission/service/Android.bp
index 2eb7e99..2d92d00 100644
--- a/apex/permission/service/Android.bp
+++ b/apex/permission/service/Android.bp
@@ -41,12 +41,14 @@
name: "service-permission-stubs-srcs",
srcs: [ ":service-permission-sources" ],
defaults: ["service-module-stubs-srcs-defaults"],
- visibility: ["//visibility:private"]
+ visibility: ["//visibility:private"],
+ dist: { dest: "service-permission.txt" },
}
java_library {
name: "service-permission-stubs",
srcs: [":service-permission-stubs-srcs"],
defaults: ["service-module-stubs-defaults"],
- visibility: ["//frameworks/base/services/core"]
+ visibility: ["//frameworks/base/services/core"],
+ dist: { dest: "service-permission.jar" },
}
diff --git a/apex/sdkextensions/framework/Android.bp b/apex/sdkextensions/framework/Android.bp
index 3eabb88..6a78711 100644
--- a/apex/sdkextensions/framework/Android.bp
+++ b/apex/sdkextensions/framework/Android.bp
@@ -48,6 +48,7 @@
name: "framework-sdkextensions-stubs-defaults",
srcs: [ ":framework-sdkextensions-sources" ],
libs: [ "framework-annotations-lib" ],
+ dist: { dest: "framework-sdkextensions.txt" },
}
droidstubs {
@@ -55,7 +56,7 @@
defaults: [
"framework-module-stubs-defaults-publicapi",
"framework-sdkextensions-stubs-defaults",
- ]
+ ],
}
droidstubs {
@@ -63,7 +64,7 @@
defaults: [
"framework-module-stubs-defaults-systemapi",
"framework-sdkextensions-stubs-defaults",
- ]
+ ],
}
droidstubs {
@@ -71,7 +72,7 @@
defaults: [
"framework-module-api-defaults-module_libs_api",
"framework-sdkextensions-stubs-defaults",
- ]
+ ],
}
droidstubs {
@@ -79,7 +80,7 @@
defaults: [
"framework-module-stubs-defaults-module_libs_api",
"framework-sdkextensions-stubs-defaults",
- ]
+ ],
}
java_library {
@@ -89,7 +90,8 @@
visibility: [
"//frameworks/base", // Framework
"//frameworks/base/apex/sdkextensions", // sdkextensions SDK
- ]
+ ],
+ dist: { dest: "framework-sdkextensions.jar" },
}
java_library {
@@ -99,7 +101,8 @@
visibility: [
"//frameworks/base", // Framework
"//frameworks/base/apex/sdkextensions", // sdkextensions SDK
- ]
+ ],
+ dist: { dest: "framework-sdkextensions.jar" },
}
java_library {
@@ -109,5 +112,6 @@
visibility: [
"//frameworks/base", // Framework
"//frameworks/base/apex/sdkextensions", // sdkextensions SDK
- ]
+ ],
+ dist: { dest: "framework-sdkextensions.jar" },
}
diff --git a/apex/statsd/framework/Android.bp b/apex/statsd/framework/Android.bp
index 6f29141..7d0f2ee 100644
--- a/apex/statsd/framework/Android.bp
+++ b/apex/statsd/framework/Android.bp
@@ -84,6 +84,7 @@
"framework-annotations-lib",
],
sdk_version: "system_current",
+ dist: { dest: "framework-statsd.txt" },
}
droidstubs {
@@ -100,7 +101,6 @@
"framework-module-stubs-defaults-systemapi",
"framework-statsd-stubs-srcs-defaults",
],
-
}
droidstubs {
@@ -127,6 +127,7 @@
"//frameworks/base", // Framework
"//frameworks/base/apex/statsd", // statsd apex
],
+ dist: { dest: "framework-statsd.jar" },
}
java_library {
@@ -137,6 +138,7 @@
"//frameworks/base", // Framework
"//frameworks/base/apex/statsd", // statsd apex
],
+ dist: { dest: "framework-statsd.jar" },
}
java_library {
@@ -149,6 +151,7 @@
"//frameworks/opt/net/wifi/service", // wifi service
"//packages/providers/MediaProvider", // MediaProvider apk
],
+ dist: { dest: "framework-statsd.jar" },
}
android_test {
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 674978b5..9a73fdd 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -427,6 +427,7 @@
AccessibilityShortcutReported accessibility_shortcut_reported =
266 [(module) = "framework"];
AccessibilityServiceReported accessibility_service_reported = 267 [(module) = "settings"];
+ DocsUIDragAndDropReported docs_ui_drag_and_drop_reported = 268 [(module) = "docsui"];
SdkExtensionStatus sdk_extension_status = 354;
// StatsdStats tracks platform atoms with ids upto 500.
@@ -6481,6 +6482,15 @@
optional int32 repeatedly_pick_times = 7;
}
+/** Logs the drag and drop of files.
+
+ * Logged from:
+ * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java
+ */
+message DocsUIDragAndDropReported {
+ optional bool drag_initiated_from_docsui = 1;
+}
+
/**
* Logs when an app's memory is compacted.
*
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index 1098fa1..635ed13 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -29,6 +29,7 @@
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
+import android.hardware.display.VirtualDisplay;
import android.os.Bundle;
import android.os.UserHandle;
import android.util.AttributeSet;
@@ -444,6 +445,14 @@
}
/**
+ * @hide
+ * @return virtual display.
+ */
+ public VirtualDisplay getVirtualDisplay() {
+ return mTaskEmbedder.getVirtualDisplay();
+ }
+
+ /**
* Injects a pair of down/up key events with keycode {@link KeyEvent#KEYCODE_BACK} to the
* virtual display.
*/
diff --git a/core/java/android/app/RemoteAction.java b/core/java/android/app/RemoteAction.java
index 1b13772..5a4244f 100644
--- a/core/java/android/app/RemoteAction.java
+++ b/core/java/android/app/RemoteAction.java
@@ -161,4 +161,4 @@
return new RemoteAction[size];
}
};
-}
\ No newline at end of file
+}
diff --git a/core/java/android/service/textclassifier/TextClassifierService.java b/core/java/android/service/textclassifier/TextClassifierService.java
index 9dfbc28..93faa58 100644
--- a/core/java/android/service/textclassifier/TextClassifierService.java
+++ b/core/java/android/service/textclassifier/TextClassifierService.java
@@ -424,6 +424,11 @@
return bundle.getParcelable(KEY_RESULT);
}
+ /** @hide **/
+ public static <T extends Parcelable> void putResponse(Bundle bundle, T response) {
+ bundle.putParcelable(KEY_RESULT, response);
+ }
+
/**
* Callbacks for TextClassifierService results.
*
diff --git a/core/java/android/view/inputmethod/InlineSuggestionsRequest.java b/core/java/android/view/inputmethod/InlineSuggestionsRequest.java
index 4d4faa4..cce1090 100644
--- a/core/java/android/view/inputmethod/InlineSuggestionsRequest.java
+++ b/core/java/android/view/inputmethod/InlineSuggestionsRequest.java
@@ -72,6 +72,9 @@
/**
* The extras state propagated from the IME to pass extra data.
+ *
+ * <p>Note: There should be no remote objects in the bundle, all included remote objects will
+ * be removed from the bundle before transmission.</p>
*/
private @NonNull Bundle mExtras;
@@ -261,6 +264,9 @@
/**
* The extras state propagated from the IME to pass extra data.
+ *
+ * <p>Note: There should be no remote objects in the bundle, all included remote objects will
+ * be removed from the bundle before transmission.</p>
*/
@DataClass.Generated.Member
public @NonNull Bundle getExtras() {
@@ -513,6 +519,9 @@
/**
* The extras state propagated from the IME to pass extra data.
+ *
+ * <p>Note: There should be no remote objects in the bundle, all included remote objects will
+ * be removed from the bundle before transmission.</p>
*/
@DataClass.Generated.Member
public @NonNull Builder setExtras(@NonNull Bundle value) {
@@ -595,7 +604,7 @@
}
@DataClass.Generated(
- time = 1587537617922L,
+ time = 1588109685838L,
codegenVersion = "1.0.15",
sourceFile = "frameworks/base/core/java/android/view/inputmethod/InlineSuggestionsRequest.java",
inputSignatures = "public static final int SUGGESTION_COUNT_UNLIMITED\nprivate final int mMaxSuggestionCount\nprivate final @android.annotation.NonNull java.util.List<android.widget.inline.InlinePresentationSpec> mInlinePresentationSpecs\nprivate @android.annotation.NonNull java.lang.String mHostPackageName\nprivate @android.annotation.NonNull android.os.LocaleList mSupportedLocales\nprivate @android.annotation.NonNull android.os.Bundle mExtras\nprivate @android.annotation.Nullable android.os.IBinder mHostInputToken\nprivate int mHostDisplayId\npublic void setHostInputToken(android.os.IBinder)\nprivate boolean extrasEquals(android.os.Bundle)\nprivate void parcelHostInputToken(android.os.Parcel,int)\nprivate @android.annotation.Nullable android.os.IBinder unparcelHostInputToken(android.os.Parcel)\npublic void setHostDisplayId(int)\nprivate void onConstructed()\npublic void filterContentTypes()\nprivate static int defaultMaxSuggestionCount()\nprivate static java.lang.String defaultHostPackageName()\nprivate static android.os.LocaleList defaultSupportedLocales()\nprivate static @android.annotation.Nullable android.os.IBinder defaultHostInputToken()\nprivate static @android.annotation.Nullable int defaultHostDisplayId()\nprivate static @android.annotation.NonNull android.os.Bundle defaultExtras()\nclass InlineSuggestionsRequest extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genBuilder=true)\nabstract android.view.inputmethod.InlineSuggestionsRequest.Builder setInlinePresentationSpecs(java.util.List<android.widget.inline.InlinePresentationSpec>)\nabstract android.view.inputmethod.InlineSuggestionsRequest.Builder setHostPackageName(java.lang.String)\nabstract android.view.inputmethod.InlineSuggestionsRequest.Builder setHostInputToken(android.os.IBinder)\nabstract android.view.inputmethod.InlineSuggestionsRequest.Builder setHostDisplayId(int)\nclass BaseBuilder extends java.lang.Object implements []")
diff --git a/core/java/android/view/textclassifier/ConversationAction.java b/core/java/android/view/textclassifier/ConversationAction.java
index e633404..bf0409d 100644
--- a/core/java/android/view/textclassifier/ConversationAction.java
+++ b/core/java/android/view/textclassifier/ConversationAction.java
@@ -206,6 +206,15 @@
return mExtras;
}
+ /** @hide */
+ public Builder toBuilder() {
+ return new Builder(mType)
+ .setTextReply(mTextReply)
+ .setAction(mAction)
+ .setConfidenceScore(mScore)
+ .setExtras(mExtras);
+ }
+
/** Builder class to construct {@link ConversationAction}. */
public static final class Builder {
@Nullable
diff --git a/core/java/android/view/textclassifier/EntityConfidence.java b/core/java/android/view/textclassifier/EntityConfidence.java
index 4c12dda..b4313b7 100644
--- a/core/java/android/view/textclassifier/EntityConfidence.java
+++ b/core/java/android/view/textclassifier/EntityConfidence.java
@@ -88,6 +88,10 @@
return 0;
}
+ public Map<String, Float> toMap() {
+ return new ArrayMap(mEntityConfidence);
+ }
+
@Override
public String toString() {
return mEntityConfidence.toString();
diff --git a/core/java/android/view/textclassifier/TextClassification.java b/core/java/android/view/textclassifier/TextClassification.java
index 3aed32a..ab6dcb1 100644
--- a/core/java/android/view/textclassifier/TextClassification.java
+++ b/core/java/android/view/textclassifier/TextClassification.java
@@ -48,6 +48,7 @@
import java.lang.annotation.RetentionPolicy;
import java.time.ZonedDateTime;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
@@ -270,6 +271,20 @@
return mExtras;
}
+ /** @hide */
+ public Builder toBuilder() {
+ return new Builder()
+ .setId(mId)
+ .setText(mText)
+ .addActions(mActions)
+ .setEntityConfidence(mEntityConfidence)
+ .setIcon(mLegacyIcon)
+ .setLabel(mLegacyLabel)
+ .setIntent(mLegacyIntent)
+ .setOnClickListener(mLegacyOnClickListener)
+ .setExtras(mExtras);
+ }
+
@Override
public String toString() {
return String.format(Locale.US,
@@ -323,7 +338,7 @@
*/
public static final class Builder {
- @NonNull private List<RemoteAction> mActions = new ArrayList<>();
+ @NonNull private final List<RemoteAction> mActions = new ArrayList<>();
@NonNull private final Map<String, Float> mTypeScoreMap = new ArrayMap<>();
@Nullable private String mText;
@Nullable private Drawable mLegacyIcon;
@@ -332,8 +347,6 @@
@Nullable private OnClickListener mLegacyOnClickListener;
@Nullable private String mId;
@Nullable private Bundle mExtras;
- @NonNull private final ArrayList<Intent> mActionIntents = new ArrayList<>();
- @Nullable private Bundle mForeignLanguageExtra;
/**
* Sets the classified text.
@@ -361,6 +374,18 @@
return this;
}
+ Builder setEntityConfidence(EntityConfidence scores) {
+ mTypeScoreMap.clear();
+ mTypeScoreMap.putAll(scores.toMap());
+ return this;
+ }
+
+ /** @hide */
+ public Builder clearEntityTypes() {
+ mTypeScoreMap.clear();
+ return this;
+ }
+
/**
* Adds an action that may be performed on the classified text. Actions should be added in
* order of likelihood that the user will use them, with the most likely action being added
@@ -368,19 +393,21 @@
*/
@NonNull
public Builder addAction(@NonNull RemoteAction action) {
- return addAction(action, null);
- }
-
- /**
- * @param intent the intent in the remote action.
- * @see #addAction(RemoteAction)
- * @hide
- */
- @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
- public Builder addAction(RemoteAction action, @Nullable Intent intent) {
Preconditions.checkArgument(action != null);
mActions.add(action);
- mActionIntents.add(intent);
+ return this;
+ }
+
+ /** @hide */
+ public Builder addActions(Collection<RemoteAction> actions) {
+ Objects.requireNonNull(actions);
+ mActions.addAll(actions);
+ return this;
+ }
+
+ /** @hide */
+ public Builder clearActions() {
+ mActions.clear();
return this;
}
@@ -466,16 +493,6 @@
}
/**
- * @see #setExtras(Bundle)
- * @hide
- */
- @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
- public Builder setForeignLanguageExtra(@Nullable Bundle extra) {
- mForeignLanguageExtra = extra;
- return this;
- }
-
- /**
* Builds and returns a {@link TextClassification} object.
*/
@NonNull
diff --git a/core/java/android/widget/inline/InlinePresentationSpec.java b/core/java/android/widget/inline/InlinePresentationSpec.java
index 9f966d8..5f924c6 100644
--- a/core/java/android/widget/inline/InlinePresentationSpec.java
+++ b/core/java/android/widget/inline/InlinePresentationSpec.java
@@ -44,6 +44,9 @@
/**
* The extras encoding the UI style information. Defaults to {@code Bundle.Empty} in which case
* the default system UI style will be used.
+ *
+ * <p>Note: There should be no remote objects in the bundle, all included remote objects will
+ * be removed from the bundle before transmission.</p>
*/
@NonNull
private final Bundle mStyle;
@@ -122,6 +125,9 @@
/**
* The extras encoding the UI style information. Defaults to {@code Bundle.Empty} in which case
* the default system UI style will be used.
+ *
+ * <p>Note: There should be no remote objects in the bundle, all included remote objects will
+ * be removed from the bundle before transmission.</p>
*/
@DataClass.Generated.Member
public @NonNull Bundle getStyle() {
@@ -260,6 +266,9 @@
/**
* The extras encoding the UI style information. Defaults to {@code Bundle.Empty} in which case
* the default system UI style will be used.
+ *
+ * <p>Note: There should be no remote objects in the bundle, all included remote objects will
+ * be removed from the bundle before transmission.</p>
*/
@DataClass.Generated.Member
public @NonNull Builder setStyle(@NonNull Bundle value) {
@@ -293,7 +302,7 @@
}
@DataClass.Generated(
- time = 1586935491105L,
+ time = 1588109681295L,
codegenVersion = "1.0.15",
sourceFile = "frameworks/base/core/java/android/widget/inline/InlinePresentationSpec.java",
inputSignatures = "private final @android.annotation.NonNull android.util.Size mMinSize\nprivate final @android.annotation.NonNull android.util.Size mMaxSize\nprivate final @android.annotation.NonNull android.os.Bundle mStyle\nprivate static @android.annotation.NonNull android.os.Bundle defaultStyle()\nprivate boolean styleEquals(android.os.Bundle)\npublic void filterContentTypes()\nclass InlinePresentationSpec extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genBuilder=true)\nclass BaseBuilder extends java.lang.Object implements []")
diff --git a/core/java/android/window/TaskEmbedder.java b/core/java/android/window/TaskEmbedder.java
index 2ead37a..4257ce0 100644
--- a/core/java/android/window/TaskEmbedder.java
+++ b/core/java/android/window/TaskEmbedder.java
@@ -23,7 +23,6 @@
import android.annotation.Nullable;
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
-import android.app.ActivityView;
import android.app.IActivityTaskManager;
import android.app.PendingIntent;
import android.content.ComponentName;
@@ -36,9 +35,8 @@
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
-import android.os.RemoteException;
+import android.hardware.display.VirtualDisplay;
import android.os.UserHandle;
-import android.util.Log;
import android.view.IWindow;
import android.view.IWindowManager;
import android.view.KeyEvent;
@@ -256,6 +254,10 @@
return INVALID_DISPLAY;
}
+ public VirtualDisplay getVirtualDisplay() {
+ return null;
+ }
+
/**
* Set forwarded insets on the task content.
*
diff --git a/core/java/android/window/VirtualDisplayTaskEmbedder.java b/core/java/android/window/VirtualDisplayTaskEmbedder.java
index 1c0598b..6f85dc2 100644
--- a/core/java/android/window/VirtualDisplayTaskEmbedder.java
+++ b/core/java/android/window/VirtualDisplayTaskEmbedder.java
@@ -251,6 +251,14 @@
return INVALID_DISPLAY;
}
+ @Override
+ public VirtualDisplay getVirtualDisplay() {
+ if (isInitialized()) {
+ return mVirtualDisplay;
+ }
+ return null;
+ }
+
/**
* Check if container is ready to launch and create {@link ActivityOptions} to target the
* virtual display.
diff --git a/core/java/com/android/internal/widget/LockSettingsInternal.java b/core/java/com/android/internal/widget/LockSettingsInternal.java
index 90a18ef..38588ea 100644
--- a/core/java/com/android/internal/widget/LockSettingsInternal.java
+++ b/core/java/com/android/internal/widget/LockSettingsInternal.java
@@ -107,4 +107,10 @@
* @return true if the arming worked
*/
public abstract boolean armRebootEscrow();
+
+
+ /**
+ * Refreshes pending strong auth timeout with the latest admin requirement set by device policy.
+ */
+ public abstract void refreshStrongAuthTimeout(int userId);
}
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 88161f6..53e0bf9 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1200,6 +1200,7 @@
<java-symbol type="string" name="personal_apps_suspension_title" />
<java-symbol type="string" name="personal_apps_suspension_tomorrow_text" />
<java-symbol type="string" name="personal_apps_suspension_text" />
+ <java-symbol type="string" name="personal_apps_suspended_turn_profile_on" />
<java-symbol type="string" name="factory_reset_warning" />
<java-symbol type="string" name="factory_reset_message" />
<java-symbol type="string" name="lockscreen_transport_play_description" />
diff --git a/core/tests/coretests/src/android/view/textclassifier/ConversationActionTest.java b/core/tests/coretests/src/android/view/textclassifier/ConversationActionTest.java
new file mode 100644
index 0000000..6b62635
--- /dev/null
+++ b/core/tests/coretests/src/android/view/textclassifier/ConversationActionTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2020 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.view.textclassifier;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.PendingIntent;
+import android.app.RemoteAction;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.drawable.Icon;
+import android.os.Bundle;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public final class ConversationActionTest {
+
+ @Test
+ public void toBuilder() {
+ final Context context = InstrumentationRegistry.getTargetContext();
+ final PendingIntent intent = PendingIntent.getActivity(context, 0, new Intent(), 0);
+ final Icon icon = Icon.createWithData(new byte[]{0}, 0, 1);
+ final Bundle extras = new Bundle();
+ extras.putInt("key", 5);
+ final ConversationAction convAction =
+ new ConversationAction.Builder(ConversationAction.TYPE_CALL_PHONE)
+ .setAction(new RemoteAction(icon, "title", "descr", intent))
+ .setConfidenceScore(0.5f)
+ .setExtras(extras)
+ .build();
+
+ final ConversationAction fromBuilder = convAction.toBuilder().build();
+
+ assertThat(fromBuilder.getType()).isEqualTo(convAction.getType());
+ assertThat(fromBuilder.getAction()).isEqualTo(convAction.getAction());
+ assertThat(fromBuilder.getConfidenceScore()).isEqualTo(convAction.getConfidenceScore());
+ assertThat(fromBuilder.getExtras()).isEqualTo(convAction.getExtras());
+ assertThat(fromBuilder.getTextReply()).isEqualTo(convAction.getTextReply());
+ }
+
+ @Test
+ public void toBuilder_textReply() {
+ final ConversationAction convAction =
+ new ConversationAction.Builder(ConversationAction.TYPE_TEXT_REPLY)
+ .setTextReply(":P")
+ .build();
+
+ final ConversationAction fromBuilder = convAction.toBuilder().build();
+
+ assertThat(fromBuilder.getTextReply()).isEqualTo(convAction.getTextReply());
+ }
+}
diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassificationTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassificationTest.java
index 39ededa..cf742b0 100644
--- a/core/tests/coretests/src/android/view/textclassifier/TextClassificationTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/TextClassificationTest.java
@@ -57,6 +57,7 @@
static {
BUNDLE.putString(BUNDLE_KEY, BUNDLE_VALUE);
}
+ private static final float EPSILON = 1e-7f;
public Icon generateTestIcon(int width, int height, int colorValue) {
final int numPixels = width * height;
@@ -128,8 +129,8 @@
assertEquals(2, result.getEntityCount());
assertEquals(TextClassifier.TYPE_PHONE, result.getEntity(0));
assertEquals(TextClassifier.TYPE_ADDRESS, result.getEntity(1));
- assertEquals(0.7f, result.getConfidenceScore(TextClassifier.TYPE_PHONE), 1e-7f);
- assertEquals(0.3f, result.getConfidenceScore(TextClassifier.TYPE_ADDRESS), 1e-7f);
+ assertEquals(0.7f, result.getConfidenceScore(TextClassifier.TYPE_PHONE), EPSILON);
+ assertEquals(0.3f, result.getConfidenceScore(TextClassifier.TYPE_ADDRESS), EPSILON);
// Extras
assertEquals(BUNDLE_VALUE, result.getExtras().getString(BUNDLE_KEY));
@@ -226,4 +227,45 @@
assertEquals(1, resultSystemTcMetadata.getUserId());
assertFalse(resultSystemTcMetadata.useDefaultTextClassifier());
}
+
+ @Test
+ public void testToBuilder() {
+ final Context context = InstrumentationRegistry.getInstrumentation().getContext();
+ final Icon icon1 = generateTestIcon(5, 5, Color.RED);
+ final Icon icon2 = generateTestIcon(2, 10, Color.BLUE);
+ final TextClassification classification = new TextClassification.Builder()
+ .setIcon(icon1.loadDrawable(context))
+ .setLabel("label")
+ .setIntent(new Intent("action"))
+ .setOnClickListener(view -> { })
+ .addAction(new RemoteAction(icon1, "title1", "desc1",
+ PendingIntent.getActivity(context, 0, new Intent("action1"), 0)))
+ .addAction(new RemoteAction(icon1, "title2", "desc2",
+ PendingIntent.getActivity(context, 0, new Intent("action2"), 0)))
+ .setEntityType(TextClassifier.TYPE_EMAIL, 0.5f)
+ .setEntityType(TextClassifier.TYPE_PHONE, 0.4f)
+ .build();
+
+ final TextClassification fromBuilder = classification.toBuilder().build();
+
+ assertEquals(classification.getId(), fromBuilder.getId());
+ assertEquals(classification.getText(), fromBuilder.getText());
+ assertEquals(classification.getIcon(), fromBuilder.getIcon());
+ assertEquals(classification.getLabel(), fromBuilder.getLabel());
+ assertEquals(classification.getIntent(), fromBuilder.getIntent());
+ assertEquals(classification.getOnClickListener(), fromBuilder.getOnClickListener());
+ assertEquals(classification.getExtras(), fromBuilder.getExtras());
+ assertEquals(classification.getActions(), fromBuilder.getActions());
+ assertEquals(classification.getEntityCount(), fromBuilder.getEntityCount());
+ assertEquals(classification.getEntity(0), fromBuilder.getEntity(0));
+ assertEquals(classification.getEntity(1), fromBuilder.getEntity(1));
+ assertEquals(
+ classification.getConfidenceScore(TextClassifier.TYPE_EMAIL),
+ fromBuilder.getConfidenceScore(TextClassifier.TYPE_EMAIL),
+ EPSILON);
+ assertEquals(
+ classification.getConfidenceScore(TextClassifier.TYPE_PHONE),
+ fromBuilder.getConfidenceScore(TextClassifier.TYPE_PHONE),
+ EPSILON);
+ }
}
diff --git a/core/tests/utiltests/src/com/android/internal/util/InlinePresentationStyleUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/InlinePresentationStyleUtilsTest.java
index 8e4f38e..35c5681 100644
--- a/core/tests/utiltests/src/com/android/internal/util/InlinePresentationStyleUtilsTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/InlinePresentationStyleUtilsTest.java
@@ -16,9 +16,13 @@
package com.android.internal.util;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import android.os.Binder;
import android.os.Bundle;
import androidx.test.filters.SmallTest;
@@ -110,4 +114,54 @@
bundle2.putInt("KEY", 22);
assertFalse(InlinePresentationStyleUtils.bundleEquals(bundle1, bundle2));
}
+
+ @Test
+ public void testFilterContentTypes_nullOrEmpty() {
+ InlinePresentationStyleUtils.filterContentTypes(null);
+ InlinePresentationStyleUtils.filterContentTypes(new Bundle());
+ }
+
+ @Test
+ public void testFilterContentTypes_basic() {
+ Bundle bundle = new Bundle();
+ bundle.putInt("int", 11);
+ bundle.putString("str", "test");
+ bundle.putString("null", null);
+
+ InlinePresentationStyleUtils.filterContentTypes(bundle);
+
+ assertEquals(11, bundle.getInt("int"));
+ assertEquals("test", bundle.getString("str"));
+ assertTrue(bundle.keySet().contains("null"));
+ }
+
+ @Test
+ public void testFilterContentTypes_binder_removedBinder() {
+ Bundle bundle = new Bundle();
+ bundle.putInt("int", 11);
+ bundle.putString("str", "test");
+ bundle.putString("null", null);
+ bundle.putBinder("binder", new Binder());
+
+ InlinePresentationStyleUtils.filterContentTypes(bundle);
+
+ assertEquals(11, bundle.getInt("int"));
+ assertEquals("test", bundle.getString("str"));
+ assertTrue(bundle.keySet().contains("null"));
+ assertNull(bundle.getBinder("binder"));
+ }
+
+ @Test
+ public void testFilterContentTypes_binderInChild_removedBinder() {
+ Bundle child = new Bundle();
+ child.putBinder("binder", new Binder());
+ Bundle bundle = new Bundle();
+ bundle.putBundle("child", child);
+
+ InlinePresentationStyleUtils.filterContentTypes(bundle);
+
+ Bundle child2 = bundle.getBundle("child");
+ assertNotNull(child2);
+ assertNull(child2.getBinder("binder"));
+ }
}
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index aba74e5..ed56b43 100755
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -165,6 +165,7 @@
MtpConstants.PROPERTY_TRACK,
MtpConstants.PROPERTY_ORIGINAL_RELEASE_DATE,
MtpConstants.PROPERTY_DURATION,
+ MtpConstants.PROPERTY_GENRE,
MtpConstants.PROPERTY_COMPOSER,
MtpConstants.PROPERTY_AUDIO_WAVE_CODEC,
MtpConstants.PROPERTY_BITRATE_TYPE,
diff --git a/media/java/android/mtp/MtpPropertyGroup.java b/media/java/android/mtp/MtpPropertyGroup.java
index 5bb0c1b..aff2e1b4 100644
--- a/media/java/android/mtp/MtpPropertyGroup.java
+++ b/media/java/android/mtp/MtpPropertyGroup.java
@@ -122,15 +122,21 @@
type = MtpConstants.TYPE_STR;
break;
case MtpConstants.PROPERTY_ARTIST:
+ column = Audio.AudioColumns.ARTIST;
type = MtpConstants.TYPE_STR;
break;
case MtpConstants.PROPERTY_ALBUM_NAME:
+ column = Audio.AudioColumns.ALBUM;
type = MtpConstants.TYPE_STR;
break;
case MtpConstants.PROPERTY_ALBUM_ARTIST:
column = Audio.AudioColumns.ALBUM_ARTIST;
type = MtpConstants.TYPE_STR;
break;
+ case MtpConstants.PROPERTY_GENRE:
+ column = Audio.AudioColumns.GENRE;
+ type = MtpConstants.TYPE_STR;
+ break;
case MtpConstants.PROPERTY_COMPOSER:
column = Audio.AudioColumns.COMPOSER;
type = MtpConstants.TYPE_STR;
diff --git a/packages/SystemUI/res/layout/controls_app_item.xml b/packages/SystemUI/res/layout/controls_app_item.xml
index d54cd6d..a208098 100644
--- a/packages/SystemUI/res/layout/controls_app_item.xml
+++ b/packages/SystemUI/res/layout/controls_app_item.xml
@@ -16,33 +16,25 @@
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
+ android:layout_height="64dp"
android:background="?android:attr/selectableItemBackground">
<LinearLayout
android:layout_width="match_parent"
- android:layout_height="wrap_content"
+ android:layout_height="match_parent"
android:layout_gravity="start|top"
- android:gravity="center_vertical"
- android:minHeight="?android:attr/listPreferredItemHeightSmall"
- android:paddingStart="?android:attr/listPreferredItemPaddingStart"
- android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
- android:layout_marginBottom="@dimen/controls_app_bottom_margin">
+ android:gravity="center_vertical">
<FrameLayout
android:id="@+id/icon_frame"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:gravity="start|center_vertical"
- android:minWidth="56dp"
+ android:layout_height="match_parent"
android:orientation="horizontal"
- android:paddingTop="@dimen/controls_app_icon_frame_top_padding"
- android:paddingBottom="@dimen/controls_app_icon_frame_top_padding"
- android:paddingEnd="@dimen/controls_app_icon_frame_side_padding"
- android:paddingStart="@dimen/controls_app_icon_frame_side_padding" >
+ android:paddingEnd="@dimen/controls_app_icon_frame_side_padding">
<ImageView
android:id="@android:id/icon"
+ android:layout_gravity="start|center_vertical"
android:layout_width="@dimen/controls_app_icon_size"
android:layout_height="@dimen/controls_app_icon_size" />
</FrameLayout>
@@ -51,9 +43,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
- android:orientation="vertical"
- android:paddingTop="@dimen/controls_app_text_padding"
- android:paddingBottom="@dimen/controls_app_text_padding">
+ android:orientation="vertical">
<TextView
android:id="@android:id/title"
@@ -62,8 +52,7 @@
android:ellipsize="end"
android:fadingEdge="horizontal"
android:singleLine="true"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:textColor="?android:attr/textColorPrimary"/>
+ android:textAppearance="@style/TextAppearance.Control.Management.Subtitle"/>
<TextView
android:id="@+id/favorites"
@@ -81,7 +70,5 @@
android:layout_width="match_parent"
android:layout_height="@dimen/controls_app_divider_height"
android:layout_gravity="center_horizontal|bottom"
- android:layout_marginStart="@dimen/controls_app_divider_side_margin"
- android:layout_marginEnd="@dimen/controls_app_divider_side_margin"
android:background="?android:attr/listDivider" />
</FrameLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/controls_base_item.xml b/packages/SystemUI/res/layout/controls_base_item.xml
index e7bb3af..477a70f 100644
--- a/packages/SystemUI/res/layout/controls_base_item.xml
+++ b/packages/SystemUI/res/layout/controls_base_item.xml
@@ -98,15 +98,15 @@
<CheckBox
android:id="@+id/favorite"
android:visibility="invisible"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom|end"
+ android:layout_width="@dimen/controls_management_checkbox_size"
+ android:layout_height="@dimen/controls_management_checkbox_size"
+ android:minHeight="0dp"
+ android:minWidth="0dp"
+ android:gravity="center"
android:background="@android:color/transparent"
android:clickable="false"
android:selectable="false"
android:importantForAccessibility="no"
- android:layout_marginTop="4dp"
- android:layout_marginStart="4dp"
app:layout_constraintStart_toEndOf="@id/subtitle"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
diff --git a/packages/SystemUI/res/layout/controls_detail_dialog.xml b/packages/SystemUI/res/layout/controls_detail_dialog.xml
index d1ce10e..d61122f 100644
--- a/packages/SystemUI/res/layout/controls_detail_dialog.xml
+++ b/packages/SystemUI/res/layout/controls_detail_dialog.xml
@@ -26,7 +26,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
- android:layout_marginBottom="10dp">
+ android:layout_marginBottom="4dp">
<ImageView
android:id="@+id/control_detail_close"
android:contentDescription="@string/accessibility_desc_close"
@@ -55,10 +55,7 @@
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
- android:paddingTop="@dimen/controls_activity_view_top_padding"
- android:paddingLeft="@dimen/controls_activity_view_side_padding"
- android:paddingRight="@dimen/controls_activity_view_side_padding"
- android:background="@drawable/rounded_bg_top"
+ android:background="@android:color/black"
android:orientation="vertical" />
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/controls_horizontal_divider_with_empty.xml b/packages/SystemUI/res/layout/controls_horizontal_divider_with_empty.xml
index 90b3398..11144f6 100644
--- a/packages/SystemUI/res/layout/controls_horizontal_divider_with_empty.xml
+++ b/packages/SystemUI/res/layout/controls_horizontal_divider_with_empty.xml
@@ -22,23 +22,17 @@
>
<View
- android:layout_width="match_parent"
- android:layout_height="@dimen/controls_management_list_margin"
- />
-
- <FrameLayout
android:id="@+id/frame"
android:layout_width="match_parent"
android:layout_height="@dimen/control_height"
android:visibility="gone"
>
- </FrameLayout>
+ </View>
<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="1dp"
- android:layout_marginBottom="10dp"
- android:layout_marginStart="40dp"
- android:layout_marginEnd="40dp"
+ android:layout_marginBottom="@dimen/controls_management_editing_divider_margin"
+ android:layout_marginTop="@dimen/controls_management_editing_divider_margin"
android:background="#4dffffff" />
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/controls_management.xml b/packages/SystemUI/res/layout/controls_management.xml
index 835e54e..46f79de 100644
--- a/packages/SystemUI/res/layout/controls_management.xml
+++ b/packages/SystemUI/res/layout/controls_management.xml
@@ -31,18 +31,15 @@
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceLarge"
- android:textSize="@dimen/controls_title_size"
+ android:textAppearance="@style/TextAppearance.Control.Management.Title"
android:textAlignment="center" />
-
-
<TextView
android:id="@+id/subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/controls_management_titles_margin"
- android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textAppearance="@style/TextAppearance.Control.Management.Subtitle"
android:textAlignment="center" />
<ViewStub
@@ -53,7 +50,7 @@
<FrameLayout
android:layout_width="match_parent"
- android:layout_height="64dp">
+ android:layout_height="72dp">
<View
android:layout_width="match_parent"
@@ -64,7 +61,7 @@
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:padding="4dp">
+ android:padding="@dimen/controls_management_footer_side_margin">
<Button
android:id="@+id/other_apps"
diff --git a/packages/SystemUI/res/layout/controls_management_apps.xml b/packages/SystemUI/res/layout/controls_management_apps.xml
index 94df9d8..4348ffe 100644
--- a/packages/SystemUI/res/layout/controls_management_apps.xml
+++ b/packages/SystemUI/res/layout/controls_management_apps.xml
@@ -19,6 +19,8 @@
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout_marginTop="@dimen/controls_management_list_margin"
+ android:layout_marginTop="@dimen/controls_management_apps_list_margin"
+ android:layout_marginStart="@dimen/controls_management_apps_extra_side_margin"
+ android:layout_marginEnd="@dimen/controls_management_apps_extra_side_margin"
/>
diff --git a/packages/SystemUI/res/layout/controls_management_editing.xml b/packages/SystemUI/res/layout/controls_management_editing.xml
index 8a14ec3..7356b290 100644
--- a/packages/SystemUI/res/layout/controls_management_editing.xml
+++ b/packages/SystemUI/res/layout/controls_management_editing.xml
@@ -22,6 +22,6 @@
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
- android:paddingTop="@dimen/controls_management_list_margin"
+ android:paddingTop="@dimen/controls_management_editing_list_margin"
/>
diff --git a/packages/SystemUI/res/layout/controls_management_favorites.xml b/packages/SystemUI/res/layout/controls_management_favorites.xml
index d2ccfcb..a0d8ae4 100644
--- a/packages/SystemUI/res/layout/controls_management_favorites.xml
+++ b/packages/SystemUI/res/layout/controls_management_favorites.xml
@@ -32,10 +32,10 @@
<com.android.systemui.controls.management.ManagementPageIndicator
android:id="@+id/structure_page_indicator"
android:layout_width="wrap_content"
- android:layout_height="match_parent"
+ android:layout_height="@dimen/controls_management_page_indicator_height"
android:layout_gravity="center"
android:layout_marginTop="@dimen/controls_management_list_margin"
- android:visibility="gone" />
+ android:visibility="invisible" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/structure_pager"
diff --git a/packages/SystemUI/res/layout/controls_structure_page.xml b/packages/SystemUI/res/layout/controls_structure_page.xml
index 047ab98..f048d62 100644
--- a/packages/SystemUI/res/layout/controls_structure_page.xml
+++ b/packages/SystemUI/res/layout/controls_structure_page.xml
@@ -21,4 +21,4 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
- android:layout_marginTop="@dimen/controls_management_list_margin"/>
\ No newline at end of file
+ android:layout_marginTop="@dimen/controls_management_zone_top_margin"/>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/controls_zone_header.xml b/packages/SystemUI/res/layout/controls_zone_header.xml
index 93f99b1..74c020a 100644
--- a/packages/SystemUI/res/layout/controls_zone_header.xml
+++ b/packages/SystemUI/res/layout/controls_zone_header.xml
@@ -18,10 +18,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:textAppearance="@style/TextAppearance.Control.Title"
- android:layout_marginStart="12dp"
- android:layout_marginEnd="2dp"
- android:layout_marginTop="8dp"
+ android:textAppearance="@style/TextAppearance.Control.Management.Subtitle"
+ android:layout_marginTop="@dimen/controls_management_zone_top_margin"
android:layout_marginBottom="4dp">
-
</TextView>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/global_screenshot.xml b/packages/SystemUI/res/layout/global_screenshot.xml
index 94a6bc5..de19303 100644
--- a/packages/SystemUI/res/layout/global_screenshot.xml
+++ b/packages/SystemUI/res/layout/global_screenshot.xml
@@ -14,60 +14,89 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <ImageView
- android:id="@+id/global_screenshot_background"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:src="@android:color/black"
- android:visibility="gone"/>
+<androidx.constraintlayout.widget.ConstraintLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/global_screenshot_frame"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
<ImageView
android:id="@+id/global_screenshot_actions_background"
- android:layout_height="400dp"
+ android:layout_height="@dimen/global_screenshot_bg_protection_height"
android:layout_width="match_parent"
- android:layout_gravity="bottom|center"
+ android:alpha="0.0"
android:src="@drawable/screenshot_actions_background_protection"
- android:alpha="0"/>
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+ <ImageView
+ android:id="@+id/global_screenshot_actions_container_background"
+ android:visibility="gone"
+ android:layout_height="0dp"
+ android:layout_width="0dp"
+ android:elevation="1dp"
+ android:background="@drawable/action_chip_container_background"
+ android:layout_marginStart="@dimen/screenshot_action_container_margin_horizontal"
+ app:layout_constraintBottom_toBottomOf="@+id/global_screenshot_actions_container"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="@+id/global_screenshot_actions_container"
+ app:layout_constraintEnd_toEndOf="@+id/global_screenshot_actions_container"/>
<HorizontalScrollView
android:id="@+id/global_screenshot_actions_container"
- android:layout_width="wrap_content"
+ android:layout_width="0dp"
android:layout_height="wrap_content"
- android:layout_gravity="bottom|left"
- android:elevation="1dp"
- android:fillViewport="true"
- android:layout_marginHorizontal="@dimen/screenshot_action_container_margin_horizontal"
+ android:layout_marginEnd="@dimen/screenshot_action_container_margin_horizontal"
android:layout_marginBottom="@dimen/screenshot_action_container_offset_y"
- android:gravity="center"
- android:paddingLeft="@dimen/screenshot_action_container_padding_left"
- android:paddingRight="@dimen/screenshot_action_container_padding_right"
+ android:paddingHorizontal="@dimen/screenshot_action_container_padding_right"
android:paddingVertical="@dimen/screenshot_action_container_padding_vertical"
- android:visibility="gone"
+ android:elevation="1dp"
android:scrollbars="none"
- android:background="@drawable/action_chip_container_background">
+ app:layout_constraintHorizontal_bias="0"
+ app:layout_constraintWidth_percent="1.0"
+ app:layout_constraintWidth_max="wrap"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toEndOf="@+id/global_screenshot_preview"
+ app:layout_constraintEnd_toEndOf="parent">
<LinearLayout
android:id="@+id/global_screenshot_actions"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</HorizontalScrollView>
<ImageView
- android:id="@+id/global_screenshot"
- android:layout_width="wrap_content"
+ android:id="@+id/global_screenshot_animated_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center"
+ android:visibility="gone"
+ android:elevation="@dimen/screenshot_preview_elevation"
+ android:background="@drawable/screenshot_rounded_corners"
+ android:adjustViewBounds="true"/>
+ <ImageView
+ android:id="@+id/global_screenshot_preview"
+ android:layout_width="@dimen/global_screenshot_x_scale"
android:layout_height="wrap_content"
android:layout_gravity="center"
+ android:layout_marginStart="@dimen/screenshot_offset_x"
+ android:layout_marginBottom="@dimen/screenshot_offset_y"
+ android:scaleType="fitEnd"
android:elevation="@dimen/screenshot_preview_elevation"
android:visibility="gone"
android:background="@drawable/screenshot_rounded_corners"
android:adjustViewBounds="true"
- android:contentDescription="@string/screenshot_preview_description"/>
+ android:contentDescription="@string/screenshot_preview_description"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"/>
<FrameLayout
android:id="@+id/global_screenshot_dismiss_button"
android:layout_width="@dimen/screenshot_dismiss_button_tappable_size"
android:layout_height="@dimen/screenshot_dismiss_button_tappable_size"
android:elevation="7dp"
android:visibility="gone"
- android:contentDescription="@string/screenshot_dismiss_ui_description">
+ android:contentDescription="@string/screenshot_dismiss_ui_description"
+ app:layout_constraintStart_toEndOf="@+id/global_screenshot_preview"
+ app:layout_constraintEnd_toEndOf="@+id/global_screenshot_preview"
+ app:layout_constraintTop_toTopOf="@+id/global_screenshot_preview"
+ app:layout_constraintBottom_toTopOf="@+id/global_screenshot_preview">
<ImageView
android:id="@+id/global_screenshot_dismiss_image"
android:layout_width="match_parent"
@@ -79,14 +108,13 @@
android:id="@+id/global_screenshot_flash"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:src="@android:color/white"
+ android:visibility="gone"
android:elevation="@dimen/screenshot_preview_elevation"
- android:visibility="gone"/>
+ android:src="@android:color/white"/>
<com.android.systemui.screenshot.ScreenshotSelectorView
android:id="@+id/global_screenshot_selector"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:pointerIcon="crosshair"/>
-
-</FrameLayout>
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/packages/SystemUI/res/layout/global_screenshot_action_chip.xml b/packages/SystemUI/res/layout/global_screenshot_action_chip.xml
index bd91ddb..e4ae7c1 100644
--- a/packages/SystemUI/res/layout/global_screenshot_action_chip.xml
+++ b/packages/SystemUI/res/layout/global_screenshot_action_chip.xml
@@ -19,11 +19,11 @@
android:id="@+id/global_screenshot_action_chip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginRight="@dimen/screenshot_action_chip_margin_right"
+ android:layout_marginEnd="@dimen/screenshot_action_chip_margin_right"
android:layout_gravity="center"
android:paddingVertical="@dimen/screenshot_action_chip_padding_vertical"
android:background="@drawable/action_chip_background"
- android:alpha="0"
+ android:alpha="0.0"
android:gravity="center">
<ImageView
android:id="@+id/screenshot_action_chip_icon"
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 23a887c..c68c814 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -304,6 +304,7 @@
<!-- The padding on the global screenshot background image -->
<dimen name="global_screenshot_legacy_bg_padding">20dp</dimen>
<dimen name="global_screenshot_bg_padding">20dp</dimen>
+ <dimen name="global_screenshot_bg_protection_height">400dp</dimen>
<dimen name="global_screenshot_x_scale">80dp</dimen>
<dimen name="screenshot_preview_elevation">6dp</dimen>
<dimen name="screenshot_offset_y">48dp</dimen>
@@ -994,7 +995,7 @@
<dimen name="pip_expand_container_edge_margin">30dp</dimen>
<!-- The touchable/draggable edge size for PIP resize. -->
- <dimen name="pip_resize_edge_size">30dp</dimen>
+ <dimen name="pip_resize_edge_size">48dp</dimen>
<!-- The corner radius for PiP window. -->
<dimen name="pip_corner_radius">8dp</dimen>
@@ -1276,20 +1277,29 @@
<fraction name="controls_dimmed_alpha">40%</fraction>
<!-- Home Controls activity view detail panel-->
- <dimen name="controls_activity_view_top_padding">25dp</dimen>
- <dimen name="controls_activity_view_side_padding">12dp</dimen>
<dimen name="controls_activity_view_top_offset">100dp</dimen>
<dimen name="controls_activity_view_text_size">17sp</dimen>
+ <dimen name="controls_activity_view_corner_radius">@*android:dimen/config_bottomDialogCornerRadius</dimen>
<!-- Home Controls management screens -->
<dimen name="controls_management_top_padding">48dp</dimen>
- <dimen name="controls_management_side_padding">8dp</dimen>
- <dimen name="controls_management_titles_margin">8dp</dimen>
+ <dimen name="controls_management_side_padding">16dp</dimen>
+ <dimen name="controls_management_titles_margin">16dp</dimen>
+ <dimen name="controls_management_footer_side_margin">8dp</dimen>
<dimen name="controls_management_list_margin">16dp</dimen>
- <dimen name="controls_title_size">26sp</dimen>
+ <dimen name="controls_management_apps_list_margin">64dp</dimen>
+ <dimen name="controls_management_editing_list_margin">48dp</dimen>
+ <dimen name="controls_management_editing_divider_margin">24dp</dimen>
+ <dimen name="controls_management_apps_extra_side_margin">8dp</dimen>
+ <dimen name="controls_management_apps_top_margin"></dimen>
+ <dimen name="controls_management_zone_top_margin">32dp</dimen>
+ <dimen name="controls_management_page_indicator_height">24dp</dimen>
+ <dimen name="controls_management_checkbox_size">25dp</dimen>
+ <dimen name="controls_title_size">24sp</dimen>
+ <dimen name="controls_subtitle_size">16sp</dimen>
- <dimen name="controls_app_icon_size">32dp</dimen>
- <dimen name="controls_app_icon_frame_side_padding">8dp</dimen>
+ <dimen name="controls_app_icon_size">24dp</dimen>
+ <dimen name="controls_app_icon_frame_side_padding">16dp</dimen>
<dimen name="controls_app_icon_frame_top_padding">4dp</dimen>
<dimen name="controls_app_icon_frame_bottom_padding">@dimen/controls_app_icon_frame_top_padding</dimen>
<dimen name="controls_app_bottom_margin">8dp</dimen>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index d3a5f04..6e25625 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -734,6 +734,18 @@
<item name="android:textSize">@dimen/control_text_size</item>
<item name="android:textColor">@color/control_secondary_text</item>
</style>
+ <style name="TextAppearance.Control.Management" >
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
+ </style>
+ <style name="TextAppearance.Control.Management.Title">
+ <item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item>
+ <item name="android:textSize">@dimen/controls_title_size</item>
+ </style>
+ <style name="TextAppearance.Control.Management.Subtitle">
+ <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
+ <item name="android:textSize">@dimen/controls_subtitle_size</item>
+ </style>
+
<style name="Control.ListPopupWindow" parent="@*android:style/Widget.DeviceDefault.ListPopupWindow">
<item name="android:overlapAnchor">true</item>
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 0af026e..02d2b8e 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -76,7 +76,6 @@
import com.android.systemui.statusbar.notification.NotificationFilter;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
-import com.android.systemui.statusbar.notification.row.ChannelEditorDialogController;
import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.phone.AutoHideController;
@@ -308,7 +307,6 @@
@Inject Lazy<PackageManagerWrapper> mPackageManagerWrapper;
@Inject Lazy<SensorPrivacyController> mSensorPrivacyController;
@Inject Lazy<DockManager> mDockManager;
- @Inject Lazy<ChannelEditorDialogController> mChannelEditorDialogController;
@Inject Lazy<INotificationManager> mINotificationManager;
@Inject Lazy<SysUiState> mSysUiStateFlagsContainer;
@Inject Lazy<AlarmManager> mAlarmManager;
@@ -498,7 +496,6 @@
mProviders.put(PackageManagerWrapper.class, mPackageManagerWrapper::get);
mProviders.put(SensorPrivacyController.class, mSensorPrivacyController::get);
mProviders.put(DockManager.class, mDockManager::get);
- mProviders.put(ChannelEditorDialogController.class, mChannelEditorDialogController::get);
mProviders.put(INotificationManager.class, mINotificationManager::get);
mProviders.put(SysUiState.class, mSysUiStateFlagsContainer::get);
mProviders.put(AlarmManager.class, mAlarmManager::get);
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
index e367927..b3c2c6d 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -19,9 +19,15 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
+import static android.graphics.PixelFormat.TRANSPARENT;
import static android.view.Display.INVALID_DISPLAY;
+import static android.view.InsetsState.ITYPE_IME;
import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
import static android.view.ViewRootImpl.sNewInsetsMode;
+import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_EXPANDED_VIEW;
import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES;
@@ -42,9 +48,12 @@
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.ShapeDrawable;
+import android.hardware.display.VirtualDisplay;
+import android.os.Binder;
import android.os.RemoteException;
import android.util.AttributeSet;
import android.util.Log;
+import android.view.Gravity;
import android.view.View;
import android.view.WindowInsets;
import android.view.WindowManager;
@@ -62,6 +71,7 @@
*/
public class BubbleExpandedView extends LinearLayout {
private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleExpandedView" : TAG_BUBBLES;
+ private static final String WINDOW_TITLE = "ImeInsetsWindowWithoutContent";
private enum ActivityViewStatus {
// ActivityView is being initialized, cannot start an activity yet.
@@ -107,6 +117,9 @@
private WindowManager mWindowManager;
private BubbleStackView mStackView;
+ private View mVirtualImeView;
+ private WindowManager mVirtualDisplayWindowManager;
+ private boolean mImeShowing = false;
private ActivityView.StateCallback mStateCallback = new ActivityView.StateCallback() {
@Override
@@ -317,11 +330,8 @@
mKeyboardVisible = false;
mNeedsNewHeight = false;
if (mActivityView != null) {
- // TODO: Temporary hack to offset the view until we can properly inset Bubbles again.
if (sNewInsetsMode == NEW_INSETS_MODE_FULL) {
- mStackView.animate()
- .setDuration(100)
- .translationY(0);
+ setImeWindowToDisplay(0, 0);
} else {
mActivityView.setForwardedInsets(Insets.of(0, 0, 0, 0));
}
@@ -365,18 +375,61 @@
: 0);
final int insetsBottom = Math.max(activityViewBottom - keyboardTop, 0);
- // TODO: Temporary hack to offset the view until we can properly inset Bubbles again.
if (sNewInsetsMode == NEW_INSETS_MODE_FULL) {
- mStackView.animate()
- .setDuration(100)
- .translationY(-insetsBottom)
- .withEndAction(() -> mActivityView.onLocationChanged());
+ setImeWindowToDisplay(getWidth(), insetsBottom);
} else {
mActivityView.setForwardedInsets(Insets.of(0, 0, 0, insetsBottom));
}
}
}
+ private void setImeWindowToDisplay(int w, int h) {
+ if (getVirtualDisplayId() == INVALID_DISPLAY) {
+ return;
+ }
+ if (h == 0 || w == 0) {
+ if (mImeShowing) {
+ mVirtualImeView.setVisibility(GONE);
+ mImeShowing = false;
+ }
+ return;
+ }
+ final Context virtualDisplayContext = mContext.createDisplayContext(
+ getVirtualDisplay().getDisplay());
+
+ if (mVirtualDisplayWindowManager == null) {
+ mVirtualDisplayWindowManager =
+ (WindowManager) virtualDisplayContext.getSystemService(Context.WINDOW_SERVICE);
+ }
+ if (mVirtualImeView == null) {
+ mVirtualImeView = new View(virtualDisplayContext);
+ mVirtualImeView.setVisibility(VISIBLE);
+ mVirtualDisplayWindowManager.addView(mVirtualImeView,
+ getVirtualImeViewAttrs(w, h));
+ } else {
+ mVirtualDisplayWindowManager.updateViewLayout(mVirtualImeView,
+ getVirtualImeViewAttrs(w, h));
+ mVirtualImeView.setVisibility(VISIBLE);
+ }
+
+ mImeShowing = true;
+ }
+
+ private WindowManager.LayoutParams getVirtualImeViewAttrs(int w, int h) {
+ // To use TYPE_NAVIGATION_BAR_PANEL instead of TYPE_IME_BAR to bypass the IME window type
+ // token check when adding the window.
+ final WindowManager.LayoutParams attrs =
+ new WindowManager.LayoutParams(w, h, TYPE_NAVIGATION_BAR_PANEL,
+ FLAG_LAYOUT_NO_LIMITS | FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCHABLE,
+ TRANSPARENT);
+ attrs.gravity = Gravity.BOTTOM;
+ attrs.setTitle(WINDOW_TITLE);
+ attrs.token = new Binder();
+ attrs.providesInsetsTypes = new int[]{ITYPE_IME};
+ attrs.alpha = 0.0f;
+ return attrs;
+ }
+
void setStackView(BubbleStackView stackView) {
mStackView = stackView;
}
@@ -570,4 +623,11 @@
}
return INVALID_DISPLAY;
}
+
+ private VirtualDisplay getVirtualDisplay() {
+ if (usingActivityView()) {
+ return mActivityView.getVirtualDisplay();
+ }
+ return null;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
index 03ca393..79dd9ed 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
@@ -18,6 +18,7 @@
import android.content.ComponentName
import android.graphics.Rect
+import android.service.controls.Control
import android.service.controls.DeviceTypes
import android.view.LayoutInflater
import android.view.View
@@ -46,9 +47,9 @@
) : RecyclerView.Adapter<Holder>() {
companion object {
- private const val TYPE_ZONE = 0
- private const val TYPE_CONTROL = 1
- private const val TYPE_DIVIDER = 2
+ const val TYPE_ZONE = 0
+ const val TYPE_CONTROL = 1
+ const val TYPE_DIVIDER = 2
}
val spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
@@ -142,7 +143,7 @@
/**
* Holder for using with [DividerWrapper] to display a divider between zones.
*
- * The divider can be shown or hidden. It also has a frame view the height of a control, that can
+ * The divider can be shown or hidden. It also has a view the height of a control, that can
* be toggled visible or gone.
*/
private class DividerHolder(view: View) : Holder(view) {
@@ -229,10 +230,25 @@
parent: RecyclerView,
state: RecyclerView.State
) {
- outRect.apply {
- top = topMargin
- left = sideMargins
- right = sideMargins
+ val position = parent.getChildAdapterPosition(view)
+ if (position == RecyclerView.NO_POSITION) return
+ val type = parent.adapter?.getItemViewType(position)
+ if (type == ControlAdapter.TYPE_CONTROL) {
+ outRect.apply {
+ top = topMargin
+ left = sideMargins
+ right = sideMargins
+ bottom = 0
+ }
+ } else if (type == ControlAdapter.TYPE_ZONE && position == 0) {
+ // add negative padding to the first zone to counteract the margin
+ val margin = (view.layoutParams as ViewGroup.MarginLayoutParams).topMargin
+ outRect.apply {
+ top = -margin
+ left = 0
+ right = 0
+ bottom = 0
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
index e3175aa..bd75116 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
@@ -104,7 +104,9 @@
override fun onServicesUpdated(serviceInfos: List<ControlsServiceInfo>) {
if (serviceInfos.size > 1) {
- otherAppsButton.visibility = View.VISIBLE
+ otherAppsButton.post {
+ otherAppsButton.visibility = View.VISIBLE
+ }
}
}
}
@@ -170,7 +172,7 @@
pageIndicator.setNumPages(listOfStructures.size)
pageIndicator.setLocation(0f)
pageIndicator.visibility =
- if (listOfStructures.size > 1) View.VISIBLE else View.GONE
+ if (listOfStructures.size > 1) View.VISIBLE else View.INVISIBLE
ControlsAnimations.enterAnimation(pageIndicator).apply {
addListener(object : AnimatorListenerAdapter() {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
index 65ed967..236fa2d 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
@@ -28,6 +28,7 @@
import android.view.WindowManager
import android.widget.ImageView
+import com.android.internal.policy.ScreenDecorationsUtils
import com.android.systemui.R
/**
@@ -41,8 +42,12 @@
) : Dialog(cvh.context, R.style.Theme_SystemUI_Dialog_Control_DetailPanel) {
companion object {
- private const val ALPHA = (0.8f * 255).toInt()
private const val PANEL_TOP_OFFSET = "systemui.controls_panel_top_offset"
+ /*
+ * Indicate to the activity that it is being rendered in a bottomsheet, and they
+ * should optimize the layout for a smaller space.
+ */
+ private const val EXTRA_USE_PANEL = "controls.DISPLAY_IN_PANEL"
}
var activityView = ActivityView(context, null, 0, false)
@@ -50,6 +55,7 @@
val stateCallback: ActivityView.StateCallback = object : ActivityView.StateCallback() {
override fun onActivityViewReady(view: ActivityView) {
val launchIntent = Intent(intent)
+ launchIntent.putExtra(EXTRA_USE_PANEL, true)
// Apply flags to make behaviour match documentLaunchMode=always.
launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
@@ -112,6 +118,12 @@
setOnClickListener { dismiss() }
(getParent() as View).setOnClickListener { dismiss() }
}
+
+ if (ScreenDecorationsUtils.supportsRoundedCornersOnWindows(context.getResources())) {
+ val cornerRadius = context.resources
+ .getDimensionPixelSize(R.dimen.controls_activity_view_corner_radius)
+ activityView.setCornerRadius(cornerRadius.toFloat())
+ }
}
override fun show() {
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index 9509e6d..f876053 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -315,11 +315,8 @@
appName.setTextColor(mForegroundColor);
}
+ // Can be null!
MediaMetadata mediaMetadata = mController.getMetadata();
- if (mediaMetadata == null) {
- Log.e(TAG, "Media metadata was null");
- return;
- }
ImageView albumView = mMediaNotifView.findViewById(R.id.album_art);
if (albumView != null) {
@@ -329,14 +326,20 @@
// Song name
TextView titleText = mMediaNotifView.findViewById(R.id.header_title);
- String songName = mediaMetadata.getString(MediaMetadata.METADATA_KEY_TITLE);
+ String songName = "";
+ if (mediaMetadata != null) {
+ songName = mediaMetadata.getString(MediaMetadata.METADATA_KEY_TITLE);
+ }
titleText.setText(songName);
titleText.setTextColor(mForegroundColor);
// Artist name (not in mini player)
TextView artistText = mMediaNotifView.findViewById(R.id.header_artist);
if (artistText != null) {
- String artistName = mediaMetadata.getString(MediaMetadata.METADATA_KEY_ARTIST);
+ String artistName = "";
+ if (mediaMetadata != null) {
+ artistName = mediaMetadata.getString(MediaMetadata.METADATA_KEY_ARTIST);
+ }
artistText.setText(artistName);
artistText.setTextColor(mForegroundColor);
}
@@ -439,21 +442,23 @@
private void processAlbumArt(MediaMetadata metadata, Icon largeIcon, ImageView albumView) {
Bitmap albumArt = null;
- // First look in URI fields
- for (String field : ART_URIS) {
- String uriString = metadata.getString(field);
- if (!TextUtils.isEmpty(uriString)) {
- albumArt = loadBitmapFromUri(Uri.parse(uriString));
- if (albumArt != null) {
- Log.d(TAG, "loaded art from " + field);
- break;
+ if (metadata != null) {
+ // First look in URI fields
+ for (String field : ART_URIS) {
+ String uriString = metadata.getString(field);
+ if (!TextUtils.isEmpty(uriString)) {
+ albumArt = loadBitmapFromUri(Uri.parse(uriString));
+ if (albumArt != null) {
+ Log.d(TAG, "loaded art from " + field);
+ break;
+ }
}
}
- }
- // Then check bitmap field
- if (albumArt == null) {
- albumArt = metadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART);
+ // Then check bitmap field
+ if (albumArt == null) {
+ albumArt = metadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART);
+ }
}
// Finally try the notification's largeIcon
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 5814221..4148289 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -17,7 +17,6 @@
package com.android.systemui.screenshot;
import static android.provider.DeviceConfig.NAMESPACE_SYSTEMUI;
-import static android.view.View.VISIBLE;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.SCREENSHOT_SCROLLING_ENABLED;
@@ -72,7 +71,6 @@
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
-import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;
@@ -187,10 +185,11 @@
private final View mScreenshotLayout;
private final ScreenshotSelectorView mScreenshotSelectorView;
- private final ImageView mBackgroundView;
- private final ImageView mScreenshotView;
+ private final ImageView mScreenshotAnimatedView;
+ private final ImageView mScreenshotPreview;
private final ImageView mScreenshotFlash;
- private final HorizontalScrollView mActionsContainer;
+ private final ImageView mActionsContainerBackground;
+ private final FrameLayout mActionsContainer;
private final LinearLayout mActionsView;
private final ImageView mBackgroundProtection;
private final FrameLayout mDismissButton;
@@ -205,8 +204,6 @@
private float mScreenshotOffsetXPx;
private float mScreenshotOffsetYPx;
- private float mScreenshotHeightPx;
- private float mDismissButtonSize;
private float mCornerSizeX;
private float mDismissDeltaY;
@@ -244,10 +241,19 @@
// Inflate the screenshot layout
mScreenshotLayout = layoutInflater.inflate(R.layout.global_screenshot, null);
- mBackgroundView = mScreenshotLayout.findViewById(R.id.global_screenshot_background);
- mScreenshotView = mScreenshotLayout.findViewById(R.id.global_screenshot);
- mScreenshotView.setClipToOutline(true);
- mScreenshotView.setOutlineProvider(new ViewOutlineProvider() {
+ mScreenshotAnimatedView =
+ mScreenshotLayout.findViewById(R.id.global_screenshot_animated_view);
+ mScreenshotAnimatedView.setClipToOutline(true);
+ mScreenshotAnimatedView.setOutlineProvider(new ViewOutlineProvider() {
+ @Override
+ public void getOutline(View view, Outline outline) {
+ outline.setRoundRect(new Rect(0, 0, view.getWidth(), view.getHeight()),
+ ROUNDED_CORNER_RADIUS * view.getWidth());
+ }
+ });
+ mScreenshotPreview = mScreenshotLayout.findViewById(R.id.global_screenshot_preview);
+ mScreenshotPreview.setClipToOutline(true);
+ mScreenshotPreview.setOutlineProvider(new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
outline.setRoundRect(new Rect(0, 0, view.getWidth(), view.getHeight()),
@@ -255,6 +261,8 @@
}
});
+ mActionsContainerBackground = mScreenshotLayout.findViewById(
+ R.id.global_screenshot_actions_container_background);
mActionsContainer = mScreenshotLayout.findViewById(
R.id.global_screenshot_actions_container);
mActionsView = mScreenshotLayout.findViewById(R.id.global_screenshot_actions);
@@ -273,9 +281,8 @@
mScreenshotLayout.setFocusable(true);
mScreenshotSelectorView.setFocusable(true);
mScreenshotSelectorView.setFocusableInTouchMode(true);
- mScreenshotView.setPivotX(0);
- mScreenshotView.setPivotY(0);
- mActionsContainer.setPivotX(0);
+ mScreenshotAnimatedView.setPivotX(0);
+ mScreenshotAnimatedView.setPivotY(0);
// Setup the window that we are going to use
mWindowLayoutParams = new WindowManager.LayoutParams(
@@ -297,10 +304,6 @@
mScreenshotOffsetXPx = resources.getDimensionPixelSize(R.dimen.screenshot_offset_x);
mScreenshotOffsetYPx = resources.getDimensionPixelSize(R.dimen.screenshot_offset_y);
- mScreenshotHeightPx =
- resources.getDimensionPixelSize(R.dimen.screenshot_action_container_offset_y);
- mDismissButtonSize = resources.getDimensionPixelSize(
- R.dimen.screenshot_dismiss_button_tappable_size);
mCornerSizeX = resources.getDimensionPixelSize(R.dimen.global_screenshot_x_scale);
mDismissDeltaY = resources.getDimensionPixelSize(R.dimen.screenshot_dismissal_height_delta);
@@ -318,7 +321,7 @@
Region touchRegion = new Region();
Rect screenshotRect = new Rect();
- mScreenshotView.getBoundsOnScreen(screenshotRect);
+ mScreenshotPreview.getBoundsOnScreen(screenshotRect);
touchRegion.op(screenshotRect, Region.Op.UNION);
Rect actionsRect = new Rect();
mActionsContainer.getBoundsOnScreen(actionsRect);
@@ -469,6 +472,8 @@
*/
private void dismissScreenshot(String reason, boolean immediate) {
Log.v(TAG, "clearing screenshot: " + reason);
+ mScreenshotHandler.removeMessages(MESSAGE_CORNER_TIMEOUT);
+ mScreenshotLayout.getViewTreeObserver().removeOnComputeInternalInsetsListener(this);
if (!immediate) {
mDismissAnimation = createScreenshotDismissAnimation();
mDismissAnimation.addListener(new AnimatorListenerAdapter() {
@@ -488,23 +493,23 @@
if (mScreenshotLayout.isAttachedToWindow()) {
mWindowManager.removeView(mScreenshotLayout);
}
- mScreenshotHandler.removeMessages(MESSAGE_CORNER_TIMEOUT);
- mScreenshotLayout.getViewTreeObserver().removeOnComputeInternalInsetsListener(this);
// Clear any references to the bitmap
- mScreenshotView.setImageBitmap(null);
+ mScreenshotPreview.setImageBitmap(null);
+ mScreenshotAnimatedView.setImageBitmap(null);
+ mActionsContainerBackground.setVisibility(View.GONE);
mActionsContainer.setVisibility(View.GONE);
- mBackgroundView.setVisibility(View.GONE);
mBackgroundProtection.setAlpha(0f);
mDismissButton.setVisibility(View.GONE);
- mScreenshotView.setVisibility(View.GONE);
- mScreenshotView.setLayerType(View.LAYER_TYPE_NONE, null);
- mScreenshotView.setContentDescription(
+ mScreenshotPreview.setVisibility(View.GONE);
+ mScreenshotPreview.setLayerType(View.LAYER_TYPE_NONE, null);
+ mScreenshotPreview.setContentDescription(
mContext.getResources().getString(R.string.screenshot_preview_description));
mScreenshotLayout.setAlpha(1);
mDismissButton.setTranslationY(0);
mActionsContainer.setTranslationY(0);
- mScreenshotView.setTranslationY(0);
+ mActionsContainerBackground.setTranslationY(0);
+ mScreenshotPreview.setTranslationY(0);
}
/**
@@ -514,9 +519,8 @@
*/
private void reloadAssets() {
mDismissImage.setImageDrawable(mContext.getDrawable(R.drawable.screenshot_cancel));
- mActionsContainer.setBackground(
+ mActionsContainerBackground.setBackground(
mContext.getDrawable(R.drawable.action_chip_container_background));
-
}
/**
@@ -558,10 +562,6 @@
Toast.LENGTH_SHORT).show();
}
-
- // Add the view for the animation
- mScreenshotView.setImageBitmap(mScreenBitmap);
-
mScreenshotAnimation = createScreenshotDropInAnimation(w, h, screenRect);
saveScreenshotInWorkerThread(finisher, new ActionsReadyListener() {
@@ -600,8 +600,8 @@
// Play the shutter sound to notify that we've taken a screenshot
mCameraSound.play(MediaActionSound.SHUTTER_CLICK);
- mScreenshotView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
- mScreenshotView.buildLayer();
+ mScreenshotPreview.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ mScreenshotPreview.buildLayer();
mScreenshotAnimation.start();
});
}
@@ -609,6 +609,14 @@
private AnimatorSet createScreenshotDropInAnimation(int width, int height, Rect bounds) {
float cornerScale = mCornerSizeX / (float) width;
+ mScreenshotAnimatedView.setScaleX(1);
+ mScreenshotAnimatedView.setScaleY(1);
+ mScreenshotAnimatedView.setX(0);
+ mScreenshotAnimatedView.setY(0);
+
+ mScreenshotAnimatedView.setImageBitmap(mScreenBitmap);
+ mScreenshotPreview.setImageBitmap(mScreenBitmap);
+
AnimatorSet dropInAnimation = new AnimatorSet();
ValueAnimator flashInAnimator = ValueAnimator.ofFloat(0, 1);
flashInAnimator.setDuration(SCREENSHOT_FLASH_IN_DURATION_MS);
@@ -623,9 +631,16 @@
mScreenshotFlash.setAlpha((float) animation.getAnimatedValue()));
final PointF startPos = new PointF(bounds.centerX(), bounds.centerY());
- final PointF finalPos = new PointF(mScreenshotOffsetXPx + width * cornerScale / 2f,
- mDisplayMetrics.heightPixels - mScreenshotOffsetYPx
- - height * cornerScale / 2f);
+ float finalX;
+ if (mContext.getResources().getConfiguration().getLayoutDirection()
+ == View.LAYOUT_DIRECTION_LTR) {
+ finalX = mScreenshotOffsetXPx + width * cornerScale / 2f;
+ } else {
+ finalX = width - mScreenshotOffsetXPx - width * cornerScale / 2f;
+ }
+ float finalY =
+ mDisplayMetrics.heightPixels - mScreenshotOffsetYPx - height * cornerScale / 2f;
+ final PointF finalPos = new PointF(finalX, finalY);
ValueAnimator toCorner = ValueAnimator.ofFloat(0, 1);
toCorner.setDuration(SCREENSHOT_TO_CORNER_Y_DURATION_MS);
@@ -639,30 +654,33 @@
if (t < scalePct) {
float scale = MathUtils.lerp(
1, cornerScale, mFastOutSlowIn.getInterpolation(t / scalePct));
- mScreenshotView.setScaleX(scale);
- mScreenshotView.setScaleY(scale);
+ mScreenshotAnimatedView.setScaleX(scale);
+ mScreenshotAnimatedView.setScaleY(scale);
} else {
- mScreenshotView.setScaleX(cornerScale);
- mScreenshotView.setScaleY(cornerScale);
+ mScreenshotAnimatedView.setScaleX(cornerScale);
+ mScreenshotAnimatedView.setScaleY(cornerScale);
}
+ float currentScaleX = mScreenshotAnimatedView.getScaleX();
+ float currentScaleY = mScreenshotAnimatedView.getScaleY();
+
if (t < xPositionPct) {
float xCenter = MathUtils.lerp(startPos.x, finalPos.x,
mFastOutSlowIn.getInterpolation(t / xPositionPct));
- mScreenshotView.setX(xCenter - width * mScreenshotView.getScaleX() / 2f);
+ mScreenshotAnimatedView.setX(xCenter - width * currentScaleX / 2f);
} else {
- mScreenshotView.setX(finalPos.x - width * mScreenshotView.getScaleX() / 2f);
+ mScreenshotAnimatedView.setX(finalPos.x - width * currentScaleX / 2f);
}
float yCenter = MathUtils.lerp(startPos.y, finalPos.y,
mFastOutSlowIn.getInterpolation(t));
- mScreenshotView.setY(yCenter - height * mScreenshotView.getScaleY() / 2f);
+ mScreenshotAnimatedView.setY(yCenter - height * currentScaleY / 2f);
});
toCorner.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
- mScreenshotView.setVisibility(View.VISIBLE);
+ mScreenshotAnimatedView.setVisibility(View.VISIBLE);
}
});
@@ -676,15 +694,16 @@
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
- mScreenshotView.setScaleX(cornerScale);
- mScreenshotView.setScaleY(cornerScale);
- mScreenshotView.setX(finalPos.x - width * cornerScale / 2f);
- mScreenshotView.setY(finalPos.y - height * cornerScale / 2f);
+ mScreenshotAnimatedView.setScaleX(1);
+ mScreenshotAnimatedView.setScaleY(1);
+ mScreenshotAnimatedView.setX(finalPos.x - width * cornerScale / 2f);
+ mScreenshotAnimatedView.setY(finalPos.y - height * cornerScale / 2f);
Rect bounds = new Rect();
- mScreenshotView.getBoundsOnScreen(bounds);
- mDismissButton.setX(bounds.right - mDismissButtonSize / 2f);
- mDismissButton.setY(bounds.top - mDismissButtonSize / 2f);
+ mDismissButton.getBoundsOnScreen(bounds);
+ mScreenshotAnimatedView.setVisibility(View.GONE);
+ mScreenshotPreview.setVisibility(View.VISIBLE);
mDismissButton.setVisibility(View.VISIBLE);
+ mScreenshotLayout.forceLayout();
}
});
@@ -747,7 +766,7 @@
mActionsView.addView(editChip);
chips.add(editChip);
- mScreenshotView.setOnClickListener(v -> {
+ mScreenshotPreview.setOnClickListener(v -> {
try {
imageData.editAction.actionIntent.send();
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_PREVIEW_TAPPED);
@@ -757,7 +776,7 @@
Log.e(TAG, "Intent cancelled", e);
}
});
- mScreenshotView.setContentDescription(imageData.editAction.title);
+ mScreenshotPreview.setContentDescription(imageData.editAction.title);
if (DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI, SCREENSHOT_SCROLLING_ENABLED, false)) {
ScreenshotActionChip scrollChip = (ScreenshotActionChip) inflater.inflate(
@@ -775,20 +794,33 @@
chips.add(scrollChip);
}
+ // remove the margin from the last chip so that it's correctly aligned with the end
+ LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)
+ mActionsView.getChildAt(mActionsView.getChildCount() - 1).getLayoutParams();
+ params.setMarginEnd(0);
+
ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
animator.setDuration(SCREENSHOT_ACTIONS_EXPANSION_DURATION_MS);
float alphaFraction = (float) SCREENSHOT_ACTIONS_ALPHA_DURATION_MS
/ SCREENSHOT_ACTIONS_EXPANSION_DURATION_MS;
- mActionsContainer.setVisibility(VISIBLE);
- mActionsContainer.setAlpha(0);
+ mActionsContainer.setVisibility(View.VISIBLE);
+ mActionsContainer.setAlpha(0f);
+ mActionsContainerBackground.setAlpha(0f);
+ mActionsContainerBackground.setVisibility(View.VISIBLE);
+
+ mActionsContainer.setPivotX(0);
+ mActionsContainerBackground.setPivotX(0);
animator.addUpdateListener(animation -> {
float t = animation.getAnimatedFraction();
mBackgroundProtection.setAlpha(t);
- mActionsContainer.setAlpha(t < alphaFraction ? t / alphaFraction : 1);
+ float containerAlpha = t < alphaFraction ? t / alphaFraction : 1;
+ mActionsContainer.setAlpha(containerAlpha);
+ mActionsContainerBackground.setAlpha(containerAlpha);
float containerScale = SCREENSHOT_ACTIONS_START_SCALE_X
+ (t * (1 - SCREENSHOT_ACTIONS_START_SCALE_X));
mActionsContainer.setScaleX(containerScale);
+ mActionsContainerBackground.setScaleX(containerScale);
for (ScreenshotActionChip chip : chips) {
chip.setAlpha(t);
chip.setScaleX(1 / containerScale); // invert to keep size of children constant
@@ -808,13 +840,14 @@
ValueAnimator yAnim = ValueAnimator.ofFloat(0, 1);
yAnim.setInterpolator(mAccelerateInterpolator);
yAnim.setDuration(SCREENSHOT_DISMISS_Y_DURATION_MS);
- float screenshotStartY = mScreenshotView.getTranslationY();
+ float screenshotStartY = mScreenshotPreview.getTranslationY();
float dismissStartY = mDismissButton.getTranslationY();
yAnim.addUpdateListener(animation -> {
float yDelta = MathUtils.lerp(0, mDismissDeltaY, animation.getAnimatedFraction());
- mScreenshotView.setTranslationY(screenshotStartY + yDelta);
+ mScreenshotPreview.setTranslationY(screenshotStartY + yDelta);
mDismissButton.setTranslationY(dismissStartY + yDelta);
mActionsContainer.setTranslationY(yDelta);
+ mActionsContainerBackground.setTranslationY(yDelta);
});
AnimatorSet animSet = new AnimatorSet();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
index 1dbfa32..f55ce77 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
@@ -49,6 +49,7 @@
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.logging.NotificationPanelLogger;
import com.android.systemui.statusbar.notification.logging.NotificationPanelLoggerImpl;
+import com.android.systemui.statusbar.notification.row.ChannelEditorDialogController;
import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.row.PriorityOnboardingDialogController;
@@ -109,6 +110,7 @@
INotificationManager notificationManager,
LauncherApps launcherApps,
ShortcutManager shortcutManager,
+ ChannelEditorDialogController channelEditorDialogController,
CurrentUserContextTracker contextTracker,
Provider<PriorityOnboardingDialogController.Builder> builderProvider) {
return new NotificationGutsManager(
@@ -121,6 +123,7 @@
notificationManager,
launcherApps,
shortcutManager,
+ channelEditorDialogController,
contextTracker,
builderProvider);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt
index e75b705..b163818 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt
@@ -22,8 +22,8 @@
import android.app.NotificationChannel.DEFAULT_CHANNEL_ID
import android.app.NotificationChannelGroup
import android.app.NotificationManager.IMPORTANCE_NONE
+import android.app.NotificationManager.Importance
import android.content.Context
-import android.content.DialogInterface
import android.graphics.Color
import android.graphics.PixelFormat
import android.graphics.drawable.ColorDrawable
@@ -37,8 +37,10 @@
import android.view.WindowInsets.Type.statusBars
import android.view.WindowManager
import android.widget.TextView
+
import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.R
+
import javax.inject.Inject
import javax.inject.Singleton
@@ -59,11 +61,13 @@
@Singleton
class ChannelEditorDialogController @Inject constructor(
c: Context,
- private val noMan: INotificationManager
+ private val noMan: INotificationManager,
+ private val dialogBuilder: ChannelEditorDialog.Builder
) {
val context: Context = c.applicationContext
- lateinit var dialog: Dialog
+ private var prepared = false
+ private lateinit var dialog: ChannelEditorDialog
private var appIcon: Drawable? = null
private var appUid: Int? = null
@@ -74,13 +78,16 @@
// Caller should set this if they care about when we dismiss
var onFinishListener: OnChannelEditorDialogFinishedListener? = null
- // Channels handed to us from NotificationInfo
@VisibleForTesting
- internal val providedChannels = mutableListOf<NotificationChannel>()
+ internal val paddedChannels = mutableListOf<NotificationChannel>()
+ // Channels handed to us from NotificationInfo
+ private val providedChannels = mutableListOf<NotificationChannel>()
// Map from NotificationChannel to importance
private val edits = mutableMapOf<NotificationChannel, Int>()
- var appNotificationsEnabled = true
+ private var appNotificationsEnabled = true
+ // System settings for app notifications
+ private var appNotificationsCurrentlyEnabled: Boolean? = null
// Keep a mapping of NotificationChannel.getGroup() to the actual group name for display
@VisibleForTesting
@@ -106,10 +113,18 @@
this.appNotificationsEnabled = checkAreAppNotificationsOn()
this.onSettingsClickListener = onSettingsClickListener
+ // These will always start out the same
+ appNotificationsCurrentlyEnabled = appNotificationsEnabled
+
channelGroupList.clear()
channelGroupList.addAll(fetchNotificationChannelGroups())
buildGroupNameLookup()
+ providedChannels.clear()
+ providedChannels.addAll(channels)
padToFourChannels(channels)
+ initDialog()
+
+ prepared = true
}
private fun buildGroupNameLookup() {
@@ -121,21 +136,21 @@
}
private fun padToFourChannels(channels: Set<NotificationChannel>) {
- providedChannels.clear()
+ paddedChannels.clear()
// First, add all of the given channels
- providedChannels.addAll(channels.asSequence().take(4))
+ paddedChannels.addAll(channels.asSequence().take(4))
// Then pad to 4 if we haven't been given that many
- providedChannels.addAll(getDisplayableChannels(channelGroupList.asSequence())
- .filterNot { providedChannels.contains(it) }
+ paddedChannels.addAll(getDisplayableChannels(channelGroupList.asSequence())
+ .filterNot { paddedChannels.contains(it) }
.distinct()
- .take(4 - providedChannels.size))
+ .take(4 - paddedChannels.size))
// If we only got one channel and it has the default miscellaneous tag, then we actually
// are looking at an app with a targetSdk <= O, and it doesn't make much sense to show the
// channel
- if (providedChannels.size == 1 && DEFAULT_CHANNEL_ID == providedChannels[0].id) {
- providedChannels.clear()
+ if (paddedChannels.size == 1 && DEFAULT_CHANNEL_ID == paddedChannels[0].id) {
+ paddedChannels.clear()
}
}
@@ -157,7 +172,9 @@
}
fun show() {
- initDialog()
+ if (!prepared) {
+ throw IllegalStateException("Must call prepareDialogForApp() before calling show()")
+ }
dialog.show()
}
@@ -178,8 +195,10 @@
appUid = null
packageName = null
appName = null
+ appNotificationsCurrentlyEnabled = null
edits.clear()
+ paddedChannels.clear()
providedChannels.clear()
groupNameLookup.clear()
}
@@ -188,12 +207,27 @@
return groupNameLookup[groupId] ?: ""
}
- fun proposeEditForChannel(channel: NotificationChannel, edit: Int) {
+ fun proposeEditForChannel(channel: NotificationChannel, @Importance edit: Int) {
if (channel.importance == edit) {
edits.remove(channel)
} else {
edits[channel] = edit
}
+
+ dialog.updateDoneButtonText(hasChanges())
+ }
+
+ fun proposeSetAppNotificationsEnabled(enabled: Boolean) {
+ appNotificationsEnabled = enabled
+ dialog.updateDoneButtonText(hasChanges())
+ }
+
+ fun areAppNotificationsEnabled(): Boolean {
+ return appNotificationsEnabled
+ }
+
+ private fun hasChanges(): Boolean {
+ return edits.isNotEmpty() || (appNotificationsEnabled != appNotificationsCurrentlyEnabled)
}
@Suppress("unchecked_cast")
@@ -241,7 +275,7 @@
}
}
- if (appNotificationsEnabled != checkAreAppNotificationsOn()) {
+ if (appNotificationsEnabled != appNotificationsCurrentlyEnabled) {
applyAppNotificationsOn(appNotificationsEnabled)
}
}
@@ -252,7 +286,8 @@
}
private fun initDialog() {
- dialog = Dialog(context)
+ dialogBuilder.setContext(context)
+ dialog = dialogBuilder.build()
dialog.window?.requestFeature(Window.FEATURE_NO_TITLE)
// Prevent a11y readers from reading the first element in the dialog twice
@@ -260,16 +295,21 @@
dialog.apply {
setContentView(R.layout.notif_half_shelf)
setCanceledOnTouchOutside(true)
- setOnDismissListener(object : DialogInterface.OnDismissListener {
- override fun onDismiss(dialog: DialogInterface?) {
- onFinishListener?.onChannelEditorDialogFinished()
- }
- })
- findViewById<ChannelEditorListView>(R.id.half_shelf_container).apply {
+ setOnDismissListener { onFinishListener?.onChannelEditorDialogFinished() }
+
+ val listView = findViewById<ChannelEditorListView>(R.id.half_shelf_container)
+ listView?.apply {
controller = this@ChannelEditorDialogController
appIcon = this@ChannelEditorDialogController.appIcon
appName = this@ChannelEditorDialogController.appName
- channels = providedChannels
+ channels = paddedChannels
+ }
+
+ setOnShowListener {
+ // play a highlight animation for the given channels
+ for (channel in providedChannels) {
+ listView?.highlightChannel(channel)
+ }
}
findViewById<TextView>(R.id.done_button)?.setOnClickListener {
@@ -306,6 +346,28 @@
or WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED)
}
+class ChannelEditorDialog(context: Context) : Dialog(context) {
+ fun updateDoneButtonText(hasChanges: Boolean) {
+ findViewById<TextView>(R.id.done_button)?.setText(
+ if (hasChanges)
+ R.string.inline_ok_button
+ else
+ R.string.inline_done_button)
+ }
+
+ class Builder @Inject constructor() {
+ private lateinit var context: Context
+ fun setContext(context: Context): Builder {
+ this.context = context
+ return this
+ }
+
+ fun build(): ChannelEditorDialog {
+ return ChannelEditorDialog(context)
+ }
+ }
+}
+
interface OnChannelEditorDialogFinishedListener {
fun onChannelEditorDialogFinished()
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorListView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorListView.kt
index 983315e..38a1579 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorListView.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorListView.kt
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.notification.row
+import android.animation.ArgbEvaluator
+import android.animation.ValueAnimator
import android.app.NotificationChannel
import android.app.NotificationManager.IMPORTANCE_DEFAULT
import android.app.NotificationManager.IMPORTANCE_NONE
@@ -33,8 +35,10 @@
import android.widget.LinearLayout
import android.widget.Switch
import android.widget.TextView
+import com.android.settingslib.Utils
import com.android.systemui.R
+import com.android.systemui.util.Assert
/**
* Half-shelf for notification channel controls
@@ -51,6 +55,7 @@
// The first row is for the entire app
private lateinit var appControlRow: AppControlView
+ private val channelRows = mutableListOf<ChannelRow>()
override fun onFinishInflate() {
super.onFinishInflate()
@@ -58,8 +63,21 @@
appControlRow = findViewById(R.id.app_control)
}
+ /**
+ * Play a highlight animation for the given channel (it really should exist but this will just
+ * fail silently if it doesn't)
+ */
+ fun highlightChannel(channel: NotificationChannel) {
+ Assert.isMainThread()
+ for (row in channelRows) {
+ if (row.channel == channel) {
+ row.playHighlight()
+ }
+ }
+ }
+
private fun updateRows() {
- val enabled = controller.appNotificationsEnabled
+ val enabled = controller.areAppNotificationsEnabled()
val transition = AutoTransition()
transition.duration = 200
@@ -83,13 +101,10 @@
TransitionManager.beginDelayedTransition(this, transition)
// Remove any rows
- val n = childCount
- for (i in n.downTo(0)) {
- val child = getChildAt(i)
- if (child is ChannelRow) {
- removeView(child)
- }
+ for (row in channelRows) {
+ removeView(row)
}
+ channelRows.clear()
updateAppControlRow(enabled)
@@ -105,6 +120,8 @@
val row = inflater.inflate(R.layout.notif_half_shelf_row, null) as ChannelRow
row.controller = controller
row.channel = channel
+
+ channelRows.add(row)
addView(row)
}
@@ -114,7 +131,7 @@
.getString(R.string.notification_channel_dialog_title, appName)
appControlRow.switch.isChecked = enabled
appControlRow.switch.setOnCheckedChangeListener { _, b ->
- controller.appNotificationsEnabled = b
+ controller.proposeSetAppNotificationsEnabled(b)
updateRows()
}
}
@@ -140,8 +157,14 @@
private lateinit var channelName: TextView
private lateinit var channelDescription: TextView
private lateinit var switch: Switch
+ private val highlightColor: Int
var gentle = false
+ init {
+ highlightColor = Utils.getColorAttrDefaultColor(
+ context, android.R.attr.colorControlHighlight)
+ }
+
var channel: NotificationChannel? = null
set(newValue) {
field = newValue
@@ -150,6 +173,7 @@
}
override fun onFinishInflate() {
+ super.onFinishInflate()
channelName = findViewById(R.id.channel_name)
channelDescription = findViewById(R.id.channel_description)
switch = findViewById(R.id.toggle)
@@ -161,6 +185,22 @@
setOnClickListener { switch.toggle() }
}
+ /**
+ * Play an animation that highlights this row
+ */
+ fun playHighlight() {
+ // Use 0 for the start value because our background is given to us by our parent
+ val fadeInLoop = ValueAnimator.ofObject(ArgbEvaluator(), 0, highlightColor)
+ fadeInLoop.duration = 200L
+ fadeInLoop.addUpdateListener { animator ->
+ setBackgroundColor(animator.animatedValue as Int)
+ }
+ fadeInLoop.repeatMode = ValueAnimator.REVERSE
+ // Repeat an odd number of times to we end up normal
+ fadeInLoop.repeatCount = 5
+ fadeInLoop.start()
+ }
+
private fun updateViews() {
val nc = channel ?: return
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index 75affdf..3f7c7ca 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -87,6 +87,7 @@
private final VisualStabilityManager mVisualStabilityManager;
private final AccessibilityManager mAccessibilityManager;
private final HighPriorityProvider mHighPriorityProvider;
+ private final ChannelEditorDialogController mChannelEditorDialogController;
// Dependencies:
private final NotificationLockscreenUserManager mLockscreenUserManager =
@@ -127,6 +128,7 @@
INotificationManager notificationManager,
LauncherApps launcherApps,
ShortcutManager shortcutManager,
+ ChannelEditorDialogController channelEditorDialogController,
CurrentUserContextTracker contextTracker,
Provider<PriorityOnboardingDialogController.Builder> builderProvider) {
mContext = context;
@@ -140,6 +142,7 @@
mShortcutManager = shortcutManager;
mContextTracker = contextTracker;
mBuilderProvider = builderProvider;
+ mChannelEditorDialogController = channelEditorDialogController;
}
public void setUpWithPresenter(NotificationPresenter presenter,
@@ -348,6 +351,7 @@
pmUser,
mNotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
packageName,
row.getEntry().getChannel(),
row.getUniqueChannels(),
@@ -390,6 +394,7 @@
notificationInfoView.bindNotification(
pmUser,
mNotificationManager,
+ mChannelEditorDialogController,
packageName,
row.getEntry().getChannel(),
row.getUniqueChannels(),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
index 12aa4df..08affa8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
@@ -174,6 +174,7 @@
PackageManager pm,
INotificationManager iNotificationManager,
VisualStabilityManager visualStabilityManager,
+ ChannelEditorDialogController channelEditorDialogController,
String pkg,
NotificationChannel notificationChannel,
Set<NotificationChannel> uniqueChannelsInRow,
@@ -187,7 +188,7 @@
mINotificationManager = iNotificationManager;
mMetricsLogger = Dependency.get(MetricsLogger.class);
mVisualStabilityManager = visualStabilityManager;
- mChannelEditorDialogController = Dependency.get(ChannelEditorDialogController.class);
+ mChannelEditorDialogController = channelEditorDialogController;
mPackageName = pkg;
mUniqueChannelsInRow = uniqueChannelsInRow;
mNumUniqueChannelsInRow = uniqueChannelsInRow.size();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PartialConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PartialConversationInfo.java
index 2189b87..cc5de65 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PartialConversationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PartialConversationInfo.java
@@ -17,10 +17,6 @@
package com.android.systemui.statusbar.notification.row;
import static android.app.Notification.EXTRA_IS_GROUP_CONVERSATION;
-import static android.app.NotificationManager.IMPORTANCE_LOW;
-import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
-
-import static com.android.systemui.Interpolators.FAST_OUT_SLOW_IN;
import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -39,10 +35,6 @@
import android.os.RemoteException;
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;
-import android.transition.ChangeBounds;
-import android.transition.Fade;
-import android.transition.TransitionManager;
-import android.transition.TransitionSet;
import android.util.AttributeSet;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
@@ -51,7 +43,6 @@
import android.widget.TextView;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -108,6 +99,7 @@
public void bindNotification(
PackageManager pm,
INotificationManager iNotificationManager,
+ ChannelEditorDialogController channelEditorDialogController,
String pkg,
NotificationChannel notificationChannel,
Set<NotificationChannel> uniqueChannelsInRow,
@@ -127,7 +119,7 @@
mDelegatePkg = mSbn.getOpPkg();
mIsDeviceProvisioned = isDeviceProvisioned;
mIsNonBlockable = isNonBlockable;
- mChannelEditorDialogController = Dependency.get(ChannelEditorDialogController.class);
+ mChannelEditorDialogController = channelEditorDialogController;
mUniqueChannelsInRow = uniqueChannelsInRow;
bindHeader();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
index 45e47f1..f8da03a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
@@ -46,6 +46,8 @@
private static final String TAG = "KeyguardUserSwitcher";
private static final boolean ALWAYS_ON = false;
+ private static final float USER_SWITCH_ENABLED_ALPHA = 1.0f;
+ private static final float USER_SWITCH_DISABLED_ALPHA = 0.38f;
private final Container mUserSwitcherContainer;
private final KeyguardStatusBarView mStatusBarView;
@@ -293,6 +295,9 @@
mCurrentUserView = convertView;
}
convertView.setTag(item);
+ convertView.setAlpha(
+ item.isCurrent || item.isSwitchToEnabled ? USER_SWITCH_ENABLED_ALPHA
+ : USER_SWITCH_DISABLED_ALPHA);
return convertView;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt
index 8b81a7a..64d0256 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt
@@ -36,12 +36,14 @@
import org.junit.Before
import org.junit.runner.RunWith
import org.junit.Test
+import org.mockito.Answers
import org.mockito.ArgumentMatchers.anyBoolean
import org.mockito.ArgumentMatchers.eq
import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.Mockito.`when`
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
@SmallTest
@@ -59,11 +61,16 @@
@Mock
private lateinit var mockNoMan: INotificationManager
+ @Mock(answer = Answers.RETURNS_SELF)
+ private lateinit var dialogBuilder: ChannelEditorDialog.Builder
+ @Mock
+ private lateinit var dialog: ChannelEditorDialog
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
- controller = ChannelEditorDialogController(mContext, mockNoMan)
+ `when`(dialogBuilder.build()).thenReturn(dialog)
+ controller = ChannelEditorDialogController(mContext, mockNoMan, dialogBuilder)
channel1 = NotificationChannel(TEST_CHANNEL, TEST_CHANNEL_NAME, IMPORTANCE_DEFAULT)
channel2 = NotificationChannel(TEST_CHANNEL2, TEST_CHANNEL_NAME2, IMPORTANCE_DEFAULT)
@@ -86,7 +93,7 @@
controller.prepareDialogForApp(TEST_APP_NAME, TEST_PACKAGE_NAME, TEST_UID,
setOf(channel1, channel2), appIcon, clickListener)
- assertEquals(2, controller.providedChannels.size)
+ assertEquals(2, controller.paddedChannels.size)
}
@Test
@@ -97,7 +104,7 @@
setOf(channelDefault), appIcon, clickListener)
assertEquals("No channels should be shown when there is only the miscellaneous channel",
- 0, controller.providedChannels.size)
+ 0, controller.paddedChannels.size)
}
@Test
@@ -119,7 +126,7 @@
setOf(channel1), appIcon, clickListener)
assertEquals("ChannelEditorDialog should fetch enough channels to show 4",
- 4, controller.providedChannels.size)
+ 4, controller.paddedChannels.size)
}
@Test
@@ -147,7 +154,7 @@
controller.prepareDialogForApp(TEST_APP_NAME, TEST_PACKAGE_NAME, TEST_UID,
setOf(channel1, channel2), appIcon, clickListener)
- controller.appNotificationsEnabled = false
+ controller.proposeSetAppNotificationsEnabled(false)
controller.apply()
verify(mockNoMan, times(1)).setNotificationsEnabledForPackage(
@@ -162,7 +169,7 @@
controller.prepareDialogForApp(TEST_APP_NAME, TEST_PACKAGE_NAME, TEST_UID,
setOf(channel1, channel2), appIcon, clickListener)
- controller.appNotificationsEnabled = true
+ controller.proposeSetAppNotificationsEnabled(true)
controller.apply()
verify(mockNoMan, times(1)).setNotificationsEnabledForPackage(
@@ -171,12 +178,52 @@
@Test
fun testSettingsClickListenerNull_noCrash() {
+ // GIVEN editor dialog
group.channels = listOf(channel1, channel2)
controller.prepareDialogForApp(TEST_APP_NAME, TEST_PACKAGE_NAME, TEST_UID,
setOf(channel1, channel2), appIcon, null)
+ // WHEN user taps settings
// Pass in any old view, it should never actually be used
controller.launchSettings(View(context))
+
+ // THEN no crash
+ }
+
+ @Test
+ fun testDoneButtonSaysDone_noChanges() {
+ // GIVEN the editor dialog with no changes
+ `when`(dialogBuilder.build()).thenReturn(dialog)
+
+ group.channels = listOf(channel1, channel2)
+ controller.prepareDialogForApp(TEST_APP_NAME, TEST_PACKAGE_NAME, TEST_UID,
+ setOf(channel1, channel2), appIcon, null)
+
+ // WHEN the user proposes a change
+ controller.proposeEditForChannel(channel1, IMPORTANCE_NONE)
+
+ // THEN the "done" button has been updated to "apply"
+ verify(dialog).updateDoneButtonText(true /* hasChanges */)
+ }
+
+ @Test
+ fun testDoneButtonGoesBackToNormal_changeThenNoChange() {
+ val inOrderDialog = Mockito.inOrder(dialog)
+ // GIVEN the editor dialog with no changes
+ `when`(dialogBuilder.build()).thenReturn(dialog)
+
+ group.channels = listOf(channel1, channel2)
+ controller.prepareDialogForApp(TEST_APP_NAME, TEST_PACKAGE_NAME, TEST_UID,
+ setOf(channel1, channel2), appIcon, null)
+
+ // WHEN the user proposes a change
+ controller.proposeEditForChannel(channel1, IMPORTANCE_NONE)
+ // and WHEN the user sets the importance back to its original value
+ controller.proposeEditForChannel(channel1, channel1.importance)
+
+ // THEN the "done" button has been changed back to done
+ inOrderDialog.verify(dialog, times(1)).updateDoneButtonText(eq(true))
+ inOrderDialog.verify(dialog, times(1)).updateDoneButtonText(eq(false))
}
private val clickListener = object : NotificationInfo.OnSettingsClickListener {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
index 5813740..eeb912e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
@@ -123,6 +123,7 @@
@Mock private INotificationManager mINotificationManager;
@Mock private LauncherApps mLauncherApps;
@Mock private ShortcutManager mShortcutManager;
+ @Mock private ChannelEditorDialogController mChannelEditorDialogController;
@Mock private PeopleNotificationIdentifier mPeopleNotificationIdentifier;
@Mock private CurrentUserContextTracker mContextTracker;
@Mock(answer = Answers.RETURNS_SELF)
@@ -144,7 +145,8 @@
mGutsManager = new NotificationGutsManager(mContext, mVisualStabilityManager,
() -> mStatusBar, mHandler, mAccessibilityManager, mHighPriorityProvider,
- mINotificationManager, mLauncherApps, mShortcutManager, mContextTracker, mProvider);
+ mINotificationManager, mLauncherApps, mShortcutManager,
+ mChannelEditorDialogController, mContextTracker, mProvider);
mGutsManager.setUpWithPresenter(mPresenter, mStackScroller,
mCheckSaveListener, mOnSettingsClickListener);
mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);
@@ -350,6 +352,7 @@
any(PackageManager.class),
any(INotificationManager.class),
eq(mVisualStabilityManager),
+ eq(mChannelEditorDialogController),
eq(statusBarNotification.getPackageName()),
any(NotificationChannel.class),
anySet(),
@@ -381,6 +384,7 @@
any(PackageManager.class),
any(INotificationManager.class),
eq(mVisualStabilityManager),
+ eq(mChannelEditorDialogController),
eq(statusBarNotification.getPackageName()),
any(NotificationChannel.class),
anySet(),
@@ -410,6 +414,7 @@
any(PackageManager.class),
any(INotificationManager.class),
eq(mVisualStabilityManager),
+ eq(mChannelEditorDialogController),
eq(statusBarNotification.getPackageName()),
any(NotificationChannel.class),
anySet(),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
index 98ef691..8ee86a2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
@@ -30,17 +30,13 @@
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyString;
-import static org.mockito.Mockito.doCallRealMethod;
-import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -53,13 +49,11 @@
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
-import android.os.IBinder;
import android.os.UserHandle;
import android.provider.Settings;
import android.service.notification.StatusBarNotification;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
-import android.testing.PollingCheck;
import android.testing.TestableLooper;
import android.testing.UiThreadTest;
import android.view.LayoutInflater;
@@ -68,7 +62,6 @@
import android.widget.TextView;
import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
@@ -120,6 +113,8 @@
private PackageManager mMockPackageManager;
@Mock
private VisualStabilityManager mVisualStabilityManager;
+ @Mock
+ private ChannelEditorDialogController mChannelEditorDialogController;
@Before
public void setUp() throws Exception {
@@ -185,6 +180,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -208,6 +204,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -227,6 +224,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -257,6 +255,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -277,6 +276,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -304,6 +304,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -326,6 +327,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -345,6 +347,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mDefaultNotificationChannel,
mDefaultNotificationChannelSet,
@@ -368,6 +371,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mDefaultNotificationChannel,
mDefaultNotificationChannelSet,
@@ -387,6 +391,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -407,6 +412,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -432,6 +438,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -452,6 +459,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -473,6 +481,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -486,6 +495,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -506,6 +516,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME, mNotificationChannel,
createMultipleChannelSet(MULTIPLE_CHANNEL_COUNT),
mEntry,
@@ -531,6 +542,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
createMultipleChannelSet(MULTIPLE_CHANNEL_COUNT),
@@ -552,6 +564,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
createMultipleChannelSet(MULTIPLE_CHANNEL_COUNT),
@@ -573,6 +586,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -596,6 +610,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -614,6 +629,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -632,6 +648,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -653,6 +670,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -677,6 +695,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -701,6 +720,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -726,6 +746,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -751,6 +772,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -782,6 +804,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -814,6 +837,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -846,6 +870,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -881,6 +906,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -915,6 +941,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -940,6 +967,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -968,6 +996,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -999,6 +1028,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -1025,6 +1055,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -1056,6 +1087,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -1080,6 +1112,7 @@
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java
index c390e39..1bfebfb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java
@@ -98,6 +98,8 @@
private INotificationManager mMockINotificationManager;
@Mock
private PackageManager mMockPackageManager;
+ @Mock
+ private ChannelEditorDialogController mChannelEditorDialogController;
@Mock
private Icon mIcon;
@@ -160,6 +162,7 @@
mInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -181,6 +184,7 @@
mInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -207,6 +211,7 @@
mInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -223,6 +228,7 @@
mInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -250,6 +256,7 @@
mInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -267,6 +274,7 @@
mInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -291,6 +299,7 @@
mInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -310,6 +319,7 @@
mInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -327,6 +337,7 @@
mInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -349,6 +360,7 @@
mInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -365,6 +377,7 @@
mInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
@@ -383,6 +396,7 @@
mInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
+ mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
diff --git a/packages/Tethering/common/TetheringLib/Android.bp b/packages/Tethering/common/TetheringLib/Android.bp
index b520bc8..8ae1593 100644
--- a/packages/Tethering/common/TetheringLib/Android.bp
+++ b/packages/Tethering/common/TetheringLib/Android.bp
@@ -67,6 +67,7 @@
stubs_defaults {
name: "framework-tethering-stubs-defaults",
srcs: [":framework-tethering-srcs"],
+ dist: { dest: "framework-tethering.txt" },
}
filegroup {
@@ -123,16 +124,19 @@
name: "framework-tethering-stubs-publicapi",
srcs: [":framework-tethering-stubs-srcs-publicapi"],
defaults: ["framework-module-stubs-lib-defaults-publicapi"],
+ dist: { dest: "framework-tethering.jar" },
}
java_library {
name: "framework-tethering-stubs-systemapi",
srcs: [":framework-tethering-stubs-srcs-systemapi"],
defaults: ["framework-module-stubs-lib-defaults-systemapi"],
+ dist: { dest: "framework-tethering.jar" },
}
java_library {
name: "framework-tethering-stubs-module_libs_api",
srcs: [":framework-tethering-stubs-srcs-module_libs_api"],
defaults: ["framework-module-stubs-lib-defaults-module_libs_api"],
+ dist: { dest: "framework-tethering.jar" },
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index e4eb585..2c63c6f 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -3011,10 +3011,13 @@
// Legacy version of notifyNetworkTestedWithExtras.
// Would only be called if the system has a NetworkStack module older than the
// framework, which does not happen in practice.
+ Slog.wtf(TAG, "Deprecated notifyNetworkTested called: no action taken");
}
@Override
public void notifyNetworkTestedWithExtras(NetworkTestResultParcelable p) {
+ // Notify mTrackerHandler and mConnectivityDiagnosticsHandler of the event. Both use
+ // the same looper so messages will be processed in sequence.
final Message msg = mTrackerHandler.obtainMessage(
EVENT_NETWORK_TESTED,
new NetworkTestedResults(
diff --git a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
index 228966c..103f659 100644
--- a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
+++ b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
@@ -17,7 +17,6 @@
package com.android.server.connectivity;
import static android.net.ConnectivityManager.NetworkCallback;
-import static android.net.ipsec.ike.SaProposal.DH_GROUP_1024_BIT_MODP;
import static android.net.ipsec.ike.SaProposal.DH_GROUP_2048_BIT_MODP;
import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_CBC;
import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12;
@@ -85,6 +84,12 @@
public class VpnIkev2Utils {
private static final String TAG = VpnIkev2Utils.class.getSimpleName();
+ // TODO: Use IKE library exposed constants when @SystemApi is updated.
+ /** IANA-defined 3072 group for use in IKEv2 */
+ private static final int DH_GROUP_3072_BIT_MODP = 15;
+ /** IANA-defined 4096 group for use in IKEv2 */
+ private static final int DH_GROUP_4096_BIT_MODP = 16;
+
static IkeSessionParams buildIkeSessionParams(
@NonNull Context context, @NonNull Ikev2VpnProfile profile, @NonNull Network network) {
final IkeIdentification localId = parseIkeIdentification(profile.getUserIdentity());
@@ -177,8 +182,9 @@
// Add dh, prf for both builders
for (final IkeSaProposal.Builder builder : Arrays.asList(normalModeBuilder, aeadBuilder)) {
+ builder.addDhGroup(DH_GROUP_4096_BIT_MODP);
+ builder.addDhGroup(DH_GROUP_3072_BIT_MODP);
builder.addDhGroup(DH_GROUP_2048_BIT_MODP);
- builder.addDhGroup(DH_GROUP_1024_BIT_MODP);
builder.addPseudorandomFunction(PSEUDORANDOM_FUNCTION_AES128_XCBC);
builder.addPseudorandomFunction(PSEUDORANDOM_FUNCTION_HMAC_SHA1);
}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 7972f24..93d45c8 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -3441,6 +3441,11 @@
public boolean armRebootEscrow() {
return mRebootEscrowManager.armRebootEscrowIfNeeded();
}
+
+ @Override
+ public void refreshStrongAuthTimeout(int userId) {
+ mStrongAuth.refreshStrongAuthTimeout(userId);
+ }
}
private class RebootEscrowCallbacks implements RebootEscrowManager.Callbacks {
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java b/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java
index 8480197..a102406 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java
@@ -58,6 +58,7 @@
private static final int MSG_SCHEDULE_NON_STRONG_BIOMETRIC_TIMEOUT = 7;
private static final int MSG_STRONG_BIOMETRIC_UNLOCK = 8;
private static final int MSG_SCHEDULE_NON_STRONG_BIOMETRIC_IDLE_TIMEOUT = 9;
+ private static final int MSG_REFRESH_STRONG_AUTH_TIMEOUT = 10;
@VisibleForTesting
protected static final String STRONG_AUTH_TIMEOUT_ALARM_TAG =
@@ -143,6 +144,15 @@
public long getNextAlarmTimeMs(long timeout) {
return SystemClock.elapsedRealtime() + timeout;
}
+
+ /**
+ * Wraps around {@link SystemClock#elapsedRealtime}, which returns the number of
+ * milliseconds since boot, including time spent in sleep.
+ */
+ @VisibleForTesting
+ public long getElapsedRealtimeMs() {
+ return SystemClock.elapsedRealtime();
+ }
}
private void handleAddStrongAuthTracker(IStrongAuthTracker tracker) {
@@ -231,22 +241,33 @@
}
}
- private void handleScheduleStrongAuthTimeout(int userId) {
+ /**
+ * Re-schedule the strong auth timeout alarm with latest information on the most recent
+ * successful strong auth time and strong auth timeout from device policy.
+ */
+ private void rescheduleStrongAuthTimeoutAlarm(long strongAuthTime, int userId) {
final DevicePolicyManager dpm =
(DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
- long nextAlarmTime =
- mInjector.getNextAlarmTimeMs(dpm.getRequiredStrongAuthTimeout(null, userId));
// cancel current alarm listener for the user (if there was one)
StrongAuthTimeoutAlarmListener alarm = mStrongAuthTimeoutAlarmListenerForUser.get(userId);
if (alarm != null) {
mAlarmManager.cancel(alarm);
+ alarm.setLatestStrongAuthTime(strongAuthTime);
} else {
- alarm = new StrongAuthTimeoutAlarmListener(userId);
+ alarm = new StrongAuthTimeoutAlarmListener(strongAuthTime, userId);
mStrongAuthTimeoutAlarmListenerForUser.put(userId, alarm);
}
+ // AlarmManager.set() correctly handles the case where nextAlarmTime has already been in
+ // the past (by firing the listener straight away), so nothing special for us to do here.
+ long nextAlarmTime = strongAuthTime + dpm.getRequiredStrongAuthTimeout(null, userId);
+
// schedule a new alarm listener for the user
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, nextAlarmTime,
STRONG_AUTH_TIMEOUT_ALARM_TAG, alarm, mHandler);
+ }
+
+ private void handleScheduleStrongAuthTimeout(int userId) {
+ rescheduleStrongAuthTimeoutAlarm(mInjector.getElapsedRealtimeMs(), userId);
// cancel current non-strong biometric alarm listener for the user (if there was one)
cancelNonStrongBiometricAlarmListener(userId);
@@ -256,6 +277,13 @@
setIsNonStrongBiometricAllowed(true, userId);
}
+ private void handleRefreshStrongAuthTimeout(int userId) {
+ StrongAuthTimeoutAlarmListener alarm = mStrongAuthTimeoutAlarmListenerForUser.get(userId);
+ if (alarm != null) {
+ rescheduleStrongAuthTimeoutAlarm(alarm.getLatestStrongAuthTime(), userId);
+ }
+ }
+
private void handleScheduleNonStrongBiometricTimeout(int userId) {
if (DEBUG) Slog.d(TAG, "handleScheduleNonStrongBiometricTimeout for userId=" + userId);
long nextAlarmTime = mInjector.getNextAlarmTimeMs(DEFAULT_NON_STRONG_BIOMETRIC_TIMEOUT_MS);
@@ -456,6 +484,13 @@
}
/**
+ * Refreshes pending strong auth timeout with the latest admin requirement set by device policy.
+ */
+ public void refreshStrongAuthTimeout(int userId) {
+ mHandler.obtainMessage(MSG_REFRESH_STRONG_AUTH_TIMEOUT, userId, 0).sendToTarget();
+ }
+
+ /**
* Report successful unlocking with biometric
*/
public void reportSuccessfulBiometricUnlock(boolean isStrongBiometric, int userId) {
@@ -489,12 +524,30 @@
@VisibleForTesting
protected class StrongAuthTimeoutAlarmListener implements OnAlarmListener {
+ private long mLatestStrongAuthTime;
private final int mUserId;
- public StrongAuthTimeoutAlarmListener(int userId) {
+ public StrongAuthTimeoutAlarmListener(long latestStrongAuthTime, int userId) {
+ mLatestStrongAuthTime = latestStrongAuthTime;
mUserId = userId;
}
+ /**
+ * Sets the most recent time when a successful strong auth happened, in number of
+ * milliseconds.
+ */
+ public void setLatestStrongAuthTime(long strongAuthTime) {
+ mLatestStrongAuthTime = strongAuthTime;
+ }
+
+ /**
+ * Returns the most recent time when a successful strong auth happened, in number of
+ * milliseconds.
+ */
+ public long getLatestStrongAuthTime() {
+ return mLatestStrongAuthTime;
+ }
+
@Override
public void onAlarm() {
requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_TIMEOUT, mUserId);
@@ -558,6 +611,9 @@
case MSG_SCHEDULE_STRONG_AUTH_TIMEOUT:
handleScheduleStrongAuthTimeout(msg.arg1);
break;
+ case MSG_REFRESH_STRONG_AUTH_TIMEOUT:
+ handleRefreshStrongAuthTimeout(msg.arg1);
+ break;
case MSG_NO_LONGER_REQUIRE_STRONG_AUTH:
handleNoLongerRequireStrongAuth(msg.arg1, msg.arg2);
break;
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 76acf57..d007b77 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -235,6 +235,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.compat.IPlatformCompat;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
+import com.android.internal.logging.InstanceId;
import com.android.internal.logging.InstanceIdSequence;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto;
@@ -6490,7 +6491,7 @@
// Log event to statsd
mNotificationRecordLogger.maybeLogNotificationPosted(r, old, position,
- buzzBeepBlinkLoggingCode);
+ buzzBeepBlinkLoggingCode, getGroupInstanceId(n.getGroupKey()));
} finally {
int N = mEnqueuedNotifications.size();
for (int i = 0; i < N; i++) {
@@ -6506,6 +6507,21 @@
}
/**
+ *
+ */
+ @GuardedBy("mNotificationLock")
+ InstanceId getGroupInstanceId(String groupKey) {
+ if (groupKey == null) {
+ return null;
+ }
+ NotificationRecord group = mSummaryByGroupKey.get(groupKey);
+ if (group == null) {
+ return null;
+ }
+ return group.getSbn().getInstanceId();
+ }
+
+ /**
* If the notification differs enough visually, consider it a new interruptive notification.
*/
@GuardedBy("mNotificationLock")
diff --git a/services/core/java/com/android/server/notification/NotificationRecordLogger.java b/services/core/java/com/android/server/notification/NotificationRecordLogger.java
index eba5730..34e6ec1 100644
--- a/services/core/java/com/android/server/notification/NotificationRecordLogger.java
+++ b/services/core/java/com/android/server/notification/NotificationRecordLogger.java
@@ -27,6 +27,7 @@
import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationStats;
+import com.android.internal.logging.InstanceId;
import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
@@ -48,10 +49,12 @@
* @param old The previous NotificationRecord. Null if there was no previous record.
* @param position The position at which this notification is ranked.
* @param buzzBeepBlink Logging code reflecting whether this notification alerted the user.
+ * @param groupId The instance Id of the group summary notification, or null.
*/
void maybeLogNotificationPosted(@Nullable NotificationRecord r,
@Nullable NotificationRecord old,
- int position, int buzzBeepBlink);
+ int position, int buzzBeepBlink,
+ InstanceId groupId);
/**
* Logs a notification cancel / dismiss event using UiEventReported (event ids from the
diff --git a/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java b/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
index 494ff31..c6ec95a 100644
--- a/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
+++ b/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
@@ -16,6 +16,7 @@
package com.android.server.notification;
+import com.android.internal.logging.InstanceId;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.UiEventLoggerImpl;
import com.android.internal.util.FrameworkStatsLog;
@@ -30,7 +31,8 @@
@Override
public void maybeLogNotificationPosted(NotificationRecord r, NotificationRecord old,
- int position, int buzzBeepBlink) {
+ int position, int buzzBeepBlink,
+ InstanceId groupId) {
NotificationRecordPair p = new NotificationRecordPair(r, old);
if (!p.shouldLogReported(buzzBeepBlink)) {
return;
@@ -43,7 +45,7 @@
/* int32 notification_id_hash = 5 */ p.getNotificationIdHash(),
/* int32 channel_id_hash = 6 */ p.getChannelIdHash(),
/* string group_id_hash = 7 */ p.getGroupIdHash(),
- /* int32 group_instance_id = 8 */ 0, // TODO generate and fill instance ids
+ /* int32 group_instance_id = 8 */ (groupId == null) ? 0 : groupId.getId(),
/* bool is_group_summary = 9 */ r.getSbn().getNotification().isGroupSummary(),
/* string category = 10 */ r.getSbn().getNotification().category,
/* int32 style = 11 */ p.getStyle(),
diff --git a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
index 9a5b020..5657c74 100644
--- a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
+++ b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
@@ -19,14 +19,18 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
+import android.app.RemoteAction;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
+import android.graphics.drawable.Icon;
+import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
+import android.os.Parcelable;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -39,6 +43,7 @@
import android.util.ArrayMap;
import android.util.Slog;
import android.util.SparseArray;
+import android.view.textclassifier.ConversationAction;
import android.view.textclassifier.ConversationActions;
import android.view.textclassifier.SelectionEvent;
import android.view.textclassifier.SystemTextClassifierMetadata;
@@ -69,6 +74,7 @@
import java.util.Map;
import java.util.Objects;
import java.util.Queue;
+import java.util.stream.Collectors;
/**
* A manager for TextClassifier services.
@@ -203,7 +209,7 @@
request.getSystemTextClassifierMetadata(),
/* verifyCallingPackage= */ true,
/* attemptToBind= */ true,
- service -> service.onClassifyText(sessionId, request, callback),
+ service -> service.onClassifyText(sessionId, request, wrap(callback)),
"onClassifyText",
callback);
}
@@ -289,7 +295,8 @@
request.getSystemTextClassifierMetadata(),
/* verifyCallingPackage= */ true,
/* attemptToBind= */ true,
- service -> service.onSuggestConversationActions(sessionId, request, callback),
+ service -> service.onSuggestConversationActions(
+ sessionId, request, wrap(callback)),
"onSuggestConversationActions",
callback);
}
@@ -464,6 +471,10 @@
}
}
+ private static ITextClassifierCallback wrap(ITextClassifierCallback orig) {
+ return new CallbackWrapper(orig);
+ }
+
private void onTextClassifierServicePackageOverrideChanged(String overriddenPackage) {
synchronized (mLock) {
final int size = mUserStates.size();
@@ -1004,4 +1015,112 @@
onTextClassifierServicePackageOverrideChanged(currentServicePackageOverride);
}
}
+
+ /**
+ * Wraps an ITextClassifierCallback and modifies the response to it where necessary.
+ */
+ private static final class CallbackWrapper extends ITextClassifierCallback.Stub {
+
+ private final ITextClassifierCallback mWrapped;
+
+ CallbackWrapper(ITextClassifierCallback wrapped) {
+ mWrapped = Objects.requireNonNull(wrapped);
+ }
+
+ @Override
+ public void onSuccess(Bundle result) {
+ final Parcelable parcelled = TextClassifierService.getResponse(result);
+ if (parcelled instanceof TextClassification) {
+ rewriteTextClassificationIcons(result);
+ } else if (parcelled instanceof ConversationActions) {
+ rewriteConversationActionsIcons(result);
+ } else {
+ // do nothing.
+ }
+ try {
+ mWrapped.onSuccess(result);
+ } catch (RemoteException e) {
+ Slog.e(LOG_TAG, "Callback error", e);
+ }
+ }
+
+ private static void rewriteTextClassificationIcons(Bundle result) {
+ final TextClassification classification = TextClassifierService.getResponse(result);
+ boolean rewrite = false;
+ for (RemoteAction action : classification.getActions()) {
+ rewrite |= shouldRewriteIcon(action);
+ }
+ if (rewrite) {
+ TextClassifierService.putResponse(
+ result,
+ classification.toBuilder()
+ .clearActions()
+ .addActions(classification.getActions()
+ .stream()
+ .map(action -> validAction(action))
+ .collect(Collectors.toList()))
+ .build());
+ }
+ }
+
+ private static void rewriteConversationActionsIcons(Bundle result) {
+ final ConversationActions convActions = TextClassifierService.getResponse(result);
+ boolean rewrite = false;
+ for (ConversationAction convAction : convActions.getConversationActions()) {
+ rewrite |= shouldRewriteIcon(convAction.getAction());
+ }
+ if (rewrite) {
+ TextClassifierService.putResponse(
+ result,
+ new ConversationActions(
+ convActions.getConversationActions()
+ .stream()
+ .map(convAction -> convAction.toBuilder()
+ .setAction(validAction(convAction.getAction()))
+ .build())
+ .collect(Collectors.toList()),
+ convActions.getId()));
+ }
+ }
+
+ @Nullable
+ private static RemoteAction validAction(@Nullable RemoteAction action) {
+ if (!shouldRewriteIcon(action)) {
+ return action;
+ }
+
+ final RemoteAction newAction = new RemoteAction(
+ changeIcon(action.getIcon()),
+ action.getTitle(),
+ action.getContentDescription(),
+ action.getActionIntent());
+ newAction.setEnabled(action.isEnabled());
+ newAction.setShouldShowIcon(action.shouldShowIcon());
+ return newAction;
+ }
+
+ private static boolean shouldRewriteIcon(@Nullable RemoteAction action) {
+ // Check whether to rewrite the icon.
+ // Rewrite icons to ensure that the icons do not:
+ // 1. Leak package names
+ // 2. are renderable in the client process.
+ return action != null && action.getIcon().getType() == Icon.TYPE_RESOURCE;
+ }
+
+ /** Changes icon of type=RESOURCES to icon of type=URI. */
+ private static Icon changeIcon(Icon icon) {
+ final Uri uri = IconsUriHelper.getInstance()
+ .getContentUri(icon.getResPackage(), icon.getResId());
+ return Icon.createWithContentUri(uri);
+ }
+
+ @Override
+ public void onFailure() {
+ try {
+ mWrapped.onFailure();
+ } catch (RemoteException e) {
+ Slog.e(LOG_TAG, "Callback error", e);
+ }
+ }
+ }
}
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index f692660..9026b81 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -1092,8 +1092,7 @@
final boolean uidPresentOnDisplay = displayContent.isUidPresent(callingUid);
final int displayOwnerUid = displayContent.mDisplay.getOwnerUid();
- if (displayContent.mDisplay.getType() == TYPE_VIRTUAL && displayOwnerUid != SYSTEM_UID
- && displayOwnerUid != aInfo.applicationInfo.uid) {
+ if (displayContent.mDisplay.getType() == TYPE_VIRTUAL && displayOwnerUid != SYSTEM_UID) {
// Limit launching on virtual displays, because their contents can be read from Surface
// by apps that created them.
if ((aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index e109ded..9868446 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -5640,6 +5640,11 @@
Slog.w(TAG, "Failed to deliver showInsets", e);
}
}
+
+ @Override
+ public boolean isClientControlled() {
+ return false;
+ }
}
/**
diff --git a/services/core/java/com/android/server/wm/InsetsControlTarget.java b/services/core/java/com/android/server/wm/InsetsControlTarget.java
index bbc6c2b..42c1a07 100644
--- a/services/core/java/com/android/server/wm/InsetsControlTarget.java
+++ b/services/core/java/com/android/server/wm/InsetsControlTarget.java
@@ -61,4 +61,12 @@
default boolean canShowTransient() {
return false;
}
+
+ /**
+ * Returns {@code true} if the object controlling the insets is on client.
+ */
+ default boolean isClientControlled() {
+ return true;
+ }
+
}
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 351743f..56986c2 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -38,6 +38,7 @@
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.function.TriConsumer;
import com.android.server.wm.SurfaceAnimator.AnimationType;
import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
@@ -288,6 +289,7 @@
t.deferTransactionUntil(leash, barrier, frameNumber);
}
mControlTarget = target;
+ updateVisibility();
mControl = new InsetsSourceControl(mSource.getType(), leash,
new Point(mWin.getWindowFrames().mFrame.left, mWin.getWindowFrames().mFrame.top));
}
@@ -330,13 +332,16 @@
updateVisibility();
}
- private void setServerVisible(boolean serverVisible) {
+ @VisibleForTesting
+ void setServerVisible(boolean serverVisible) {
mServerVisible = serverVisible;
updateVisibility();
}
private void updateVisibility() {
- mSource.setVisible(mServerVisible && mClientVisible);
+ final boolean isClientControlled = mControlTarget != null
+ && mControlTarget.isClientControlled();
+ mSource.setVisible(mServerVisible && (!isClientControlled || mClientVisible));
}
InsetsSourceControl getControl(InsetsControlTarget target) {
@@ -408,10 +413,10 @@
public void onAnimationCancelled(SurfaceControl animationLeash) {
if (mAdapter == this) {
mStateController.notifyControlRevoked(mControlTarget, InsetsSourceProvider.this);
- setClientVisible(InsetsState.getDefaultVisibility(mSource.getType()));
mControl = null;
mControlTarget = null;
mAdapter = null;
+ setClientVisible(InsetsState.getDefaultVisibility(mSource.getType()));
}
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index a74706b..3323fa4 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -22,6 +22,7 @@
import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_ALL_MASK;
import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
import static android.app.admin.DeviceAdminReceiver.EXTRA_TRANSFER_OWNERSHIP_ADMIN_EXTRAS_BUNDLE;
+import static android.app.admin.DevicePolicyManager.ACTION_CHECK_POLICY_COMPLIANCE;
import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_USER;
import static android.app.admin.DevicePolicyManager.CODE_ACCOUNTS_NOT_EMPTY;
import static android.app.admin.DevicePolicyManager.CODE_CANNOT_ADD_MANAGED_PROFILE;
@@ -409,6 +410,12 @@
private static final String ACTION_EXPIRED_PASSWORD_NOTIFICATION =
"com.android.server.ACTION_EXPIRED_PASSWORD_NOTIFICATION";
+ /** Broadcast action invoked when the user taps a notification to turn the profile on. */
+ @VisibleForTesting
+ static final String ACTION_TURN_PROFILE_ON_NOTIFICATION =
+ "com.android.server.ACTION_TURN_PROFILE_ON_NOTIFICATION";
+
+ /** Broadcast action for tracking managed profile maximum time off. */
@VisibleForTesting
static final String ACTION_PROFILE_OFF_DEADLINE =
"com.android.server.ACTION_PROFILE_OFF_DEADLINE";
@@ -951,7 +958,10 @@
}
if (isManagedProfile(userHandle)) {
Slog.d(LOG_TAG, "Managed profile became unlocked");
- updatePersonalAppsSuspension(userHandle, true /* unlocked */);
+ if (updatePersonalAppsSuspension(userHandle, true /* unlocked */)
+ == PERSONAL_APPS_SUSPENDED_PROFILE_TIMEOUT) {
+ triggerPolicyComplianceCheck(userHandle);
+ }
}
} else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
handlePackagesChanged(null /* check all admins */, userHandle);
@@ -982,6 +992,9 @@
} else {
Slog.wtf(LOG_TAG, "Got deadline alarm for nonexistent profile");
}
+ } else if (ACTION_TURN_PROFILE_ON_NOTIFICATION.equals(action)) {
+ Slog.i(LOG_TAG, "requesting to turn on the profile: " + userHandle);
+ mUserManager.requestQuietModeEnabled(false, UserHandle.of(userHandle));
}
}
@@ -2568,6 +2581,7 @@
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_BOOT_COMPLETED);
filter.addAction(ACTION_EXPIRED_PASSWORD_NOTIFICATION);
+ filter.addAction(ACTION_TURN_PROFILE_ON_NOTIFICATION);
filter.addAction(ACTION_PROFILE_OFF_DEADLINE);
filter.addAction(Intent.ACTION_USER_ADDED);
filter.addAction(Intent.ACTION_USER_REMOVED);
@@ -5904,12 +5918,22 @@
}
final int userHandle = mInjector.userHandleGetCallingUserId();
+ boolean changed = false;
synchronized (getLockObject()) {
ActiveAdmin ap = getActiveAdminForCallerLocked(who,
DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, parent);
if (ap.strongAuthUnlockTimeout != timeoutMs) {
ap.strongAuthUnlockTimeout = timeoutMs;
saveSettingsLocked(userHandle);
+ changed = true;
+ }
+ }
+ if (changed) {
+ mLockSettingsInternal.refreshStrongAuthTimeout(userHandle);
+ // Refreshes the parent if profile has unified challenge, since the timeout would
+ // also affect the parent user in this case.
+ if (isManagedProfile(userHandle) && !isSeparateProfileChallengeEnabled(userHandle)) {
+ mLockSettingsInternal.refreshStrongAuthTimeout(getProfileParentId(userHandle));
}
}
}
@@ -15940,14 +15964,29 @@
.write();
}
+ /** Starts an activity to check policy compliance in the DPC. */
+ private void triggerPolicyComplianceCheck(int profileUserId) {
+ final Intent intent = new Intent(ACTION_CHECK_POLICY_COMPLIANCE);
+ synchronized (getLockObject()) {
+ final ActiveAdmin profileOwner = getProfileOwnerAdminLocked(profileUserId);
+ if (profileOwner == null) {
+ Slog.wtf(LOG_TAG, "Profile owner not found for compliance check");
+ return;
+ }
+ intent.setPackage(profileOwner.info.getPackageName());
+ }
+ mContext.startActivityAsUser(intent, UserHandle.of(profileUserId));
+ }
+
/**
* Checks whether personal apps should be suspended according to the policy and applies the
* change if needed.
*
* @param unlocked whether the profile is currently running unlocked.
*/
- private void updatePersonalAppsSuspension(int profileUserId, boolean unlocked) {
- final boolean suspended;
+ private @PersonalAppsSuspensionReason int updatePersonalAppsSuspension(
+ int profileUserId, boolean unlocked) {
+ final boolean suspendedExplicitly;
final int deadlineState;
final String poPackage;
synchronized (getLockObject()) {
@@ -15955,26 +15994,28 @@
if (profileOwner != null) {
deadlineState =
updateProfileOffDeadlineLocked(profileUserId, profileOwner, unlocked);
- suspended = profileOwner.mSuspendPersonalApps
- || deadlineState == PROFILE_OFF_DEADLINE_REACHED;
+ suspendedExplicitly = profileOwner.mSuspendPersonalApps;
poPackage = profileOwner.info.getPackageName();
} else {
poPackage = null;
- suspended = false;
+ suspendedExplicitly = false;
deadlineState = PROFILE_OFF_DEADLINE_DEFAULT;
}
}
- Slog.d(LOG_TAG, String.format("Personal apps suspended: %b, deadline state: %d",
- suspended, deadlineState));
+ Slog.d(LOG_TAG, String.format("Personal apps suspended explicitly: %b, deadline state: %d",
+ suspendedExplicitly, deadlineState));
if (poPackage != null) {
final int notificationState = unlocked ? PROFILE_OFF_DEADLINE_DEFAULT : deadlineState;
updateProfileOffDeadlineNotification(profileUserId, poPackage, notificationState);
}
+ final boolean suspendedByTimeout = deadlineState == PROFILE_OFF_DEADLINE_REACHED;
final int parentUserId = getProfileParentId(profileUserId);
- suspendPersonalAppsInternal(parentUserId, suspended);
+ suspendPersonalAppsInternal(parentUserId, suspendedExplicitly || suspendedByTimeout);
+
+ return makeSuspensionReasons(suspendedExplicitly, suspendedByTimeout);
}
/**
@@ -16034,8 +16075,10 @@
}
final AlarmManager am = mInjector.getAlarmManager();
+ final Intent intent = new Intent(ACTION_PROFILE_OFF_DEADLINE);
+ intent.setPackage(mContext.getPackageName());
final PendingIntent pi = mInjector.pendingIntentGetBroadcast(
- mContext, REQUEST_PROFILE_OFF_DEADLINE, new Intent(ACTION_PROFILE_OFF_DEADLINE),
+ mContext, REQUEST_PROFILE_OFF_DEADLINE, intent,
PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT);
if (alarmTime == 0) {
@@ -16084,28 +16127,35 @@
return;
}
- final Intent intent = new Intent(DevicePolicyManager.ACTION_CHECK_POLICY_COMPLIANCE);
- intent.setPackage(profileOwnerPackage);
+ final Intent intent = new Intent(ACTION_TURN_PROFILE_ON_NOTIFICATION);
+ intent.setPackage(mContext.getPackageName());
+ intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
- final PendingIntent pendingIntent = mInjector.pendingIntentGetActivityAsUser(mContext,
- 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT,
- null /* options */, UserHandle.of(profileUserId));
+ final PendingIntent pendingIntent = mInjector.pendingIntentGetBroadcast(mContext,
+ 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
- // TODO(b/149075510): Only the first of the notifications should be dismissible.
+ final String buttonText =
+ mContext.getString(R.string.personal_apps_suspended_turn_profile_on);
+ final Notification.Action turnProfileOnButton =
+ new Notification.Action.Builder(null /* icon */, buttonText, pendingIntent).build();
+
final String text = mContext.getString(
notificationState == PROFILE_OFF_DEADLINE_WARNING
? R.string.personal_apps_suspension_tomorrow_text
: R.string.personal_apps_suspension_text);
+ final boolean ongoing = notificationState == PROFILE_OFF_DEADLINE_REACHED;
final Notification notification =
new Notification.Builder(mContext, SystemNotificationChannels.DEVICE_ADMIN)
.setSmallIcon(android.R.drawable.stat_sys_warning)
- .setOngoing(true)
+ .setOngoing(ongoing)
+ .setAutoCancel(false)
.setContentTitle(mContext.getString(
R.string.personal_apps_suspension_title))
.setContentText(text)
+ .setStyle(new Notification.BigTextStyle().bigText(text))
.setColor(mContext.getColor(R.color.system_notification_accent_color))
- .setContentIntent(pendingIntent)
+ .addAction(turnProfileOnButton)
.build();
mInjector.getNotificationManager().notify(
SystemMessage.NOTE_PERSONAL_APPS_SUSPENDED, notification);
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index c228508..6b36bc5 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -17,6 +17,7 @@
import static android.app.Notification.EXTRA_TEXT;
import static android.app.Notification.EXTRA_TITLE;
+import static android.app.admin.DevicePolicyManager.ACTION_CHECK_POLICY_COMPLIANCE;
import static android.app.admin.DevicePolicyManager.DELEGATION_APP_RESTRICTIONS;
import static android.app.admin.DevicePolicyManager.DELEGATION_CERT_INSTALL;
import static android.app.admin.DevicePolicyManager.ID_TYPE_BASE_INFO;
@@ -32,6 +33,9 @@
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
import static com.android.internal.widget.LockPatternUtils.EscrowTokenStateChangeCallback;
+import static com.android.server.devicepolicy.DevicePolicyManagerService.ACTION_PROFILE_OFF_DEADLINE;
+import static com.android.server.devicepolicy.DevicePolicyManagerService.ACTION_TURN_PROFILE_ON_NOTIFICATION;
+import static com.android.server.devicepolicy.DpmMockContext.CALLER_USER_HANDLE;
import static com.android.server.testutils.TestUtils.assertExpectException;
import static com.google.common.truth.Truth.assertThat;
@@ -220,7 +224,7 @@
// Make createContextAsUser to work.
mContext.packageName = "com.android.frameworks.servicestests";
getServices().addPackageContext(UserHandle.of(0), mContext);
- getServices().addPackageContext(UserHandle.of(DpmMockContext.CALLER_USER_HANDLE), mContext);
+ getServices().addPackageContext(UserHandle.of(CALLER_USER_HANDLE), mContext);
// By default, pretend all users are running and unlocked.
when(getServices().userManager.isUserUnlocked(anyInt())).thenReturn(true);
@@ -321,22 +325,21 @@
anyString(), any(UserHandle.class));
// Add the first secondary user.
- getServices().addUser(DpmMockContext.CALLER_USER_HANDLE, 0,
- UserManager.USER_TYPE_FULL_SECONDARY);
+ getServices().addUser(CALLER_USER_HANDLE, 0, UserManager.USER_TYPE_FULL_SECONDARY);
}
private void setAsProfileOwner(ComponentName admin) {
final long ident = mServiceContext.binder.clearCallingIdentity();
mServiceContext.binder.callingUid =
- UserHandle.getUid(DpmMockContext.CALLER_USER_HANDLE, DpmMockContext.SYSTEM_UID);
+ UserHandle.getUid(CALLER_USER_HANDLE, DpmMockContext.SYSTEM_UID);
runAsCaller(mServiceContext, dpms, dpm -> {
// PO needs to be a DA.
dpm.setActiveAdmin(admin, /*replace=*/ false);
// Fire!
- assertTrue(dpm.setProfileOwner(admin, "owner-name", DpmMockContext.CALLER_USER_HANDLE));
+ assertTrue(dpm.setProfileOwner(admin, "owner-name", CALLER_USER_HANDLE));
// Check
- assertEquals(admin, dpm.getProfileOwnerAsUser(DpmMockContext.CALLER_USER_HANDLE));
+ assertEquals(admin, dpm.getProfileOwnerAsUser(CALLER_USER_HANDLE));
});
mServiceContext.binder.restoreCallingIdentity(ident);
@@ -360,12 +363,10 @@
setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID);
setAsProfileOwner(admin2);
// Active admin in CALLER_USER_HANDLE
- final int ANOTHER_UID = UserHandle.getUid(DpmMockContext.CALLER_USER_HANDLE, 1306);
+ final int ANOTHER_UID = UserHandle.getUid(CALLER_USER_HANDLE, 1306);
setUpPackageManagerForFakeAdmin(adminAnotherPackage, ANOTHER_UID, admin2);
- dpm.setActiveAdmin(adminAnotherPackage, /* replace =*/ false,
- DpmMockContext.CALLER_USER_HANDLE);
- assertTrue(dpm.isAdminActiveAsUser(adminAnotherPackage,
- DpmMockContext.CALLER_USER_HANDLE));
+ dpm.setActiveAdmin(adminAnotherPackage, /* replace =*/ false, CALLER_USER_HANDLE);
+ assertTrue(dpm.isAdminActiveAsUser(adminAnotherPackage, CALLER_USER_HANDLE));
initializeDpms();
@@ -376,7 +377,7 @@
verify(getServices().usageStatsManagerInternal).setActiveAdminApps(
MockUtils.checkApps(admin2.getPackageName(),
adminAnotherPackage.getPackageName()),
- eq(DpmMockContext.CALLER_USER_HANDLE));
+ eq(CALLER_USER_HANDLE));
verify(getServices().usageStatsManagerInternal).onAdminDataAvailable();
verify(getServices().networkPolicyManagerInternal).onAdminDataAvailable();
}
@@ -389,7 +390,7 @@
// Verify
verify(getServices().usageStatsManagerInternal).setActiveAdminApps(
- null, DpmMockContext.CALLER_USER_HANDLE);
+ null, CALLER_USER_HANDLE);
verify(getServices().usageStatsManagerInternal).setActiveAdminApps(
null, ANOTHER_USER_ID);
verify(getServices().usageStatsManagerInternal).onAdminDataAvailable();
@@ -410,7 +411,7 @@
mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
assertExpectException(SecurityException.class, /* messageRegex= */ null,
- () -> dpm.setActiveAdmin(admin1, false, DpmMockContext.CALLER_USER_HANDLE + 1));
+ () -> dpm.setActiveAdmin(admin1, false, CALLER_USER_HANDLE + 1));
}
/**
@@ -435,11 +436,11 @@
verify(mContext.spiedContext).sendBroadcastAsUser(
MockUtils.checkIntentAction(
DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
- MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE));
+ MockUtils.checkUserHandle(CALLER_USER_HANDLE));
verify(mContext.spiedContext).sendBroadcastAsUser(
MockUtils.checkIntentAction(
DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED),
- MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE),
+ MockUtils.checkUserHandle(CALLER_USER_HANDLE),
eq(null),
any(Bundle.class));
@@ -447,11 +448,11 @@
eq(admin1.getPackageName()),
eq(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT),
eq(PackageManager.DONT_KILL_APP),
- eq(DpmMockContext.CALLER_USER_HANDLE),
+ eq(CALLER_USER_HANDLE),
anyString());
verify(getServices().usageStatsManagerInternal).onActiveAdminAdded(
- admin1.getPackageName(), DpmMockContext.CALLER_USER_HANDLE);
+ admin1.getPackageName(), CALLER_USER_HANDLE);
// TODO Verify other calls too.
@@ -466,8 +467,8 @@
// (Because we're checking a different user's status from CALLER_USER_HANDLE.)
mContext.callerPermissions.add("android.permission.INTERACT_ACROSS_USERS_FULL");
- assertFalse(dpm.isAdminActiveAsUser(admin1, DpmMockContext.CALLER_USER_HANDLE + 1));
- assertFalse(dpm.isAdminActiveAsUser(admin2, DpmMockContext.CALLER_USER_HANDLE + 1));
+ assertFalse(dpm.isAdminActiveAsUser(admin1, CALLER_USER_HANDLE + 1));
+ assertFalse(dpm.isAdminActiveAsUser(admin2, CALLER_USER_HANDLE + 1));
mContext.callerPermissions.remove("android.permission.INTERACT_ACROSS_USERS_FULL");
@@ -489,13 +490,13 @@
eq(admin1.getPackageName()),
eq(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT),
eq(PackageManager.DONT_KILL_APP),
- eq(DpmMockContext.CALLER_USER_HANDLE),
+ eq(CALLER_USER_HANDLE),
anyString());
// times(2) because it was previously called for admin1 which is in the same package
// as admin2.
verify(getServices().usageStatsManagerInternal, times(2)).onActiveAdminAdded(
- admin2.getPackageName(), DpmMockContext.CALLER_USER_HANDLE);
+ admin2.getPackageName(), CALLER_USER_HANDLE);
// 4. Add the same admin1 again without replace, which should throw.
assertExpectException(IllegalArgumentException.class, /* messageRegex= */ null,
@@ -520,7 +521,7 @@
mContext.callerPermissions.add("android.permission.INTERACT_ACROSS_USERS_FULL");
assertEquals(0, DpmTestUtils.getListSizeAllowingNull(
- dpm.getActiveAdminsAsUser(DpmMockContext.CALLER_USER_HANDLE + 1)));
+ dpm.getActiveAdminsAsUser(CALLER_USER_HANDLE + 1)));
mContext.callerPermissions.remove("android.permission.INTERACT_ACROSS_USERS_FULL");
}
@@ -606,11 +607,11 @@
assertTrue(dpm.isAdminActive(admin1));
- assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
+ assertFalse(dpm.isRemovingAdmin(admin1, CALLER_USER_HANDLE));
// Directly call the DPMS method with a different userid, which should fail.
assertExpectException(SecurityException.class, /* messageRegex =*/ null,
- () -> dpms.removeActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE + 1));
+ () -> dpms.removeActiveAdmin(admin1, CALLER_USER_HANDLE + 1));
// Try to remove active admin with a different caller userid should fail too, without
// having MANAGE_DEVICE_ADMINS.
@@ -620,7 +621,7 @@
mContext.binder.callingUid = 1234567;
assertExpectException(SecurityException.class, /* messageRegex =*/ null,
- () -> dpms.removeActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
+ () -> dpms.removeActiveAdmin(admin1, CALLER_USER_HANDLE));
}
/**
@@ -638,27 +639,25 @@
assertTrue(dpm.isAdminActive(admin1));
- assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
+ assertFalse(dpm.isRemovingAdmin(admin1, CALLER_USER_HANDLE));
// 1. User not unlocked.
- when(getServices().userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE)))
- .thenReturn(false);
+ setUserUnlocked(CALLER_USER_HANDLE, false);
assertExpectException(IllegalStateException.class,
/* messageRegex= */ "User must be running and unlocked",
() -> dpm.removeActiveAdmin(admin1));
- assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
+ assertFalse(dpm.isRemovingAdmin(admin1, CALLER_USER_HANDLE));
verify(getServices().usageStatsManagerInternal, times(0)).setActiveAdminApps(
- null, DpmMockContext.CALLER_USER_HANDLE);
+ null, CALLER_USER_HANDLE);
// 2. User unlocked.
- when(getServices().userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE)))
- .thenReturn(true);
+ setUserUnlocked(CALLER_USER_HANDLE, true);
dpm.removeActiveAdmin(admin1);
- assertFalse(dpm.isAdminActiveAsUser(admin1, DpmMockContext.CALLER_USER_HANDLE));
+ assertFalse(dpm.isAdminActiveAsUser(admin1, CALLER_USER_HANDLE));
verify(getServices().usageStatsManagerInternal).setActiveAdminApps(
- null, DpmMockContext.CALLER_USER_HANDLE);
+ null, CALLER_USER_HANDLE);
}
/**
@@ -673,7 +672,7 @@
dpm.setActiveAdmin(admin1, /* replace =*/ false);
assertTrue(dpm.isAdminActive(admin1));
- assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
+ assertFalse(dpm.isRemovingAdmin(admin1, CALLER_USER_HANDLE));
// Different user, but should work, because caller has proper permissions.
mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
@@ -681,10 +680,10 @@
// Change the caller, and call into DPMS directly with a different user-id.
mContext.binder.callingUid = 1234567;
- dpms.removeActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE);
- assertFalse(dpm.isAdminActiveAsUser(admin1, DpmMockContext.CALLER_USER_HANDLE));
+ dpms.removeActiveAdmin(admin1, CALLER_USER_HANDLE);
+ assertFalse(dpm.isAdminActiveAsUser(admin1, CALLER_USER_HANDLE));
verify(getServices().usageStatsManagerInternal).setActiveAdminApps(
- null, DpmMockContext.CALLER_USER_HANDLE);
+ null, CALLER_USER_HANDLE);
// TODO DO Still can't be removed in this case.
}
@@ -702,13 +701,13 @@
dpm.setActiveAdmin(admin1, /* replace =*/ false);
assertTrue(dpm.isAdminActive(admin1));
- assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
+ assertFalse(dpm.isRemovingAdmin(admin1, CALLER_USER_HANDLE));
// Broadcast from saveSettingsLocked().
verify(mContext.spiedContext, times(1)).sendBroadcastAsUser(
MockUtils.checkIntentAction(
DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
- MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE));
+ MockUtils.checkUserHandle(CALLER_USER_HANDLE));
// Remove. No permissions, but same user, so it'll work.
mContext.callerPermissions.clear();
@@ -717,7 +716,7 @@
verify(mContext.spiedContext).sendOrderedBroadcastAsUser(
MockUtils.checkIntentAction(
DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLED),
- MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE),
+ MockUtils.checkUserHandle(CALLER_USER_HANDLE),
isNull(String.class),
eq(AppOpsManager.OP_NONE),
any(Bundle.class),
@@ -727,15 +726,15 @@
isNull(String.class),
isNull(Bundle.class));
- assertFalse(dpm.isAdminActiveAsUser(admin1, DpmMockContext.CALLER_USER_HANDLE));
+ assertFalse(dpm.isAdminActiveAsUser(admin1, CALLER_USER_HANDLE));
verify(getServices().usageStatsManagerInternal).setActiveAdminApps(
- null, DpmMockContext.CALLER_USER_HANDLE);
+ null, CALLER_USER_HANDLE);
// Again broadcast from saveSettingsLocked().
verify(mContext.spiedContext, times(2)).sendBroadcastAsUser(
MockUtils.checkIntentAction(
DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
- MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE));
+ MockUtils.checkUserHandle(CALLER_USER_HANDLE));
// TODO Check other internal calls.
}
@@ -748,19 +747,19 @@
dpm.setActiveAdmin(admin1, /* replace =*/ false);
assertTrue(dpm.isAdminActive(admin1));
- assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
+ assertFalse(dpm.isRemovingAdmin(admin1, CALLER_USER_HANDLE));
// Add admin2.
dpm.setActiveAdmin(admin2, /* replace =*/ false);
assertTrue(dpm.isAdminActive(admin2));
- assertFalse(dpm.isRemovingAdmin(admin2, DpmMockContext.CALLER_USER_HANDLE));
+ assertFalse(dpm.isRemovingAdmin(admin2, CALLER_USER_HANDLE));
// Broadcast from saveSettingsLocked().
verify(mContext.spiedContext, times(2)).sendBroadcastAsUser(
MockUtils.checkIntentAction(
DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
- MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE));
+ MockUtils.checkUserHandle(CALLER_USER_HANDLE));
// Remove. No permissions, but same user, so it'll work.
mContext.callerPermissions.clear();
@@ -769,7 +768,7 @@
verify(mContext.spiedContext).sendOrderedBroadcastAsUser(
MockUtils.checkIntentAction(
DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLED),
- MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE),
+ MockUtils.checkUserHandle(CALLER_USER_HANDLE),
isNull(String.class),
eq(AppOpsManager.OP_NONE),
any(Bundle.class),
@@ -779,16 +778,16 @@
isNull(String.class),
isNull(Bundle.class));
- assertFalse(dpm.isAdminActiveAsUser(admin1, DpmMockContext.CALLER_USER_HANDLE));
+ assertFalse(dpm.isAdminActiveAsUser(admin1, CALLER_USER_HANDLE));
verify(getServices().usageStatsManagerInternal).setActiveAdminApps(
MockUtils.checkApps(admin2.getPackageName()),
- eq(DpmMockContext.CALLER_USER_HANDLE));
+ eq(CALLER_USER_HANDLE));
// Again broadcast from saveSettingsLocked().
verify(mContext.spiedContext, times(3)).sendBroadcastAsUser(
MockUtils.checkIntentAction(
DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
- MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE));
+ MockUtils.checkUserHandle(CALLER_USER_HANDLE));
}
/**
@@ -800,7 +799,7 @@
// Add admin.
setupPackageInPackageManager(admin1.getPackageName(),
- /* userId= */ DpmMockContext.CALLER_USER_HANDLE,
+ /* userId= */ CALLER_USER_HANDLE,
/* appId= */ 10138,
/* flags= */ ApplicationInfo.FLAG_TEST_ONLY);
dpm.setActiveAdmin(admin1, /* replace =*/ false);
@@ -810,16 +809,16 @@
mContext.binder.callingUid = 123456;
assertExpectException(SecurityException.class,
/* messageRegex =*/ "Non-shell user attempted to call",
- () -> dpms.forceRemoveActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
+ () -> dpms.forceRemoveActiveAdmin(admin1, CALLER_USER_HANDLE));
mContext.binder.callingUid = Process.SHELL_UID;
- dpms.forceRemoveActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE);
+ dpms.forceRemoveActiveAdmin(admin1, CALLER_USER_HANDLE);
mContext.callerPermissions.add(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
// Verify
- assertFalse(dpm.isAdminActiveAsUser(admin1, DpmMockContext.CALLER_USER_HANDLE));
+ assertFalse(dpm.isAdminActiveAsUser(admin1, CALLER_USER_HANDLE));
verify(getServices().usageStatsManagerInternal).setActiveAdminApps(
- null, DpmMockContext.CALLER_USER_HANDLE);
+ null, CALLER_USER_HANDLE);
}
/**
@@ -1244,12 +1243,12 @@
setAsProfileOwner(admin1);
verify(getServices().ibackupManager, times(1)).setBackupServiceActive(
- eq(DpmMockContext.CALLER_USER_HANDLE), eq(false));
+ eq(CALLER_USER_HANDLE), eq(false));
dpm.clearProfileOwner(admin1);
verify(getServices().ibackupManager, times(1)).setBackupServiceActive(
- eq(DpmMockContext.CALLER_USER_HANDLE), eq(true));
+ eq(CALLER_USER_HANDLE), eq(true));
}
public void testClearDeviceOwner_fromDifferentUser() throws Exception {
@@ -1341,11 +1340,11 @@
setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID);
mServiceContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
runAsCaller(mServiceContext, dpms, dpm -> {
- dpm.setActiveAdmin(admin2, /* refreshing= */ true, DpmMockContext.CALLER_USER_HANDLE);
+ dpm.setActiveAdmin(admin2, /* refreshing= */ true, CALLER_USER_HANDLE);
assertExpectException(IllegalStateException.class,
/* messageRegex= */ "already has a profile owner",
() -> dpm.setDeviceOwner(admin2, "owner-name",
- DpmMockContext.CALLER_USER_HANDLE));
+ CALLER_USER_HANDLE));
});
}
@@ -1355,7 +1354,7 @@
mContext.binder.callingUid = DpmMockContext.CALLER_UID;
assertTrue(dpm.isProfileOwnerApp(admin1.getPackageName()));
- assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
+ assertFalse(dpm.isRemovingAdmin(admin1, CALLER_USER_HANDLE));
// First try when the user is locked, which should fail.
when(getServices().userManager.isUserUnlocked(anyInt()))
@@ -1370,9 +1369,9 @@
// Check
assertFalse(dpm.isProfileOwnerApp(admin1.getPackageName()));
- assertFalse(dpm.isAdminActiveAsUser(admin1, DpmMockContext.CALLER_USER_HANDLE));
+ assertFalse(dpm.isAdminActiveAsUser(admin1, CALLER_USER_HANDLE));
verify(getServices().usageStatsManagerInternal).setActiveAdminApps(
- null, DpmMockContext.CALLER_USER_HANDLE);
+ null, CALLER_USER_HANDLE);
}
public void testSetProfileOwner_failures() throws Exception {
@@ -1416,14 +1415,14 @@
dpm.setActiveAdmin(admin1, /* replace =*/ false);
dpm.setActiveAdmin(admin3, /* replace =*/ false);
- dpm.setActiveAdmin(admin1, /* replace =*/ false, DpmMockContext.CALLER_USER_HANDLE);
- dpm.setActiveAdmin(admin2, /* replace =*/ false, DpmMockContext.CALLER_USER_HANDLE);
+ dpm.setActiveAdmin(admin1, /* replace =*/ false, CALLER_USER_HANDLE);
+ dpm.setActiveAdmin(admin2, /* replace =*/ false, CALLER_USER_HANDLE);
dpm.setActiveAdmin(admin2, /* replace =*/ false, ANOTHER_USER_ID);
// Set DO on the first non-system user.
- getServices().setUserRunning(DpmMockContext.CALLER_USER_HANDLE, true);
- assertTrue(dpm.setDeviceOwner(admin2, "owner-name", DpmMockContext.CALLER_USER_HANDLE));
+ getServices().setUserRunning(CALLER_USER_HANDLE, true);
+ assertTrue(dpm.setDeviceOwner(admin2, "owner-name", CALLER_USER_HANDLE));
assertEquals(admin2, dpms.getDeviceOwnerComponent(/* callingUserOnly =*/ false));
@@ -1447,7 +1446,7 @@
// Overwrite the device owner setting and clears the clas name.
dpms.mOwners.setDeviceOwner(
new ComponentName(admin2.getPackageName(), ""),
- "owner-name", DpmMockContext.CALLER_USER_HANDLE);
+ "owner-name", CALLER_USER_HANDLE);
dpms.mOwners.writeDeviceOwner();
// Make sure the DO component name doesn't have a class name.
@@ -1508,7 +1507,7 @@
*/
private int setupPackageInPackageManager(final String packageName, final int appId)
throws Exception {
- return setupPackageInPackageManager(packageName, DpmMockContext.CALLER_USER_HANDLE, appId,
+ return setupPackageInPackageManager(packageName, CALLER_USER_HANDLE, appId,
ApplicationInfo.FLAG_HAS_CODE);
}
@@ -1549,7 +1548,7 @@
}
public void testCertificateDisclosure() throws Exception {
- final int userId = DpmMockContext.CALLER_USER_HANDLE;
+ final int userId = CALLER_USER_HANDLE;
final UserHandle user = UserHandle.of(userId);
mContext.applicationInfo = new ApplicationInfo();
@@ -1591,7 +1590,7 @@
public void testDelegation() throws Exception {
setAsProfileOwner(admin1);
- final int userHandle = DpmMockContext.CALLER_USER_HANDLE;
+ final int userHandle = CALLER_USER_HANDLE;
// Given two packages
final String CERT_DELEGATE = "com.delegate.certs";
@@ -1895,23 +1894,22 @@
DpmTestUtils.assertRestrictions(
DpmTestUtils.newRestrictions(),
- dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE)
- .ensureUserRestrictions()
+ dpms.getProfileOwnerAdminLocked(CALLER_USER_HANDLE).ensureUserRestrictions()
);
dpm.addUserRestriction(admin1, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
- eq(DpmMockContext.CALLER_USER_HANDLE),
+ eq(CALLER_USER_HANDLE),
MockUtils.checkUserRestrictions(),
- MockUtils.checkUserRestrictions(DpmMockContext.CALLER_USER_HANDLE,
+ MockUtils.checkUserRestrictions(CALLER_USER_HANDLE,
UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES),
eq(false));
dpm.addUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
- eq(DpmMockContext.CALLER_USER_HANDLE),
+ eq(CALLER_USER_HANDLE),
MockUtils.checkUserRestrictions(),
- MockUtils.checkUserRestrictions(DpmMockContext.CALLER_USER_HANDLE,
+ MockUtils.checkUserRestrictions(CALLER_USER_HANDLE,
UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
UserManager.DISALLOW_OUTGOING_CALLS),
eq(false));
@@ -1921,7 +1919,7 @@
UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
UserManager.DISALLOW_OUTGOING_CALLS
),
- dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE)
+ dpms.getProfileOwnerAdminLocked(CALLER_USER_HANDLE)
.ensureUserRestrictions()
);
DpmTestUtils.assertRestrictions(
@@ -1934,9 +1932,9 @@
dpm.clearUserRestriction(admin1, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
- eq(DpmMockContext.CALLER_USER_HANDLE),
+ eq(CALLER_USER_HANDLE),
MockUtils.checkUserRestrictions(),
- MockUtils.checkUserRestrictions(DpmMockContext.CALLER_USER_HANDLE,
+ MockUtils.checkUserRestrictions(CALLER_USER_HANDLE,
UserManager.DISALLOW_OUTGOING_CALLS),
eq(false));
@@ -1944,7 +1942,7 @@
DpmTestUtils.newRestrictions(
UserManager.DISALLOW_OUTGOING_CALLS
),
- dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE)
+ dpms.getProfileOwnerAdminLocked(CALLER_USER_HANDLE)
.ensureUserRestrictions()
);
DpmTestUtils.assertRestrictions(
@@ -1956,13 +1954,13 @@
dpm.clearUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
- eq(DpmMockContext.CALLER_USER_HANDLE),
+ eq(CALLER_USER_HANDLE),
MockUtils.checkUserRestrictions(),
- MockUtils.checkUserRestrictions(DpmMockContext.CALLER_USER_HANDLE), eq(false));
+ MockUtils.checkUserRestrictions(CALLER_USER_HANDLE), eq(false));
DpmTestUtils.assertRestrictions(
DpmTestUtils.newRestrictions(),
- dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE)
+ dpms.getProfileOwnerAdminLocked(CALLER_USER_HANDLE)
.ensureUserRestrictions()
);
DpmTestUtils.assertRestrictions(
@@ -1976,18 +1974,18 @@
dpm.addUserRestriction(admin1, UserManager.DISALLOW_UNMUTE_MICROPHONE);
verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
- eq(DpmMockContext.CALLER_USER_HANDLE),
+ eq(CALLER_USER_HANDLE),
MockUtils.checkUserRestrictions(),
- MockUtils.checkUserRestrictions(DpmMockContext.CALLER_USER_HANDLE,
+ MockUtils.checkUserRestrictions(CALLER_USER_HANDLE,
UserManager.DISALLOW_ADJUST_VOLUME,
UserManager.DISALLOW_UNMUTE_MICROPHONE),
eq(false));
dpm.setCameraDisabled(admin1, true);
verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
- eq(DpmMockContext.CALLER_USER_HANDLE),
+ eq(CALLER_USER_HANDLE),
MockUtils.checkUserRestrictions(),
- MockUtils.checkUserRestrictions(DpmMockContext.CALLER_USER_HANDLE,
+ MockUtils.checkUserRestrictions(CALLER_USER_HANDLE,
UserManager.DISALLOW_ADJUST_VOLUME,
UserManager.DISALLOW_UNMUTE_MICROPHONE,
UserManager.DISALLOW_CAMERA),
@@ -2029,13 +2027,13 @@
public void testSetUserRestriction_asPoOfOrgOwnedDevice() throws Exception {
final int MANAGED_PROFILE_ADMIN_UID =
- UserHandle.getUid(DpmMockContext.CALLER_USER_HANDLE, DpmMockContext.SYSTEM_UID);
+ UserHandle.getUid(CALLER_USER_HANDLE, DpmMockContext.SYSTEM_UID);
mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
- configureProfileOwnerOfOrgOwnedDevice(admin1, DpmMockContext.CALLER_USER_HANDLE);
+ configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE);
- when(getServices().userManager.getProfileParent(DpmMockContext.CALLER_USER_HANDLE))
+ when(getServices().userManager.getProfileParent(CALLER_USER_HANDLE))
.thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0));
for (String restriction : PROFILE_OWNER_ORGANIZATION_OWNED_GLOBAL_RESTRICTIONS) {
@@ -2047,13 +2045,13 @@
parentDpm.setCameraDisabled(admin1, true);
verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
- eq(DpmMockContext.CALLER_USER_HANDLE),
+ eq(CALLER_USER_HANDLE),
MockUtils.checkUserRestrictions(UserManager.DISALLOW_CAMERA),
- MockUtils.checkUserRestrictions(DpmMockContext.CALLER_USER_HANDLE),
+ MockUtils.checkUserRestrictions(CALLER_USER_HANDLE),
eq(false));
DpmTestUtils.assertRestrictions(
DpmTestUtils.newRestrictions(UserManager.DISALLOW_CAMERA),
- dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE)
+ dpms.getProfileOwnerAdminLocked(CALLER_USER_HANDLE)
.getParentActiveAdmin()
.getEffectiveRestrictions()
);
@@ -2061,7 +2059,7 @@
parentDpm.setCameraDisabled(admin1, false);
DpmTestUtils.assertRestrictions(
DpmTestUtils.newRestrictions(),
- dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE)
+ dpms.getProfileOwnerAdminLocked(CALLER_USER_HANDLE)
.getParentActiveAdmin()
.getEffectiveRestrictions()
);
@@ -2071,14 +2069,14 @@
private void addAndRemoveGlobalUserRestrictionOnParentDpm(String restriction) {
parentDpm.addUserRestriction(admin1, restriction);
verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
- eq(DpmMockContext.CALLER_USER_HANDLE),
+ eq(CALLER_USER_HANDLE),
MockUtils.checkUserRestrictions(restriction),
- MockUtils.checkUserRestrictions(DpmMockContext.CALLER_USER_HANDLE),
+ MockUtils.checkUserRestrictions(CALLER_USER_HANDLE),
eq(false));
parentDpm.clearUserRestriction(admin1, restriction);
DpmTestUtils.assertRestrictions(
DpmTestUtils.newRestrictions(),
- dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE)
+ dpms.getProfileOwnerAdminLocked(CALLER_USER_HANDLE)
.getParentActiveAdmin()
.getEffectiveRestrictions()
);
@@ -2087,14 +2085,14 @@
private void addAndRemoveLocalUserRestrictionOnParentDpm(String restriction) {
parentDpm.addUserRestriction(admin1, restriction);
verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
- eq(DpmMockContext.CALLER_USER_HANDLE),
+ eq(CALLER_USER_HANDLE),
MockUtils.checkUserRestrictions(),
MockUtils.checkUserRestrictions(UserHandle.USER_SYSTEM, restriction),
eq(false));
parentDpm.clearUserRestriction(admin1, restriction);
DpmTestUtils.assertRestrictions(
DpmTestUtils.newRestrictions(),
- dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE)
+ dpms.getProfileOwnerAdminLocked(CALLER_USER_HANDLE)
.getParentActiveAdmin()
.getEffectiveRestrictions()
);
@@ -2155,7 +2153,7 @@
verify(mContext.spiedContext).sendBroadcastAsUser(
MockUtils.checkIntentAction(
DevicePolicyManager.ACTION_RESET_PROTECTION_POLICY_CHANGED),
- MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE),
+ MockUtils.checkUserHandle(CALLER_USER_HANDLE),
eq(android.Manifest.permission.MANAGE_FACTORY_RESET_PROTECTION));
}
@@ -2173,7 +2171,7 @@
public void testSetFactoryResetProtectionPolicyWithPOOfOrganizationOwnedDevice()
throws Exception {
setupProfileOwner();
- configureProfileOwnerOfOrgOwnedDevice(admin1, DpmMockContext.CALLER_USER_HANDLE);
+ configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE);
when(getServices().persistentDataBlockManagerInternal.getAllowedUid()).thenReturn(
DpmMockContext.CALLER_UID);
@@ -2195,15 +2193,15 @@
verify(mContext.spiedContext, times(2)).sendBroadcastAsUser(
MockUtils.checkIntentAction(
DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
- MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE));
+ MockUtils.checkUserHandle(CALLER_USER_HANDLE));
verify(mContext.spiedContext).sendBroadcastAsUser(
MockUtils.checkIntentAction(
DevicePolicyManager.ACTION_PROFILE_OWNER_CHANGED),
- MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE));
+ MockUtils.checkUserHandle(CALLER_USER_HANDLE));
verify(mContext.spiedContext).sendBroadcastAsUser(
MockUtils.checkIntentAction(
DevicePolicyManager.ACTION_RESET_PROTECTION_POLICY_CHANGED),
- MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE),
+ MockUtils.checkUserHandle(CALLER_USER_HANDLE),
eq(android.Manifest.permission.MANAGE_FACTORY_RESET_PROTECTION));
}
@@ -2231,7 +2229,7 @@
verify(mContext.spiedContext).sendBroadcastAsUser(
MockUtils.checkIntentAction(
DevicePolicyManager.ACTION_RESET_PROTECTION_POLICY_CHANGED),
- MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE),
+ MockUtils.checkUserHandle(CALLER_USER_HANDLE),
eq(android.Manifest.permission.MANAGE_FACTORY_RESET_PROTECTION));
}
@@ -2269,13 +2267,13 @@
public void testSetKeyguardDisabledFeaturesWithPOOfOrganizationOwnedDevice()
throws Exception {
- final int MANAGED_PROFILE_USER_ID = DpmMockContext.CALLER_USER_HANDLE;
+ final int MANAGED_PROFILE_USER_ID = CALLER_USER_HANDLE;
final int MANAGED_PROFILE_ADMIN_UID =
UserHandle.getUid(MANAGED_PROFILE_USER_ID, DpmMockContext.SYSTEM_UID);
mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
- configureProfileOwnerOfOrgOwnedDevice(admin1, DpmMockContext.CALLER_USER_HANDLE);
+ configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE);
parentDpm.setKeyguardDisabledFeatures(admin1,
DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA);
@@ -2308,13 +2306,13 @@
}
public void testSetApplicationHiddenWithPOOfOrganizationOwnedDevice() throws Exception {
- final int MANAGED_PROFILE_USER_ID = DpmMockContext.CALLER_USER_HANDLE;
+ final int MANAGED_PROFILE_USER_ID = CALLER_USER_HANDLE;
final int MANAGED_PROFILE_ADMIN_UID =
UserHandle.getUid(MANAGED_PROFILE_USER_ID, DpmMockContext.SYSTEM_UID);
mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
- configureProfileOwnerOfOrgOwnedDevice(admin1, DpmMockContext.CALLER_USER_HANDLE);
+ configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE);
mContext.packageName = admin1.getPackageName();
setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid);
@@ -2388,7 +2386,7 @@
public void testGetMacAddressByOrgOwnedPO() throws Exception {
setupProfileOwner();
- configureProfileOwnerOfOrgOwnedDevice(admin1, DpmMockContext.CALLER_USER_HANDLE);
+ configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE);
final String[] macAddresses = new String[]{"11:22:33:44:55:66"};
when(getServices().wifiManager.getFactoryMacAddresses()).thenReturn(macAddresses);
@@ -2450,21 +2448,17 @@
assertNull(dpm.getLongSupportMessage(admin1));
assertNull(dpm.getShortSupportMessage(admin1));
mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
- assertNull(dpm.getShortSupportMessageForUser(admin1,
- DpmMockContext.CALLER_USER_HANDLE));
- assertNull(dpm.getLongSupportMessageForUser(admin1,
- DpmMockContext.CALLER_USER_HANDLE));
+ assertNull(dpm.getShortSupportMessageForUser(admin1, CALLER_USER_HANDLE));
+ assertNull(dpm.getLongSupportMessageForUser(admin1, CALLER_USER_HANDLE));
mMockContext.binder.callingUid = DpmMockContext.CALLER_UID;
}
// Only system can call the per user versions.
{
assertExpectException(SecurityException.class, /* messageRegex= */ "message for user",
- () -> dpm.getShortSupportMessageForUser(admin1,
- DpmMockContext.CALLER_USER_HANDLE));
+ () -> dpm.getShortSupportMessageForUser(admin1, CALLER_USER_HANDLE));
assertExpectException(SecurityException.class, /* messageRegex= */ "message for user",
- () -> dpm.getLongSupportMessageForUser(admin1,
- DpmMockContext.CALLER_USER_HANDLE));
+ () -> dpm.getLongSupportMessageForUser(admin1, CALLER_USER_HANDLE));
}
// Can't set message for admin in another uid.
@@ -2486,11 +2480,9 @@
mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
assertEquals(supportText, dpm.getShortSupportMessageForUser(admin1,
- DpmMockContext.CALLER_USER_HANDLE));
- assertNull(dpm.getShortSupportMessageForUser(admin2,
- DpmMockContext.CALLER_USER_HANDLE));
- assertNull(dpm.getLongSupportMessageForUser(admin1,
- DpmMockContext.CALLER_USER_HANDLE));
+ CALLER_USER_HANDLE));
+ assertNull(dpm.getShortSupportMessageForUser(admin2, CALLER_USER_HANDLE));
+ assertNull(dpm.getLongSupportMessageForUser(admin1, CALLER_USER_HANDLE));
mMockContext.binder.callingUid = DpmMockContext.CALLER_UID;
dpm.setShortSupportMessage(admin1, null);
@@ -2507,11 +2499,9 @@
mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
assertEquals(supportText, dpm.getLongSupportMessageForUser(admin1,
- DpmMockContext.CALLER_USER_HANDLE));
- assertNull(dpm.getLongSupportMessageForUser(admin2,
- DpmMockContext.CALLER_USER_HANDLE));
- assertNull(dpm.getShortSupportMessageForUser(admin1,
- DpmMockContext.CALLER_USER_HANDLE));
+ CALLER_USER_HANDLE));
+ assertNull(dpm.getLongSupportMessageForUser(admin2, CALLER_USER_HANDLE));
+ assertNull(dpm.getShortSupportMessageForUser(admin1, CALLER_USER_HANDLE));
mMockContext.binder.callingUid = DpmMockContext.CALLER_UID;
dpm.setLongSupportMessage(admin1, null);
@@ -2531,8 +2521,8 @@
final String package2 = "com.example.two";
pkgsToRestrict.add(package1);
pkgsToRestrict.add(package2);
- setupPackageInPackageManager(package1, DpmMockContext.CALLER_USER_HANDLE, 123, 0);
- setupPackageInPackageManager(package2, DpmMockContext.CALLER_USER_HANDLE, 456, 0);
+ setupPackageInPackageManager(package1, CALLER_USER_HANDLE, 123, 0);
+ setupPackageInPackageManager(package2, CALLER_USER_HANDLE, 456, 0);
List<String> excludedPkgs = dpm.setMeteredDataDisabledPackages(admin1, pkgsToRestrict);
// Verify
@@ -2540,7 +2530,7 @@
assertEquals(pkgsToRestrict, dpm.getMeteredDataDisabledPackages(admin1));
verify(getServices().networkPolicyManagerInternal).setMeteredRestrictedPackages(
MockUtils.checkApps(pkgsToRestrict.toArray(new String[0])),
- eq(DpmMockContext.CALLER_USER_HANDLE));
+ eq(CALLER_USER_HANDLE));
// Setup
pkgsToRestrict.remove(package1);
@@ -2551,7 +2541,7 @@
assertEquals(pkgsToRestrict, dpm.getMeteredDataDisabledPackages(admin1));
verify(getServices().networkPolicyManagerInternal).setMeteredRestrictedPackages(
MockUtils.checkApps(pkgsToRestrict.toArray(new String[0])),
- eq(DpmMockContext.CALLER_USER_HANDLE));
+ eq(CALLER_USER_HANDLE));
}
public void testSetGetMeteredDataDisabledPackages_deviceAdmin() {
@@ -2577,22 +2567,19 @@
final String package3 = "com.example.three";
pkgsToRestrict.add(package1);
pkgsToRestrict.add(package2);
- setupPackageInPackageManager(package1, DpmMockContext.CALLER_USER_HANDLE, 123, 0);
- setupPackageInPackageManager(package2, DpmMockContext.CALLER_USER_HANDLE, 456, 0);
+ setupPackageInPackageManager(package1, CALLER_USER_HANDLE, 123, 0);
+ setupPackageInPackageManager(package2, CALLER_USER_HANDLE, 456, 0);
List<String> excludedPkgs = dpm.setMeteredDataDisabledPackages(admin1, pkgsToRestrict);
// Verify
assertEquals(emptyList, excludedPkgs);
mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
assertTrue(package1 + "should be restricted",
- dpm.isMeteredDataDisabledPackageForUser(admin1, package1,
- DpmMockContext.CALLER_USER_HANDLE));
+ dpm.isMeteredDataDisabledPackageForUser(admin1, package1, CALLER_USER_HANDLE));
assertTrue(package2 + "should be restricted",
- dpm.isMeteredDataDisabledPackageForUser(admin1, package2,
- DpmMockContext.CALLER_USER_HANDLE));
+ dpm.isMeteredDataDisabledPackageForUser(admin1, package2, CALLER_USER_HANDLE));
assertFalse(package3 + "should not be restricted",
- dpm.isMeteredDataDisabledPackageForUser(admin1, package3,
- DpmMockContext.CALLER_USER_HANDLE));
+ dpm.isMeteredDataDisabledPackageForUser(admin1, package3, CALLER_USER_HANDLE));
}
public void testIsMeteredDataDisabledForUserPackage_nonSystemUidCaller() throws Exception {
@@ -2600,14 +2587,14 @@
assertExpectException(SecurityException.class,
/* messageRegex= */ "Only the system can query restricted pkgs",
() -> dpm.isMeteredDataDisabledPackageForUser(
- admin1, "com.example.one", DpmMockContext.CALLER_USER_HANDLE));
+ admin1, "com.example.one", CALLER_USER_HANDLE));
dpm.clearProfileOwner(admin1);
setDeviceOwner();
assertExpectException(SecurityException.class,
/* messageRegex= */ "Only the system can query restricted pkgs",
() -> dpm.isMeteredDataDisabledPackageForUser(
- admin1, "com.example.one", DpmMockContext.CALLER_USER_HANDLE));
+ admin1, "com.example.one", CALLER_USER_HANDLE));
clearDeviceOwner();
}
@@ -2774,7 +2761,7 @@
public void testSetUserProvisioningState_permission() throws Exception {
setupProfileOwner();
- exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
+ exerciseUserProvisioningTransitions(CALLER_USER_HANDLE,
DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
}
@@ -2782,7 +2769,7 @@
setupProfileOwner();
assertExpectException(SecurityException.class, /* messageRegex =*/ null,
() -> dpm.setUserProvisioningState(DevicePolicyManager.STATE_USER_SETUP_FINALIZED,
- DpmMockContext.CALLER_USER_HANDLE));
+ CALLER_USER_HANDLE));
}
public void testSetUserProvisioningState_noManagement() {
@@ -2791,7 +2778,7 @@
assertExpectException(IllegalStateException.class,
/* messageRegex= */ "change provisioning state unless a .* owner is set",
() -> dpm.setUserProvisioningState(DevicePolicyManager.STATE_USER_SETUP_FINALIZED,
- DpmMockContext.CALLER_USER_HANDLE));
+ CALLER_USER_HANDLE));
assertEquals(DevicePolicyManager.STATE_USER_UNMANAGED, dpm.getUserProvisioningState());
}
@@ -2826,7 +2813,7 @@
throws Exception {
setupProfileOwner();
- exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
+ exerciseUserProvisioningTransitions(CALLER_USER_HANDLE,
DevicePolicyManager.STATE_USER_PROFILE_COMPLETE,
DevicePolicyManager.STATE_USER_UNMANAGED);
}
@@ -2835,7 +2822,7 @@
throws Exception {
setupProfileOwner();
- exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
+ exerciseUserProvisioningTransitions(CALLER_USER_HANDLE,
DevicePolicyManager.STATE_USER_SETUP_COMPLETE,
DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
}
@@ -2843,7 +2830,7 @@
public void testSetUserProvisioningState_managedProfileWithoutSetupWizard() throws Exception {
setupProfileOwner();
- exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
+ exerciseUserProvisioningTransitions(CALLER_USER_HANDLE,
DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
}
@@ -2852,7 +2839,7 @@
assertExpectException(IllegalStateException.class,
/* messageRegex= */ "Cannot move to user provisioning state",
- () -> exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
+ () -> exerciseUserProvisioningTransitions(CALLER_USER_HANDLE,
DevicePolicyManager.STATE_USER_SETUP_FINALIZED,
DevicePolicyManager.STATE_USER_UNMANAGED));
}
@@ -2863,7 +2850,7 @@
assertExpectException(IllegalStateException.class,
/* messageRegex= */ "Cannot move to user provisioning state",
- () -> exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
+ () -> exerciseUserProvisioningTransitions(CALLER_USER_HANDLE,
DevicePolicyManager.STATE_USER_SETUP_INCOMPLETE,
DevicePolicyManager.STATE_USER_SETUP_COMPLETE));
}
@@ -2884,7 +2871,7 @@
setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID);
dpm.setActiveAdmin(admin1, false);
- assertTrue(dpm.setProfileOwner(admin1, null, DpmMockContext.CALLER_USER_HANDLE));
+ assertTrue(dpm.setProfileOwner(admin1, null, CALLER_USER_HANDLE));
mContext.callerPermissions.removeAll(OWNER_SETUP_PERMISSIONS);
}
@@ -3552,9 +3539,9 @@
when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
.thenReturn(true);
when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
- when(getServices().userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
+ when(getServices().userManager.canAddMoreManagedProfiles(CALLER_USER_HANDLE,
true)).thenReturn(true);
- setUserSetupCompleteForUser(false, DpmMockContext.CALLER_USER_HANDLE);
+ setUserSetupCompleteForUser(false, CALLER_USER_HANDLE);
mContext.binder.callingUid = DpmMockContext.CALLER_UID;
}
@@ -3592,9 +3579,9 @@
when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
.thenReturn(true);
when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
- when(getServices().userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
+ when(getServices().userManager.canAddMoreManagedProfiles(CALLER_USER_HANDLE,
true)).thenReturn(true);
- setUserSetupCompleteForUser(true, DpmMockContext.CALLER_USER_HANDLE);
+ setUserSetupCompleteForUser(true, CALLER_USER_HANDLE);
mContext.binder.callingUid = DpmMockContext.CALLER_UID;
}
@@ -3668,11 +3655,11 @@
when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
.thenReturn(true);
when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(false);
- when(getServices().userManager.getProfileParent(DpmMockContext.CALLER_USER_HANDLE))
+ when(getServices().userManager.getProfileParent(CALLER_USER_HANDLE))
.thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0));
- when(getServices().userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
+ when(getServices().userManager.canAddMoreManagedProfiles(CALLER_USER_HANDLE,
true)).thenReturn(true);
- setUserSetupCompleteForUser(false, DpmMockContext.CALLER_USER_HANDLE);
+ setUserSetupCompleteForUser(false, CALLER_USER_HANDLE);
mContext.binder.callingUid = DpmMockContext.ANOTHER_UID;
}
@@ -3703,13 +3690,13 @@
when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
when(getServices().userManager.hasUserRestriction(
eq(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE),
- eq(UserHandle.of(DpmMockContext.CALLER_USER_HANDLE))))
+ eq(UserHandle.of(CALLER_USER_HANDLE))))
.thenReturn(true);
- when(getServices().userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
+ when(getServices().userManager.canAddMoreManagedProfiles(CALLER_USER_HANDLE,
false /* we can't remove a managed profile */)).thenReturn(false);
- when(getServices().userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
+ when(getServices().userManager.canAddMoreManagedProfiles(CALLER_USER_HANDLE,
true)).thenReturn(true);
- setUserSetupCompleteForUser(false, DpmMockContext.CALLER_USER_HANDLE);
+ setUserSetupCompleteForUser(false, CALLER_USER_HANDLE);
mContext.binder.callingUid = DpmMockContext.CALLER_UID;
}
@@ -3817,7 +3804,7 @@
// setUp() adds a secondary user for CALLER_USER_HANDLE. Remove it as otherwise the
// feature is disabled because there are non-affiliated secondary users.
- getServices().removeUser(DpmMockContext.CALLER_USER_HANDLE);
+ getServices().removeUser(CALLER_USER_HANDLE);
when(mContext.resources.getBoolean(R.bool.config_supportPreRebootSecurityLogs))
.thenReturn(true);
@@ -3902,7 +3889,7 @@
public void testSetConfiguredNetworksLockdownStateWithPOOfOrganizationOwnedDevice()
throws Exception {
setupProfileOwner();
- configureProfileOwnerOfOrgOwnedDevice(admin1, DpmMockContext.CALLER_USER_HANDLE);
+ configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE);
dpm.setConfiguredNetworksLockdownState(admin1, true);
verify(getServices().settings).settingsGlobalPutInt(
Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, 1);
@@ -3931,7 +3918,7 @@
setupProfileOwner();
dpm.setSystemSetting(admin1, Settings.System.SCREEN_BRIGHTNESS, "0");
verify(getServices().settings).settingsSystemPutStringForUser(
- Settings.System.SCREEN_BRIGHTNESS, "0", DpmMockContext.CALLER_USER_HANDLE);
+ Settings.System.SCREEN_BRIGHTNESS, "0", CALLER_USER_HANDLE);
}
public void testSetAutoTimeEnabledModifiesSetting() throws Exception {
@@ -3963,7 +3950,7 @@
public void testSetAutoTimeEnabledWithPOOfOrganizationOwnedDevice() throws Exception {
setupProfileOwner();
- configureProfileOwnerOfOrgOwnedDevice(admin1, DpmMockContext.CALLER_USER_HANDLE);
+ configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE);
dpm.setAutoTimeEnabled(admin1, true);
verify(getServices().settings).settingsGlobalPutInt(Settings.Global.AUTO_TIME, 1);
@@ -4002,7 +3989,7 @@
public void testSetAutoTimeZoneEnabledWithPOOfOrganizationOwnedDevice() throws Exception {
setupProfileOwner();
- configureProfileOwnerOfOrgOwnedDevice(admin1, DpmMockContext.CALLER_USER_HANDLE);
+ configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE);
dpm.setAutoTimeZoneEnabled(admin1, true);
verify(getServices().settings).settingsGlobalPutInt(Settings.Global.AUTO_TIME_ZONE, 1);
@@ -4017,7 +4004,7 @@
// Any caller should be able to call this method.
assertFalse(dpm.isOrganizationOwnedDeviceWithManagedProfile());
- configureProfileOwnerOfOrgOwnedDevice(admin1, DpmMockContext.CALLER_USER_HANDLE);
+ configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE);
assertTrue(dpm.isOrganizationOwnedDeviceWithManagedProfile());
// A random caller from another user should also be able to get the right result.
@@ -4039,7 +4026,7 @@
public void testSetTimeWithPOOfOrganizationOwnedDevice() throws Exception {
setupProfileOwner();
- configureProfileOwnerOfOrgOwnedDevice(admin1, DpmMockContext.CALLER_USER_HANDLE);
+ configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE);
dpm.setTime(admin1, 0);
verify(getServices().alarmManager).setTime(0);
}
@@ -4067,7 +4054,7 @@
public void testSetTimeZoneWithPOOfOrganizationOwnedDevice() throws Exception {
setupProfileOwner();
- configureProfileOwnerOfOrgOwnedDevice(admin1, DpmMockContext.CALLER_USER_HANDLE);
+ configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE);
dpm.setTimeZone(admin1, "Asia/Shanghai");
verify(getServices().alarmManager).setTimeZone("Asia/Shanghai");
}
@@ -4093,7 +4080,7 @@
// setUp() adds a secondary user for CALLER_USER_HANDLE. Remove it as otherwise the
// feature is disabled because there are non-affiliated secondary users.
- getServices().removeUser(DpmMockContext.CALLER_USER_HANDLE);
+ getServices().removeUser(CALLER_USER_HANDLE);
// No bug reports were requested so far.
assertEquals(-1, dpm.getLastBugReportRequestTime());
@@ -4141,7 +4128,7 @@
// setUp() adds a secondary user for CALLER_USER_HANDLE. Remove it as otherwise the
// feature is disabled because there are non-affiliated secondary users.
- getServices().removeUser(DpmMockContext.CALLER_USER_HANDLE);
+ getServices().removeUser(CALLER_USER_HANDLE);
when(getServices().iipConnectivityMetrics.addNetdEventCallback(anyInt(), anyObject()))
.thenReturn(true);
@@ -4273,13 +4260,13 @@
// Setup a PO
mContext.binder.callingUid = DpmMockContext.CALLER_UID;
setAsProfileOwner(admin1);
- verifyLockTaskState(DpmMockContext.CALLER_USER_HANDLE);
+ verifyLockTaskState(CALLER_USER_HANDLE);
final String[] poPackages = {"poPackage1", "poPackage2"};
final int poFlags = DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS
| DevicePolicyManager.LOCK_TASK_FEATURE_HOME
| DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW;
- verifyCanSetLockTask(DpmMockContext.CALLER_UID, DpmMockContext.CALLER_USER_HANDLE, admin1,
+ verifyCanSetLockTask(DpmMockContext.CALLER_UID, CALLER_USER_HANDLE, admin1,
poPackages, poFlags);
// Set up a managed profile managed by different package (package name shouldn't matter)
@@ -4318,7 +4305,7 @@
// Initial state is disabled.
assertFalse(dpm.isSecondaryLockscreenEnabled(UserHandle.of(
- DpmMockContext.CALLER_USER_HANDLE)));
+ CALLER_USER_HANDLE)));
// Profile owner can set enabled state.
setAsProfileOwner(admin1);
@@ -4327,7 +4314,7 @@
.thenReturn(admin1.flattenToString());
dpm.setSecondaryLockscreenEnabled(admin1, true);
assertTrue(dpm.isSecondaryLockscreenEnabled(UserHandle.of(
- DpmMockContext.CALLER_USER_HANDLE)));
+ CALLER_USER_HANDLE)));
// Managed profile managed by different package is unaffiliated - cannot set enabled.
final int managedProfileUserId = 15;
@@ -4359,8 +4346,7 @@
mContext.binder.callingUid = DpmMockContext.CALLER_UID;
// Initial state is disabled.
- assertFalse(dpm.isSecondaryLockscreenEnabled(UserHandle.of(
- DpmMockContext.CALLER_USER_HANDLE)));
+ assertFalse(dpm.isSecondaryLockscreenEnabled(UserHandle.of(CALLER_USER_HANDLE)));
// Non-DO/PO cannot set enabled state.
when(mServiceContext.resources
@@ -4368,23 +4354,20 @@
.thenReturn(admin1.flattenToString());
assertExpectException(SecurityException.class, /* messageRegex= */ null,
() -> dpm.setSecondaryLockscreenEnabled(admin1, true));
- assertFalse(dpm.isSecondaryLockscreenEnabled(UserHandle.of(
- DpmMockContext.CALLER_USER_HANDLE)));
+ assertFalse(dpm.isSecondaryLockscreenEnabled(UserHandle.of(CALLER_USER_HANDLE)));
}
public void testSecondaryLockscreen_nonSupervisionApp() throws Exception {
mContext.binder.callingUid = DpmMockContext.CALLER_UID;
// Initial state is disabled.
- assertFalse(dpm.isSecondaryLockscreenEnabled(UserHandle.of(
- DpmMockContext.CALLER_USER_HANDLE)));
+ assertFalse(dpm.isSecondaryLockscreenEnabled(UserHandle.of(CALLER_USER_HANDLE)));
// Caller is Profile Owner, but no supervision app is configured.
setAsProfileOwner(admin1);
assertExpectException(SecurityException.class, "no default supervision component defined",
() -> dpm.setSecondaryLockscreenEnabled(admin1, true));
- assertFalse(dpm.isSecondaryLockscreenEnabled(UserHandle.of(
- DpmMockContext.CALLER_USER_HANDLE)));
+ assertFalse(dpm.isSecondaryLockscreenEnabled(UserHandle.of(CALLER_USER_HANDLE)));
// Caller is Profile Owner, but is not the default configured supervision app.
when(mServiceContext.resources
@@ -4392,8 +4375,7 @@
.thenReturn(admin2.flattenToString());
assertExpectException(SecurityException.class, "is not the default supervision component",
() -> dpm.setSecondaryLockscreenEnabled(admin1, true));
- assertFalse(dpm.isSecondaryLockscreenEnabled(UserHandle.of(
- DpmMockContext.CALLER_USER_HANDLE)));
+ assertFalse(dpm.isSecondaryLockscreenEnabled(UserHandle.of(CALLER_USER_HANDLE)));
}
public void testIsDeviceManaged() throws Exception {
@@ -4729,14 +4711,14 @@
doReturn(PackageManager.FLAG_PERMISSION_POLICY_FIXED).when(getServices().packageManager)
.getPermissionFlags(permission, app1, UserHandle.SYSTEM);
when(getServices().packageManager.getPermissionFlags(permission, app1,
- UserHandle.of(DpmMockContext.CALLER_USER_HANDLE)))
+ UserHandle.of(CALLER_USER_HANDLE)))
.thenReturn(PackageManager.FLAG_PERMISSION_POLICY_FIXED);
when(getServices().ipackageManager.checkPermission(eq(permission), eq(app2), anyInt()))
.thenReturn(PackageManager.PERMISSION_DENIED);
doReturn(0).when(getServices().packageManager).getPermissionFlags(permission, app2,
UserHandle.SYSTEM);
when(getServices().packageManager.getPermissionFlags(permission, app2,
- UserHandle.of(DpmMockContext.CALLER_USER_HANDLE))).thenReturn(0);
+ UserHandle.of(CALLER_USER_HANDLE))).thenReturn(0);
// System can retrieve permission grant state.
mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
@@ -4879,7 +4861,7 @@
}
public void testIsPasswordSufficientAfterProfileUnification() throws Exception {
- final int managedProfileUserId = DpmMockContext.CALLER_USER_HANDLE;
+ final int managedProfileUserId = CALLER_USER_HANDLE;
final int managedProfileAdminUid =
UserHandle.getUid(managedProfileUserId, DpmMockContext.SYSTEM_UID);
mContext.binder.callingUid = managedProfileAdminUid;
@@ -4955,7 +4937,7 @@
final int deviceOwnerUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
final int firstUserSystemUid = UserHandle.getUid(UserHandle.USER_SYSTEM,
DpmMockContext.SYSTEM_UID);
- final int secondUserSystemUid = UserHandle.getUid(DpmMockContext.CALLER_USER_HANDLE,
+ final int secondUserSystemUid = UserHandle.getUid(CALLER_USER_HANDLE,
DpmMockContext.SYSTEM_UID);
// Set up a device owner.
@@ -4983,7 +4965,7 @@
assertFalse(dpm.isCurrentInputMethodSetByOwner());
// Second user changes IME manually.
- dpms.notifyChangeToContentObserver(currentImeUri, DpmMockContext.CALLER_USER_HANDLE);
+ dpms.notifyChangeToContentObserver(currentImeUri, CALLER_USER_HANDLE);
mContext.binder.callingUid = firstUserSystemUid;
assertTrue(dpm.isCurrentInputMethodSetByOwner());
mContext.binder.callingUid = secondUserSystemUid;
@@ -5034,7 +5016,7 @@
final int profileOwnerUid = DpmMockContext.CALLER_UID;
final int firstUserSystemUid = UserHandle.getUid(UserHandle.USER_SYSTEM,
DpmMockContext.SYSTEM_UID);
- final int secondUserSystemUid = UserHandle.getUid(DpmMockContext.CALLER_USER_HANDLE,
+ final int secondUserSystemUid = UserHandle.getUid(CALLER_USER_HANDLE,
DpmMockContext.SYSTEM_UID);
// Set up a profile owner.
@@ -5050,12 +5032,12 @@
// Profile owner changes IME for second user.
mContext.binder.callingUid = profileOwnerUid;
when(getServices().settings.settingsSecureGetStringForUser(currentIme,
- DpmMockContext.CALLER_USER_HANDLE)).thenReturn("ime1");
+ CALLER_USER_HANDLE)).thenReturn("ime1");
dpm.setSecureSetting(admin1, currentIme, "ime2");
verify(getServices().settings).settingsSecurePutStringForUser(currentIme, "ime2",
- DpmMockContext.CALLER_USER_HANDLE);
+ CALLER_USER_HANDLE);
reset(getServices().settings);
- dpms.notifyChangeToContentObserver(currentImeUri, DpmMockContext.CALLER_USER_HANDLE);
+ dpms.notifyChangeToContentObserver(currentImeUri, CALLER_USER_HANDLE);
mContext.binder.callingUid = firstUserSystemUid;
assertFalse(dpm.isCurrentInputMethodSetByOwner());
mContext.binder.callingUid = secondUserSystemUid;
@@ -5069,7 +5051,7 @@
assertTrue(dpm.isCurrentInputMethodSetByOwner());
// Second user changes IME manually.
- dpms.notifyChangeToContentObserver(currentImeUri, DpmMockContext.CALLER_USER_HANDLE);
+ dpms.notifyChangeToContentObserver(currentImeUri, CALLER_USER_HANDLE);
mContext.binder.callingUid = firstUserSystemUid;
assertFalse(dpm.isCurrentInputMethodSetByOwner());
mContext.binder.callingUid = secondUserSystemUid;
@@ -5078,11 +5060,11 @@
// Profile owner changes IME for second user again.
mContext.binder.callingUid = profileOwnerUid;
when(getServices().settings.settingsSecureGetStringForUser(currentIme,
- DpmMockContext.CALLER_USER_HANDLE)).thenReturn("ime2");
+ CALLER_USER_HANDLE)).thenReturn("ime2");
dpm.setSecureSetting(admin1, currentIme, "ime3");
verify(getServices().settings).settingsSecurePutStringForUser(currentIme, "ime3",
- DpmMockContext.CALLER_USER_HANDLE);
- dpms.notifyChangeToContentObserver(currentImeUri, DpmMockContext.CALLER_USER_HANDLE);
+ CALLER_USER_HANDLE);
+ dpms.notifyChangeToContentObserver(currentImeUri, CALLER_USER_HANDLE);
mContext.binder.callingUid = firstUserSystemUid;
assertFalse(dpm.isCurrentInputMethodSetByOwner());
mContext.binder.callingUid = secondUserSystemUid;
@@ -5337,7 +5319,7 @@
final DpmMockContext caller = new DpmMockContext(getServices(), mRealTestContext);
caller.packageName = "com.example.delegate";
caller.binder.callingUid = setupPackageInPackageManager(caller.packageName,
- DpmMockContext.CALLER_USER_HANDLE, 20988, ApplicationInfo.FLAG_HAS_CODE);
+ CALLER_USER_HANDLE, 20988, ApplicationInfo.FLAG_HAS_CODE);
// Make caller a delegated cert installer.
runAsCaller(mAdmin1Context, dpms,
@@ -5355,8 +5337,7 @@
mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
RestrictionsListener listener = new RestrictionsListener(mContext);
- listener.onUserRestrictionsChanged(DpmMockContext.CALLER_USER_HANDLE, restriction,
- new Bundle());
+ listener.onUserRestrictionsChanged(CALLER_USER_HANDLE, restriction, new Bundle());
verifyDataSharingChangedBroadcast();
}
@@ -5368,15 +5349,13 @@
mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
RestrictionsListener listener = new RestrictionsListener(mContext);
- listener.onUserRestrictionsChanged(DpmMockContext.CALLER_USER_HANDLE, new Bundle(),
- restriction);
+ listener.onUserRestrictionsChanged(CALLER_USER_HANDLE, new Bundle(), restriction);
verifyDataSharingChangedBroadcast();
}
public void testDisallowSharingIntoProfileUnchanged() {
RestrictionsListener listener = new RestrictionsListener(mContext);
- listener.onUserRestrictionsChanged(DpmMockContext.CALLER_USER_HANDLE, new Bundle(),
- new Bundle());
+ listener.onUserRestrictionsChanged(CALLER_USER_HANDLE, new Bundle(), new Bundle());
verify(mContext.spiedContext, never()).sendBroadcastAsUser(any(), any());
}
@@ -5384,7 +5363,7 @@
Intent expectedIntent = new Intent(
DevicePolicyManager.ACTION_DATA_SHARING_RESTRICTION_CHANGED);
expectedIntent.setPackage("com.android.managedprovisioning");
- expectedIntent.putExtra(Intent.EXTRA_USER_ID, DpmMockContext.CALLER_USER_HANDLE);
+ expectedIntent.putExtra(Intent.EXTRA_USER_ID, CALLER_USER_HANDLE);
verify(mContext.spiedContext, times(1)).sendBroadcastAsUser(
MockUtils.checkIntent(expectedIntent),
MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
@@ -5615,9 +5594,8 @@
setupProfileOwner();
initializeDpms();
assertFalse(getMockTransferMetadataManager().metadataFileExists());
- assertTrue(dpms.isProfileOwner(admin1, DpmMockContext.CALLER_USER_HANDLE));
- assertTrue(dpms.isAdminActive(admin1, DpmMockContext.CALLER_USER_HANDLE));
- UserHandle userHandle = UserHandle.of(DpmMockContext.CALLER_USER_HANDLE);
+ assertTrue(dpms.isProfileOwner(admin1, CALLER_USER_HANDLE));
+ assertTrue(dpms.isAdminActive(admin1, CALLER_USER_HANDLE));
}
// @FlakyTest(bugId = 148934649)
@@ -5647,7 +5625,7 @@
// }
public void testRevertProfileOwnership_adminAndProfileNotMigrated() throws Exception {
- getServices().addUser(DpmMockContext.CALLER_USER_HANDLE, 0,
+ getServices().addUser(CALLER_USER_HANDLE, 0,
UserManager.USER_TYPE_PROFILE_MANAGED, UserHandle.USER_SYSTEM);
DpmTestUtils.writeInputStreamToFile(
getRawStream(com.android.frameworks.servicestests.R.raw.active_admin_not_migrated),
@@ -5679,7 +5657,7 @@
// This method will throw if the system context could not call
// markProfileOwnerOfOrganizationOwnedDevice successfully.
- configureProfileOwnerOfOrgOwnedDevice(admin1, DpmMockContext.CALLER_USER_HANDLE);
+ configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE);
}
private void configureContextForAccess(DpmMockContext context, boolean granted) {
@@ -5699,7 +5677,7 @@
configureContextForAccess(mServiceContext, true);
mServiceContext.binder.callingUid =
- UserHandle.getUid(DpmMockContext.CALLER_USER_HANDLE,
+ UserHandle.getUid(CALLER_USER_HANDLE,
DpmMockContext.CALLER_MANAGED_PROVISIONING_UID);
try {
runAsCaller(mServiceContext, dpms, dpm -> {
@@ -5741,7 +5719,7 @@
admin1.getPackageName(), DpmMockContext.CALLER_SYSTEM_USER_UID));
setupProfileOwner();
- configureProfileOwnerOfOrgOwnedDevice(admin1, DpmMockContext.CALLER_USER_HANDLE);
+ configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE);
// The profile owner is allowed to request Device ID attestation.
mServiceContext.binder.callingUid = DpmMockContext.CALLER_UID;
@@ -5760,7 +5738,7 @@
public void runAsDelegatedCertInstaller(DpmRunnable action) throws Exception {
final long ident = mServiceContext.binder.clearCallingIdentity();
- mServiceContext.binder.callingUid = UserHandle.getUid(DpmMockContext.CALLER_USER_HANDLE,
+ mServiceContext.binder.callingUid = UserHandle.getUid(CALLER_USER_HANDLE,
DpmMockContext.DELEGATE_CERT_INSTALLER_UID);
try {
runAsCaller(mServiceContext, dpms, action);
@@ -5778,7 +5756,7 @@
dpm -> dpm.setDelegatedScopes(admin1, DpmMockContext.DELEGATE_PACKAGE_NAME,
Arrays.asList(DELEGATION_CERT_INSTALL)));
- configureProfileOwnerOfOrgOwnedDevice(admin1, DpmMockContext.CALLER_USER_HANDLE);
+ configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE);
// Make sure that the profile owner can still request Device ID attestation.
mServiceContext.binder.callingUid = DpmMockContext.CALLER_UID;
@@ -5788,7 +5766,7 @@
runAsDelegatedCertInstaller(dpm -> {
dpms.enforceCallerCanRequestDeviceIdAttestation(null,
DpmMockContext.DELEGATE_PACKAGE_NAME,
- UserHandle.getUid(DpmMockContext.CALLER_USER_HANDLE,
+ UserHandle.getUid(CALLER_USER_HANDLE,
DpmMockContext.DELEGATE_CERT_INSTALLER_UID));
});
}
@@ -5813,7 +5791,7 @@
assertExpectException(SecurityException.class, /* messageRegex= */ null,
() -> dpms.enforceCallerCanRequestDeviceIdAttestation(null,
DpmMockContext.DELEGATE_PACKAGE_NAME,
- UserHandle.getUid(DpmMockContext.CALLER_USER_HANDLE,
+ UserHandle.getUid(CALLER_USER_HANDLE,
DpmMockContext.DELEGATE_CERT_INSTALLER_UID)));
});
}
@@ -5834,8 +5812,7 @@
mContext.binder.callingUid = DpmMockContext.CALLER_UID;
when(getServices().packageManager.getPackagesForUid(DpmMockContext.CALLER_UID)).thenReturn(
new String[0]);
- when(getServices().userManager.isUserUnlocked(DpmMockContext.CALLER_USER_HANDLE))
- .thenReturn(false);
+ when(getServices().userManager.isUserUnlocked(CALLER_USER_HANDLE)).thenReturn(false);
assertThrows(IllegalStateException.class, () -> dpm.getPasswordComplexity());
}
@@ -5843,8 +5820,7 @@
mContext.binder.callingUid = DpmMockContext.CALLER_UID;
when(getServices().packageManager.getPackagesForUid(DpmMockContext.CALLER_UID)).thenReturn(
new String[0]);
- when(getServices().userManager.isUserUnlocked(DpmMockContext.CALLER_USER_HANDLE))
- .thenReturn(true);
+ when(getServices().userManager.isUserUnlocked(CALLER_USER_HANDLE)).thenReturn(true);
assertThrows(SecurityException.class, () -> dpm.getPasswordComplexity());
}
@@ -5853,11 +5829,10 @@
mContext.binder.callingUid = DpmMockContext.CALLER_UID;
when(getServices().packageManager.getPackagesForUid(DpmMockContext.CALLER_UID)).thenReturn(
new String[0]);
- when(getServices().userManager.isUserUnlocked(DpmMockContext.CALLER_USER_HANDLE))
- .thenReturn(true);
+ when(getServices().userManager.isUserUnlocked(CALLER_USER_HANDLE)).thenReturn(true);
mServiceContext.permissions.add(permission.REQUEST_PASSWORD_COMPLEXITY);
- when(getServices().userManager.getCredentialOwnerProfile(DpmMockContext.CALLER_USER_HANDLE))
- .thenReturn(DpmMockContext.CALLER_USER_HANDLE);
+ when(getServices().userManager.getCredentialOwnerProfile(CALLER_USER_HANDLE))
+ .thenReturn(CALLER_USER_HANDLE);
assertEquals(PASSWORD_COMPLEXITY_NONE, dpm.getPasswordComplexity());
}
@@ -5866,13 +5841,12 @@
mContext.binder.callingUid = DpmMockContext.CALLER_UID;
when(getServices().packageManager.getPackagesForUid(DpmMockContext.CALLER_UID)).thenReturn(
new String[0]);
- when(getServices().userManager.isUserUnlocked(DpmMockContext.CALLER_USER_HANDLE))
- .thenReturn(true);
+ when(getServices().userManager.isUserUnlocked(CALLER_USER_HANDLE)).thenReturn(true);
mServiceContext.permissions.add(permission.REQUEST_PASSWORD_COMPLEXITY);
- when(getServices().userManager.getCredentialOwnerProfile(DpmMockContext.CALLER_USER_HANDLE))
- .thenReturn(DpmMockContext.CALLER_USER_HANDLE);
+ when(getServices().userManager.getCredentialOwnerProfile(CALLER_USER_HANDLE))
+ .thenReturn(CALLER_USER_HANDLE);
when(getServices().lockSettingsInternal
- .getUserPasswordMetrics(DpmMockContext.CALLER_USER_HANDLE))
+ .getUserPasswordMetrics(CALLER_USER_HANDLE))
.thenReturn(computeForPassword("asdf".getBytes()));
assertEquals(PASSWORD_COMPLEXITY_MEDIUM, dpm.getPasswordComplexity());
@@ -5882,17 +5856,16 @@
mContext.binder.callingUid = DpmMockContext.CALLER_UID;
when(getServices().packageManager.getPackagesForUid(DpmMockContext.CALLER_UID)).thenReturn(
new String[0]);
- when(getServices().userManager.isUserUnlocked(DpmMockContext.CALLER_USER_HANDLE))
- .thenReturn(true);
+ when(getServices().userManager.isUserUnlocked(CALLER_USER_HANDLE)).thenReturn(true);
mServiceContext.permissions.add(permission.REQUEST_PASSWORD_COMPLEXITY);
UserInfo parentUser = new UserInfo();
- parentUser.id = DpmMockContext.CALLER_USER_HANDLE + 10;
- when(getServices().userManager.getCredentialOwnerProfile(DpmMockContext.CALLER_USER_HANDLE))
+ parentUser.id = CALLER_USER_HANDLE + 10;
+ when(getServices().userManager.getCredentialOwnerProfile(CALLER_USER_HANDLE))
.thenReturn(parentUser.id);
when(getServices().lockSettingsInternal
- .getUserPasswordMetrics(DpmMockContext.CALLER_USER_HANDLE))
+ .getUserPasswordMetrics(CALLER_USER_HANDLE))
.thenReturn(computeForPassword("asdf".getBytes()));
when(getServices().lockSettingsInternal
.getUserPasswordMetrics(parentUser.id))
@@ -5945,7 +5918,7 @@
dpm.setCrossProfileCalendarPackages(admin1, Collections.emptySet());
when(getServices().settings.settingsSecureGetIntForUser(
Settings.Secure.CROSS_PROFILE_CALENDAR_ENABLED,
- 0, DpmMockContext.CALLER_USER_HANDLE)).thenReturn(1);
+ 0, CALLER_USER_HANDLE)).thenReturn(1);
assertFalse(dpm.isPackageAllowedToAccessCalendar("TEST_PACKAGE"));
}
@@ -5955,7 +5928,7 @@
dpm.setCrossProfileCalendarPackages(admin1, Collections.singleton(testPackage));
when(getServices().settings.settingsSecureGetIntForUser(
Settings.Secure.CROSS_PROFILE_CALENDAR_ENABLED,
- 0, DpmMockContext.CALLER_USER_HANDLE)).thenReturn(0);
+ 0, CALLER_USER_HANDLE)).thenReturn(0);
assertFalse(dpm.isPackageAllowedToAccessCalendar(testPackage));
}
@@ -5965,7 +5938,7 @@
dpm.setCrossProfileCalendarPackages(admin1, null);
when(getServices().settings.settingsSecureGetIntForUser(
Settings.Secure.CROSS_PROFILE_CALENDAR_ENABLED,
- 0, DpmMockContext.CALLER_USER_HANDLE)).thenReturn(1);
+ 0, CALLER_USER_HANDLE)).thenReturn(1);
assertTrue(dpm.isPackageAllowedToAccessCalendar(testPackage));
}
@@ -6149,7 +6122,7 @@
mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
assertFalse("po is not direct boot aware",
- dpm.canProfileOwnerResetPasswordWhenLocked(DpmMockContext.CALLER_USER_HANDLE));
+ dpm.canProfileOwnerResetPasswordWhenLocked(CALLER_USER_HANDLE));
}
public void testCanProfileOwnerResetPasswordWhenLocked_noActiveToken() throws Exception {
@@ -6159,7 +6132,7 @@
mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
assertFalse("po doesn't have an active password reset token",
- dpm.canProfileOwnerResetPasswordWhenLocked(DpmMockContext.CALLER_USER_HANDLE));
+ dpm.canProfileOwnerResetPasswordWhenLocked(CALLER_USER_HANDLE));
}
public void testCanProfileOwnerResetPasswordWhenLocked_nonFbeDevice() throws Exception {
@@ -6169,7 +6142,7 @@
mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
assertFalse("device is not FBE",
- dpm.canProfileOwnerResetPasswordWhenLocked(DpmMockContext.CALLER_USER_HANDLE));
+ dpm.canProfileOwnerResetPasswordWhenLocked(CALLER_USER_HANDLE));
}
public void testCanProfileOwnerResetPasswordWhenLocked() throws Exception {
@@ -6180,7 +6153,7 @@
mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
assertTrue("direct boot aware po with active password reset token",
- dpm.canProfileOwnerResetPasswordWhenLocked(DpmMockContext.CALLER_USER_HANDLE));
+ dpm.canProfileOwnerResetPasswordWhenLocked(CALLER_USER_HANDLE));
}
private void setupPasswordResetToken() {
@@ -6188,14 +6161,14 @@
final long handle = 123456;
when(getServices().lockPatternUtils
- .addEscrowToken(eq(token), eq(DpmMockContext.CALLER_USER_HANDLE),
+ .addEscrowToken(eq(token), eq(CALLER_USER_HANDLE),
nullable(EscrowTokenStateChangeCallback.class)))
.thenReturn(handle);
dpm.setResetPasswordToken(admin1, token);
when(getServices().lockPatternUtils
- .isEscrowTokenActive(eq(handle), eq(DpmMockContext.CALLER_USER_HANDLE)))
+ .isEscrowTokenActive(eq(handle), eq(CALLER_USER_HANDLE)))
.thenReturn(true);
assertTrue("failed to activate token", dpm.isResetPasswordTokenActive(admin1));
@@ -6214,7 +6187,7 @@
doReturn(ai).when(getServices().ipackageManager).getApplicationInfo(
eq(admin1.getPackageName()),
anyInt(),
- eq(DpmMockContext.CALLER_USER_HANDLE));
+ eq(CALLER_USER_HANDLE));
}
private void setDeviceEncryptionPerUser() {
@@ -6302,7 +6275,8 @@
verifyZeroInteractions(getServices().ipackageManager);
clearInvocations(getServices().alarmManager);
- sendUserStoppedBroadcastForProfile();
+ setUserUnlocked(CALLER_USER_HANDLE, false);
+ sendBroadcastWithUser(Intent.ACTION_USER_STOPPED, CALLER_USER_HANDLE);
// Verify the alarm was scheduled for time when the warning should be shown.
verify(getServices().alarmManager, times(1))
@@ -6316,7 +6290,7 @@
// Pretend the alarm went off.
dpms.mMockInjector.setSystemCurrentTimeMillis(PROFILE_OFF_WARNING_TIME + 10);
- sendProfileOffDeadlineAlarmBroadcast();
+ sendBroadcastWithUser(ACTION_PROFILE_OFF_DEADLINE, CALLER_USER_HANDLE);
// Verify the alarm was scheduled for the actual deadline this time.
verify(getServices().alarmManager, times(1)).set(anyInt(), eq(PROFILE_OFF_DEADLINE), any());
@@ -6331,7 +6305,7 @@
// Pretend the alarm went off.
dpms.mMockInjector.setSystemCurrentTimeMillis(PROFILE_OFF_DEADLINE + 10);
- sendProfileOffDeadlineAlarmBroadcast();
+ sendBroadcastWithUser(ACTION_PROFILE_OFF_DEADLINE, CALLER_USER_HANDLE);
// Verify the alarm was not set.
verifyZeroInteractions(getServices().alarmManager);
@@ -6354,9 +6328,11 @@
dpm.setManagedProfileMaximumTimeOff(admin1, PROFILE_OFF_TIMEOUT);
mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
- sendUserStoppedBroadcastForProfile();
+ setUserUnlocked(CALLER_USER_HANDLE, false);
+ sendBroadcastWithUser(Intent.ACTION_USER_STOPPED, CALLER_USER_HANDLE);
clearInvocations(getServices().alarmManager);
- sendUserUnlockedBroadcastForProfile();
+ setUserUnlocked(CALLER_USER_HANDLE, true);
+ sendBroadcastWithUser(Intent.ACTION_USER_UNLOCKED, CALLER_USER_HANDLE);
// Verify that the alarm got discharged.
verify(getServices().alarmManager, times(1)).cancel((PendingIntent) null);
@@ -6372,15 +6348,17 @@
dpm.setManagedProfileMaximumTimeOff(admin1, PROFILE_OFF_TIMEOUT);
mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
- sendUserStoppedBroadcastForProfile();
+ setUserUnlocked(CALLER_USER_HANDLE, false);
+ sendBroadcastWithUser(Intent.ACTION_USER_STOPPED, CALLER_USER_HANDLE);
// Pretend the alarm went off.
dpms.mMockInjector.setSystemCurrentTimeMillis(PROFILE_OFF_WARNING_TIME + 10);
- sendProfileOffDeadlineAlarmBroadcast();
+ sendBroadcastWithUser(ACTION_PROFILE_OFF_DEADLINE, CALLER_USER_HANDLE);
clearInvocations(getServices().alarmManager);
clearInvocations(getServices().notificationManager);
- sendUserUnlockedBroadcastForProfile();
+ setUserUnlocked(CALLER_USER_HANDLE, true);
+ sendBroadcastWithUser(Intent.ACTION_USER_UNLOCKED, CALLER_USER_HANDLE);
// Verify that the alarm got discharged.
verify(getServices().alarmManager, times(1)).cancel((PendingIntent) null);
@@ -6399,17 +6377,25 @@
dpm.setManagedProfileMaximumTimeOff(admin1, PROFILE_OFF_TIMEOUT);
mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
- sendUserStoppedBroadcastForProfile();
+ setUserUnlocked(CALLER_USER_HANDLE, false);
+ sendBroadcastWithUser(Intent.ACTION_USER_STOPPED, CALLER_USER_HANDLE);
// Pretend the alarm went off after the deadline.
dpms.mMockInjector.setSystemCurrentTimeMillis(PROFILE_OFF_DEADLINE + 10);
- sendProfileOffDeadlineAlarmBroadcast();
+ sendBroadcastWithUser(ACTION_PROFILE_OFF_DEADLINE, CALLER_USER_HANDLE);
clearInvocations(getServices().alarmManager);
clearInvocations(getServices().notificationManager);
clearInvocations(getServices().ipackageManager);
- sendUserUnlockedBroadcastForProfile();
+ // Pretend the user clicked on the "apps suspended" notification to turn the profile on.
+ sendBroadcastWithUser(ACTION_TURN_PROFILE_ON_NOTIFICATION, CALLER_USER_HANDLE);
+ // Verify that the profile is turned on.
+ verify(getServices().userManager, times(1))
+ .requestQuietModeEnabled(eq(false), eq(UserHandle.of(CALLER_USER_HANDLE)));
+
+ setUserUnlocked(CALLER_USER_HANDLE, true);
+ sendBroadcastWithUser(Intent.ACTION_USER_UNLOCKED, CALLER_USER_HANDLE);
// Verify that the notification is removed (at this point DPC should show it).
verify(getServices().notificationManager, times(1))
@@ -6417,50 +6403,36 @@
// Verify that the apps are NOT unsuspeded.
verify(getServices().ipackageManager, never()).setPackagesSuspendedAsUser(
any(), eq(false), any(), any(), any(), any(), anyInt());
+ // Verify that DPC is invoked to check policy compliance.
+ verify(mContext.spiedContext).startActivityAsUser(
+ MockUtils.checkIntentAction(ACTION_CHECK_POLICY_COMPLIANCE),
+ MockUtils.checkUserHandle(CALLER_USER_HANDLE));
}
- private void sendUserUnlockedBroadcastForProfile() throws Exception {
- when(getServices().userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE)))
- .thenReturn(true);
- final Intent unlockedIntent = new Intent(Intent.ACTION_USER_UNLOCKED)
- .putExtra(Intent.EXTRA_USER_HANDLE, DpmMockContext.CALLER_USER_HANDLE);
- getServices().injectBroadcast(
- mServiceContext, unlockedIntent, DpmMockContext.CALLER_USER_HANDLE);
+ private void sendBroadcastWithUser(String action, int userHandle) throws Exception {
+ final Intent intent = new Intent(action);
+ intent.putExtra(Intent.EXTRA_USER_HANDLE, userHandle);
+ getServices().injectBroadcast(mServiceContext, intent, userHandle);
flushTasks();
}
-
- private void sendProfileOffDeadlineAlarmBroadcast() throws Exception {
- final Intent deadlineAlarmIntent =
- new Intent(DevicePolicyManagerService.ACTION_PROFILE_OFF_DEADLINE);
- getServices().injectBroadcast(
- mServiceContext, deadlineAlarmIntent, DpmMockContext.CALLER_USER_HANDLE);
- flushTasks();
- }
-
- private void sendUserStoppedBroadcastForProfile() throws Exception {
- when(getServices().userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE)))
- .thenReturn(false);
- final Intent stoppedIntent = new Intent(Intent.ACTION_USER_STOPPED)
- .putExtra(Intent.EXTRA_USER_HANDLE, DpmMockContext.CALLER_USER_HANDLE);
- getServices().injectBroadcast(mServiceContext, stoppedIntent,
- DpmMockContext.CALLER_USER_HANDLE);
- flushTasks();
+ private void setUserUnlocked(int userHandle, boolean unlocked) {
+ when(getServices().userManager.isUserUnlocked(eq(userHandle))).thenReturn(unlocked);
}
private void prepareMocksForSetMaximumProfileTimeOff() throws Exception {
addManagedProfile(admin1, DpmMockContext.CALLER_UID, admin1);
- configureProfileOwnerOfOrgOwnedDevice(admin1, DpmMockContext.CALLER_USER_HANDLE);
+ configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE);
when(getServices().userManager.isUserUnlocked()).thenReturn(true);
// Pretend our admin handles CHECK_POLICY_COMPLIANCE intent.
- final Intent intent = new Intent(DevicePolicyManager.ACTION_CHECK_POLICY_COMPLIANCE);
+ final Intent intent = new Intent(ACTION_CHECK_POLICY_COMPLIANCE);
intent.setPackage(admin1.getPackageName());
doReturn(Collections.singletonList(new ResolveInfo()))
.when(getServices().packageManager).queryIntentActivitiesAsUser(
- any(Intent.class), anyInt(), eq(DpmMockContext.CALLER_USER_HANDLE));
+ any(Intent.class), anyInt(), eq(CALLER_USER_HANDLE));
dpms.mMockInjector.setSystemCurrentTimeMillis(PROFILE_OFF_START);
// To allow creation of Notification via Notification.Builder
@@ -6536,10 +6508,10 @@
// admin1 is the outgoing DPC, adminAnotherPackage is the incoming one.
private void assertProfileOwnershipRevertedWithFakeTransferMetadata() throws Exception {
- writeFakeTransferMetadataFile(DpmMockContext.CALLER_USER_HANDLE,
+ writeFakeTransferMetadataFile(CALLER_USER_HANDLE,
TransferOwnershipMetadataManager.ADMIN_TYPE_PROFILE_OWNER);
- int uid = UserHandle.getUid(DpmMockContext.CALLER_USER_HANDLE,
+ int uid = UserHandle.getUid(CALLER_USER_HANDLE,
DpmMockContext.CALLER_SYSTEM_USER_UID);
setUpPackageManagerForAdmin(admin1, uid);
setUpPackageManagerForFakeAdmin(adminAnotherPackage, uid, admin1);
@@ -6550,7 +6522,7 @@
assertTrue(dpm.isAdminActive(admin1));
assertFalse(dpm.isProfileOwnerApp(adminAnotherPackage.getPackageName()));
assertFalse(dpm.isAdminActive(adminAnotherPackage));
- assertEquals(dpm.getProfileOwnerAsUser(DpmMockContext.CALLER_USER_HANDLE), admin1);
+ assertEquals(dpm.getProfileOwnerAsUser(CALLER_USER_HANDLE), admin1);
assertFalse(getMockTransferMetadataManager().metadataFileExists());
}
@@ -6571,12 +6543,12 @@
}
private File getProfileOwnerFile() {
- return dpms.mOwners.getProfileOwnerFile(DpmMockContext.CALLER_USER_HANDLE);
+ return dpms.mOwners.getProfileOwnerFile(CALLER_USER_HANDLE);
}
private File getProfileOwnerPoliciesFile() {
File parentDir = dpms.mMockInjector.environmentGetUserSystemDirectory(
- DpmMockContext.CALLER_USER_HANDLE);
+ CALLER_USER_HANDLE);
return getPoliciesFile(parentDir);
}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
index 20716ab..ce7ac9e 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
@@ -482,4 +482,9 @@
public int checkCallingPermission(String permission) {
return spiedContext.checkCallingPermission(permission);
}
+
+ @Override
+ public void startActivityAsUser(Intent intent, UserHandle userHandle) {
+ spiedContext.startActivityAsUser(intent, userHandle);
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStrongAuthTest.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStrongAuthTest.java
index c9dbdd2..acb20ed 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStrongAuthTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStrongAuthTest.java
@@ -24,6 +24,7 @@
import static com.android.server.locksettings.LockSettingsStrongAuth.NON_STRONG_BIOMETRIC_TIMEOUT_ALARM_TAG;
import static com.android.server.locksettings.LockSettingsStrongAuth.STRONG_AUTH_TIMEOUT_ALARM_TAG;
+import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
@@ -163,9 +164,11 @@
@Test
public void testReportSuccessfulStrongAuthUnlock_schedulePrimaryAuthTimeout() {
- final long nextAlarmTime = 1000;
- when(mInjector.getNextAlarmTimeMs(mDPM.getRequiredStrongAuthTimeout(null, PRIMARY_USER_ID)))
- .thenReturn(nextAlarmTime);
+ final long currentTime = 1000;
+ final long timeout = 1000;
+ final long nextAlarmTime = currentTime + timeout;
+ when(mInjector.getElapsedRealtimeMs()).thenReturn(currentTime);
+ when(mDPM.getRequiredStrongAuthTimeout(null, PRIMARY_USER_ID)).thenReturn(timeout);
mStrongAuth.reportSuccessfulStrongAuthUnlock(PRIMARY_USER_ID);
waitForIdle();
@@ -178,6 +181,29 @@
}
@Test
+ public void testReportSuccessfulStrongAuthUnlock_testRefreshStrongAuthTimeout() {
+ final long currentTime = 1000;
+ final long oldTimeout = 5000;
+ final long nextAlarmTime = currentTime + oldTimeout;
+ when(mInjector.getElapsedRealtimeMs()).thenReturn(currentTime);
+ when(mDPM.getRequiredStrongAuthTimeout(null, PRIMARY_USER_ID)).thenReturn(oldTimeout);
+ mStrongAuth.reportSuccessfulStrongAuthUnlock(PRIMARY_USER_ID);
+ waitForIdle();
+
+ StrongAuthTimeoutAlarmListener alarm =
+ mStrongAuth.mStrongAuthTimeoutAlarmListenerForUser.get(PRIMARY_USER_ID);
+ assertEquals(currentTime, alarm.getLatestStrongAuthTime());
+ verifyAlarm(nextAlarmTime, STRONG_AUTH_TIMEOUT_ALARM_TAG, alarm);
+
+ final long newTimeout = 3000;
+ when(mDPM.getRequiredStrongAuthTimeout(null, PRIMARY_USER_ID)).thenReturn(newTimeout);
+ mStrongAuth.refreshStrongAuthTimeout(PRIMARY_USER_ID);
+ waitForIdle();
+ verify(mAlarmManager).cancel(alarm);
+ verifyAlarm(currentTime + newTimeout, STRONG_AUTH_TIMEOUT_ALARM_TAG, alarm);
+ }
+
+ @Test
public void testReportSuccessfulStrongAuthUnlock_cancelAlarmsAndAllowNonStrongBio() {
setupAlarms(PRIMARY_USER_ID);
mStrongAuth.reportSuccessfulStrongAuthUnlock(PRIMARY_USER_ID);
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index bec37e9..6b3ee5a 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -802,6 +802,7 @@
@Test
public void testCreateProfile_withContextUserId() throws Exception {
+ assumeManagedUsersSupported();
final int primaryUserId = mUserManager.getPrimaryUser().id;
UserInfo userProfile = createProfileForUser("Managed 1",
@@ -820,6 +821,7 @@
@Test
public void testSetUserName_withContextUserId() throws Exception {
+ assumeManagedUsersSupported();
final int primaryUserId = mUserManager.getPrimaryUser().id;
UserInfo userInfo1 = createProfileForUser("Managed 1",
@@ -855,6 +857,7 @@
@Test
public void testGetUserIcon_withContextUserId() throws Exception {
+ assumeManagedUsersSupported();
final int primaryUserId = mUserManager.getPrimaryUser().id;
UserInfo userInfo1 = createProfileForUser("Managed 1",
@@ -975,8 +978,11 @@
}
private void assumeManagedUsersSupported() {
+ // In Automotive, if headless system user is enabled, a managed user cannot be created
+ // under a primary user.
assumeTrue("device doesn't support managed users",
- mPackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS));
+ mPackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS)
+ && (!isAutomotive() || !UserManager.isHeadlessSystemUserMode()));
}
private boolean isAutomotive() {
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index d5ecfeb..e644f64 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -1772,6 +1772,28 @@
}
@Test
+ public void testGroupInstanceIds() throws Exception {
+ final NotificationRecord group1 = generateNotificationRecord(
+ mTestNotificationChannel, 1, "group1", true);
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, "testFindGroupNotificationsLocked",
+ group1.getSbn().getId(), group1.getSbn().getNotification(),
+ group1.getSbn().getUserId());
+ waitForIdle();
+
+ // same group, child, should be returned
+ final NotificationRecord group1Child = generateNotificationRecord(
+ mTestNotificationChannel, 2, "group1", false);
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, "testFindGroupNotificationsLocked",
+ group1Child.getSbn().getId(),
+ group1Child.getSbn().getNotification(), group1Child.getSbn().getUserId());
+ waitForIdle();
+
+ assertEquals(2, mNotificationRecordLogger.numCalls());
+ assertEquals(mNotificationRecordLogger.get(0).getInstanceId(),
+ mNotificationRecordLogger.get(1).groupInstanceId.getId());
+ }
+
+ @Test
public void testFindGroupNotificationsLocked() throws Exception {
// make sure the same notification can be found in both lists and returned
final NotificationRecord group1 = generateNotificationRecord(
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerFake.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerFake.java
index 6b18cc6..64fd19e 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerFake.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerFake.java
@@ -16,6 +16,7 @@
package com.android.server.notification;
+import com.android.internal.logging.InstanceId;
import com.android.internal.logging.UiEventLogger;
import java.util.ArrayList;
@@ -32,14 +33,16 @@
static final int INVALID = -1;
public int position = INVALID, buzzBeepBlink = INVALID;
public boolean wasLogged;
+ public InstanceId groupInstanceId;
CallRecord(NotificationRecord r, NotificationRecord old, int position,
- int buzzBeepBlink) {
+ int buzzBeepBlink, InstanceId groupId) {
super(r, old);
this.position = position;
this.buzzBeepBlink = buzzBeepBlink;
wasLogged = shouldLogReported(buzzBeepBlink);
event = wasLogged ? NotificationReportedEvent.fromRecordPair(this) : null;
+ groupInstanceId = groupId;
}
CallRecord(NotificationRecord r, UiEventLogger.UiEventEnum event) {
@@ -67,8 +70,8 @@
@Override
public void maybeLogNotificationPosted(NotificationRecord r, NotificationRecord old,
- int position, int buzzBeepBlink) {
- mCalls.add(new CallRecord(r, old, position, buzzBeepBlink));
+ int position, int buzzBeepBlink, InstanceId groupId) {
+ mCalls.add(new CallRecord(r, old, position, buzzBeepBlink, groupId));
}
@Override
diff --git a/services/tests/wmtests/Android.bp b/services/tests/wmtests/Android.bp
index 6cb8b86..e2821f4 100644
--- a/services/tests/wmtests/Android.bp
+++ b/services/tests/wmtests/Android.bp
@@ -25,6 +25,7 @@
"testables",
"ub-uiautomator",
"hamcrest-library",
+ "compatibility-device-util-axt",
],
libs: [
diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml
index 123bb07..7e7d69a 100644
--- a/services/tests/wmtests/AndroidManifest.xml
+++ b/services/tests/wmtests/AndroidManifest.xml
@@ -55,7 +55,7 @@
<activity android:name="com.android.server.wm.TaskStackChangedListenerTest$ActivityInActivityView"
android:resizeableActivity="true" />
<activity android:name="com.android.server.wm.ScreenDecorWindowTests$TestActivity"
- android:showWhenLocked="true" />
+ android:showWhenLocked="true" android:allowEmbedded="true"/>
</application>
<instrumentation
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
index f831287..2444c24 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
@@ -221,7 +221,7 @@
addNonFocusableWindow(TYPE_STATUS_BAR, "statusBar")
.getControllableInsetProvider().getSource().setVisible(false);
addNonFocusableWindow(TYPE_NAVIGATION_BAR, "navBar")
- .getControllableInsetProvider().getSource().setVisible(true);
+ .getControllableInsetProvider().setServerVisible(true);
final InsetsPolicy policy = spy(mDisplayContent.getInsetsPolicy());
doNothing().when(policy).startAnimation(anyBoolean(), any(), any());
diff --git a/services/tests/wmtests/src/com/android/server/wm/ScreenDecorWindowTests.java b/services/tests/wmtests/src/com/android/server/wm/ScreenDecorWindowTests.java
index 5e8de87..31a102a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ScreenDecorWindowTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ScreenDecorWindowTests.java
@@ -64,6 +64,8 @@
import androidx.test.filters.SmallTest;
+import com.android.compatibility.common.util.SystemUtil;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -343,7 +345,10 @@
intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
final ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchDisplayId(displayId);
- final Activity activity = mInstrumentation.startActivitySync(intent, options.toBundle());
+
+ final Activity activity = SystemUtil.runWithShellPermissionIdentity(
+ () -> mInstrumentation.startActivitySync(intent, options.toBundle()),
+ "android.permission.ACTIVITY_EMBEDDING");
waitForIdle();
assertEquals(displayId, activity.getDisplayId());
diff --git a/wifi/Android.bp b/wifi/Android.bp
index 99beb7b..6a8600a 100644
--- a/wifi/Android.bp
+++ b/wifi/Android.bp
@@ -134,6 +134,7 @@
"framework-wifi-util-lib",
],
sdk_version: "module_current",
+ dist: { dest: "framework-wifi.txt" },
}
droidstubs {
@@ -172,6 +173,7 @@
name: "framework-wifi-stubs-publicapi",
srcs: [":framework-wifi-stubs-srcs-publicapi"],
defaults: ["framework-module-stubs-lib-defaults-publicapi"],
+ dist: { dest: "framework-wifi.jar" },
}
java_library {
@@ -179,6 +181,7 @@
srcs: [":framework-wifi-stubs-srcs-systemapi"],
libs: ["framework-annotations-lib"],
defaults: ["framework-module-stubs-lib-defaults-systemapi"],
+ dist: { dest: "framework-wifi.jar" },
}
java_library {
@@ -186,6 +189,7 @@
srcs: [":framework-wifi-stubs-srcs-module_libs_api"],
libs: ["framework-annotations-lib"],
defaults: ["framework-module-stubs-lib-defaults-module_libs_api"],
+ dist: { dest: "framework-wifi.jar" },
}
// defaults for tests that need to build against framework-wifi's @hide APIs