Merge "[MS31] Fix several hidden API usages" am: 0892c27c57 am: b7048e076e
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1935964
Change-Id: I8b3dd856ff75333f14234c81147bd173a8623768
diff --git a/apct-tests/perftests/autofill/AndroidManifest.xml b/apct-tests/perftests/autofill/AndroidManifest.xml
index 57595a2..de2a3f2 100644
--- a/apct-tests/perftests/autofill/AndroidManifest.xml
+++ b/apct-tests/perftests/autofill/AndroidManifest.xml
@@ -16,6 +16,16 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.perftests.autofill">
+ <uses-permission android:name="android.permission.CONTROL_KEYGUARD" />
+ <uses-permission android:name="android.permission.DEVICE_POWER" />
+ <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
+ <uses-permission android:name="android.permission.MANAGE_USERS" />
+ <uses-permission android:name="android.permission.REAL_GET_TASKS" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+
<application>
<uses-library android:name="android.test.runner" />
<activity android:name="android.perftests.utils.PerfTestActivity"
diff --git a/cmds/idmap2/OWNERS b/cmds/idmap2/OWNERS
index def9f40..062ffd4 100644
--- a/cmds/idmap2/OWNERS
+++ b/cmds/idmap2/OWNERS
@@ -1,3 +1,4 @@
set noparent
+toddke@google.com
patb@google.com
zyy@google.com
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 6cfa39c..1a1bdd9 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -226,6 +226,14 @@
*/
public static final String EXTRA_NEW_WALLPAPER_ID = "android.service.wallpaper.extra.ID";
+ /**
+ * Extra passed on {@link Intent.ACTION_WALLPAPER_CHANGED} indicating if wallpaper was set from
+ * a foreground app.
+ * @hide
+ */
+ public static final String EXTRA_FROM_FOREGROUND_APP =
+ "android.service.wallpaper.extra.FROM_FOREGROUND_APP";
+
// flags for which kind of wallpaper to act on
/** @hide */
@@ -1452,18 +1460,27 @@
mContext.getUserId());
if (fd != null) {
FileOutputStream fos = null;
- boolean ok = false;
+ final Bitmap tmp = BitmapFactory.decodeStream(resources.openRawResource(resid));
try {
- fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
- copyStreamToWallpaperFile(resources.openRawResource(resid), fos);
- // The 'close()' is the trigger for any server-side image manipulation,
- // so we must do that before waiting for completion.
- fos.close();
- completion.waitForCompletion();
+ // If the stream can't be decoded, treat it as an invalid input.
+ if (tmp != null) {
+ fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
+ tmp.compress(Bitmap.CompressFormat.PNG, 100, fos);
+ // The 'close()' is the trigger for any server-side image manipulation,
+ // so we must do that before waiting for completion.
+ fos.close();
+ completion.waitForCompletion();
+ } else {
+ throw new IllegalArgumentException(
+ "Resource 0x" + Integer.toHexString(resid) + " is invalid");
+ }
} finally {
// Might be redundant but completion shouldn't wait unless the write
// succeeded; this is a fallback if it threw past the close+wait.
IoUtils.closeQuietly(fos);
+ if (tmp != null) {
+ tmp.recycle();
+ }
}
}
} catch (RemoteException e) {
@@ -1705,13 +1722,22 @@
result, which, completion, mContext.getUserId());
if (fd != null) {
FileOutputStream fos = null;
+ final Bitmap tmp = BitmapFactory.decodeStream(bitmapData);
try {
- fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
- copyStreamToWallpaperFile(bitmapData, fos);
- fos.close();
- completion.waitForCompletion();
+ // If the stream can't be decoded, treat it as an invalid input.
+ if (tmp != null) {
+ fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
+ tmp.compress(Bitmap.CompressFormat.PNG, 100, fos);
+ fos.close();
+ completion.waitForCompletion();
+ } else {
+ throw new IllegalArgumentException("InputStream is invalid");
+ }
} finally {
IoUtils.closeQuietly(fos);
+ if (tmp != null) {
+ tmp.recycle();
+ }
}
}
} catch (RemoteException e) {
diff --git a/core/java/android/app/admin/DevicePolicyManagerInternal.java b/core/java/android/app/admin/DevicePolicyManagerInternal.java
index a0d2977..01875ed 100644
--- a/core/java/android/app/admin/DevicePolicyManagerInternal.java
+++ b/core/java/android/app/admin/DevicePolicyManagerInternal.java
@@ -16,6 +16,7 @@
package android.app.admin;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.content.ComponentName;
@@ -77,6 +78,13 @@
OnCrossProfileWidgetProvidersChangeListener listener);
/**
+ * @param userHandle the handle of the user whose profile owner is being fetched.
+ * @return the configured supervision app if it exists and is the device owner or policy owner.
+ */
+ public abstract @Nullable ComponentName getProfileOwnerOrDeviceOwnerSupervisionComponent(
+ @NonNull UserHandle userHandle);
+
+ /**
* Checks if an app with given uid is an active device owner of its user.
*
* <p>This takes the DPMS lock. DO NOT call from PM/UM/AM with their lock held.
diff --git a/core/java/android/content/integrity/OWNERS b/core/java/android/content/integrity/OWNERS
index a1fe59c..20c758a 100644
--- a/core/java/android/content/integrity/OWNERS
+++ b/core/java/android/content/integrity/OWNERS
@@ -1,3 +1,5 @@
# Bug component: 722021
+toddke@android.com
+toddke@google.com
patb@google.com
diff --git a/core/java/android/content/om/OWNERS b/core/java/android/content/om/OWNERS
index 9c47336..3669817 100644
--- a/core/java/android/content/om/OWNERS
+++ b/core/java/android/content/om/OWNERS
@@ -1,4 +1,6 @@
# Bug component: 568631
+toddke@android.com
+toddke@google.com
patb@google.com
zyy@google.com
diff --git a/core/java/android/content/pm/OWNERS b/core/java/android/content/pm/OWNERS
index 128bfb9..4e674f6 100644
--- a/core/java/android/content/pm/OWNERS
+++ b/core/java/android/content/pm/OWNERS
@@ -1,9 +1,11 @@
# Bug component: 36137
+toddke@android.com
+toddke@google.com
patb@google.com
per-file PackageParser.java = set noparent
-per-file PackageParser.java = chiuwinson@google.com,patb@google.com
+per-file PackageParser.java = chiuwinson@google.com,patb@google.com,toddke@google.com
per-file *Shortcut* = file:/core/java/android/content/pm/SHORTCUT_OWNERS
per-file AppSearchPerson.java = file:/core/java/android/content/pm/SHORTCUT_OWNERS
per-file *Launcher* = file:/core/java/android/content/pm/LAUNCHER_OWNERS
diff --git a/core/java/android/content/pm/dex/OWNERS b/core/java/android/content/pm/dex/OWNERS
index b590f659..267e5d58 100644
--- a/core/java/android/content/pm/dex/OWNERS
+++ b/core/java/android/content/pm/dex/OWNERS
@@ -1,5 +1,7 @@
# Bug component: 86431
+toddke@android.com
+toddke@google.com
patb@google.com
calin@google.com
ngeoffray@google.com
diff --git a/core/java/android/content/pm/parsing/OWNERS b/core/java/android/content/pm/parsing/OWNERS
index 445a833..8049d5c 100644
--- a/core/java/android/content/pm/parsing/OWNERS
+++ b/core/java/android/content/pm/parsing/OWNERS
@@ -2,3 +2,4 @@
chiuwinson@google.com
patb@google.com
+toddke@google.com
diff --git a/core/java/android/content/pm/permission/OWNERS b/core/java/android/content/pm/permission/OWNERS
index f9c51dd..cf7e689 100644
--- a/core/java/android/content/pm/permission/OWNERS
+++ b/core/java/android/content/pm/permission/OWNERS
@@ -2,5 +2,7 @@
include platform/frameworks/base:/core/java/android/permission/OWNERS
+toddke@android.com
+toddke@google.com
patb@google.com
diff --git a/core/java/android/content/pm/split/OWNERS b/core/java/android/content/pm/split/OWNERS
index b8fa1a9..3d126d2 100644
--- a/core/java/android/content/pm/split/OWNERS
+++ b/core/java/android/content/pm/split/OWNERS
@@ -1,3 +1,5 @@
# Bug component: 36137
+toddke@android.com
+toddke@google.com
patb@google.com
diff --git a/core/java/android/content/pm/verify/domain/OWNERS b/core/java/android/content/pm/verify/domain/OWNERS
index 445a833..c669112 100644
--- a/core/java/android/content/pm/verify/domain/OWNERS
+++ b/core/java/android/content/pm/verify/domain/OWNERS
@@ -2,3 +2,4 @@
chiuwinson@google.com
patb@google.com
+toddke@google.com
\ No newline at end of file
diff --git a/core/java/android/content/res/OWNERS b/core/java/android/content/res/OWNERS
index 7460a14..d12d920 100644
--- a/core/java/android/content/res/OWNERS
+++ b/core/java/android/content/res/OWNERS
@@ -1,4 +1,6 @@
# Bug component: 568761
+toddke@android.com
+toddke@google.com
patb@google.com
zyy@google.com
diff --git a/core/java/android/hardware/OWNERS b/core/java/android/hardware/OWNERS
index 4143bfc..95f13b5 100644
--- a/core/java/android/hardware/OWNERS
+++ b/core/java/android/hardware/OWNERS
@@ -1,5 +1,5 @@
# Camera
-per-file *Camera*=cychen@google.com,epeev@google.com,etalvala@google.com,shuzhenwang@google.com,zhijunhe@google.com,jchowdhary@google.com
+per-file *Camera*=cychen@google.com,epeev@google.com,etalvala@google.com,shuzhenwang@google.com,yinchiayeh@google.com,zhijunhe@google.com,jchowdhary@google.com
# Sensor Privacy
per-file *SensorPrivacy* = file:platform/frameworks/native:/libs/sensorprivacy/OWNERS
diff --git a/core/java/android/os/incremental/OWNERS b/core/java/android/os/incremental/OWNERS
index 3634869..47eee64 100644
--- a/core/java/android/os/incremental/OWNERS
+++ b/core/java/android/os/incremental/OWNERS
@@ -1,5 +1,6 @@
# Bug component: 554432
alexbuy@google.com
schfan@google.com
+toddke@google.com
zyy@google.com
patb@google.com
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index d0ef546..38cc30e 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6331,6 +6331,27 @@
public static final String ALLOW_MOCK_LOCATION = "mock_location";
/**
+ * This is used by Bluetooth Manager to store adapter name
+ * @hide
+ */
+ @Readable(maxTargetSdk = Build.VERSION_CODES.S)
+ public static final String BLUETOOTH_NAME = "bluetooth_name";
+
+ /**
+ * This is used by Bluetooth Manager to store adapter address
+ * @hide
+ */
+ @Readable(maxTargetSdk = Build.VERSION_CODES.S)
+ public static final String BLUETOOTH_ADDRESS = "bluetooth_address";
+
+ /**
+ * This is used by Bluetooth Manager to store whether adapter address is valid
+ * @hide
+ */
+ @Readable(maxTargetSdk = Build.VERSION_CODES.S)
+ public static final String BLUETOOTH_ADDR_VALID = "bluetooth_addr_valid";
+
+ /**
* Setting to indicate that on device captions are enabled.
*
* @hide
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 2a82d99..675297d 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -800,11 +800,7 @@
context);
mCompatibleVisibilityInfo = new SystemUiVisibilityInfo();
mAccessibilityManager = AccessibilityManager.getInstance(context);
- mAccessibilityManager.addAccessibilityStateChangeListener(
- mAccessibilityInteractionConnectionManager, mHandler);
mHighContrastTextManager = new HighContrastTextManager();
- mAccessibilityManager.addHighTextContrastStateChangeListener(
- mHighContrastTextManager, mHandler);
mViewConfiguration = ViewConfiguration.get(context);
mDensity = context.getResources().getDisplayMetrics().densityDpi;
mNoncompatDensity = context.getResources().getDisplayMetrics().noncompatDensityDpi;
@@ -1004,8 +1000,6 @@
mView = view;
mAttachInfo.mDisplayState = mDisplay.getState();
- mDisplayManager.registerDisplayListener(mDisplayListener, mHandler);
-
mViewLayoutDirectionInitial = mView.getRawLayoutDirection();
mFallbackEventHandler.setView(view);
mWindowAttributes.copyFrom(attrs);
@@ -1198,6 +1192,7 @@
"Unable to add window -- unknown error code " + res);
}
+ registerListeners();
if ((res & WindowManagerGlobal.ADD_FLAG_USE_BLAST) != 0) {
mUseBLASTAdapter = true;
}
@@ -1254,6 +1249,28 @@
}
}
+ /**
+ * Register any kind of listeners if setView was success.
+ */
+ private void registerListeners() {
+ mAccessibilityManager.addAccessibilityStateChangeListener(
+ mAccessibilityInteractionConnectionManager, mHandler);
+ mAccessibilityManager.addHighTextContrastStateChangeListener(
+ mHighContrastTextManager, mHandler);
+ mDisplayManager.registerDisplayListener(mDisplayListener, mHandler);
+ }
+
+ /**
+ * Unregister all listeners while detachedFromWindow.
+ */
+ private void unregisterListeners() {
+ mAccessibilityManager.removeAccessibilityStateChangeListener(
+ mAccessibilityInteractionConnectionManager);
+ mAccessibilityManager.removeHighTextContrastStateChangeListener(
+ mHighContrastTextManager);
+ mDisplayManager.unregisterDisplayListener(mDisplayListener);
+ }
+
private void setTag() {
final String[] split = mWindowAttributes.getTitle().toString().split("\\.");
if (split.length > 0) {
@@ -4979,10 +4996,6 @@
}
mAccessibilityInteractionConnectionManager.ensureNoConnection();
- mAccessibilityManager.removeAccessibilityStateChangeListener(
- mAccessibilityInteractionConnectionManager);
- mAccessibilityManager.removeHighTextContrastStateChangeListener(
- mHighContrastTextManager);
removeSendWindowContentChangedCallback();
destroyHardwareRenderer();
@@ -5015,8 +5028,7 @@
mInputEventReceiver = null;
}
- mDisplayManager.unregisterDisplayListener(mDisplayListener);
-
+ unregisterListeners();
unscheduleTraversals();
}
diff --git a/core/java/android/window/SplashScreen.java b/core/java/android/window/SplashScreen.java
index 3e00758..0c4d273 100644
--- a/core/java/android/window/SplashScreen.java
+++ b/core/java/android/window/SplashScreen.java
@@ -92,6 +92,9 @@
* overrides and persists the theme used for the {@link SplashScreen} of this application.
* <p>
* To reset to the default theme, set this the themeId to {@link Resources#ID_NULL}.
+ * <p>
+ * <b>Note:</b> The theme name must be stable across versions, otherwise it won't be found
+ * after your application is updated.
*/
void setSplashScreenTheme(@StyleRes int themeId);
diff --git a/core/java/android/window/SplashScreenView.java b/core/java/android/window/SplashScreenView.java
index acf20d7..6a875d1 100644
--- a/core/java/android/window/SplashScreenView.java
+++ b/core/java/android/window/SplashScreenView.java
@@ -316,7 +316,8 @@
}
private SurfaceView createSurfaceView(@NonNull SplashScreenView view) {
- final SurfaceView surfaceView = new SurfaceView(view.getContext());
+ final Context viewContext = view.getContext();
+ final SurfaceView surfaceView = new SurfaceView(viewContext);
surfaceView.setPadding(0, 0, 0, 0);
surfaceView.setBackground(mIconBackground);
if (mSurfacePackage == null) {
@@ -326,10 +327,10 @@
+ Thread.currentThread().getId());
}
- SurfaceControlViewHost viewHost = new SurfaceControlViewHost(mContext,
- mContext.getDisplay(),
+ SurfaceControlViewHost viewHost = new SurfaceControlViewHost(viewContext,
+ viewContext.getDisplay(),
surfaceView.getHostToken());
- ImageView imageView = new ImageView(mContext);
+ ImageView imageView = new ImageView(viewContext);
imageView.setBackground(mIconDrawable);
viewHost.setView(imageView, mIconSize, mIconSize);
SurfaceControlViewHost.SurfacePackage surfacePackage = viewHost.getSurfacePackage();
diff --git a/core/java/com/android/internal/infra/OWNERS b/core/java/com/android/internal/infra/OWNERS
index e69de29..4550358 100644
--- a/core/java/com/android/internal/infra/OWNERS
+++ b/core/java/com/android/internal/infra/OWNERS
@@ -0,0 +1,6 @@
+per-file AndroidFuture.java = eugenesusla@google.com
+per-file RemoteStream.java = eugenesusla@google.com
+per-file PerUser.java = eugenesusla@google.com
+per-file ServiceConnector.java = eugenesusla@google.com
+per-file AndroidFuture.aidl = eugenesusla@google.com
+per-file IAndroidFuture.aidl = eugenesusla@google.com
\ No newline at end of file
diff --git a/core/java/com/android/internal/util/OWNERS b/core/java/com/android/internal/util/OWNERS
index 2b7f8b2..100a605d 100644
--- a/core/java/com/android/internal/util/OWNERS
+++ b/core/java/com/android/internal/util/OWNERS
@@ -4,3 +4,4 @@
per-file *ContrastColor* = file:/services/core/java/com/android/server/notification/OWNERS
per-file Protocol* = etancohen@google.com, lorenzo@google.com
per-file State* = jchalard@google.com, lorenzo@google.com, satk@google.com
+per-file DataClass* = eugenesusla@google.com
\ No newline at end of file
diff --git a/core/java/com/android/internal/util/function/pooled/OWNERS b/core/java/com/android/internal/util/function/pooled/OWNERS
index e69de29..da723b3 100644
--- a/core/java/com/android/internal/util/function/pooled/OWNERS
+++ b/core/java/com/android/internal/util/function/pooled/OWNERS
@@ -0,0 +1 @@
+eugenesusla@google.com
\ No newline at end of file
diff --git a/core/java/com/android/server/OWNERS b/core/java/com/android/server/OWNERS
index 81bad6a..554e278 100644
--- a/core/java/com/android/server/OWNERS
+++ b/core/java/com/android/server/OWNERS
@@ -1 +1 @@
-per-file SystemConfig.java = patb@google.com
+per-file SystemConfig.java = toddke@google.com,patb@google.com
diff --git a/core/jni/OWNERS b/core/jni/OWNERS
index 832c498..6c76481 100644
--- a/core/jni/OWNERS
+++ b/core/jni/OWNERS
@@ -1,9 +1,9 @@
# Camera
per-file *Camera*,*camera* = cychen@google.com, epeev@google.com, etalvala@google.com
-per-file *Camera*,*camera* = shuzhenwang@google.com, zhijunhe@google.com
+per-file *Camera*,*camera* = shuzhenwang@google.com, yinchiayeh@google.com, zhijunhe@google.com
# Connectivity
-per-file android_net_* = jchalard@google.com, lorenzo@google.com, reminv@google.com, satk@google.com
+per-file android_net_* = codewiz@google.com, jchalard@google.com, lorenzo@google.com, reminv@google.com, satk@google.com
# CPU
per-file *Cpu* = file:/core/java/com/android/internal/os/CPU_OWNERS
diff --git a/core/proto/OWNERS b/core/proto/OWNERS
index 931ef44..78650ed 100644
--- a/core/proto/OWNERS
+++ b/core/proto/OWNERS
@@ -5,6 +5,7 @@
singhtejinder@google.com
yanmin@google.com
yaochen@google.com
+yro@google.com
zhouwenjie@google.com
# Frameworks
@@ -12,7 +13,7 @@
jjaggi@google.com
kwekua@google.com
roosa@google.com
-per-file package_item_info.proto = patb@google.com
+per-file package_item_info.proto = toddke@google.com,patb@google.com
per-file usagestatsservice.proto, usagestatsservice_v2.proto = file:/core/java/android/app/usage/OWNERS
per-file apphibernationservice.proto = file:/core/java/android/apphibernation/OWNERS
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 6ecfcec..b0bb821 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -5693,6 +5693,10 @@
<!-- Allows input events to be monitored. Very dangerous! @hide -->
<permission android:name="android.permission.MONITOR_INPUT"
android:protectionLevel="signature|recents" />
+ <!-- Allows the use of FLAG_SLIPPERY, which permits touch events to slip from the current
+ window to the window where the touch currently is on top of. @hide -->
+ <permission android:name="android.permission.ALLOW_SLIPPERY_TOUCHES"
+ android:protectionLevel="signature|recents" />
<!-- Allows the caller to change the associations between input devices and displays.
Very dangerous! @hide -->
<permission android:name="android.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY"
diff --git a/core/res/OWNERS b/core/res/OWNERS
index e241dd6..165dcad 100644
--- a/core/res/OWNERS
+++ b/core/res/OWNERS
@@ -22,6 +22,7 @@
shanh@google.com
svetoslavganov@android.com
svetoslavganov@google.com
+toddke@google.com
tsuji@google.com
yamasani@google.com
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index fb7cdda..2f33498 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1908,8 +1908,9 @@
STREAM_MUSIC as if it's on TV platform. -->
<bool name="config_single_volume">false</bool>
- <!-- Flag indicating whether the volume panel should show remote sessions. -->
- <bool name="config_volumeShowRemoteSessions">true</bool>
+ <!-- Flag indicating whether platform level volume adjustments are enabled for remote sessions
+ on grouped devices. -->
+ <bool name="config_volumeAdjustmentForRemoteGroupSessions">true</bool>
<!-- Flag indicating that an outbound call must have a call capable phone account
that has declared it can process the call's handle. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 8ed7991..4db6499 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -4432,7 +4432,7 @@
<java-symbol type="dimen" name="config_wallpaperDimAmount" />
- <java-symbol type="bool" name="config_volumeShowRemoteSessions" />
+ <java-symbol type="bool" name="config_volumeAdjustmentForRemoteGroupSessions" />
<!-- List of shared library packages that should be loaded by the classloader after the
code and resources provided by applications. -->
diff --git a/data/etc/OWNERS b/data/etc/OWNERS
index 2c93d5a..ea23aba 100644
--- a/data/etc/OWNERS
+++ b/data/etc/OWNERS
@@ -8,6 +8,8 @@
lorenzo@google.com
svetoslavganov@android.com
svetoslavganov@google.com
+toddke@android.com
+toddke@google.com
patb@google.com
yamasani@google.com
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java
index b7235a3..a568c28 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java
@@ -83,6 +83,19 @@
private boolean mHasStatusBar = false;
private int mNavBarFrameHeight = 0;
+ /**
+ * Different from {@link #equals(Object)}, this method compares the basic geometry properties
+ * of two {@link DisplayLayout} objects including width, height, rotation, density and cutout.
+ * @return {@code true} if the given {@link DisplayLayout} is identical geometry wise.
+ */
+ public boolean isSameGeometry(@NonNull DisplayLayout other) {
+ return mWidth == other.mWidth
+ && mHeight == other.mHeight
+ && mRotation == other.mRotation
+ && mDensityDpi == other.mDensityDpi
+ && Objects.equals(mCutout, other.mCutout);
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index 63f1985..8967457 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -76,7 +76,6 @@
import com.android.wm.shell.pip.PipUtils;
import java.io.PrintWriter;
-import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;
@@ -441,7 +440,7 @@
}
private void onDisplayChanged(DisplayLayout layout, boolean saveRestoreSnapFraction) {
- if (Objects.equals(layout, mPipBoundsState.getDisplayLayout())) {
+ if (mPipBoundsState.getDisplayLayout().isSameGeometry(layout)) {
return;
}
Runnable updateDisplayLayout = () -> {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
index 29326ec..cdd745f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
@@ -50,6 +50,7 @@
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.Slog;
+import android.view.ContextThemeWrapper;
import android.view.SurfaceControl;
import android.view.View;
import android.window.SplashScreenView;
@@ -299,6 +300,11 @@
}
}
+ /** Creates the wrapper with system theme to avoid unexpected styles from app. */
+ ContextThemeWrapper createViewContextWrapper(Context appContext) {
+ return new ContextThemeWrapper(appContext, mContext.getTheme());
+ }
+
/** The configuration of the splash screen window. */
public static class SplashScreenWindowAttrs {
private int mWindowBgResId = 0;
@@ -472,7 +478,8 @@
}
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "fillViewWithIcon");
- final SplashScreenView.Builder builder = new SplashScreenView.Builder(mContext)
+ final ContextThemeWrapper wrapper = createViewContextWrapper(mContext);
+ final SplashScreenView.Builder builder = new SplashScreenView.Builder(wrapper)
.setBackgroundColor(mThemeColor)
.setOverlayDrawable(mOverlayDrawable)
.setIconSize(iconSize)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
index 147f5e3..4dae634 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
@@ -137,24 +137,11 @@
private final SparseArray<SurfaceControlViewHost> mAnimatedSplashScreenSurfaceHosts =
new SparseArray<>(1);
- /** Obtain proper context for showing splash screen on the provided display. */
- private Context getDisplayContext(Context context, int displayId) {
- if (displayId == DEFAULT_DISPLAY) {
- // The default context fits.
- return context;
- }
-
- final Display targetDisplay = mDisplayManager.getDisplay(displayId);
- if (targetDisplay == null) {
- // Failed to obtain the non-default display where splash screen should be shown,
- // lets not show at all.
- return null;
- }
-
- return context.createDisplayContext(targetDisplay);
+ private Display getDisplay(int displayId) {
+ return mDisplayManager.getDisplay(displayId);
}
- private int getSplashScreenTheme(int splashScreenThemeResId, ActivityInfo activityInfo) {
+ int getSplashScreenTheme(int splashScreenThemeResId, ActivityInfo activityInfo) {
return splashScreenThemeResId != 0
? splashScreenThemeResId
: activityInfo.getThemeResource() != 0 ? activityInfo.getThemeResource()
@@ -177,7 +164,7 @@
final int displayId = taskInfo.displayId;
final int taskId = taskInfo.taskId;
- Context context = mContext;
+
// replace with the default theme if the application didn't set
final int theme = getSplashScreenTheme(windowInfo.splashScreenThemeResId, activityInfo);
if (DEBUG_SPLASH_SCREEN) {
@@ -186,13 +173,16 @@
+ " suggestType=" + suggestType);
}
- // Obtain proper context to launch on the right display.
- final Context displayContext = getDisplayContext(context, displayId);
- if (displayContext == null) {
+ final Display display = getDisplay(displayId);
+ if (display == null) {
// Can't show splash screen on requested display, so skip showing at all.
return;
}
- context = displayContext;
+ Context context = displayId == DEFAULT_DISPLAY
+ ? mContext : mContext.createDisplayContext(display);
+ if (context == null) {
+ return;
+ }
if (theme != context.getThemeResId()) {
try {
context = context.createPackageContextAsUser(activityInfo.packageName,
@@ -303,7 +293,8 @@
// Record whether create splash screen view success, notify to current thread after
// create splash screen view finished.
final SplashScreenViewSupplier viewSupplier = new SplashScreenViewSupplier();
- final FrameLayout rootLayout = new FrameLayout(context);
+ final FrameLayout rootLayout = new FrameLayout(
+ mSplashscreenContentDrawer.createViewContextWrapper(context));
rootLayout.setPadding(0, 0, 0, 0);
rootLayout.setFitsSystemWindows(false);
final Runnable setViewSynchronized = () -> {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
index eef0d9b..18b8faf 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
@@ -30,6 +30,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -101,7 +102,6 @@
static final class TestStartingSurfaceDrawer extends StartingSurfaceDrawer{
int mAddWindowForTask = 0;
- int mViewThemeResId;
TestStartingSurfaceDrawer(Context context, ShellExecutor splashScreenExecutor,
TransactionPool pool) {
@@ -113,7 +113,6 @@
View view, WindowManager wm, WindowManager.LayoutParams params, int suggestType) {
// listen for addView
mAddWindowForTask = taskId;
- mViewThemeResId = view.getContext().getThemeResId();
// Do not wait for background color
return false;
}
@@ -183,12 +182,15 @@
final int taskId = 1;
final StartingWindowInfo windowInfo =
createWindowInfo(taskId, 0);
+ final int[] theme = new int[1];
+ doAnswer(invocation -> theme[0] = (Integer) invocation.callRealMethod())
+ .when(mStartingSurfaceDrawer).getSplashScreenTheme(eq(0), any());
+
mStartingSurfaceDrawer.addSplashScreenStartingWindow(windowInfo, mBinder,
STARTING_WINDOW_TYPE_SPLASH_SCREEN);
waitHandlerIdle(mTestHandler);
- verify(mStartingSurfaceDrawer).addWindow(eq(taskId), eq(mBinder), any(), any(), any(),
- eq(STARTING_WINDOW_TYPE_SPLASH_SCREEN));
- assertNotEquals(mStartingSurfaceDrawer.mViewThemeResId, 0);
+ verify(mStartingSurfaceDrawer).getSplashScreenTheme(eq(0), any());
+ assertNotEquals(theme[0], 0);
}
@Test
diff --git a/libs/androidfw/LoadedArsc.cpp b/libs/androidfw/LoadedArsc.cpp
index d17c328..8150e78 100644
--- a/libs/androidfw/LoadedArsc.cpp
+++ b/libs/androidfw/LoadedArsc.cpp
@@ -686,6 +686,12 @@
std::unordered_set<uint32_t> finalized_ids;
const auto lib_alias = child_chunk.header<ResTable_staged_alias_header>();
if (!lib_alias) {
+ LOG(ERROR) << "RES_TABLE_STAGED_ALIAS_TYPE is too small.";
+ return {};
+ }
+ if ((child_chunk.data_size() / sizeof(ResTable_staged_alias_entry))
+ < dtohl(lib_alias->count)) {
+ LOG(ERROR) << "RES_TABLE_STAGED_ALIAS_TYPE is too small to hold entries.";
return {};
}
const auto entry_begin = child_chunk.data_ptr().convert<ResTable_staged_alias_entry>();
diff --git a/libs/androidfw/OWNERS b/libs/androidfw/OWNERS
index 38b6425..17f5164 100644
--- a/libs/androidfw/OWNERS
+++ b/libs/androidfw/OWNERS
@@ -1,4 +1,5 @@
set noparent
+toddke@google.com
zyy@google.com
patb@google.com
diff --git a/media/java/android/media/IMediaRouterService.aidl b/media/java/android/media/IMediaRouterService.aidl
index 48289ec..25b582d 100644
--- a/media/java/android/media/IMediaRouterService.aidl
+++ b/media/java/android/media/IMediaRouterService.aidl
@@ -39,6 +39,7 @@
MediaRouterClientState getState(IMediaRouterClient client);
boolean isPlaybackActive(IMediaRouterClient client);
+ void setBluetoothA2dpOn(IMediaRouterClient client, boolean on);
void setDiscoveryRequest(IMediaRouterClient client, int routeTypes, boolean activeScan);
void setSelectedRoute(IMediaRouterClient client, String routeId, boolean explicit);
void requestSetVolume(IMediaRouterClient client, String routeId, int volume);
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index 2986f7c..dfdfeac 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -1070,7 +1070,8 @@
&& (types & ROUTE_TYPE_LIVE_AUDIO) != 0
&& (route.isBluetooth() || route.isDefault())) {
try {
- sStatic.mAudioService.setBluetoothA2dpOn(route.isBluetooth());
+ sStatic.mMediaRouterService.setBluetoothA2dpOn(sStatic.mClient,
+ route.isBluetooth());
} catch (RemoteException e) {
Log.e(TAG, "Error changing Bluetooth A2DP state", e);
}
diff --git a/mms/OWNERS b/mms/OWNERS
index f56845e..2e419c1 100644
--- a/mms/OWNERS
+++ b/mms/OWNERS
@@ -3,6 +3,7 @@
tgunn@google.com
breadley@google.com
rgreenwalt@google.com
+amitmahajan@google.com
fionaxu@google.com
jackyu@google.com
jminjie@google.com
diff --git a/native/android/OWNERS b/native/android/OWNERS
index 8b35f8d..02dfd39 100644
--- a/native/android/OWNERS
+++ b/native/android/OWNERS
@@ -1,7 +1,7 @@
jreck@google.com
per-file libandroid_net.map.txt, net.c = set noparent
-per-file libandroid_net.map.txt, net.c = jchalard@google.com, junyulai@google.com
+per-file libandroid_net.map.txt, net.c = codewiz@google.com, jchalard@google.com, junyulai@google.com
per-file libandroid_net.map.txt, net.c = lorenzo@google.com, reminv@google.com, satk@google.com
per-file system_fonts.cpp = file:/graphics/java/android/graphics/fonts/OWNERS
diff --git a/packages/CarrierDefaultApp/OWNERS b/packages/CarrierDefaultApp/OWNERS
index b9de5a3..a2352e2 100644
--- a/packages/CarrierDefaultApp/OWNERS
+++ b/packages/CarrierDefaultApp/OWNERS
@@ -2,6 +2,7 @@
tgunn@google.com
breadley@google.com
rgreenwalt@google.com
+amitmahajan@google.com
fionaxu@google.com
jackyu@google.com
jminjie@google.com
diff --git a/packages/CtsShim/OWNERS b/packages/CtsShim/OWNERS
index eb631bc..9419771 100644
--- a/packages/CtsShim/OWNERS
+++ b/packages/CtsShim/OWNERS
@@ -1,2 +1,3 @@
ioffe@google.com
+toddke@google.com
patb@google.com
\ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
index 54230c8..86604a2 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
@@ -71,6 +71,7 @@
MediaRouter2Manager mRouterManager;
@VisibleForTesting
String mPackageName;
+ private final boolean mVolumeAdjustmentForRemoteGroupSessions;
private MediaDevice mCurrentConnectedDevice;
private LocalBluetoothManager mBluetoothManager;
@@ -84,6 +85,9 @@
if (!TextUtils.isEmpty(packageName)) {
mPackageName = packageName;
}
+
+ mVolumeAdjustmentForRemoteGroupSessions = context.getResources().getBoolean(
+ com.android.internal.R.bool.config_volumeAdjustmentForRemoteGroupSessions);
}
@Override
@@ -388,7 +392,9 @@
@TargetApi(Build.VERSION_CODES.R)
boolean shouldEnableVolumeSeekBar(RoutingSessionInfo sessionInfo) {
- return false;
+ return sessionInfo.isSystemSession() // System sessions are not remote
+ || mVolumeAdjustmentForRemoteGroupSessions
+ || sessionInfo.getSelectedRoutes().size() <= 1;
}
private void refreshDevices() {
diff --git a/packages/Shell/OWNERS b/packages/Shell/OWNERS
index 80bb307..177f86b 100644
--- a/packages/Shell/OWNERS
+++ b/packages/Shell/OWNERS
@@ -6,6 +6,7 @@
svetoslavganov@google.com
hackbod@google.com
yamasani@google.com
+toddke@google.com
patb@google.com
cbrubaker@google.com
omakoto@google.com
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 9de1c5e..3d1bd24 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -121,6 +121,7 @@
<uses-permission android:name="android.permission.SET_ORIENTATION" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.MONITOR_INPUT" />
+ <uses-permission android:name="android.permission.ALLOW_SLIPPERY_TOUCHES" />
<uses-permission android:name="android.permission.INPUT_CONSUMER" />
<!-- DreamManager -->
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt
index 9286175..471bac1 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt
@@ -43,8 +43,7 @@
val shouldListenForFingerprintAssistant: Boolean,
val switchingUser: Boolean,
val udfps: Boolean,
- val userDoesNotHaveTrust: Boolean,
- val userNeedsStrongAuth: Boolean
+ val userDoesNotHaveTrust: Boolean
) : KeyguardListenModel() {
override val modality: Int = TYPE_FACE
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 877e764..7a518d2 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -2254,11 +2254,9 @@
!(mFingerprintLockedOut && mBouncer && mCredentialAttempted);
final boolean isEncryptedOrLockdownForUser = isEncryptedOrLockdown(user);
- final boolean userNeedsStrongAuth = userNeedsStrongAuth();
final boolean shouldListenUdfpsState = !isUdfps
|| (!userCanSkipBouncer
&& !isEncryptedOrLockdownForUser
- && !userNeedsStrongAuth
&& userDoesNotHaveTrust
&& !mFingerprintLockedOut);
@@ -2289,8 +2287,7 @@
shouldListenForFingerprintAssistant,
mSwitchingUser,
isUdfps,
- userDoesNotHaveTrust,
- userNeedsStrongAuth));
+ userDoesNotHaveTrust));
}
return shouldListen;
@@ -2394,7 +2391,15 @@
|| (DEBUG_FINGERPRINT
&& model instanceof KeyguardFingerprintListenModel
&& mFingerprintRunningState != BIOMETRIC_STATE_RUNNING);
- if (notYetRunning && model.getListening()) {
+ final boolean running =
+ (DEBUG_FACE
+ && model instanceof KeyguardFaceListenModel
+ && mFaceRunningState == BIOMETRIC_STATE_RUNNING)
+ || (DEBUG_FINGERPRINT
+ && model instanceof KeyguardFingerprintListenModel
+ && mFingerprintRunningState == BIOMETRIC_STATE_RUNNING);
+ if (notYetRunning && model.getListening()
+ || running && !model.getListening()) {
mListenModels.add(model);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index e9c5653..2c0b526 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -496,6 +496,9 @@
lp.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS
| WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
+ // FLAG_SLIPPERY can only be set by trusted overlays
+ lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
+
if (!DEBUG_SCREENSHOT_ROUNDED_CORNERS) {
lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
index 37a6cfa..0a93298 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
@@ -330,7 +330,7 @@
|| mTestHarness
|| mDataProvider.isJustUnlockedWithFace()
|| mDataProvider.isDocked()
- || mAccessibilityManager.isEnabled();
+ || mAccessibilityManager.isTouchExplorationEnabled();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
index d3d6e03..6f30ac3 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
@@ -18,6 +18,7 @@
import android.annotation.MainThread
import android.app.Dialog
+import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
@@ -88,7 +89,7 @@
bouncerOrRun(createAction(cvh.cws.ci.controlId, {
cvh.layout.performHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK)
if (cvh.usePanel()) {
- showDetail(cvh, control.getAppIntent().getIntent())
+ showDetail(cvh, control.getAppIntent())
} else {
cvh.action(CommandAction(templateId))
}
@@ -116,7 +117,7 @@
// Long press snould only be called when there is valid control state, otherwise ignore
cvh.cws.control?.let {
cvh.layout.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
- showDetail(cvh, it.getAppIntent().getIntent())
+ showDetail(cvh, it.getAppIntent())
}
}, false /* blockable */))
}
@@ -167,10 +168,10 @@
bgExecutor.execute { vibrator.vibrate(effect) }
}
- private fun showDetail(cvh: ControlViewHolder, intent: Intent) {
+ private fun showDetail(cvh: ControlViewHolder, pendingIntent: PendingIntent) {
bgExecutor.execute {
val activities: List<ResolveInfo> = context.packageManager.queryIntentActivities(
- intent,
+ pendingIntent.getIntent(),
PackageManager.MATCH_DEFAULT_ONLY
)
@@ -178,7 +179,7 @@
// make sure the intent is valid before attempting to open the dialog
if (activities.isNotEmpty() && taskViewFactory.isPresent) {
taskViewFactory.get().create(context, uiExecutor, {
- dialog = DetailDialog(activityContext, it, intent, cvh).also {
+ dialog = DetailDialog(activityContext, it, pendingIntent, cvh).also {
it.setOnDismissListener { _ -> dialog = null }
it.show()
}
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 8a47a36..4758ab0 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
@@ -43,7 +43,7 @@
class DetailDialog(
val activityContext: Context?,
val taskView: TaskView,
- val intent: Intent,
+ val pendingIntent: PendingIntent,
val cvh: ControlViewHolder
) : Dialog(
activityContext ?: cvh.context,
@@ -59,6 +59,14 @@
var detailTaskId = INVALID_TASK_ID
+ private val fillInIntent = Intent().apply {
+ putExtra(EXTRA_USE_PANEL, true)
+
+ // Apply flags to make behaviour match documentLaunchMode=always.
+ addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT)
+ addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
+ }
+
fun removeDetailTask() {
if (detailTaskId == INVALID_TASK_ID) return
ActivityTaskManager.getInstance().removeTask(detailTaskId)
@@ -67,13 +75,6 @@
val stateCallback = object : TaskView.Listener {
override fun onInitialized() {
- val launchIntent = Intent(intent)
- launchIntent.putExtra(EXTRA_USE_PANEL, true)
-
- // Apply flags to make behaviour match documentLaunchMode=always.
- launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT)
- launchIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
-
val options = activityContext?.let {
ActivityOptions.makeCustomAnimation(
it,
@@ -82,9 +83,8 @@
)
} ?: ActivityOptions.makeBasic()
taskView.startActivity(
- PendingIntent.getActivity(context, 0, launchIntent,
- PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE),
- null /* fillInIntent */,
+ pendingIntent,
+ fillInIntent,
options,
getTaskViewBounds()
)
@@ -97,6 +97,9 @@
override fun onTaskCreated(taskId: Int, name: ComponentName?) {
detailTaskId = taskId
+ requireViewById<ViewGroup>(R.id.controls_activity_view).apply {
+ setAlpha(1f)
+ }
}
override fun onReleased() {
@@ -121,6 +124,7 @@
requireViewById<ViewGroup>(R.id.controls_activity_view).apply {
addView(taskView)
+ setAlpha(0f)
}
requireViewById<ImageView>(R.id.control_detail_close).apply {
@@ -134,7 +138,7 @@
removeDetailTask()
dismiss()
context.sendBroadcast(Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS))
- v.context.startActivity(intent)
+ pendingIntent.send()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
index b2def7a..802e5eb 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -75,6 +75,7 @@
private final ActivityStarter mActivityStarter;
private final List<MediaDevice> mGroupMediaDevices = new CopyOnWriteArrayList<>();
private final boolean mAboveStatusbar;
+ private final boolean mVolumeAdjustmentForRemoteGroupSessions;
private final NotificationEntryManager mNotificationEntryManager;
@VisibleForTesting
final List<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>();
@@ -104,6 +105,8 @@
mLocalMediaManager = new LocalMediaManager(mContext, lbm, imm, packageName);
mMetricLogger = new MediaOutputMetricLogger(mContext, mPackageName);
mUiEventLogger = uiEventLogger;
+ mVolumeAdjustmentForRemoteGroupSessions = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_volumeAdjustmentForRemoteGroupSessions);
}
void start(@NonNull Callback cb) {
@@ -466,7 +469,9 @@
}
boolean isVolumeControlEnabled(@NonNull MediaDevice device) {
- return !isActiveRemoteDevice(device);
+ // TODO(b/202500642): Also enable volume control for remote non-group sessions.
+ return !isActiveRemoteDevice(device)
+ || mVolumeAdjustmentForRemoteGroupSessions;
}
private final MediaController.Callback mCb = new MediaController.Callback() {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
index 70c21e4..2c6e77c 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
@@ -108,6 +108,7 @@
private final int mNavColorSampleMargin;
private final SysUiState mSysUiFlagContainer;
+ // The current view is one of mHorizontal or mVertical depending on the current configuration
View mCurrentView = null;
private View mVertical;
private View mHorizontal;
@@ -370,12 +371,6 @@
}
}
- @Override
- protected boolean onSetAlpha(int alpha) {
- Log.e(TAG, "onSetAlpha", new Throwable());
- return super.onSetAlpha(alpha);
- }
-
public void setAutoHideController(AutoHideController autoHideController) {
mAutoHideController = autoHideController;
}
@@ -474,6 +469,18 @@
return mCurrentView;
}
+ /**
+ * Applies {@param consumer} to each of the nav bar views.
+ */
+ public void forEachView(Consumer<View> consumer) {
+ if (mVertical != null) {
+ consumer.accept(mVertical);
+ }
+ if (mHorizontal != null) {
+ consumer.accept(mHorizontal);
+ }
+ }
+
public RotationButtonController getRotationButtonController() {
return mRotationButtonController;
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
index dae357e..d0271f7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
@@ -66,11 +66,13 @@
import com.android.systemui.R;
import com.android.systemui.accessibility.floatingmenu.AnnotationLinkSpan;
import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.wifitrackerlib.WifiEntry;
import java.util.List;
+import java.util.concurrent.Executor;
/**
* Dialog for showing mobile network, connected Wi-Fi network and Wi-Fi networks.
@@ -84,6 +86,7 @@
static final long PROGRESS_DELAY_MS = 2000L;
private final Handler mHandler;
+ private final Executor mBackgroundExecutor;
private final LinearLayoutManager mLayoutManager;
@VisibleForTesting
@@ -158,13 +161,14 @@
public InternetDialog(Context context, InternetDialogFactory internetDialogFactory,
InternetDialogController internetDialogController, boolean canConfigMobileData,
boolean canConfigWifi, boolean aboveStatusBar, UiEventLogger uiEventLogger,
- @Main Handler handler) {
+ @Main Handler handler, @Background Executor executor) {
super(context, R.style.Theme_SystemUI_Dialog_Internet);
if (DEBUG) {
Log.d(TAG, "Init InternetDialog");
}
mContext = context;
mHandler = handler;
+ mBackgroundExecutor = executor;
mInternetDialogFactory = internetDialogFactory;
mInternetDialogController = internetDialogController;
mSubscriptionManager = mInternetDialogController.getSubscriptionManager();
@@ -299,7 +303,13 @@
dismiss();
}
- void updateDialog() {
+ /**
+ * Update the internet dialog when receiving the callback.
+ *
+ * @param shouldUpdateMobileNetwork {@code true} for update the mobile network layout,
+ * otherwise {@code false}.
+ */
+ void updateDialog(boolean shouldUpdateMobileNetwork) {
if (DEBUG) {
Log.d(TAG, "updateDialog");
}
@@ -309,8 +319,10 @@
mInternetDialogSubTitle.setText(getSubtitleText());
}
updateEthernet();
- setMobileDataLayout(mInternetDialogController.activeNetworkIsCellular()
- || mInternetDialogController.isCarrierNetworkActive());
+ if (shouldUpdateMobileNetwork) {
+ setMobileDataLayout(mInternetDialogController.activeNetworkIsCellular()
+ || mInternetDialogController.isCarrierNetworkActive());
+ }
if (!mCanConfigWifi) {
return;
@@ -319,7 +331,7 @@
showProgressBar();
final boolean isDeviceLocked = mInternetDialogController.isDeviceLocked();
final boolean isWifiEnabled = mWifiManager.isWifiEnabled();
- final boolean isWifiScanEnabled = mWifiManager.isScanAlwaysAvailable();
+ final boolean isWifiScanEnabled = mInternetDialogController.isWifiScanEnabled();
updateWifiToggle(isWifiEnabled, isDeviceLocked);
updateConnectedWifi(isWifiEnabled, isDeviceLocked);
updateWifiScanNotify(isWifiEnabled, isWifiScanEnabled, isDeviceLocked);
@@ -379,7 +391,13 @@
} else {
mMobileSummaryText.setVisibility(View.GONE);
}
- mSignalIcon.setImageDrawable(getSignalStrengthDrawable());
+
+ mBackgroundExecutor.execute(() -> {
+ Drawable drawable = getSignalStrengthDrawable();
+ mHandler.post(() -> {
+ mSignalIcon.setImageDrawable(drawable);
+ });
+ });
mMobileTitleText.setTextAppearance(isCarrierNetworkConnected
? R.style.TextAppearance_InternetDialog_Active
: R.style.TextAppearance_InternetDialog);
@@ -534,52 +552,57 @@
@Override
public void onRefreshCarrierInfo() {
- mHandler.post(() -> updateDialog());
+ mHandler.post(() -> updateDialog(true /* shouldUpdateMobileNetwork */));
}
@Override
public void onSimStateChanged() {
- mHandler.post(() -> updateDialog());
+ mHandler.post(() -> updateDialog(true /* shouldUpdateMobileNetwork */));
}
@Override
@WorkerThread
public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
- mHandler.post(() -> updateDialog());
+ mHandler.post(() -> updateDialog(true /* shouldUpdateMobileNetwork */));
}
@Override
@WorkerThread
public void onLost(Network network) {
- mHandler.post(() -> updateDialog());
+ mHandler.post(() -> updateDialog(true /* shouldUpdateMobileNetwork */));
}
@Override
public void onSubscriptionsChanged(int defaultDataSubId) {
mDefaultDataSubId = defaultDataSubId;
mTelephonyManager = mTelephonyManager.createForSubscriptionId(mDefaultDataSubId);
- mHandler.post(() -> updateDialog());
+ mHandler.post(() -> updateDialog(true /* shouldUpdateMobileNetwork */));
+ }
+
+ @Override
+ public void onUserMobileDataStateChanged(boolean enabled) {
+ mHandler.post(() -> updateDialog(true /* shouldUpdateMobileNetwork */));
}
@Override
public void onServiceStateChanged(ServiceState serviceState) {
- mHandler.post(() -> updateDialog());
+ mHandler.post(() -> updateDialog(true /* shouldUpdateMobileNetwork */));
}
@Override
@WorkerThread
public void onDataConnectionStateChanged(int state, int networkType) {
- mHandler.post(() -> updateDialog());
+ mHandler.post(() -> updateDialog(true /* shouldUpdateMobileNetwork */));
}
@Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
- mHandler.post(() -> updateDialog());
+ mHandler.post(() -> updateDialog(true /* shouldUpdateMobileNetwork */));
}
@Override
public void onDisplayInfoChanged(TelephonyDisplayInfo telephonyDisplayInfo) {
- mHandler.post(() -> updateDialog());
+ mHandler.post(() -> updateDialog(true /* shouldUpdateMobileNetwork */));
}
@Override
@@ -591,7 +614,7 @@
mAdapter.setWifiEntries(wifiEntries, mWifiEntriesCount);
mHandler.post(() -> {
mAdapter.notifyDataSetChanged();
- updateDialog();
+ updateDialog(false /* shouldUpdateMobileNetwork */);
});
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
index 276c0be..67e3411 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
@@ -76,6 +76,7 @@
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.statusbar.policy.LocationController;
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.NetworkController.AccessPointController;
import com.android.systemui.toast.SystemUIToast;
@@ -149,6 +150,8 @@
private ConnectivityManager.NetworkCallback mConnectivityManagerNetworkCallback;
private WindowManager mWindowManager;
private ToastFactory mToastFactory;
+ private SignalDrawable mSignalDrawable;
+ private LocationController mLocationController;
@VisibleForTesting
static final float TOAST_PARAMS_HORIZONTAL_WEIGHT = 1.0f;
@@ -198,7 +201,8 @@
GlobalSettings globalSettings, KeyguardStateController keyguardStateController,
WindowManager windowManager, ToastFactory toastFactory,
@Background Handler workerHandler,
- CarrierConfigTracker carrierConfigTracker) {
+ CarrierConfigTracker carrierConfigTracker,
+ LocationController locationController) {
if (DEBUG) {
Log.d(TAG, "Init InternetDialogController");
}
@@ -225,6 +229,8 @@
mConnectivityManagerNetworkCallback = new DataConnectivityListener();
mWindowManager = windowManager;
mToastFactory = toastFactory;
+ mSignalDrawable = new SignalDrawable(mContext);
+ mLocationController = locationController;
}
void onStart(@NonNull InternetDialogCallback callback, boolean canConfigWifi) {
@@ -431,10 +437,7 @@
Drawable getSignalStrengthIcon(Context context, int level, int numLevels,
int iconType, boolean cutOut) {
- Log.d(TAG, "getSignalStrengthIcon");
- final SignalDrawable signalDrawable = new SignalDrawable(context);
- signalDrawable.setLevel(
- SignalDrawable.getState(level, numLevels, cutOut));
+ mSignalDrawable.setLevel(SignalDrawable.getState(level, numLevels, cutOut));
// Make the network type drawable
final Drawable networkDrawable =
@@ -443,7 +446,7 @@
: context.getResources().getDrawable(iconType, context.getTheme());
// Overlay the two drawables
- final Drawable[] layers = {networkDrawable, signalDrawable};
+ final Drawable[] layers = {networkDrawable, mSignalDrawable};
final int iconSize =
context.getResources().getDimensionPixelSize(R.dimen.signal_strength_icon_size);
@@ -789,6 +792,14 @@
return false;
}
+ @WorkerThread
+ boolean isWifiScanEnabled() {
+ if (!mLocationController.isLocationEnabled()) {
+ return false;
+ }
+ return mWifiManager.isScanAlwaysAvailable();
+ }
+
static class WifiEntryConnectCallback implements WifiEntry.ConnectCallback {
final ActivityStarter mActivityStarter;
final WifiEntry mWifiEntry;
@@ -892,7 +903,8 @@
TelephonyCallback.DataConnectionStateListener,
TelephonyCallback.DisplayInfoListener,
TelephonyCallback.ServiceStateListener,
- TelephonyCallback.SignalStrengthsListener {
+ TelephonyCallback.SignalStrengthsListener,
+ TelephonyCallback.UserMobileDataStateListener {
@Override
public void onServiceStateChanged(@NonNull ServiceState serviceState) {
@@ -914,6 +926,11 @@
mTelephonyDisplayInfo = telephonyDisplayInfo;
mCallback.onDisplayInfoChanged(telephonyDisplayInfo);
}
+
+ @Override
+ public void onUserMobileDataStateChanged(boolean enabled) {
+ mCallback.onUserMobileDataStateChanged(enabled);
+ }
}
private class InternetOnSubscriptionChangedListener
@@ -1018,6 +1035,8 @@
void onSignalStrengthsChanged(SignalStrength signalStrength);
+ void onUserMobileDataStateChanged(boolean enabled);
+
void onDisplayInfoChanged(TelephonyDisplayInfo telephonyDisplayInfo);
void dismissDialog();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogFactory.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogFactory.kt
index 11c6980..ea5df17 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogFactory.kt
@@ -20,7 +20,9 @@
import android.util.Log
import com.android.internal.logging.UiEventLogger
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main
+import java.util.concurrent.Executor
import javax.inject.Inject
private const val TAG = "InternetDialogFactory"
@@ -32,6 +34,7 @@
@SysUISingleton
class InternetDialogFactory @Inject constructor(
@Main private val handler: Handler,
+ @Background private val executor: Executor,
private val internetDialogController: InternetDialogController,
private val context: Context,
private val uiEventLogger: UiEventLogger
@@ -49,7 +52,8 @@
return
} else {
internetDialog = InternetDialog(context, this, internetDialogController,
- canConfigMobileData, canConfigWifi, aboveStatusBar, uiEventLogger, handler)
+ canConfigMobileData, canConfigWifi, aboveStatusBar, uiEventLogger, handler,
+ executor)
internetDialog?.show()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseDialog.kt b/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseDialog.kt
index c50365f..71c5fad 100644
--- a/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseDialog.kt
@@ -15,7 +15,8 @@
class SensorUseDialog(
context: Context,
val sensor: Int,
- val clickListener: DialogInterface.OnClickListener
+ val clickListener: DialogInterface.OnClickListener,
+ val dismissListener: DialogInterface.OnDismissListener
) : SystemUIDialog(context) {
// TODO move to onCreate (b/200815309)
@@ -69,6 +70,8 @@
context.getString(com.android.internal.R.string
.cancel), clickListener)
+ setOnDismissListener(dismissListener)
+
setCancelable(false)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt b/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt
index b0071d9..dae375a 100644
--- a/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt
@@ -50,7 +50,7 @@
private val keyguardStateController: KeyguardStateController,
private val keyguardDismissUtil: KeyguardDismissUtil,
@Background private val bgHandler: Handler
-) : Activity(), DialogInterface.OnClickListener {
+) : Activity(), DialogInterface.OnClickListener, DialogInterface.OnDismissListener {
companion object {
private val LOG_TAG = SensorUseStartedActivity::class.java.simpleName
@@ -120,7 +120,7 @@
}
}
- mDialog = SensorUseDialog(this, sensor, this)
+ mDialog = SensorUseDialog(this, sensor, this, this)
mDialog!!.show()
}
@@ -212,4 +212,8 @@
.suppressSensorPrivacyReminders(sensor, suppressed)
}
}
+
+ override fun onDismiss(dialog: DialogInterface?) {
+ finish()
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
index 2c76cfe..67f51cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
@@ -485,7 +485,7 @@
private void showBouncer() {
if (mMode == MODE_SHOW_BOUNCER) {
- mKeyguardViewController.showBouncer(false);
+ mKeyguardViewController.showBouncer(true);
}
mShadeController.animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, true /* force */,
false /* delayed */, BIOMETRIC_COLLAPSE_SPEEDUP_FACTOR);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 1e3e47b..e5119fe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -552,12 +552,13 @@
public void onStartedWakingUp() {
mStatusBar.getNotificationShadeWindowView().getWindowInsetsController()
.setAnimationsDisabled(false);
- View currentView = getCurrentNavBarView();
- if (currentView != null) {
- currentView.animate()
- .alpha(1f)
- .setDuration(NAV_BAR_CONTENT_FADE_DURATION)
- .start();
+ NavigationBarView navBarView = mStatusBar.getNavigationBarView();
+ if (navBarView != null) {
+ navBarView.forEachView(view ->
+ view.animate()
+ .alpha(1f)
+ .setDuration(NAV_BAR_CONTENT_FADE_DURATION)
+ .start());
}
}
@@ -565,12 +566,13 @@
public void onStartedGoingToSleep() {
mStatusBar.getNotificationShadeWindowView().getWindowInsetsController()
.setAnimationsDisabled(true);
- View currentView = getCurrentNavBarView();
- if (currentView != null) {
- currentView.animate()
- .alpha(0f)
- .setDuration(NAV_BAR_CONTENT_FADE_DURATION)
- .start();
+ NavigationBarView navBarView = mStatusBar.getNavigationBarView();
+ if (navBarView != null) {
+ navBarView.forEachView(view ->
+ view.animate()
+ .alpha(0f)
+ .setDuration(NAV_BAR_CONTENT_FADE_DURATION)
+ .start());
}
}
@@ -899,7 +901,7 @@
@Override
public boolean bouncerIsOrWillBeShowing() {
- return mBouncer.isShowing() || mBouncer.getShowingSoon();
+ return isBouncerShowing() || mBouncer.getShowingSoon();
}
public boolean isFullscreenBouncer() {
@@ -996,17 +998,6 @@
mStatusBar.onKeyguardViewManagerStatesUpdated();
}
- /**
- * Updates the visibility of the nav bar content views.
- */
- private void updateNavigationBarContentVisibility(boolean navBarContentVisible) {
- final NavigationBarView navBarView = mStatusBar.getNavigationBarView();
- if (navBarView != null && navBarView.getCurrentView() != null) {
- final View currentView = navBarView.getCurrentView();
- currentView.setVisibility(navBarContentVisible ? View.VISIBLE : View.INVISIBLE);
- }
- }
-
private View getCurrentNavBarView() {
final NavigationBarView navBarView = mStatusBar.getNavigationBarView();
return navBarView != null ? navBarView.getCurrentView() : null;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
index 143aaba..e3f4b03 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
@@ -145,22 +145,27 @@
.setDuration(duration.toLong())
.setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
.alpha(1f)
- .withEndAction {
- aodUiAnimationPlaying = false
+ .setListener(object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animation: Animator?) {
+ aodUiAnimationPlaying = false
- // Lock the keyguard if it was waiting for the screen off animation to end.
- keyguardViewMediatorLazy.get().maybeHandlePendingLock()
+ // Lock the keyguard if it was waiting for the screen off animation to end.
+ keyguardViewMediatorLazy.get().maybeHandlePendingLock()
- // Tell the StatusBar to become keyguard for real - we waited on that since it
- // is slow and would have caused the animation to jank.
- statusBar.updateIsKeyguard()
+ // Tell the StatusBar to become keyguard for real - we waited on that since
+ // it is slow and would have caused the animation to jank.
+ statusBar.updateIsKeyguard()
- // Run the callback given to us by the KeyguardVisibilityHelper.
- after.run()
+ // Run the callback given to us by the KeyguardVisibilityHelper.
+ after.run()
- // Done going to sleep, reset this flag.
- decidedToAnimateGoingToSleep = null
- }
+ // Done going to sleep, reset this flag.
+ decidedToAnimateGoingToSleep = null
+
+ // We need to unset the listener. These are persistent for future animators
+ keyguardView.animate().setListener(null)
+ }
+ })
.start()
}
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
index 81999b5..f5bedf1 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
@@ -253,8 +253,13 @@
if (DEBUG) Log.d(TAG, "Updating overlays for user switch / profile added.");
reevaluateSystemTheme(true /* forceReload */);
} else if (Intent.ACTION_WALLPAPER_CHANGED.equals(intent.getAction())) {
- mAcceptColorEvents = true;
- Log.i(TAG, "Allowing color events again");
+ if (intent.getBooleanExtra(WallpaperManager.EXTRA_FROM_FOREGROUND_APP, false)) {
+ mAcceptColorEvents = true;
+ Log.i(TAG, "Wallpaper changed, allowing color events again");
+ } else {
+ Log.i(TAG, "Wallpaper changed from background app, "
+ + "keep deferring color events. Accepting: " + mAcceptColorEvents);
+ }
}
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index e570598..cd6a778 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -33,7 +33,11 @@
import android.media.AudioSystem;
import android.media.IAudioService;
import android.media.IVolumeController;
+import android.media.MediaRoute2Info;
+import android.media.MediaRouter2Manager;
+import android.media.RoutingSessionInfo;
import android.media.VolumePolicy;
+import android.media.session.MediaController;
import android.media.session.MediaController.PlaybackInfo;
import android.media.session.MediaSession.Token;
import android.net.Uri;
@@ -71,6 +75,7 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
@@ -118,6 +123,7 @@
private final Context mContext;
private final Looper mWorkerLooper;
private final PackageManager mPackageManager;
+ private final MediaRouter2Manager mRouter2Manager;
private final WakefulnessLifecycle mWakefulnessLifecycle;
private AudioManager mAudio;
private IAudioService mAudioService;
@@ -179,6 +185,7 @@
mWorkerLooper = theadFactory.buildLooperOnNewThread(
VolumeDialogControllerImpl.class.getSimpleName());
mWorker = new W(mWorkerLooper);
+ mRouter2Manager = MediaRouter2Manager.getInstance(mContext);
mMediaSessionsCallbacksW = new MediaSessionsCallbacks(mContext);
mMediaSessions = createMediaSessions(mContext, mWorkerLooper, mMediaSessionsCallbacksW);
mAudio = audioManager;
@@ -1149,16 +1156,16 @@
private final HashMap<Token, Integer> mRemoteStreams = new HashMap<>();
private int mNextStream = DYNAMIC_STREAM_START_INDEX;
- private final boolean mShowRemoteSessions;
+ private final boolean mVolumeAdjustmentForRemoteGroupSessions;
public MediaSessionsCallbacks(Context context) {
- mShowRemoteSessions = context.getResources().getBoolean(
- com.android.internal.R.bool.config_volumeShowRemoteSessions);
+ mVolumeAdjustmentForRemoteGroupSessions = context.getResources().getBoolean(
+ com.android.internal.R.bool.config_volumeAdjustmentForRemoteGroupSessions);
}
@Override
public void onRemoteUpdate(Token token, String name, PlaybackInfo pi) {
- if (mShowRemoteSessions) {
+ if (showForSession(token)) {
addStream(token, "onRemoteUpdate");
int stream = 0;
@@ -1190,7 +1197,7 @@
@Override
public void onRemoteVolumeChanged(Token token, int flags) {
- if (mShowRemoteSessions) {
+ if (showForSession(token)) {
addStream(token, "onRemoteVolumeChanged");
int stream = 0;
synchronized (mRemoteStreams) {
@@ -1214,7 +1221,7 @@
@Override
public void onRemoteRemoved(Token token) {
- if (mShowRemoteSessions) {
+ if (showForSession(token)) {
int stream = 0;
synchronized (mRemoteStreams) {
if (!mRemoteStreams.containsKey(token)) {
@@ -1233,14 +1240,41 @@
}
public void setStreamVolume(int stream, int level) {
- if (mShowRemoteSessions) {
- final Token t = findToken(stream);
- if (t == null) {
- Log.w(TAG, "setStreamVolume: No token found for stream: " + stream);
- return;
- }
- mMediaSessions.setVolume(t, level);
+ final Token token = findToken(stream);
+ if (token == null) {
+ Log.w(TAG, "setStreamVolume: No token found for stream: " + stream);
+ return;
}
+ if (showForSession(token)) {
+ mMediaSessions.setVolume(token, level);
+ }
+ }
+
+ private boolean showForSession(Token token) {
+ if (mVolumeAdjustmentForRemoteGroupSessions) {
+ return true;
+ }
+ MediaController ctr = new MediaController(mContext, token);
+ String packageName = ctr.getPackageName();
+ List<RoutingSessionInfo> sessions =
+ mRouter2Manager.getRoutingSessions(packageName);
+ boolean foundNonSystemSession = false;
+ boolean isGroup = false;
+ for (RoutingSessionInfo session : sessions) {
+ if (!session.isSystemSession()) {
+ foundNonSystemSession = true;
+ int selectedRouteCount = session.getSelectedRoutes().size();
+ if (selectedRouteCount > 1) {
+ isGroup = true;
+ break;
+ }
+ }
+ }
+ if (!foundNonSystemSession) {
+ Log.d(TAG, "No routing session for " + packageName);
+ return false;
+ }
+ return !isGroup;
}
private Token findToken(int stream) {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt
index db87c5d..4bdab76 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt
@@ -75,8 +75,7 @@
shouldListenForFingerprintAssistant = false,
switchingUser = false,
udfps = false,
- userDoesNotHaveTrust = false,
- userNeedsStrongAuth = false
+ userDoesNotHaveTrust = false
)
private fun faceModel(user: Int) = KeyguardFaceListenModel(
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index ec4dfba..185a291 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -19,6 +19,7 @@
import static android.telephony.SubscriptionManager.DATA_ROAMING_DISABLE;
import static android.telephony.SubscriptionManager.NAME_SOURCE_CARRIER_ID;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;
import static com.google.common.truth.Truth.assertThat;
@@ -931,6 +932,19 @@
}
@Test
+ public void testStartUdfpsServiceStrongAuthRequiredAfterTimeout() {
+ // GIVEN status bar state is on the keyguard
+ mStatusBarStateListener.onStateChanged(StatusBarState.KEYGUARD);
+
+ // WHEN user loses smart unlock trust
+ when(mStrongAuthTracker.getStrongAuthForUser(KeyguardUpdateMonitor.getCurrentUser()))
+ .thenReturn(SOME_AUTH_REQUIRED_AFTER_USER_REQUEST);
+
+ // THEN we should still listen for udfps
+ assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(true)).isEqualTo(true);
+ }
+
+ @Test
public void testShouldNotListenForUdfps_whenTrustEnabled() {
// GIVEN a "we should listen for udfps" state
mStatusBarStateListener.onStateChanged(StatusBarState.KEYGUARD);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java
index c4f480d..55ee433 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java
@@ -91,7 +91,7 @@
@Test
public void testA11yDisablesGesture() {
assertThat(mBrightLineFalsingManager.isFalseTap(1)).isTrue();
- when(mAccessibilityManager.isEnabled()).thenReturn(true);
+ when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true);
assertThat(mBrightLineFalsingManager.isFalseTap(1)).isFalse();
}
@@ -99,7 +99,7 @@
@Test
public void testA11yDisablesTap() {
assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isTrue();
- when(mAccessibilityManager.isEnabled()).thenReturn(true);
+ when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true);
assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isFalse();
}
@@ -107,7 +107,7 @@
@Test
public void testA11yDisablesDoubleTap() {
assertThat(mBrightLineFalsingManager.isFalseDoubleTap()).isTrue();
- when(mAccessibilityManager.isEnabled()).thenReturn(true);
+ when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true);
assertThat(mBrightLineFalsingManager.isFalseDoubleTap()).isFalse();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/DetailDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/DetailDialogTest.kt
new file mode 100644
index 0000000..87b9172
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/DetailDialogTest.kt
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.controls.ui
+
+import android.app.PendingIntent
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.wm.shell.TaskView
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.Mock
+import org.mockito.Mockito.any
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
+class DetailDialogTest : SysuiTestCase() {
+
+ @Mock
+ private lateinit var taskView: TaskView
+ @Mock
+ private lateinit var controlViewHolder: ControlViewHolder
+ @Mock
+ private lateinit var pendingIntent: PendingIntent
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ }
+
+ @Test
+ fun testPendingIntentIsUnModified() {
+ // GIVEN the dialog is created with a PendingIntent
+ val dialog = createDialog(pendingIntent)
+
+ // WHEN the TaskView is initialized
+ dialog.stateCallback.onInitialized()
+
+ // THEN the PendingIntent used to call startActivity is unmodified by systemui
+ verify(taskView).startActivity(eq(pendingIntent), any(), any(), any())
+ }
+
+ private fun createDialog(pendingIntent: PendingIntent): DetailDialog {
+ return DetailDialog(
+ mContext,
+ taskView,
+ pendingIntent,
+ controlViewHolder
+ )
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java
index f9d5be6..663edc7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java
@@ -49,6 +49,7 @@
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.statusbar.policy.LocationController;
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.NetworkController.AccessPointController;
import com.android.systemui.toast.SystemUIToast;
@@ -135,6 +136,8 @@
private Animator mAnimator;
@Mock
private CarrierConfigTracker mCarrierConfigTracker;
+ @Mock
+ private LocationController mLocationController;
private TestableResources mTestableResources;
private MockInternetDialogController mInternetDialogController;
@@ -170,7 +173,8 @@
mSubscriptionManager, mTelephonyManager, mWifiManager,
mock(ConnectivityManager.class), mHandler, mExecutor, mBroadcastDispatcher,
mock(KeyguardUpdateMonitor.class), mGlobalSettings, mKeyguardStateController,
- mWindowManager, mToastFactory, mWorkerHandler, mCarrierConfigTracker);
+ mWindowManager, mToastFactory, mWorkerHandler, mCarrierConfigTracker,
+ mLocationController);
mSubscriptionManager.addOnSubscriptionsChangedListener(mExecutor,
mInternetDialogController.mOnSubscriptionsChangedListener);
mInternetDialogController.onStart(mInternetDialogCallback, true);
@@ -602,6 +606,30 @@
verify(mMergedCarrierEntry).setEnabled(false);
}
+ @Test
+ public void isWifiScanEnabled_locationOff_returnFalse() {
+ when(mLocationController.isLocationEnabled()).thenReturn(false);
+ when(mWifiManager.isScanAlwaysAvailable()).thenReturn(false);
+
+ assertThat(mInternetDialogController.isWifiScanEnabled()).isFalse();
+
+ when(mWifiManager.isScanAlwaysAvailable()).thenReturn(true);
+
+ assertThat(mInternetDialogController.isWifiScanEnabled()).isFalse();
+ }
+
+ @Test
+ public void isWifiScanEnabled_locationOn_returnIsScanAlwaysAvailable() {
+ when(mLocationController.isLocationEnabled()).thenReturn(true);
+ when(mWifiManager.isScanAlwaysAvailable()).thenReturn(false);
+
+ assertThat(mInternetDialogController.isWifiScanEnabled()).isFalse();
+
+ when(mWifiManager.isScanAlwaysAvailable()).thenReturn(true);
+
+ assertThat(mInternetDialogController.isWifiScanEnabled()).isTrue();
+ }
+
private String getResourcesString(String name) {
return mContext.getResources().getString(getResourcesId(name));
}
@@ -625,12 +653,13 @@
KeyguardUpdateMonitor keyguardUpdateMonitor, GlobalSettings globalSettings,
KeyguardStateController keyguardStateController, WindowManager windowManager,
ToastFactory toastFactory, Handler workerHandler,
- CarrierConfigTracker carrierConfigTracker) {
+ CarrierConfigTracker carrierConfigTracker,
+ LocationController locationController) {
super(context, uiEventLogger, starter, accessPointController, subscriptionManager,
telephonyManager, wifiManager, connectivityManager, handler, mainExecutor,
broadcastDispatcher, keyguardUpdateMonitor, globalSettings,
keyguardStateController, windowManager, toastFactory, workerHandler,
- carrierConfigTracker);
+ carrierConfigTracker, locationController);
mGlobalSettings = globalSettings;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java
index 7cea430..5e1fea5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java
@@ -27,6 +27,8 @@
import com.android.internal.logging.UiEventLogger;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.time.FakeSystemClock;
import com.android.wifitrackerlib.WifiEntry;
import org.junit.After;
@@ -65,6 +67,7 @@
@Mock
private InternetDialogController mInternetDialogController;
+ private FakeExecutor mBgExecutor = new FakeExecutor(new FakeSystemClock());
private InternetDialog mInternetDialog;
private View mDialogView;
private View mSubTitle;
@@ -93,7 +96,8 @@
when(mInternetDialogController.getWifiManager()).thenReturn(mWifiManager);
mInternetDialog = new InternetDialog(mContext, mock(InternetDialogFactory.class),
- mInternetDialogController, true, true, true, mock(UiEventLogger.class), mHandler);
+ mInternetDialogController, true, true, true, mock(UiEventLogger.class), mHandler,
+ mBgExecutor);
mInternetDialog.mAdapter = mInternetAdapter;
mInternetDialog.onAccessPointsChanged(mWifiEntries, mInternetWifiEntry);
mInternetDialog.show();
@@ -129,7 +133,7 @@
public void updateDialog_withApmOn_internetDialogSubTitleGone() {
when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(true);
- mInternetDialog.updateDialog();
+ mInternetDialog.updateDialog(true);
assertThat(mSubTitle.getVisibility()).isEqualTo(View.GONE);
}
@@ -138,7 +142,7 @@
public void updateDialog_withApmOff_internetDialogSubTitleVisible() {
when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(false);
- mInternetDialog.updateDialog();
+ mInternetDialog.updateDialog(true);
assertThat(mSubTitle.getVisibility()).isEqualTo(View.VISIBLE);
}
@@ -148,7 +152,7 @@
when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(false);
when(mInternetDialogController.hasEthernet()).thenReturn(true);
- mInternetDialog.updateDialog();
+ mInternetDialog.updateDialog(true);
assertThat(mEthernet.getVisibility()).isEqualTo(View.VISIBLE);
}
@@ -158,7 +162,7 @@
when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(false);
when(mInternetDialogController.hasEthernet()).thenReturn(false);
- mInternetDialog.updateDialog();
+ mInternetDialog.updateDialog(true);
assertThat(mEthernet.getVisibility()).isEqualTo(View.GONE);
}
@@ -168,7 +172,7 @@
when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(true);
when(mInternetDialogController.hasEthernet()).thenReturn(true);
- mInternetDialog.updateDialog();
+ mInternetDialog.updateDialog(true);
assertThat(mEthernet.getVisibility()).isEqualTo(View.VISIBLE);
}
@@ -178,7 +182,7 @@
when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(true);
when(mInternetDialogController.hasEthernet()).thenReturn(false);
- mInternetDialog.updateDialog();
+ mInternetDialog.updateDialog(true);
assertThat(mEthernet.getVisibility()).isEqualTo(View.GONE);
}
@@ -187,7 +191,7 @@
public void updateDialog_withApmOn_mobileDataLayoutGone() {
when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(true);
- mInternetDialog.updateDialog();
+ mInternetDialog.updateDialog(true);
assertThat(mMobileDataToggle.getVisibility()).isEqualTo(View.GONE);
}
@@ -197,7 +201,7 @@
// The preconditions WiFi ON and Internet WiFi are already in setUp()
doReturn(false).when(mInternetDialogController).activeNetworkIsCellular();
- mInternetDialog.updateDialog();
+ mInternetDialog.updateDialog(false);
assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.VISIBLE);
}
@@ -208,7 +212,7 @@
mInternetDialog.onAccessPointsChanged(mWifiEntries, null /* connectedEntry*/);
doReturn(false).when(mInternetDialogController).activeNetworkIsCellular();
- mInternetDialog.updateDialog();
+ mInternetDialog.updateDialog(false);
assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.GONE);
}
@@ -218,7 +222,7 @@
// The precondition WiFi ON is already in setUp()
mInternetDialog.onAccessPointsChanged(null /* wifiEntries */, mInternetWifiEntry);
- mInternetDialog.updateDialog();
+ mInternetDialog.updateDialog(false);
assertThat(mWifiList.getVisibility()).isEqualTo(View.GONE);
assertThat(mSeeAll.getVisibility()).isEqualTo(View.GONE);
@@ -228,7 +232,7 @@
public void updateDialog_wifiOnAndHasWifiList_showWifiListAndSeeAll() {
// The preconditions WiFi ON and WiFi entries are already in setUp()
- mInternetDialog.updateDialog();
+ mInternetDialog.updateDialog(false);
assertThat(mWifiList.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(mSeeAll.getVisibility()).isEqualTo(View.VISIBLE);
@@ -239,7 +243,7 @@
// The preconditions WiFi ON and Internet WiFi are already in setUp()
when(mInternetDialogController.isDeviceLocked()).thenReturn(true);
- mInternetDialog.updateDialog();
+ mInternetDialog.updateDialog(false);
assertThat(mWifiToggle.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(mWifiToggle.getBackground()).isNotNull();
@@ -250,7 +254,7 @@
// The preconditions WiFi ON and Internet WiFi are already in setUp()
when(mInternetDialogController.isDeviceLocked()).thenReturn(true);
- mInternetDialog.updateDialog();
+ mInternetDialog.updateDialog(false);
assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.GONE);
}
@@ -260,7 +264,7 @@
// The preconditions WiFi entries are already in setUp()
when(mInternetDialogController.isDeviceLocked()).thenReturn(true);
- mInternetDialog.updateDialog();
+ mInternetDialog.updateDialog(false);
assertThat(mWifiList.getVisibility()).isEqualTo(View.GONE);
assertThat(mSeeAll.getVisibility()).isEqualTo(View.GONE);
@@ -270,7 +274,7 @@
public void updateDialog_wifiOn_hideWifiScanNotify() {
// The preconditions WiFi ON and Internet WiFi are already in setUp()
- mInternetDialog.updateDialog();
+ mInternetDialog.updateDialog(false);
assertThat(mWifiScanNotify.getVisibility()).isEqualTo(View.GONE);
}
@@ -278,9 +282,9 @@
@Test
public void updateDialog_wifiOffAndWifiScanOff_hideWifiScanNotify() {
when(mWifiManager.isWifiEnabled()).thenReturn(false);
- when(mWifiManager.isScanAlwaysAvailable()).thenReturn(false);
+ when(mInternetDialogController.isWifiScanEnabled()).thenReturn(false);
- mInternetDialog.updateDialog();
+ mInternetDialog.updateDialog(false);
assertThat(mWifiScanNotify.getVisibility()).isEqualTo(View.GONE);
}
@@ -288,10 +292,10 @@
@Test
public void updateDialog_wifiOffAndWifiScanOnAndDeviceLocked_hideWifiScanNotify() {
when(mWifiManager.isWifiEnabled()).thenReturn(false);
- when(mWifiManager.isScanAlwaysAvailable()).thenReturn(true);
+ when(mInternetDialogController.isWifiScanEnabled()).thenReturn(true);
when(mInternetDialogController.isDeviceLocked()).thenReturn(true);
- mInternetDialog.updateDialog();
+ mInternetDialog.updateDialog(false);
assertThat(mWifiScanNotify.getVisibility()).isEqualTo(View.GONE);
}
@@ -299,10 +303,10 @@
@Test
public void updateDialog_wifiOffAndWifiScanOnAndDeviceUnlocked_showWifiScanNotify() {
when(mWifiManager.isWifiEnabled()).thenReturn(false);
- when(mWifiManager.isScanAlwaysAvailable()).thenReturn(true);
+ when(mInternetDialogController.isWifiScanEnabled()).thenReturn(true);
when(mInternetDialogController.isDeviceLocked()).thenReturn(false);
- mInternetDialog.updateDialog();
+ mInternetDialog.updateDialog(false);
assertThat(mWifiScanNotify.getVisibility()).isEqualTo(View.VISIBLE);
TextView wifiScanNotifyText = mDialogView.requireViewById(R.id.wifi_scan_notify_text);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
index 4276f7c..25fd801 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
@@ -134,7 +134,7 @@
.thenReturn(false);
mBiometricUnlockController.onBiometricAuthenticated(UserHandle.USER_CURRENT,
BiometricSourceType.FINGERPRINT, true /* isStrongBiometric */);
- verify(mStatusBarKeyguardViewManager).showBouncer(eq(false));
+ verify(mStatusBarKeyguardViewManager).showBouncer(anyBoolean());
verify(mStatusBarKeyguardViewManager, never()).notifyKeyguardAuthenticated(anyBoolean());
assertThat(mBiometricUnlockController.getMode())
.isEqualTo(BiometricUnlockController.MODE_SHOW_BOUNCER);
@@ -146,7 +146,7 @@
.thenReturn(false);
mBiometricUnlockController.onBiometricAuthenticated(UserHandle.USER_CURRENT,
BiometricSourceType.FINGERPRINT, false /* isStrongBiometric */);
- verify(mStatusBarKeyguardViewManager).showBouncer(eq(false));
+ verify(mStatusBarKeyguardViewManager).showBouncer(anyBoolean());
verify(mShadeController).animateCollapsePanels(anyInt(), anyBoolean(), anyBoolean(),
anyFloat());
assertThat(mBiometricUnlockController.getMode())
@@ -265,10 +265,10 @@
BiometricSourceType.FACE, true /* isStrongBiometric */);
// Wake up before showing the bouncer
- verify(mStatusBarKeyguardViewManager, never()).showBouncer(eq(false));
+ verify(mStatusBarKeyguardViewManager, never()).showBouncer(anyBoolean());
mBiometricUnlockController.mWakefulnessObserver.onFinishedWakingUp();
- verify(mStatusBarKeyguardViewManager).showBouncer(eq(false));
+ verify(mStatusBarKeyguardViewManager).showBouncer(anyBoolean());
assertThat(mBiometricUnlockController.getMode())
.isEqualTo(BiometricUnlockController.MODE_SHOW_BOUNCER);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index 2b569f3..5ed6985 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -102,6 +102,8 @@
@Mock
private UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
@Mock
+ private StatusBarKeyguardViewManager.AlternateAuthInterceptor mAlternateAuthInterceptor;
+ @Mock
private KeyguardMessageArea mKeyguardMessageArea;
private WakefulnessLifecycle mWakefulnessLifecycle;
@@ -287,6 +289,24 @@
}
@Test
+ public void testShowing_whenAlternateAuthShowing() {
+ mStatusBarKeyguardViewManager.setAlternateAuthInterceptor(mAlternateAuthInterceptor);
+ when(mBouncer.isShowing()).thenReturn(false);
+ when(mAlternateAuthInterceptor.isShowingAlternateAuthBouncer()).thenReturn(true);
+ assertTrue("Is showing not accurate when alternative auth showing",
+ mStatusBarKeyguardViewManager.isShowing());
+ }
+
+ @Test
+ public void testWillBeShowing_whenAlternateAuthShowing() {
+ mStatusBarKeyguardViewManager.setAlternateAuthInterceptor(mAlternateAuthInterceptor);
+ when(mBouncer.isShowing()).thenReturn(false);
+ when(mAlternateAuthInterceptor.isShowingAlternateAuthBouncer()).thenReturn(true);
+ assertTrue("Is or will be showing not accurate when alternative auth showing",
+ mStatusBarKeyguardViewManager.bouncerIsOrWillBeShowing());
+ }
+
+ @Test
public void testUpdateResources_delegatesToBouncer() {
mStatusBarKeyguardViewManager.updateResources();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
index 07d3fc2..5b55c41 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
@@ -152,7 +152,7 @@
}
@Test
- public void onWallpaperColorsChanged_setsTheme() {
+ public void onWallpaperColorsChanged_setsTheme_whenForeground() {
// Should ask for a new theme when wallpaper colors change
WallpaperColors mainColors = new WallpaperColors(Color.valueOf(Color.RED),
Color.valueOf(Color.BLUE), null);
@@ -180,13 +180,43 @@
// But should change theme after changing wallpapers
clearInvocations(mThemeOverlayApplier);
- mBroadcastReceiver.getValue().onReceive(null, new Intent(Intent.ACTION_WALLPAPER_CHANGED));
+ Intent intent = new Intent(Intent.ACTION_WALLPAPER_CHANGED);
+ intent.putExtra(WallpaperManager.EXTRA_FROM_FOREGROUND_APP, true);
+ mBroadcastReceiver.getValue().onReceive(null, intent);
mColorsListener.getValue().onColorsChanged(new WallpaperColors(Color.valueOf(Color.BLACK),
null, null), WallpaperManager.FLAG_SYSTEM);
verify(mThemeOverlayApplier).applyCurrentUserOverlays(any(), any(), anyInt(), any());
}
@Test
+ public void onWallpaperColorsChanged_setsTheme_skipWhenBackground() {
+ // Should ask for a new theme when wallpaper colors change
+ WallpaperColors mainColors = new WallpaperColors(Color.valueOf(Color.RED),
+ Color.valueOf(Color.BLUE), null);
+ mColorsListener.getValue().onColorsChanged(mainColors, WallpaperManager.FLAG_SYSTEM);
+ ArgumentCaptor<Map<String, OverlayIdentifier>> themeOverlays =
+ ArgumentCaptor.forClass(Map.class);
+
+ verify(mThemeOverlayApplier)
+ .applyCurrentUserOverlays(themeOverlays.capture(), any(), anyInt(), any());
+
+ // Assert that we received the colors that we were expecting
+ assertThat(themeOverlays.getValue().get(OVERLAY_CATEGORY_SYSTEM_PALETTE))
+ .isEqualTo(new OverlayIdentifier("ffff0000"));
+ assertThat(themeOverlays.getValue().get(OVERLAY_CATEGORY_ACCENT_COLOR))
+ .isEqualTo(new OverlayIdentifier("ffff0000"));
+
+ // Should not change theme after changing wallpapers, if intent doesn't have
+ // WallpaperManager.EXTRA_FROM_FOREGROUND_APP set to true.
+ clearInvocations(mThemeOverlayApplier);
+ mBroadcastReceiver.getValue().onReceive(null, new Intent(Intent.ACTION_WALLPAPER_CHANGED));
+ mColorsListener.getValue().onColorsChanged(new WallpaperColors(Color.valueOf(Color.BLACK),
+ null, null), WallpaperManager.FLAG_SYSTEM);
+ verify(mThemeOverlayApplier, never())
+ .applyCurrentUserOverlays(any(), any(), anyInt(), any());
+ }
+
+ @Test
public void onWallpaperColorsChanged_preservesWallpaperPickerTheme() {
// Should ask for a new theme when wallpaper colors change
WallpaperColors mainColors = new WallpaperColors(Color.valueOf(Color.RED),
@@ -455,7 +485,9 @@
// Regression test: null events should not reset the internal state and allow colors to be
// applied again.
clearInvocations(mThemeOverlayApplier);
- mBroadcastReceiver.getValue().onReceive(null, new Intent(Intent.ACTION_WALLPAPER_CHANGED));
+ Intent intent = new Intent(Intent.ACTION_WALLPAPER_CHANGED);
+ intent.putExtra(WallpaperManager.EXTRA_FROM_FOREGROUND_APP, true);
+ mBroadcastReceiver.getValue().onReceive(null, intent);
mColorsListener.getValue().onColorsChanged(null, WallpaperManager.FLAG_SYSTEM);
verify(mThemeOverlayApplier, never()).applyCurrentUserOverlays(any(), any(), anyInt(),
any());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java
index 5c0efd3..c9462d6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java
@@ -101,6 +101,11 @@
// Initial non-set value
when(mRingerModeLiveData.getValue()).thenReturn(-1);
when(mRingerModeInternalLiveData.getValue()).thenReturn(-1);
+ // Enable group volume adjustments
+ mContext.getOrCreateTestableResources().addOverride(
+ com.android.internal.R.bool.config_volumeAdjustmentForRemoteGroupSessions,
+ true);
+
mCallback = mock(VolumeDialogControllerImpl.C.class);
mThreadFactory.setLooper(TestableLooper.get(this).getLooper());
mVolumeController = new TestableVolumeDialogControllerImpl(mContext,
diff --git a/proto/src/metrics_constants/OWNERS b/proto/src/metrics_constants/OWNERS
index 274d0d6..7009282 100644
--- a/proto/src/metrics_constants/OWNERS
+++ b/proto/src/metrics_constants/OWNERS
@@ -1,3 +1,4 @@
cwren@android.com
yanglu@google.com
yaochen@google.com
+yro@google.com
diff --git a/services/OWNERS b/services/OWNERS
index 9b5f0e7..67cee55 100644
--- a/services/OWNERS
+++ b/services/OWNERS
@@ -3,7 +3,7 @@
# art-team@ manages the system server profile
per-file art-profile* = calin@google.com, ngeoffray@google.com, vmarko@google.com
-per-file java/com/android/server/* = patb@google.com
+per-file java/com/android/server/* = toddke@google.com,patb@google.com
per-file tests/servicestests/src/com/android/server/systemconfig/* = patb@google.com
per-file proguard.flags = jdduke@google.com
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
index 8a42ddf..757f1ae 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
@@ -1072,26 +1072,18 @@
ParcelFileDescriptor sourceOut = servicePipe.second;
ParcelFileDescriptor sinkOut = servicePipe.first;
- mParentService.mPackagesWithShareRequests.add(mDataShareRequest.getPackageName());
-
- try {
- mClientAdapter.write(sourceIn);
- } catch (RemoteException e) {
- Slog.e(TAG, "Failed to call write() the client operation", e);
- sendErrorSignal(mClientAdapter, serviceAdapter,
- ContentCaptureManager.DATA_SHARE_ERROR_UNKNOWN);
- logServiceEvent(
- CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__DATA_SHARE_ERROR_CLIENT_PIPE_FAIL);
- return;
+ synchronized (mParentService.mLock) {
+ mParentService.mPackagesWithShareRequests.add(mDataShareRequest.getPackageName());
}
- try {
- serviceAdapter.start(sinkOut);
- } catch (RemoteException e) {
- Slog.e(TAG, "Failed to call start() the service operation", e);
+
+ if (!setUpSharingPipeline(mClientAdapter, serviceAdapter, sourceIn, sinkOut)) {
sendErrorSignal(mClientAdapter, serviceAdapter,
ContentCaptureManager.DATA_SHARE_ERROR_UNKNOWN);
- logServiceEvent(
- CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__DATA_SHARE_ERROR_SERVICE_PIPE_FAIL);
+ bestEffortCloseFileDescriptors(sourceIn, sinkIn, sourceOut, sinkOut);
+ synchronized (mParentService.mLock) {
+ mParentService.mPackagesWithShareRequests
+ .remove(mDataShareRequest.getPackageName());
+ }
return;
}
@@ -1184,6 +1176,32 @@
}
}
+ private boolean setUpSharingPipeline(
+ IDataShareWriteAdapter clientAdapter,
+ IDataShareReadAdapter serviceAdapter,
+ ParcelFileDescriptor sourceIn,
+ ParcelFileDescriptor sinkOut) {
+ try {
+ clientAdapter.write(sourceIn);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to call write() the client operation", e);
+ logServiceEvent(
+ CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__DATA_SHARE_ERROR_CLIENT_PIPE_FAIL);
+ return false;
+ }
+
+ try {
+ serviceAdapter.start(sinkOut);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to call start() the service operation", e);
+ logServiceEvent(
+ CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__DATA_SHARE_ERROR_SERVICE_PIPE_FAIL);
+ return false;
+ }
+
+ return true;
+ }
+
private void enforceDataSharingTtl(ParcelFileDescriptor sourceIn,
ParcelFileDescriptor sinkIn,
ParcelFileDescriptor sourceOut,
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 450e988..7e270d1 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -110,10 +110,6 @@
private static final String BLUETOOTH_PRIVILEGED =
android.Manifest.permission.BLUETOOTH_PRIVILEGED;
- private static final String SECURE_SETTINGS_BLUETOOTH_ADDR_VALID = "bluetooth_addr_valid";
- private static final String SECURE_SETTINGS_BLUETOOTH_ADDRESS = "bluetooth_address";
- private static final String SECURE_SETTINGS_BLUETOOTH_NAME = "bluetooth_name";
-
private static final int ACTIVE_LOG_MAX_SIZE = 20;
private static final int CRASH_LOG_MAX_SIZE = 100;
@@ -641,7 +637,7 @@
if (mContext.getResources()
.getBoolean(com.android.internal.R.bool.config_bluetooth_address_validation)
&& Settings.Secure.getIntForUser(mContentResolver,
- SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 0, mUserId)
+ Settings.Secure.BLUETOOTH_NAME, 0, mUserId)
== 0) {
// if the valid flag is not set, don't load the address and name
if (DBG) {
@@ -650,9 +646,9 @@
return;
}
mName = Settings.Secure.getStringForUser(
- mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME, mUserId);
+ mContentResolver, Settings.Secure.BLUETOOTH_NAME, mUserId);
mAddress = Settings.Secure.getStringForUser(
- mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS, mUserId);
+ mContentResolver, Settings.Secure.BLUETOOTH_ADDRESS, mUserId);
if (DBG) {
Slog.d(TAG, "Stored bluetooth Name=" + mName + ",Address=" + mAddress);
}
@@ -666,30 +662,30 @@
*/
private void storeNameAndAddress(String name, String address) {
if (name != null) {
- Settings.Secure.putStringForUser(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME, name,
+ Settings.Secure.putStringForUser(mContentResolver, Settings.Secure.BLUETOOTH_NAME, name,
mUserId);
mName = name;
if (DBG) {
Slog.d(TAG, "Stored Bluetooth name: " + Settings.Secure.getStringForUser(
- mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME,
+ mContentResolver, Settings.Secure.BLUETOOTH_NAME,
mUserId));
}
}
if (address != null) {
- Settings.Secure.putStringForUser(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS,
+ Settings.Secure.putStringForUser(mContentResolver, Settings.Secure.BLUETOOTH_ADDRESS,
address, mUserId);
mAddress = address;
if (DBG) {
Slog.d(TAG,
"Stored Bluetoothaddress: " + Settings.Secure.getStringForUser(
- mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS,
+ mContentResolver, Settings.Secure.BLUETOOTH_ADDRESS,
mUserId));
}
}
if ((name != null) && (address != null)) {
- Settings.Secure.putIntForUser(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 1,
+ Settings.Secure.putIntForUser(mContentResolver, Settings.Secure.BLUETOOTH_ADDR_VALID, 1,
mUserId);
}
}
diff --git a/services/core/java/com/android/server/am/OWNERS b/services/core/java/com/android/server/am/OWNERS
index a5cfc4a..c4efbd7 100644
--- a/services/core/java/com/android/server/am/OWNERS
+++ b/services/core/java/com/android/server/am/OWNERS
@@ -19,6 +19,7 @@
# Permissions & Packages
svetoslavganov@google.com
+toddke@google.com
patb@google.com
# Battery Stats
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 64b9bd9..6d29c37 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -1314,6 +1314,7 @@
event.getAttributionFlags(), event.getAttributionChainId());
}
+ events = isRunning ? mInProgressEvents : mPausedInProgressEvents;
InProgressStartOpEvent newEvent = events.get(binders.get(i));
if (newEvent != null) {
newEvent.numUnfinishedStarts += numPreviousUnfinishedStarts - 1;
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index bf4ef48..a2fed291 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -17,6 +17,8 @@
package com.android.server.connectivity;
import static android.Manifest.permission.BIND_VPN_SERVICE;
+import static android.Manifest.permission.CONTROL_VPN;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.RouteInfo.RTN_THROW;
import static android.net.RouteInfo.RTN_UNREACHABLE;
@@ -932,6 +934,7 @@
* - oldPackage null, newPackage non-null: ConfirmDialog calling prepareVpn().
* - oldPackage null, newPackage=LEGACY_VPN: Used internally to disconnect
* and revoke any current app VPN and re-prepare legacy vpn.
+ * - oldPackage null, newPackage null: always returns true for backward compatibility.
*
* TODO: Rename the variables - or split this method into two - and end this confusion.
* TODO: b/29032008 Migrate code from prepare(oldPackage=non-null, newPackage=LEGACY_VPN)
@@ -945,6 +948,18 @@
*/
public synchronized boolean prepare(
String oldPackage, String newPackage, @VpnManager.VpnType int vpnType) {
+ // Except for Settings and VpnDialogs, the caller should be matched one of oldPackage or
+ // newPackage. Otherwise, non VPN owner might get the VPN always-on status of the VPN owner.
+ // See b/191382886.
+ if (mContext.checkCallingOrSelfPermission(CONTROL_VPN) != PERMISSION_GRANTED) {
+ if (oldPackage != null) {
+ verifyCallingUidAndPackage(oldPackage);
+ }
+ if (newPackage != null) {
+ verifyCallingUidAndPackage(newPackage);
+ }
+ }
+
if (oldPackage != null) {
// Stop an existing always-on VPN from being dethroned by other apps.
if (mAlwaysOn && !isCurrentPreparedPackage(oldPackage)) {
@@ -1859,14 +1874,13 @@
}
private void enforceControlPermission() {
- mContext.enforceCallingPermission(Manifest.permission.CONTROL_VPN, "Unauthorized Caller");
+ mContext.enforceCallingPermission(CONTROL_VPN, "Unauthorized Caller");
}
private void enforceControlPermissionOrInternalCaller() {
// Require the caller to be either an application with CONTROL_VPN permission or a process
// in the system server.
- mContext.enforceCallingOrSelfPermission(Manifest.permission.CONTROL_VPN,
- "Unauthorized Caller");
+ mContext.enforceCallingOrSelfPermission(CONTROL_VPN, "Unauthorized Caller");
}
private void enforceSettingsPermission() {
@@ -3176,8 +3190,9 @@
}
private void verifyCallingUidAndPackage(String packageName) {
- if (getAppUid(packageName, mUserId) != Binder.getCallingUid()) {
- throw new SecurityException("Mismatched package and UID");
+ final int callingUid = Binder.getCallingUid();
+ if (getAppUid(packageName, mUserId) != callingUid) {
+ throw new SecurityException(packageName + " does not belong to uid " + callingUid);
}
}
diff --git a/services/core/java/com/android/server/devicestate/OWNERS b/services/core/java/com/android/server/devicestate/OWNERS
index 7708505..ae79fc0 100644
--- a/services/core/java/com/android/server/devicestate/OWNERS
+++ b/services/core/java/com/android/server/devicestate/OWNERS
@@ -1,2 +1,3 @@
ogunwale@google.com
akulian@google.com
+darryljohnson@google.com
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 3e52f5e..5b7f5c8 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -2837,7 +2837,7 @@
return;
}
final IBinder targetWindow = mImeTargetWindowMap.get(startInputToken);
- if (targetWindow != null && mLastImeTargetWindow != targetWindow) {
+ if (targetWindow != null) {
mWindowManagerInternal.updateInputMethodTargetWindow(token, targetWindow);
}
mLastImeTargetWindow = targetWindow;
diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java
index a57d7db..7502afc 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -338,6 +338,25 @@
// Binder call
@Override
+ public void setBluetoothA2dpOn(IMediaRouterClient client, boolean on) {
+ if (client == null) {
+ throw new IllegalArgumentException("client must not be null");
+ }
+
+ final long token = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ mAudioService.setBluetoothA2dpOn(on);
+ }
+ } catch (RemoteException ex) {
+ Slog.w(TAG, "RemoteException while calling setBluetoothA2dpOn. on=" + on);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ // Binder call
+ @Override
public void setDiscoveryRequest(IMediaRouterClient client,
int routeTypes, boolean activeScan) {
if (client == null) {
diff --git a/services/core/java/com/android/server/media/MediaSession2Record.java b/services/core/java/com/android/server/media/MediaSession2Record.java
index 607218e..b424c20 100644
--- a/services/core/java/com/android/server/media/MediaSession2Record.java
+++ b/services/core/java/com/android/server/media/MediaSession2Record.java
@@ -146,6 +146,12 @@
}
@Override
+ public boolean canHandleVolumeKey() {
+ // TODO: Implement when MediaSession2 starts to get key events.
+ return false;
+ }
+
+ @Override
public int getSessionPolicies() {
synchronized (mLock) {
return mPolicies;
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 1525cd4..4822d6a 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -26,7 +26,9 @@
import android.media.AudioManager;
import android.media.AudioSystem;
import android.media.MediaMetadata;
+import android.media.MediaRouter2Manager;
import android.media.Rating;
+import android.media.RoutingSessionInfo;
import android.media.VolumeProvider;
import android.media.session.ISession;
import android.media.session.ISessionCallback;
@@ -50,6 +52,7 @@
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.SystemClock;
+import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
@@ -121,6 +124,7 @@
private final SessionCb mSessionCb;
private final MediaSessionService mService;
private final Context mContext;
+ private final boolean mVolumeAdjustmentForRemoteGroupSessions;
private final Object mLock = new Object();
private final CopyOnWriteArrayList<ISessionControllerCallbackHolder>
@@ -180,6 +184,8 @@
mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
mAudioAttrs = DEFAULT_ATTRIBUTES;
mPolicies = policies;
+ mVolumeAdjustmentForRemoteGroupSessions = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_volumeAdjustmentForRemoteGroupSessions);
// May throw RemoteException if the session app is killed.
mSessionCb.mCb.asBinder().linkToDeath(this, 0);
@@ -285,35 +291,39 @@
asSystemService, useSuggested, previousFlagPlaySound);
} else {
if (mVolumeControlType == VolumeProvider.VOLUME_CONTROL_FIXED) {
- // Nothing to do, the volume cannot be changed
- return;
- }
- if (direction == AudioManager.ADJUST_TOGGLE_MUTE
+ if (DEBUG) {
+ Log.d(TAG, "Session does not support volume adjustment");
+ }
+ } else if (direction == AudioManager.ADJUST_TOGGLE_MUTE
|| direction == AudioManager.ADJUST_MUTE
|| direction == AudioManager.ADJUST_UNMUTE) {
Log.w(TAG, "Muting remote playback is not supported");
- return;
- }
- if (DEBUG) {
- Log.w(TAG, "adjusting volume, pkg=" + packageName + ", asSystemService="
- + asSystemService + ", dir=" + direction);
- }
- mSessionCb.adjustVolume(packageName, pid, uid, asSystemService, direction);
+ } else {
+ if (DEBUG) {
+ Log.w(TAG, "adjusting volume, pkg=" + packageName + ", asSystemService="
+ + asSystemService + ", dir=" + direction);
+ }
+ mSessionCb.adjustVolume(packageName, pid, uid, asSystemService, direction);
- int volumeBefore = (mOptimisticVolume < 0 ? mCurrentVolume : mOptimisticVolume);
- mOptimisticVolume = volumeBefore + direction;
- mOptimisticVolume = Math.max(0, Math.min(mOptimisticVolume, mMaxVolume));
- mHandler.removeCallbacks(mClearOptimisticVolumeRunnable);
- mHandler.postDelayed(mClearOptimisticVolumeRunnable, OPTIMISTIC_VOLUME_TIMEOUT);
- if (volumeBefore != mOptimisticVolume) {
- pushVolumeUpdate();
+ int volumeBefore = (mOptimisticVolume < 0 ? mCurrentVolume : mOptimisticVolume);
+ mOptimisticVolume = volumeBefore + direction;
+ mOptimisticVolume = Math.max(0, Math.min(mOptimisticVolume, mMaxVolume));
+ mHandler.removeCallbacks(mClearOptimisticVolumeRunnable);
+ mHandler.postDelayed(mClearOptimisticVolumeRunnable, OPTIMISTIC_VOLUME_TIMEOUT);
+ if (volumeBefore != mOptimisticVolume) {
+ pushVolumeUpdate();
+ }
+
+ if (DEBUG) {
+ Log.d(TAG, "Adjusted optimistic volume to " + mOptimisticVolume + " max is "
+ + mMaxVolume);
+ }
}
+ // Always notify, even if the volume hasn't changed. This is important to ensure that
+ // System UI receives an event if a hardware volume key is pressed but the session that
+ // handles it does not allow volume adjustment. Without such an event, System UI would
+ // not show volume controls to the user.
mService.notifyRemoteVolumeChanged(flags, this);
-
- if (DEBUG) {
- Log.d(TAG, "Adjusted optimistic volume to " + mOptimisticVolume + " max is "
- + mMaxVolume);
- }
}
}
@@ -337,25 +347,28 @@
});
} else {
if (mVolumeControlType != VolumeProvider.VOLUME_CONTROL_ABSOLUTE) {
- // Nothing to do. The volume can't be set directly.
- return;
- }
- value = Math.max(0, Math.min(value, mMaxVolume));
- mSessionCb.setVolumeTo(packageName, pid, uid, value);
+ if (DEBUG) {
+ Log.d(TAG, "Session does not support setting volume");
+ }
+ } else {
+ value = Math.max(0, Math.min(value, mMaxVolume));
+ mSessionCb.setVolumeTo(packageName, pid, uid, value);
- int volumeBefore = (mOptimisticVolume < 0 ? mCurrentVolume : mOptimisticVolume);
- mOptimisticVolume = Math.max(0, Math.min(value, mMaxVolume));
- mHandler.removeCallbacks(mClearOptimisticVolumeRunnable);
- mHandler.postDelayed(mClearOptimisticVolumeRunnable, OPTIMISTIC_VOLUME_TIMEOUT);
- if (volumeBefore != mOptimisticVolume) {
- pushVolumeUpdate();
+ int volumeBefore = (mOptimisticVolume < 0 ? mCurrentVolume : mOptimisticVolume);
+ mOptimisticVolume = Math.max(0, Math.min(value, mMaxVolume));
+ mHandler.removeCallbacks(mClearOptimisticVolumeRunnable);
+ mHandler.postDelayed(mClearOptimisticVolumeRunnable, OPTIMISTIC_VOLUME_TIMEOUT);
+ if (volumeBefore != mOptimisticVolume) {
+ pushVolumeUpdate();
+ }
+
+ if (DEBUG) {
+ Log.d(TAG, "Set optimistic volume to " + mOptimisticVolume + " max is "
+ + mMaxVolume);
+ }
}
+ // Always notify, even if the volume hasn't changed.
mService.notifyRemoteVolumeChanged(flags, this);
-
- if (DEBUG) {
- Log.d(TAG, "Set optimistic volume to " + mOptimisticVolume + " max is "
- + mMaxVolume);
- }
}
}
@@ -449,6 +462,33 @@
}
@Override
+ public boolean canHandleVolumeKey() {
+ if (isPlaybackTypeLocal() || mVolumeAdjustmentForRemoteGroupSessions) {
+ return true;
+ }
+ MediaRouter2Manager mRouter2Manager = MediaRouter2Manager.getInstance(mContext);
+ List<RoutingSessionInfo> sessions =
+ mRouter2Manager.getRoutingSessions(mPackageName);
+ boolean foundNonSystemSession = false;
+ boolean isGroup = false;
+ for (RoutingSessionInfo session : sessions) {
+ if (!session.isSystemSession()) {
+ foundNonSystemSession = true;
+ int selectedRouteCount = session.getSelectedRoutes().size();
+ if (selectedRouteCount > 1) {
+ isGroup = true;
+ break;
+ }
+ }
+ }
+ if (!foundNonSystemSession) {
+ Log.d(TAG, "No routing session for " + mPackageName);
+ return false;
+ }
+ return !isGroup;
+ }
+
+ @Override
public int getSessionPolicies() {
synchronized (mLock) {
return mPolicies;
diff --git a/services/core/java/com/android/server/media/MediaSessionRecordImpl.java b/services/core/java/com/android/server/media/MediaSessionRecordImpl.java
index 3c50597..8f01f02 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecordImpl.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecordImpl.java
@@ -131,6 +131,13 @@
KeyEvent ke, int sequenceId, ResultReceiver cb);
/**
+ * Returns whether the media session can handle volume key events.
+ *
+ * @return True if this media session can handle volume key events, false otherwise.
+ */
+ boolean canHandleVolumeKey();
+
+ /**
* Get session policies from custom policy provider set when MediaSessionRecord is instantiated.
* If custom policy does not exist, will return null.
*/
diff --git a/services/core/java/com/android/server/media/MediaSessionStack.java b/services/core/java/com/android/server/media/MediaSessionStack.java
index c4c21df..b75ba75 100644
--- a/services/core/java/com/android/server/media/MediaSessionStack.java
+++ b/services/core/java/com/android/server/media/MediaSessionStack.java
@@ -325,8 +325,7 @@
int size = records.size();
for (int i = 0; i < size; i++) {
MediaSessionRecord record = records.get(i);
- // Do not send the volume key events to remote sessions.
- if (record.checkPlaybackActiveState(true) && record.isPlaybackTypeLocal()) {
+ if (record.checkPlaybackActiveState(true) && record.canHandleVolumeKey()) {
mCachedVolumeDefault = record;
return record;
}
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index 27b1648..ee0b3d5 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -71,6 +71,7 @@
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AtomicFile;
+import android.util.EventLog;
import android.util.Slog;
import android.util.SparseArray;
@@ -81,7 +82,6 @@
import com.android.server.LocalServices;
import com.android.server.SystemConfig;
import com.android.server.SystemService;
-
import com.android.server.pm.UserManagerService;
import com.android.server.pm.parsing.pkg.AndroidPackage;
@@ -285,6 +285,12 @@
restoreSettings();
+ // Wipe all shell overlays on boot, to recover from a potentially broken device
+ String shellPkgName = TextUtils.emptyIfNull(
+ getContext().getString(android.R.string.config_systemShell));
+ mSettings.removeIf(overlayInfo -> overlayInfo.isFabricated
+ && shellPkgName.equals(overlayInfo.packageName));
+
initIfNeeded();
onSwitchUser(UserHandle.USER_SYSTEM);
@@ -891,6 +897,16 @@
throw new IllegalArgumentException(request.typeToString()
+ " unsupported for user " + request.userId);
}
+
+ // Normal apps are blocked from accessing OMS via SELinux, so to block non-root,
+ // non privileged callers, a simple check against the shell UID is sufficient, since
+ // that's the only exception from the other categories. This is enough while OMS
+ // is not a public API, but this will have to be changed if it's ever exposed.
+ if (callingUid == Process.SHELL_UID) {
+ EventLog.writeEvent(0x534e4554, "202768292", -1, "");
+ throw new IllegalArgumentException("Non-root shell cannot fabricate overlays");
+ }
+
realUserId = UserHandle.USER_ALL;
// Enforce that the calling process can only register and unregister fabricated
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 00e54b1..99f4a59 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -135,6 +135,8 @@
private static final long MAX_ACTIVE_SESSIONS_NO_PERMISSION = 50;
/** Upper bound on number of historical sessions for a UID */
private static final long MAX_HISTORICAL_SESSIONS = 1048576;
+ /** Destroy sessions older than this on storage free request */
+ private static final long MAX_SESSION_AGE_ON_LOW_STORAGE_MILLIS = 8 * DateUtils.HOUR_IN_MILLIS;
/**
* Allow verification-skipping if it's a development app installed through ADB with
@@ -338,22 +340,28 @@
@GuardedBy("mSessions")
private void reconcileStagesLocked(String volumeUuid) {
- final File stagingDir = getTmpSessionDir(volumeUuid);
- final ArraySet<File> unclaimedStages = newArraySet(
- stagingDir.listFiles(sStageFilter));
-
- // We also need to clean up orphaned staging directory for staged sessions
- final File stagedSessionStagingDir = Environment.getDataStagingDirectory(volumeUuid);
- unclaimedStages.addAll(newArraySet(stagedSessionStagingDir.listFiles()));
-
+ final ArraySet<File> unclaimedStages = getStagingDirsOnVolume(volumeUuid);
// Ignore stages claimed by active sessions
for (int i = 0; i < mSessions.size(); i++) {
final PackageInstallerSession session = mSessions.valueAt(i);
unclaimedStages.remove(session.stageDir);
}
+ removeStagingDirs(unclaimedStages);
+ }
+ private ArraySet<File> getStagingDirsOnVolume(String volumeUuid) {
+ final File stagingDir = getTmpSessionDir(volumeUuid);
+ final ArraySet<File> stagingDirs = newArraySet(stagingDir.listFiles(sStageFilter));
+
+ // We also need to clean up orphaned staging directory for staged sessions
+ final File stagedSessionStagingDir = Environment.getDataStagingDirectory(volumeUuid);
+ stagingDirs.addAll(newArraySet(stagedSessionStagingDir.listFiles()));
+ return stagingDirs;
+ }
+
+ private void removeStagingDirs(ArraySet<File> stagingDirsToRemove) {
// Clean up orphaned staging directories
- for (File stage : unclaimedStages) {
+ for (File stage : stagingDirsToRemove) {
Slog.w(TAG, "Deleting orphan stage " + stage);
synchronized (mPm.mInstallLock) {
mPm.removeCodePathLI(stage);
@@ -367,6 +375,33 @@
}
}
+ /**
+ * Called to free up some storage space from obsolete installation files
+ */
+ public void freeStageDirs(String volumeUuid) {
+ final ArraySet<File> unclaimedStagingDirsOnVolume = getStagingDirsOnVolume(volumeUuid);
+ final long currentTimeMillis = System.currentTimeMillis();
+ synchronized (mSessions) {
+ for (int i = 0; i < mSessions.size(); i++) {
+ final PackageInstallerSession session = mSessions.valueAt(i);
+ if (!unclaimedStagingDirsOnVolume.contains(session.stageDir)) {
+ // Only handles sessions stored on the target volume
+ continue;
+ }
+ final long age = currentTimeMillis - session.createdMillis;
+ if (age >= MAX_SESSION_AGE_ON_LOW_STORAGE_MILLIS) {
+ // Aggressively close old sessions because we are running low on storage
+ // Their staging dirs will be removed too
+ session.abandon();
+ } else {
+ // Session is new enough, so it deserves to be kept even on low storage
+ unclaimedStagingDirsOnVolume.remove(session.stageDir);
+ }
+ }
+ }
+ removeStagingDirs(unclaimedStagingDirsOnVolume);
+ }
+
public static boolean isStageName(String name) {
final boolean isFile = name.startsWith("vmdl") && name.endsWith(".tmp");
final boolean isContainer = name.startsWith("smdl") && name.endsWith(".tmp");
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 5429484..d0e4457 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -673,7 +673,7 @@
final Runnable r;
synchronized (mLock) {
assertNotChildLocked("StagedSession#abandon");
- assertCallerIsOwnerOrRoot();
+ assertCallerIsOwnerOrRootOrSystem();
if (isInTerminalState()) {
// We keep the session in the database if it's in a finalized state. It will be
// removed by PackageInstallerService when the last update time is old enough.
@@ -3704,7 +3704,7 @@
private void abandonNonStaged() {
synchronized (mLock) {
assertNotChildLocked("abandonNonStaged");
- assertCallerIsOwnerOrRoot();
+ assertCallerIsOwnerOrRootOrSystem();
if (mRelinquished) {
if (LOGD) Slog.d(TAG, "Ignoring abandon after commit relinquished control");
return;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 3e0a7fd..bc28cff 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -9305,6 +9305,10 @@
if (freeBytesRequired > 0) {
smInternal.freeCache(volumeUuid, freeBytesRequired);
}
+
+ // 12. Clear temp install session files
+ mInstallerService.freeStageDirs(volumeUuid);
+
if (file.getUsableSpace() >= bytes) return;
} else {
try {
diff --git a/services/core/java/com/android/server/pm/verify/domain/OWNERS b/services/core/java/com/android/server/pm/verify/domain/OWNERS
index 445a833..c669112 100644
--- a/services/core/java/com/android/server/pm/verify/domain/OWNERS
+++ b/services/core/java/com/android/server/pm/verify/domain/OWNERS
@@ -2,3 +2,4 @@
chiuwinson@google.com
patb@google.com
+toddke@google.com
\ No newline at end of file
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index e05f7ef..34a49cc 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -4668,6 +4668,12 @@
return mKeyguardDelegate.isInputRestricted();
}
+ /** {@inheritDoc} */
+ @Override
+ public boolean isKeyguardUnoccluding() {
+ return keyguardOn() && !mWindowManagerFuncs.isAppTransitionStateIdle();
+ }
+
@Override
public void dismissKeyguardLw(IKeyguardDismissCallback callback, CharSequence message) {
if (mKeyguardDelegate != null && mKeyguardDelegate.isShowing()) {
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 78b03b2..510ab93 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -367,6 +367,12 @@
* as the top display.
*/
void moveDisplayToTop(int displayId);
+
+ /**
+ * Return whether the app transition state is idle.
+ * @return {@code true} if app transition state is idle on the default display.
+ */
+ boolean isAppTransitionStateIdle();
}
/**
@@ -974,6 +980,14 @@
public boolean isKeyguardOccluded();
/**
+ * Return whether the keyguard is unoccluding.
+ * @return {@code true} if the keyguard is unoccluding.
+ */
+ default boolean isKeyguardUnoccluding() {
+ return false;
+ }
+
+ /**
* @return true if in keyguard is on.
*/
boolean isKeyguardShowing();
diff --git a/services/core/java/com/android/server/stats/OWNERS b/services/core/java/com/android/server/stats/OWNERS
index 2450dbb..174ad3a 100644
--- a/services/core/java/com/android/server/stats/OWNERS
+++ b/services/core/java/com/android/server/stats/OWNERS
@@ -8,3 +8,4 @@
singhtejinder@google.com
tsaichristine@google.com
yaochen@google.com
+yro@google.com
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index a51ed09..b8c712a 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -17,6 +17,7 @@
package com.android.server.wallpaper;
import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
import static android.app.WallpaperManager.COMMAND_REAPPLY;
import static android.app.WallpaperManager.FLAG_LOCK;
import static android.app.WallpaperManager.FLAG_SYSTEM;
@@ -791,6 +792,7 @@
private final Context mContext;
private final WindowManagerInternal mWindowManagerInternal;
private final IPackageManager mIPackageManager;
+ private final ActivityManager mActivityManager;
private final MyPackageMonitor mMonitor;
private final AppOpsManager mAppOpsManager;
@@ -939,6 +941,11 @@
*/
WallpaperColors primaryColors;
+ /**
+ * If the wallpaper was set from a foreground app (instead of from a background service).
+ */
+ public boolean fromForegroundApp;
+
WallpaperConnection connection;
long lastDiedTime;
boolean wallpaperUpdating;
@@ -1688,6 +1695,7 @@
mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
mDisplayManager = mContext.getSystemService(DisplayManager.class);
mDisplayManager.registerDisplayListener(mDisplayListener, null /* handler */);
+ mActivityManager = mContext.getSystemService(ActivityManager.class);
mMonitor = new MyPackageMonitor();
mColorsChangedListeners = new SparseArray<>();
@@ -2648,6 +2656,9 @@
}
}
+ final boolean fromForegroundApp = Binder.withCleanCallingIdentity(() ->
+ mActivityManager.getPackageImportance(callingPackage) == IMPORTANCE_FOREGROUND);
+
synchronized (mLock) {
if (DEBUG) Slog.v(TAG, "setWallpaper which=0x" + Integer.toHexString(which));
WallpaperData wallpaper;
@@ -2670,6 +2681,7 @@
wallpaper.imageWallpaperPending = true;
wallpaper.whichPending = which;
wallpaper.setComplete = completion;
+ wallpaper.fromForegroundApp = fromForegroundApp;
wallpaper.cropHint.set(cropHint);
wallpaper.allowBackup = allowBackup;
}
@@ -3052,6 +3064,7 @@
wallpaper.callbacks.finishBroadcast();
final Intent intent = new Intent(Intent.ACTION_WALLPAPER_CHANGED);
+ intent.putExtra(WallpaperManager.EXTRA_FROM_FOREGROUND_APP, wallpaper.fromForegroundApp);
mContext.sendBroadcastAsUser(intent, new UserHandle(mCurrentUserId));
}
@@ -3062,12 +3075,35 @@
}
}
+ private boolean packageBelongsToUid(String packageName, int uid) {
+ int userId = UserHandle.getUserId(uid);
+ int packageUid;
+ try {
+ packageUid = mContext.getPackageManager().getPackageUidAsUser(
+ packageName, userId);
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ }
+ return packageUid == uid;
+ }
+
+ private void enforcePackageBelongsToUid(String packageName, int uid) {
+ if (!packageBelongsToUid(packageName, uid)) {
+ throw new IllegalArgumentException(
+ "Invalid package or package does not belong to uid:"
+ + uid);
+ }
+ }
+
/**
* Certain user types do not support wallpapers (e.g. managed profiles). The check is
* implemented through through the OP_WRITE_WALLPAPER AppOp.
*/
public boolean isWallpaperSupported(String callingPackage) {
- return mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_WRITE_WALLPAPER, Binder.getCallingUid(),
+ final int callingUid = Binder.getCallingUid();
+ enforcePackageBelongsToUid(callingPackage, callingUid);
+
+ return mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_WRITE_WALLPAPER, callingUid,
callingPackage) == AppOpsManager.MODE_ALLOWED;
}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index b52e527..4520579 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1038,6 +1038,8 @@
pw.print(" forceNewConfig="); pw.println(forceNewConfig);
pw.print(prefix); pw.print("mActivityType=");
pw.println(activityTypeToString(getActivityType()));
+ pw.print(prefix); pw.print("mImeInsetsFrozenUntilStartInput=");
+ pw.println(mImeInsetsFrozenUntilStartInput);
if (requestedVrComponent != null) {
pw.print(prefix);
pw.print("requestedVrComponent=");
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index c1b287f..c61cfee 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -365,6 +365,10 @@
setAppTransitionState(APP_STATE_IDLE);
}
+ boolean isIdle() {
+ return mAppTransitionState == APP_STATE_IDLE;
+ }
+
boolean isTimeout() {
return mAppTransitionState == APP_STATE_TIMEOUT;
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 9335846..bb8d6ef 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -3969,11 +3969,11 @@
* which controls the visibility and animation of the input method window.
*/
void updateImeInputAndControlTarget(WindowState target) {
+ if (target != null && target.mActivityRecord != null) {
+ target.mActivityRecord.mImeInsetsFrozenUntilStartInput = false;
+ }
if (mImeInputTarget != target) {
ProtoLog.i(WM_DEBUG_IME, "setInputMethodInputTarget %s", target);
- if (target != null && target.mActivityRecord != null) {
- target.mActivityRecord.mImeInsetsFrozenUntilStartInput = false;
- }
setImeInputTarget(target);
updateImeControlTarget();
}
diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java
index b1bdc11..fea52f2 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimation.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimation.java
@@ -164,6 +164,13 @@
ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "startRecentsActivity(): intent=%s", mTargetIntent);
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "RecentsAnimation#startRecentsActivity");
+ // Cancel any existing recents animation running synchronously (do not hold the
+ // WM lock) before starting the newly requested recents animation as they can not coexist
+ if (mWindowManager.getRecentsAnimationController() != null) {
+ mWindowManager.getRecentsAnimationController().forceCancelAnimation(
+ REORDER_MOVE_TO_ORIGINAL_POSITION, "startRecentsActivity");
+ }
+
// If the activity is associated with the root recents task, then try and get that first
Task targetRootTask = mDefaultTaskDisplayArea.getRootTask(WINDOWING_MODE_UNDEFINED,
mTargetActivityType);
@@ -237,12 +244,7 @@
targetActivity.intent.replaceExtras(mTargetIntent);
// Fetch all the surface controls and pass them to the client to get the animation
- // started. Cancel any existing recents animation running synchronously (do not hold the
- // WM lock)
- if (mWindowManager.getRecentsAnimationController() != null) {
- mWindowManager.getRecentsAnimationController().forceCancelAnimation(
- REORDER_MOVE_TO_ORIGINAL_POSITION, "startRecentsActivity");
- }
+ // started
mWindowManager.initializeRecentsAnimation(mTargetActivityType, recentsAnimationRunner,
this, mDefaultTaskDisplayArea.getDisplayId(),
mTaskSupervisor.mRecentTasks.getRecentTaskIds(), targetActivity);
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 4ff6d3c..1f2a9a2 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -159,7 +159,8 @@
boolean needsShowWhenLockedWallpaper = false;
if ((w.mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0
&& mService.mPolicy.isKeyguardLocked()
- && mService.mPolicy.isKeyguardOccluded()) {
+ && (mService.mPolicy.isKeyguardOccluded()
+ || mService.mPolicy.isKeyguardUnoccluding())) {
// The lowest show when locked window decides whether we need to put the wallpaper
// behind.
needsShowWhenLockedWallpaper = !isFullscreen(w.mAttrs)
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 68e85c8..1b74e43 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -56,6 +56,7 @@
import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
+import static android.view.WindowManager.LayoutParams.FLAG_SLIPPERY;
import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
@@ -1682,6 +1683,7 @@
final DisplayPolicy displayPolicy = displayContent.getDisplayPolicy();
displayPolicy.adjustWindowParamsLw(win, win.mAttrs);
+ attrs.flags = sanitizeFlagSlippery(attrs.flags, win.getName(), callingUid, callingPid);
win.updateRequestedVisibility(requestedVisibility);
res = displayPolicy.validateAddingWindowLw(attrs, callingPid, callingUid);
@@ -2244,6 +2246,7 @@
if (attrs != null) {
displayPolicy.adjustWindowParamsLw(win, attrs);
win.mToken.adjustWindowParams(win, attrs);
+ attrs.flags = sanitizeFlagSlippery(attrs.flags, win.getName(), uid, pid);
int disableFlags =
(attrs.systemUiVisibility | attrs.subtreeSystemUiVisibility) & DISABLE_MASK;
if (disableFlags != 0 && !hasStatusBarPermission(pid, uid)) {
@@ -3081,6 +3084,11 @@
syncInputTransactions(true /* waitForAnimations */);
}
+ @Override
+ public boolean isAppTransitionStateIdle() {
+ return getDefaultDisplayContentLocked().mAppTransition.isIdle();
+ }
+
/**
* Notifies activity manager that some Keyguard flags have changed and that it needs to
* reevaluate the visibilities of the activities.
@@ -8230,6 +8238,23 @@
}
/**
+ * You need ALLOW_SLIPPERY_TOUCHES permission to be able to set FLAG_SLIPPERY.
+ */
+ private int sanitizeFlagSlippery(int flags, String windowName, int callingUid, int callingPid) {
+ if ((flags & FLAG_SLIPPERY) == 0) {
+ return flags;
+ }
+ final int permissionResult = mContext.checkPermission(
+ android.Manifest.permission.ALLOW_SLIPPERY_TOUCHES, callingPid, callingUid);
+ if (permissionResult != PackageManager.PERMISSION_GRANTED) {
+ Slog.w(TAG, "Removing FLAG_SLIPPERY from '" + windowName
+ + "' because it doesn't have ALLOW_SLIPPERY_TOUCHES permission");
+ return flags & ~FLAG_SLIPPERY;
+ }
+ return flags;
+ }
+
+ /**
* Assigns an InputChannel to a SurfaceControl and configures it to receive
* touch input according to it's on-screen geometry.
*
@@ -8267,8 +8292,10 @@
h.token = channelToken;
h.name = name;
+ flags = sanitizeFlagSlippery(flags, name, callingUid, callingPid);
+
final int sanitizedFlags = flags & (LayoutParams.FLAG_NOT_TOUCHABLE
- | LayoutParams.FLAG_SLIPPERY | LayoutParams.FLAG_NOT_FOCUSABLE);
+ | FLAG_SLIPPERY | LayoutParams.FLAG_NOT_FOCUSABLE);
h.layoutParamsFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | sanitizedFlags;
h.layoutParamsType = type;
h.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
diff --git a/services/core/jni/stats/OWNERS b/services/core/jni/stats/OWNERS
index 552cc0d..2611e5b 100644
--- a/services/core/jni/stats/OWNERS
+++ b/services/core/jni/stats/OWNERS
@@ -1,6 +1,8 @@
jeffreyhuang@google.com
jtnguyen@google.com
muhammadq@google.com
+sharaieko@google.com
singhtejinder@google.com
tsaichristine@google.com
yaochen@google.com
+yro@google.com
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 9ceabce..0792d9b 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -12648,6 +12648,13 @@
}
@Override
+ public @Nullable ComponentName getProfileOwnerOrDeviceOwnerSupervisionComponent(
+ @NonNull UserHandle userHandle) {
+ return DevicePolicyManagerService.this.getProfileOwnerOrDeviceOwnerSupervisionComponent(
+ userHandle);
+ }
+
+ @Override
public boolean isActiveDeviceOwner(int uid) {
return isDeviceOwner(new CallerIdentity(uid, null, null));
}
diff --git a/services/incremental/OWNERS b/services/incremental/OWNERS
index fe8c253..7ebb962 100644
--- a/services/incremental/OWNERS
+++ b/services/incremental/OWNERS
@@ -3,5 +3,6 @@
alexbuy@google.com
schfan@google.com
+toddke@google.com
zyy@google.com
patb@google.com
diff --git a/services/tests/mockingservicestests/src/com/android/server/usage/UserUsageStatsServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/usage/UserUsageStatsServiceTest.java
index 24c58f4..7358551 100644
--- a/services/tests/mockingservicestests/src/com/android/server/usage/UserUsageStatsServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/usage/UserUsageStatsServiceTest.java
@@ -72,7 +72,7 @@
HashMap<String, Long> installedPkgs = new HashMap<>();
installedPkgs.put(TEST_PACKAGE_NAME, System.currentTimeMillis());
- mService.init(System.currentTimeMillis(), installedPkgs);
+ mService.init(System.currentTimeMillis(), installedPkgs, true);
}
@After
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 6f04f17..29fa2d3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -37,6 +37,7 @@
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.os.Process.NOBODY_UID;
import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.InsetsState.ITYPE_IME;
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
@@ -127,6 +128,8 @@
import android.view.IRemoteAnimationRunner.Stub;
import android.view.IWindowManager;
import android.view.IWindowSession;
+import android.view.InsetsSource;
+import android.view.InsetsState;
import android.view.RemoteAnimationAdapter;
import android.view.RemoteAnimationTarget;
import android.view.Surface;
@@ -2884,6 +2887,41 @@
assertFalse(app.mActivityRecord.mImeInsetsFrozenUntilStartInput);
}
+ @UseTestDisplay(addWindows = W_INPUT_METHOD)
+ @Test
+ public void testImeInsetsFrozenFlag_resetWhenReportedToBeImeInputTarget() {
+ final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+
+ InsetsSource imeSource = new InsetsSource(ITYPE_IME);
+ app.getInsetsState().addSource(imeSource);
+ mDisplayContent.setImeLayeringTarget(app);
+ mDisplayContent.updateImeInputAndControlTarget(app);
+
+ InsetsState state = mDisplayContent.getInsetsPolicy().getInsetsForWindow(app);
+ assertFalse(state.getSource(ITYPE_IME).isVisible());
+ assertTrue(state.getSource(ITYPE_IME).getFrame().isEmpty());
+
+ // Simulate app is closing and expect IME insets is frozen.
+ mDisplayContent.mOpeningApps.clear();
+ app.mActivityRecord.commitVisibility(false, false);
+ app.mActivityRecord.onWindowsGone();
+ assertTrue(app.mActivityRecord.mImeInsetsFrozenUntilStartInput);
+
+ // Simulate app re-start input or turning screen off/on then unlocked by un-secure
+ // keyguard to back to the app, expect IME insets is not frozen
+ imeSource.setFrame(new Rect(100, 400, 500, 500));
+ app.getInsetsState().addSource(imeSource);
+ app.getInsetsState().setSourceVisible(ITYPE_IME, true);
+ mDisplayContent.updateImeInputAndControlTarget(app);
+ assertFalse(app.mActivityRecord.mImeInsetsFrozenUntilStartInput);
+
+ // Verify when IME is visible and the app can receive the right IME insets from policy.
+ makeWindowVisibleAndDrawn(app, mImeWindow);
+ state = mDisplayContent.getInsetsPolicy().getInsetsForWindow(app);
+ assertTrue(state.getSource(ITYPE_IME).isVisible());
+ assertEquals(state.getSource(ITYPE_IME).getFrame(), imeSource.getFrame());
+ }
+
private void assertHasStartingWindow(ActivityRecord atoken) {
assertNotNull(atoken.mStartingSurface);
assertNotNull(atoken.mStartingData);
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 1b84927..ac1fcce 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -380,6 +380,7 @@
if (userId == UserHandle.USER_SYSTEM) {
UsageStatsIdleService.scheduleUpdateMappingsJob(getContext());
}
+ final boolean deleteObsoleteData = shouldDeleteObsoleteData(UserHandle.of(userId));
synchronized (mLock) {
// This should be safe to add this early. Other than reportEventOrAddToQueue, every
// other user grabs the lock before accessing
@@ -402,7 +403,7 @@
boolean needToFlush = !pendingEvents.isEmpty();
initializeUserUsageStatsServiceLocked(userId, System.currentTimeMillis(),
- installedPackages);
+ installedPackages, deleteObsoleteData);
final UserUsageStatsService userService = getUserUsageStatsServiceLocked(userId);
if (userService == null) {
Slog.i(TAG, "Attempted to unlock stopped or removed user " + userId);
@@ -596,13 +597,13 @@
* when the user is initially unlocked.
*/
private void initializeUserUsageStatsServiceLocked(int userId, long currentTimeMillis,
- HashMap<String, Long> installedPackages) {
+ HashMap<String, Long> installedPackages, boolean deleteObsoleteData) {
final File usageStatsDir = new File(Environment.getDataSystemCeDirectory(userId),
"usagestats");
final UserUsageStatsService service = new UserUsageStatsService(getContext(), userId,
usageStatsDir, this);
try {
- service.init(currentTimeMillis, installedPackages);
+ service.init(currentTimeMillis, installedPackages, deleteObsoleteData);
mUserState.put(userId, service);
} catch (Exception e) {
if (mUserManager.isUserUnlocked(userId)) {
@@ -1165,6 +1166,10 @@
* Called by the Binder stub.
*/
private boolean updatePackageMappingsData() {
+ // don't update the mappings if a profile user is defined
+ if (!shouldDeleteObsoleteData(UserHandle.SYSTEM)) {
+ return true; // return true so job scheduler doesn't reschedule the job
+ }
// fetch the installed packages outside the lock so it doesn't block package manager.
final HashMap<String, Long> installedPkgs = getInstalledPackages(UserHandle.USER_SYSTEM);
synchronized (mLock) {
@@ -1309,6 +1314,13 @@
}
}
+ private boolean shouldDeleteObsoleteData(UserHandle userHandle) {
+ final DevicePolicyManagerInternal dpmInternal = getDpmInternal();
+ // If a profile owner is not defined for the given user, obsolete data should be deleted
+ return dpmInternal == null
+ || dpmInternal.getProfileOwnerOrDeviceOwnerSupervisionComponent(userHandle) == null;
+ }
+
private String buildFullToken(String packageName, String token) {
final StringBuilder sb = new StringBuilder(packageName.length() + token.length() + 1);
sb.append(packageName);
@@ -2532,8 +2544,12 @@
private class MyPackageMonitor extends PackageMonitor {
@Override
public void onPackageRemoved(String packageName, int uid) {
- mHandler.obtainMessage(MSG_PACKAGE_REMOVED, getChangingUserId(), 0, packageName)
- .sendToTarget();
+ final int changingUserId = getChangingUserId();
+ // Only remove the package's data if a profile owner is not defined for the user
+ if (shouldDeleteObsoleteData(UserHandle.of(changingUserId))) {
+ mHandler.obtainMessage(MSG_PACKAGE_REMOVED, changingUserId, 0, packageName)
+ .sendToTarget();
+ }
super.onPackageRemoved(packageName, uid);
}
}
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index 36d8c85..fee4a47 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -115,8 +115,9 @@
mSystemTimeSnapshot = System.currentTimeMillis();
}
- void init(final long currentTimeMillis, HashMap<String, Long> installedPackages) {
- readPackageMappingsLocked(installedPackages);
+ void init(final long currentTimeMillis, HashMap<String, Long> installedPackages,
+ boolean deleteObsoleteData) {
+ readPackageMappingsLocked(installedPackages, deleteObsoleteData);
mDatabase.init(currentTimeMillis);
if (mDatabase.wasUpgradePerformed()) {
mDatabase.prunePackagesDataOnUpgrade(installedPackages);
@@ -180,12 +181,13 @@
return mDatabase.onPackageRemoved(packageName, timeRemoved);
}
- private void readPackageMappingsLocked(HashMap<String, Long> installedPackages) {
+ private void readPackageMappingsLocked(HashMap<String, Long> installedPackages,
+ boolean deleteObsoleteData) {
mDatabase.readMappingsLocked();
// Package mappings for the system user are updated after 24 hours via a job scheduled by
// UsageStatsIdleService to ensure restored data is not lost on first boot. Additionally,
// this makes user service initialization a little quicker on subsequent boots.
- if (mUserId != UserHandle.USER_SYSTEM) {
+ if (mUserId != UserHandle.USER_SYSTEM && deleteObsoleteData) {
updatePackageMappingsLocked(installedPackages);
}
}
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 8cb0909..3882acf 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -175,10 +175,7 @@
// Delay for debouncing USB disconnects.
// We often get rapid connect/disconnect events when enabling USB functions,
// which need debouncing.
- private static final int DEVICE_STATE_UPDATE_DELAY = 3000;
-
- // Delay for debouncing USB disconnects on Type-C ports in host mode
- private static final int HOST_STATE_UPDATE_DELAY = 1000;
+ private static final int UPDATE_DELAY = 1000;
// Timeout for entering USB request mode.
// Request is cancelled if host does not configure device within 10 seconds.
@@ -639,7 +636,7 @@
msg.arg1 = connected;
msg.arg2 = configured;
// debounce disconnects to avoid problems bringing up USB tethering
- sendMessageDelayed(msg, (connected == 0) ? DEVICE_STATE_UPDATE_DELAY : 0);
+ sendMessageDelayed(msg, (connected == 0) ? UPDATE_DELAY : 0);
}
public void updateHostState(UsbPort port, UsbPortStatus status) {
@@ -654,7 +651,7 @@
removeMessages(MSG_UPDATE_PORT_STATE);
Message msg = obtainMessage(MSG_UPDATE_PORT_STATE, args);
// debounce rapid transitions of connect/disconnect on type-c ports
- sendMessageDelayed(msg, HOST_STATE_UPDATE_DELAY);
+ sendMessageDelayed(msg, UPDATE_DELAY);
}
private void setAdbEnabled(boolean enable) {
diff --git a/services/uwb/java/com/android/server/uwb/UwbServiceImpl.java b/services/uwb/java/com/android/server/uwb/UwbServiceImpl.java
index 70d6aab..889e182 100644
--- a/services/uwb/java/com/android/server/uwb/UwbServiceImpl.java
+++ b/services/uwb/java/com/android/server/uwb/UwbServiceImpl.java
@@ -356,7 +356,7 @@
private void handleAirplaneModeEvent() {
try {
getVendorUwbAdapter().setEnabled(isEnabled());
- } catch (RemoteException e) {
+ } catch (RemoteException | IllegalStateException e) {
Log.e(TAG, "Unable to set UWB Adapter state.", e);
}
}
diff --git a/telephony/OWNERS b/telephony/OWNERS
index 4016ba7..f248fd5 100644
--- a/telephony/OWNERS
+++ b/telephony/OWNERS
@@ -1,5 +1,6 @@
set noparent
+amitmahajan@google.com
breadley@google.com
fionaxu@google.com
jackyu@google.com
diff --git a/tests/Codegen/OWNERS b/tests/Codegen/OWNERS
index e69de29..da723b3 100644
--- a/tests/Codegen/OWNERS
+++ b/tests/Codegen/OWNERS
@@ -0,0 +1 @@
+eugenesusla@google.com
\ No newline at end of file
diff --git a/tools/aapt2/OWNERS b/tools/aapt2/OWNERS
index a96d15e..4f655e5 100644
--- a/tools/aapt2/OWNERS
+++ b/tools/aapt2/OWNERS
@@ -1,3 +1,4 @@
set noparent
+toddke@google.com
zyy@google.com
patb@google.com
\ No newline at end of file
diff --git a/tools/codegen/OWNERS b/tools/codegen/OWNERS
index e69de29..da723b3 100644
--- a/tools/codegen/OWNERS
+++ b/tools/codegen/OWNERS
@@ -0,0 +1 @@
+eugenesusla@google.com
\ No newline at end of file