summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp3
-rw-r--r--apex/appsearch/framework/Android.bp7
-rw-r--r--apex/media/framework/Android.bp7
-rw-r--r--apex/sdkextensions/framework/Android.bp5
-rw-r--r--apex/statsd/framework/Android.bp11
-rw-r--r--api/current.txt1
-rwxr-xr-xapi/system-current.txt1
-rw-r--r--core/java/android/os/Process.java5
-rw-r--r--core/java/android/widget/Editor.java27
-rw-r--r--core/java/android/widget/EditorTouchState.java14
-rw-r--r--core/jni/android/graphics/apex/android_bitmap.cpp93
-rw-r--r--core/jni/android/graphics/apex/include/android/graphics/bitmap.h5
-rw-r--r--core/res/AndroidManifest.xml1
-rw-r--r--core/tests/coretests/src/android/app/DownloadManagerBaseTest.java9
-rw-r--r--core/tests/coretests/src/android/widget/EditorCursorDragTest.java86
-rw-r--r--core/tests/coretests/src/android/widget/EditorTouchStateTest.java54
-rw-r--r--libs/hwui/pipeline/skia/SkiaPipeline.cpp5
-rw-r--r--native/graphics/jni/bitmap.cpp10
-rw-r--r--native/graphics/jni/libjnigraphics.map.txt1
-rw-r--r--packages/SystemUI/docs/broadcasts.md35
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/ScreenDecorations.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt39
-rw-r--r--packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/power/PowerUI.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt45
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/broadcast/UserBroadcastDispatcherTest.kt37
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java2
-rw-r--r--packages/Tethering/Android.bp1
-rw-r--r--packages/Tethering/common/TetheringLib/Android.bp10
-rw-r--r--services/backup/java/com/android/server/backup/BackupManagerService.java27
-rw-r--r--services/backup/java/com/android/server/backup/UserBackupManagerService.java33
-rw-r--r--services/core/java/com/android/server/notification/OWNERS4
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java2
-rw-r--r--services/net/java/android/net/ip/IpClientCallbacks.java13
-rw-r--r--services/net/java/android/net/ip/IpClientUtil.java1
-rw-r--r--services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java41
-rw-r--r--services/tests/servicestests/src/com/android/server/backup/BackupManagerServiceTest.java26
-rw-r--r--wifi/Android.bp5
54 files changed, 564 insertions, 151 deletions
diff --git a/Android.bp b/Android.bp
index 0d9cbd8daf5c..554ceae3adad 100644
--- a/Android.bp
+++ b/Android.bp
@@ -487,7 +487,8 @@ java_library {
// TODO(b/140299412): should be framework-wifi-stubs
"framework-wifi",
"ike-stubs",
- // TODO(jiyong): add more stubs for APEXes here
+ // TODO(b/147200698): should be the stub of framework-tethering
+ "framework-tethering",
],
sdk_version: "core_platform",
apex_available: ["//apex_available:platform"],
diff --git a/apex/appsearch/framework/Android.bp b/apex/appsearch/framework/Android.bp
index 3dc5a2c10b6b..1f30dda21ef7 100644
--- a/apex/appsearch/framework/Android.bp
+++ b/apex/appsearch/framework/Android.bp
@@ -26,9 +26,16 @@ java_library {
installable: true,
sdk_version: "core_platform", // TODO(b/146218515) should be core_current
srcs: [":framework-appsearch-sources"],
+ hostdex: true, // for hiddenapi check
libs: [
"framework-minus-apex", // TODO(b/146218515) should be framework-system-stubs
],
+ visibility: [
+ "//frameworks/base/apex/appsearch:__subpackages__",
+ // TODO(b/146218515) remove this when framework is built with the stub of appsearch
+ "//frameworks/base",
+ ],
+ apex_available: ["com.android.appsearch"],
}
metalava_appsearch_docs_args =
diff --git a/apex/media/framework/Android.bp b/apex/media/framework/Android.bp
index 6bd0086681a7..18382a488428 100644
--- a/apex/media/framework/Android.bp
+++ b/apex/media/framework/Android.bp
@@ -55,6 +55,13 @@ java_library {
jarjar_rules: "jarjar_rules.txt",
plugins: ["java_api_finder"],
+
+ hostdex: true, // for hiddenapi check
+ visibility: ["//frameworks/av/apex:__subpackages__"],
+ apex_available: [
+ "com.android.media",
+ "test_com.android.media",
+ ],
}
filegroup {
diff --git a/apex/sdkextensions/framework/Android.bp b/apex/sdkextensions/framework/Android.bp
index 5504f4e5dd8e..dd174734df6d 100644
--- a/apex/sdkextensions/framework/Android.bp
+++ b/apex/sdkextensions/framework/Android.bp
@@ -36,6 +36,11 @@ java_library {
"//frameworks/base/apex/sdkextensions",
"//frameworks/base/apex/sdkextensions/testing",
],
+ hostdex: true, // for hiddenapi check
+ apex_available: [
+ "com.android.sdkext",
+ "test_com.android.sdkext",
+ ],
}
droidstubs {
diff --git a/apex/statsd/framework/Android.bp b/apex/statsd/framework/Android.bp
index a2b0577fe001..0b46645ad06f 100644
--- a/apex/statsd/framework/Android.bp
+++ b/apex/statsd/framework/Android.bp
@@ -37,7 +37,16 @@ java_library {
// TODO(b/146230220): Use framework-system-stubs instead.
"android_system_stubs_current",
],
- // TODO:(b/146210774): Add apex_available field.
+ hostdex: true, // for hiddenapi check
+ visibility: [
+ "//frameworks/base/apex/statsd:__subpackages__",
+ //TODO(b/146167933) remove this when framework is built with framework-statsd-stubs
+ "//frameworks/base",
+ ],
+ apex_available: [
+ "com.android.os.statsd",
+ "test_com.android.os.statsd",
+ ],
}
droidstubs {
diff --git a/api/current.txt b/api/current.txt
index 0c93555fc483..edb31dfdf444 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -35831,6 +35831,7 @@ package android.os {
field public static final int THREAD_PRIORITY_URGENT_AUDIO = -19; // 0xffffffed
field public static final int THREAD_PRIORITY_URGENT_DISPLAY = -8; // 0xfffffff8
field public static final int THREAD_PRIORITY_VIDEO = -10; // 0xfffffff6
+ field public static final int WIFI_UID = 1010; // 0x3f2
}
public abstract class ProxyFileDescriptorCallback {
diff --git a/api/system-current.txt b/api/system-current.txt
index cb4f3333ecdc..367956c27721 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -152,6 +152,7 @@ package android {
field public static final String PROVIDE_RESOLVER_RANKER_SERVICE = "android.permission.PROVIDE_RESOLVER_RANKER_SERVICE";
field public static final String PROVIDE_TRUST_AGENT = "android.permission.PROVIDE_TRUST_AGENT";
field public static final String QUERY_TIME_ZONE_RULES = "android.permission.QUERY_TIME_ZONE_RULES";
+ field public static final String RADIO_SCAN_WITHOUT_LOCATION = "android.permission.RADIO_SCAN_WITHOUT_LOCATION";
field public static final String READ_ACTIVE_EMERGENCY_SESSION = "android.permission.READ_ACTIVE_EMERGENCY_SESSION";
field public static final String READ_CELL_BROADCASTS = "android.permission.READ_CELL_BROADCASTS";
field public static final String READ_CONTENT_RATING_SYSTEMS = "android.permission.READ_CONTENT_RATING_SYSTEMS";
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 5fe647c8b6bf..5d80ab6453cc 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -68,10 +68,9 @@ public class Process {
public static final int LOG_UID = 1007;
/**
- * Defines the UID/GID for the WIFI supplicant process.
- * @hide
+ * Defines the UID/GID for the WIFI native processes like wificond, supplicant, hostapd,
+ * vendor HAL, etc.
*/
- @UnsupportedAppUsage
public static final int WIFI_UID = 1010;
/**
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index a0cf53437a50..20af76b0d5ca 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -5921,8 +5921,6 @@ public class Editor {
// The offsets of that last touch down event. Remembered to start selection there.
private int mMinTouchOffset, mMaxTouchOffset;
- private boolean mGestureStayedInTapRegion;
-
// Where the user first starts the drag motion.
private int mStartOffset = -1;
@@ -6029,8 +6027,7 @@ public class Editor {
eventX, eventY);
// Double tap detection
- if (mGestureStayedInTapRegion
- && mTouchState.isMultiTapInSameArea()
+ if (mTouchState.isMultiTapInSameArea()
&& (isMouse || isPositionOnText(eventX, eventY))) {
if (TextView.DEBUG_CURSOR) {
logCursor("SelectionModifierCursorController: onTouchEvent",
@@ -6043,7 +6040,6 @@ public class Editor {
}
mDiscardNextActionUp = true;
}
- mGestureStayedInTapRegion = true;
mHaventMovedEnoughToStartDrag = true;
}
break;
@@ -6059,25 +6055,8 @@ public class Editor {
break;
case MotionEvent.ACTION_MOVE:
- final ViewConfiguration viewConfig = ViewConfiguration.get(
- mTextView.getContext());
-
- if (mGestureStayedInTapRegion || mHaventMovedEnoughToStartDrag) {
- final float deltaX = eventX - mTouchState.getLastDownX();
- final float deltaY = eventY - mTouchState.getLastDownY();
- final float distanceSquared = deltaX * deltaX + deltaY * deltaY;
-
- if (mGestureStayedInTapRegion) {
- int doubleTapTouchSlop = viewConfig.getScaledDoubleTapTouchSlop();
- mGestureStayedInTapRegion =
- distanceSquared <= doubleTapTouchSlop * doubleTapTouchSlop;
- }
- if (mHaventMovedEnoughToStartDrag) {
- // We don't start dragging until the user has moved enough.
- int touchSlop = viewConfig.getScaledTouchSlop();
- mHaventMovedEnoughToStartDrag =
- distanceSquared <= touchSlop * touchSlop;
- }
+ if (mHaventMovedEnoughToStartDrag) {
+ mHaventMovedEnoughToStartDrag = !mTouchState.isMovedEnoughForDrag();
}
if (isMouse && !isDragAcceleratorActive()) {
diff --git a/core/java/android/widget/EditorTouchState.java b/core/java/android/widget/EditorTouchState.java
index d53099d44f6f..6277afe2f613 100644
--- a/core/java/android/widget/EditorTouchState.java
+++ b/core/java/android/widget/EditorTouchState.java
@@ -31,13 +31,15 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
- * Helper class used by {@link Editor} to track state for touch events.
+ * Helper class used by {@link Editor} to track state for touch events. Ideally the logic here
+ * should be replaced with {@link android.view.GestureDetector}.
*
* @hide
*/
@VisibleForTesting(visibility = PACKAGE)
public class EditorTouchState {
private float mLastDownX, mLastDownY;
+ private long mLastDownMillis;
private float mLastUpX, mLastUpY;
private long mLastUpMillis;
@@ -106,9 +108,18 @@ public class EditorTouchState {
final int action = event.getActionMasked();
if (action == MotionEvent.ACTION_DOWN) {
final boolean isMouse = event.isFromSource(InputDevice.SOURCE_MOUSE);
+
+ // We check both the time between the last up and current down event, as well as the
+ // time between the first down and up events. The latter check is necessary to handle
+ // the case when the user taps, drags/holds for some time, and then lifts up and
+ // quickly taps in the same area. This scenario should not be treated as a double-tap.
+ // This follows the behavior in GestureDetector.
final long millisSinceLastUp = event.getEventTime() - mLastUpMillis;
+ final long millisBetweenLastDownAndLastUp = mLastUpMillis - mLastDownMillis;
+
// Detect double tap and triple click.
if (millisSinceLastUp <= ViewConfiguration.getDoubleTapTimeout()
+ && millisBetweenLastDownAndLastUp <= ViewConfiguration.getDoubleTapTimeout()
&& (mMultiTapStatus == MultiTapStatus.FIRST_TAP
|| (mMultiTapStatus == MultiTapStatus.DOUBLE_TAP && isMouse))) {
if (mMultiTapStatus == MultiTapStatus.FIRST_TAP) {
@@ -133,6 +144,7 @@ public class EditorTouchState {
}
mLastDownX = event.getX();
mLastDownY = event.getY();
+ mLastDownMillis = event.getEventTime();
mMovedEnoughForDrag = false;
mIsDragCloseToVertical = false;
} else if (action == MotionEvent.ACTION_UP) {
diff --git a/core/jni/android/graphics/apex/android_bitmap.cpp b/core/jni/android/graphics/apex/android_bitmap.cpp
index 90cc98699827..0f56779135b8 100644
--- a/core/jni/android/graphics/apex/android_bitmap.cpp
+++ b/core/jni/android/graphics/apex/android_bitmap.cpp
@@ -122,6 +122,99 @@ AndroidBitmapInfo ABitmap_getInfo(ABitmap* bitmapHandle) {
return getInfo(bitmap->info(), bitmap->rowBytes());
}
+static bool nearlyEqual(float a, float b) {
+ // By trial and error, this is close enough to match for the ADataSpaces we
+ // compare for.
+ return ::fabs(a-b) < .002f;
+}
+
+static bool nearlyEqual(const skcms_TransferFunction& x, const skcms_TransferFunction& y) {
+ return nearlyEqual(x.g, y.g)
+ && nearlyEqual(x.a, y.a)
+ && nearlyEqual(x.b, y.b)
+ && nearlyEqual(x.c, y.c)
+ && nearlyEqual(x.d, y.d)
+ && nearlyEqual(x.e, y.e)
+ && nearlyEqual(x.f, y.f);
+}
+
+static bool nearlyEqual(const skcms_Matrix3x3& x, const skcms_Matrix3x3& y) {
+ for (int i = 0; i < 3; i++) {
+ for (int j = 0; j < 3; j++) {
+ if (!nearlyEqual(x.vals[i][j], y.vals[i][j])) return false;
+ }
+ }
+ return true;
+}
+
+static constexpr skcms_TransferFunction k2Dot6 =
+ { 2.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
+
+// Skia's SkNamedGamut::kDCIP3 is based on a white point of D65. This gamut
+// matches the white point used by ColorSpace.Named.DCIP3.
+static constexpr skcms_Matrix3x3 kDCIP3 = {{
+ { 0.486143, 0.323835, 0.154234 },
+ { 0.226676, 0.710327, 0.0629966 },
+ { 0.000800549, 0.0432385, 0.78275 },
+}};
+
+ADataSpace ABitmap_getDataSpace(ABitmap* bitmapHandle) {
+ Bitmap* bitmap = TypeCast::toBitmap(bitmapHandle);
+ const SkImageInfo& info = bitmap->info();
+ SkColorSpace* colorSpace = info.colorSpace();
+ if (!colorSpace) {
+ return ADATASPACE_UNKNOWN;
+ }
+
+ if (colorSpace->isSRGB()) {
+ if (info.colorType() == kRGBA_F16_SkColorType) {
+ return ADATASPACE_SCRGB;
+ }
+ return ADATASPACE_SRGB;
+ }
+
+ skcms_TransferFunction fn;
+ LOG_ALWAYS_FATAL_IF(!colorSpace->isNumericalTransferFn(&fn));
+
+ skcms_Matrix3x3 gamut;
+ LOG_ALWAYS_FATAL_IF(!colorSpace->toXYZD50(&gamut));
+
+ if (nearlyEqual(gamut, SkNamedGamut::kSRGB)) {
+ if (nearlyEqual(fn, SkNamedTransferFn::kLinear)) {
+ // Skia doesn't differentiate amongst the RANGES. In Java, we associate
+ // LINEAR_EXTENDED_SRGB with F16, and LINEAR_SRGB with other Configs.
+ // Make the same association here.
+ if (info.colorType() == kRGBA_F16_SkColorType) {
+ return ADATASPACE_SCRGB_LINEAR;
+ }
+ return ADATASPACE_SRGB_LINEAR;
+ }
+
+ if (nearlyEqual(fn, SkNamedTransferFn::kRec2020)) {
+ return ADATASPACE_BT709;
+ }
+ }
+
+ if (nearlyEqual(fn, SkNamedTransferFn::kSRGB) && nearlyEqual(gamut, SkNamedGamut::kDCIP3)) {
+ return ADATASPACE_DISPLAY_P3;
+ }
+
+ if (nearlyEqual(fn, SkNamedTransferFn::k2Dot2) && nearlyEqual(gamut, SkNamedGamut::kAdobeRGB)) {
+ return ADATASPACE_ADOBE_RGB;
+ }
+
+ if (nearlyEqual(fn, SkNamedTransferFn::kRec2020)
+ && nearlyEqual(gamut, SkNamedGamut::kRec2020)) {
+ return ADATASPACE_BT2020;
+ }
+
+ if (nearlyEqual(fn, k2Dot6) && nearlyEqual(gamut, kDCIP3)) {
+ return ADATASPACE_DCI_P3;
+ }
+
+ return ADATASPACE_UNKNOWN;
+}
+
AndroidBitmapInfo ABitmap_getInfoFromJava(JNIEnv* env, jobject bitmapObj) {
uint32_t rowBytes = 0;
SkImageInfo imageInfo = GraphicsJNI::getBitmapInfo(env, bitmapObj, &rowBytes);
diff --git a/core/jni/android/graphics/apex/include/android/graphics/bitmap.h b/core/jni/android/graphics/apex/include/android/graphics/bitmap.h
index f231eeddb7e2..32b8a450e147 100644
--- a/core/jni/android/graphics/apex/include/android/graphics/bitmap.h
+++ b/core/jni/android/graphics/apex/include/android/graphics/bitmap.h
@@ -17,6 +17,7 @@
#define ANDROID_GRAPHICS_BITMAP_H
#include <android/bitmap.h>
+#include <android/data_space.h>
#include <jni.h>
#include <sys/cdefs.h>
@@ -49,6 +50,7 @@ void ABitmap_acquireRef(ABitmap* bitmap);
void ABitmap_releaseRef(ABitmap* bitmap);
AndroidBitmapInfo ABitmap_getInfo(ABitmap* bitmap);
+ADataSpace ABitmap_getDataSpace(ABitmap* bitmap);
void* ABitmap_getPixels(ABitmap* bitmap);
void ABitmap_notifyPixelsChanged(ABitmap* bitmap);
@@ -106,6 +108,7 @@ namespace graphics {
ABitmap* get() const { return mBitmap; }
AndroidBitmapInfo getInfo() const { return ABitmap_getInfo(mBitmap); }
+ ADataSpace getDataSpace() const { return ABitmap_getDataSpace(mBitmap); }
void* getPixels() const { return ABitmap_getPixels(mBitmap); }
void notifyPixelsChanged() const { ABitmap_notifyPixelsChanged(mBitmap); }
@@ -119,4 +122,4 @@ namespace graphics {
}; // namespace android
#endif // __cplusplus
-#endif // ANDROID_GRAPHICS_BITMAP_H \ No newline at end of file
+#endif // ANDROID_GRAPHICS_BITMAP_H
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 5aa0a2dda17e..03d34b595e4a 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1654,6 +1654,7 @@
<!-- Allows holder to request bluetooth/wifi scan bypassing global "use location" setting and
location permissions.
<p>Not for use by third-party or privileged applications.
+ @SystemApi
@hide
-->
<permission android:name="android.permission.RADIO_SCAN_WITHOUT_LOCATION"
diff --git a/core/tests/coretests/src/android/app/DownloadManagerBaseTest.java b/core/tests/coretests/src/android/app/DownloadManagerBaseTest.java
index 68b9b0079761..f4709ff0bc00 100644
--- a/core/tests/coretests/src/android/app/DownloadManagerBaseTest.java
+++ b/core/tests/coretests/src/android/app/DownloadManagerBaseTest.java
@@ -33,14 +33,15 @@ import android.os.ParcelFileDescriptor.AutoCloseInputStream;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
+import android.support.test.uiautomator.UiDevice;
import android.test.InstrumentationTestCase;
import android.util.Log;
-import libcore.io.Streams;
-
import com.google.mockwebserver.MockResponse;
import com.google.mockwebserver.MockWebServer;
+import libcore.io.Streams;
+
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
@@ -63,6 +64,7 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {
private static final String TAG = "DownloadManagerBaseTest";
protected DownloadManager mDownloadManager = null;
private MockWebServer mServer = null;
+ private UiDevice mUiDevice = null;
protected String mFileType = "text/plain";
protected Context mContext = null;
protected MultipleDownloadsCompletedReceiver mReceiver = null;
@@ -234,6 +236,7 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {
@Override
public void setUp() throws Exception {
mContext = getInstrumentation().getContext();
+ mUiDevice = UiDevice.getInstance(getInstrumentation());
mDownloadManager = (DownloadManager)mContext.getSystemService(Context.DOWNLOAD_SERVICE);
mServer = new MockWebServer();
mServer.play();
@@ -512,7 +515,7 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {
Log.i(LOG_TAG, "Setting WiFi State to: " + enable);
WifiManager manager = (WifiManager)mContext.getSystemService(Context.WIFI_SERVICE);
- manager.setWifiEnabled(enable);
+ mUiDevice.executeShellCommand("svc wifi " + (enable ? "enable" : "disable"));
String timeoutMessage = "Timed out waiting for Wifi to be "
+ (enable ? "enabled!" : "disabled!");
diff --git a/core/tests/coretests/src/android/widget/EditorCursorDragTest.java b/core/tests/coretests/src/android/widget/EditorCursorDragTest.java
index f497db2256dd..89c237498e5c 100644
--- a/core/tests/coretests/src/android/widget/EditorCursorDragTest.java
+++ b/core/tests/coretests/src/android/widget/EditorCursorDragTest.java
@@ -226,6 +226,61 @@ public class EditorCursorDragTest {
}
@Test
+ public void testEditor_onTouchEvent_quickTapAfterDrag() throws Throwable {
+ String text = "Hi world!";
+ onView(withId(R.id.textview)).perform(replaceText(text));
+ onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(0));
+
+ TextView tv = mActivity.findViewById(R.id.textview);
+ Editor editor = tv.getEditorForTesting();
+
+ // Simulate a tap-and-drag gesture.
+ long event1Time = 1001;
+ MotionEvent event1 = downEvent(event1Time, event1Time, 5f, 10f);
+ mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event1));
+ assertFalse(editor.getInsertionController().isCursorBeingModified());
+ assertFalse(editor.getSelectionController().isCursorBeingModified());
+
+ long event2Time = 1002;
+ MotionEvent event2 = moveEvent(event1Time, event2Time, 50f, 10f);
+ mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event2));
+ assertTrue(editor.getInsertionController().isCursorBeingModified());
+ assertFalse(editor.getSelectionController().isCursorBeingModified());
+
+ long event3Time = 1003;
+ MotionEvent event3 = moveEvent(event1Time, event3Time, 100f, 10f);
+ mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event3));
+ assertTrue(editor.getInsertionController().isCursorBeingModified());
+ assertFalse(editor.getSelectionController().isCursorBeingModified());
+
+ long event4Time = 2004;
+ MotionEvent event4 = upEvent(event1Time, event4Time, 100f, 10f);
+ mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event4));
+ assertFalse(editor.getInsertionController().isCursorBeingModified());
+ assertFalse(editor.getSelectionController().isCursorBeingModified());
+
+ // Simulate a quick tap after the drag, near the location where the drag ended.
+ long event5Time = 2005;
+ MotionEvent event5 = downEvent(event5Time, event5Time, 90f, 10f);
+ mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event5));
+ assertFalse(editor.getInsertionController().isCursorBeingModified());
+ assertFalse(editor.getSelectionController().isCursorBeingModified());
+
+ long event6Time = 2006;
+ MotionEvent event6 = upEvent(event5Time, event6Time, 90f, 10f);
+ mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event6));
+ assertFalse(editor.getInsertionController().isCursorBeingModified());
+ assertFalse(editor.getSelectionController().isCursorBeingModified());
+
+ // Simulate another quick tap in the same location; now selection should be triggered.
+ long event7Time = 2007;
+ MotionEvent event7 = downEvent(event7Time, event7Time, 90f, 10f);
+ mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event7));
+ assertFalse(editor.getInsertionController().isCursorBeingModified());
+ assertTrue(editor.getSelectionController().isCursorBeingModified());
+ }
+
+ @Test
public void testEditor_onTouchEvent_cursorDrag() throws Throwable {
String text = "testEditor_onTouchEvent_cursorDrag";
onView(withId(R.id.textview)).perform(replaceText(text));
@@ -237,29 +292,25 @@ public class EditorCursorDragTest {
// Simulate a tap-and-drag gesture. This should trigger a cursor drag.
long event1Time = 1001;
MotionEvent event1 = downEvent(event1Time, event1Time, 20f, 30f);
- mActivity.runOnUiThread(() -> editor.onTouchEvent(event1));
- mInstrumentation.waitForIdleSync();
+ mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event1));
assertFalse(editor.getInsertionController().isCursorBeingModified());
assertFalse(editor.getSelectionController().isCursorBeingModified());
long event2Time = 1002;
MotionEvent event2 = moveEvent(event1Time, event2Time, 21f, 30f);
- mActivity.runOnUiThread(() -> editor.onTouchEvent(event2));
- mInstrumentation.waitForIdleSync();
+ mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event2));
assertFalse(editor.getInsertionController().isCursorBeingModified());
assertFalse(editor.getSelectionController().isCursorBeingModified());
long event3Time = 1003;
- MotionEvent event3 = moveEvent(event3Time, event3Time, 120f, 30f);
- mActivity.runOnUiThread(() -> editor.onTouchEvent(event3));
- mInstrumentation.waitForIdleSync();
+ MotionEvent event3 = moveEvent(event1Time, event3Time, 120f, 30f);
+ mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event3));
assertTrue(editor.getInsertionController().isCursorBeingModified());
assertFalse(editor.getSelectionController().isCursorBeingModified());
long event4Time = 1004;
- MotionEvent event4 = upEvent(event3Time, event4Time, 120f, 30f);
- mActivity.runOnUiThread(() -> editor.onTouchEvent(event4));
- mInstrumentation.waitForIdleSync();
+ MotionEvent event4 = upEvent(event1Time, event4Time, 120f, 30f);
+ mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event4));
assertFalse(editor.getInsertionController().isCursorBeingModified());
assertFalse(editor.getSelectionController().isCursorBeingModified());
}
@@ -276,36 +327,31 @@ public class EditorCursorDragTest {
// Simulate a double-tap followed by a drag. This should trigger a selection drag.
long event1Time = 1001;
MotionEvent event1 = downEvent(event1Time, event1Time, 20f, 30f);
- mActivity.runOnUiThread(() -> editor.onTouchEvent(event1));
- mInstrumentation.waitForIdleSync();
+ mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event1));
assertFalse(editor.getInsertionController().isCursorBeingModified());
assertFalse(editor.getSelectionController().isCursorBeingModified());
long event2Time = 1002;
MotionEvent event2 = upEvent(event1Time, event2Time, 20f, 30f);
- mActivity.runOnUiThread(() -> editor.onTouchEvent(event2));
- mInstrumentation.waitForIdleSync();
+ mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event2));
assertFalse(editor.getInsertionController().isCursorBeingModified());
assertFalse(editor.getSelectionController().isCursorBeingModified());
long event3Time = 1003;
MotionEvent event3 = downEvent(event3Time, event3Time, 20f, 30f);
- mActivity.runOnUiThread(() -> editor.onTouchEvent(event3));
- mInstrumentation.waitForIdleSync();
+ mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event3));
assertFalse(editor.getInsertionController().isCursorBeingModified());
assertTrue(editor.getSelectionController().isCursorBeingModified());
long event4Time = 1004;
MotionEvent event4 = moveEvent(event3Time, event4Time, 120f, 30f);
- mActivity.runOnUiThread(() -> editor.onTouchEvent(event4));
- mInstrumentation.waitForIdleSync();
+ mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event4));
assertFalse(editor.getInsertionController().isCursorBeingModified());
assertTrue(editor.getSelectionController().isCursorBeingModified());
long event5Time = 1005;
MotionEvent event5 = upEvent(event3Time, event5Time, 120f, 30f);
- mActivity.runOnUiThread(() -> editor.onTouchEvent(event5));
- mInstrumentation.waitForIdleSync();
+ mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event5));
assertFalse(editor.getInsertionController().isCursorBeingModified());
assertFalse(editor.getSelectionController().isCursorBeingModified());
}
diff --git a/core/tests/coretests/src/android/widget/EditorTouchStateTest.java b/core/tests/coretests/src/android/widget/EditorTouchStateTest.java
index 6adb1b8fa0d6..215d0b800074 100644
--- a/core/tests/coretests/src/android/widget/EditorTouchStateTest.java
+++ b/core/tests/coretests/src/android/widget/EditorTouchStateTest.java
@@ -120,6 +120,60 @@ public class EditorTouchStateTest {
}
@Test
+ public void testUpdate_doubleTap_delayAfterFirstDownEvent() throws Exception {
+ // Simulate an ACTION_DOWN event.
+ long event1Time = 1000;
+ MotionEvent event1 = downEvent(event1Time, event1Time, 20f, 30f);
+ mTouchState.update(event1, mConfig);
+ assertSingleTap(mTouchState, 20f, 30f, 0, 0, false);
+
+ // Simulate an ACTION_UP event with a delay that's longer than the double-tap timeout.
+ long event2Time = 1000 + ViewConfiguration.getDoubleTapTimeout() + 1;
+ MotionEvent event2 = upEvent(event1Time, event2Time, 20f, 30f);
+ mTouchState.update(event2, mConfig);
+ assertSingleTap(mTouchState, 20f, 30f, 20f, 30f, false);
+
+ // Generate an ACTION_DOWN event whose time is within the double-tap timeout when
+ // calculated from the last ACTION_UP event time. Even though the time between the last up
+ // and this down event is within the double-tap timeout, this should not be considered a
+ // double-tap (since the first down event had a longer delay).
+ long event3Time = event2Time + 1;
+ MotionEvent event3 = downEvent(event3Time, event3Time, 22f, 33f);
+ mTouchState.update(event3, mConfig);
+ assertSingleTap(mTouchState, 22f, 33f, 20f, 30f, false);
+ }
+
+ @Test
+ public void testUpdate_quickTapAfterDrag() throws Exception {
+ // Simulate an ACTION_DOWN event.
+ long event1Time = 1000;
+ MotionEvent event1 = downEvent(event1Time, event1Time, 20f, 30f);
+ mTouchState.update(event1, mConfig);
+ assertSingleTap(mTouchState, 20f, 30f, 0, 0, false);
+
+ // Simulate an ACTION_MOVE event.
+ long event2Time = 1001;
+ MotionEvent event2 = moveEvent(event1Time, event2Time, 200f, 31f);
+ mTouchState.update(event2, mConfig);
+ assertSingleTap(mTouchState, 20f, 30f, 0, 0, true);
+
+ // Simulate an ACTION_UP event with a delay that's longer than the double-tap timeout.
+ long event3Time = 5000;
+ MotionEvent event3 = upEvent(event1Time, event3Time, 200f, 31f);
+ mTouchState.update(event3, mConfig);
+ assertSingleTap(mTouchState, 20f, 30f, 200f, 31f, false);
+
+ // Generate an ACTION_DOWN event whose time is within the double-tap timeout when
+ // calculated from the last ACTION_UP event time. Even though the time between the last up
+ // and this down event is within the double-tap timeout, this should not be considered a
+ // double-tap (since the first down event had a longer delay).
+ long event4Time = event3Time + 1;
+ MotionEvent event4 = downEvent(event4Time, event4Time, 200f, 31f);
+ mTouchState.update(event4, mConfig);
+ assertSingleTap(mTouchState, 200f, 31f, 200f, 31f, false);
+ }
+
+ @Test
public void testUpdate_tripleClick_mouse() throws Exception {
// Simulate an ACTION_DOWN event.
long event1Time = 1000;
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index 11dc013af6bc..35a885f46919 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -457,7 +457,10 @@ void SkiaPipeline::renderFrameImpl(const SkRect& clip,
const Rect& contentDrawBounds, SkCanvas* canvas,
const SkMatrix& preTransform) {
SkAutoCanvasRestore saver(canvas, true);
- canvas->androidFramework_setDeviceClipRestriction(preTransform.mapRect(clip).roundOut());
+ auto clipRestriction = preTransform.mapRect(clip).roundOut();
+ canvas->androidFramework_setDeviceClipRestriction(clipRestriction);
+ canvas->drawAnnotation(SkRect::Make(clipRestriction), "AndroidDeviceClipRestriction",
+ nullptr);
canvas->concat(preTransform);
// STOPSHIP: Revert, temporary workaround to clear always F16 frame buffer for b/74976293
diff --git a/native/graphics/jni/bitmap.cpp b/native/graphics/jni/bitmap.cpp
index 1aebeaf1e7e8..26c7f8d709e7 100644
--- a/native/graphics/jni/bitmap.cpp
+++ b/native/graphics/jni/bitmap.cpp
@@ -16,6 +16,7 @@
#include <android/bitmap.h>
#include <android/graphics/bitmap.h>
+#include <android/data_space.h>
int AndroidBitmap_getInfo(JNIEnv* env, jobject jbitmap,
AndroidBitmapInfo* info) {
@@ -29,6 +30,15 @@ int AndroidBitmap_getInfo(JNIEnv* env, jobject jbitmap,
return ANDROID_BITMAP_RESULT_SUCCESS;
}
+int32_t AndroidBitmap_getDataSpace(JNIEnv* env, jobject jbitmap) {
+ if (NULL == env || NULL == jbitmap) {
+ return ADATASPACE_UNKNOWN; // Or return a real error?
+ }
+
+ android::graphics::Bitmap bitmap(env, jbitmap);
+ return bitmap.getDataSpace();
+}
+
int AndroidBitmap_lockPixels(JNIEnv* env, jobject jbitmap, void** addrPtr) {
if (NULL == env || NULL == jbitmap) {
return ANDROID_BITMAP_RESULT_BAD_PARAMETER;
diff --git a/native/graphics/jni/libjnigraphics.map.txt b/native/graphics/jni/libjnigraphics.map.txt
index a601d8af2830..6adb95520d6c 100644
--- a/native/graphics/jni/libjnigraphics.map.txt
+++ b/native/graphics/jni/libjnigraphics.map.txt
@@ -1,6 +1,7 @@
LIBJNIGRAPHICS {
global:
AndroidBitmap_getInfo;
+ AndroidBitmap_getDataSpace;
AndroidBitmap_lockPixels;
AndroidBitmap_unlockPixels;
local:
diff --git a/packages/SystemUI/docs/broadcasts.md b/packages/SystemUI/docs/broadcasts.md
index 56a637fe588c..28657f28e53b 100644
--- a/packages/SystemUI/docs/broadcasts.md
+++ b/packages/SystemUI/docs/broadcasts.md
@@ -42,24 +42,29 @@ Acquire the dispatcher by using `@Inject` to obtain a `BroadcastDispatcher`. The
```kotlin
/**
- * Register a receiver for broadcast with the dispatcher
- *
- * @param receiver A receiver to dispatch the [Intent]
- * @param filter A filter to determine what broadcasts should be dispatched to this receiver.
- * It will only take into account actions and categories for filtering. It must
- * have at least one action.
- * @param handler A handler to dispatch [BroadcastReceiver.onReceive]. By default, it is the
- * main handler. Pass `null` to use the default.
- * @param user A user handle to determine which broadcast should be dispatched to this receiver.
- * By default, it is the current user.
- * @throws IllegalArgumentException if the filter has other constraints that are not actions or
- * categories or the filter has no actions.
- */
+ * Register a receiver for broadcast with the dispatcher
+ *
+ * @param receiver A receiver to dispatch the [Intent]
+ * @param filter A filter to determine what broadcasts should be dispatched to this receiver.
+ * It will only take into account actions and categories for filtering. It must
+ * have at least one action.
+ * @param executor An executor to dispatch [BroadcastReceiver.onReceive]. Pass null to use an
+ * executor in the main thread (default).
+ * @param user A user handle to determine which broadcast should be dispatched to this receiver.
+ * By default, it is the current user.
+ * @throws IllegalArgumentException if the filter has other constraints that are not actions or
+ * categories or the filter has no actions.
+ */
@JvmOverloads
-fun registerReceiver(BroadcastReceiver, IntentFilter, Handler? = mainHandler, UserHandle = context.user)
+fun registerReceiver(
+ BroadcastReceiver,
+ IntentFilter,
+ Executor? = context.mainExecutor,
+ UserHandle = context.user
+) {
```
-All subscriptions are done with the same overloaded method. As specified in the doc, in order to pass a `UserHandle` with the default `Handler`, pass `null` for the `Handler`.
+All subscriptions are done with the same overloaded method. As specified in the doc, in order to pass a `UserHandle` with the default `Executor`, pass `null` for the `Executor`.
In the same way as with `Context`, subscribing the same `BroadcastReceiver` for the same user using different filters will result on two subscriptions, not in replacing the filter.
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 431862f1cc11..a58e3d78bb08 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -1638,7 +1638,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
- broadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, mHandler);
+ broadcastDispatcher.registerReceiverWithHandler(mBroadcastReceiver, filter, mHandler);
final IntentFilter allUserFilter = new IntentFilter();
allUserFilter.addAction(Intent.ACTION_USER_INFO_CHANGED);
@@ -1649,8 +1649,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
allUserFilter.addAction(ACTION_USER_UNLOCKED);
allUserFilter.addAction(ACTION_USER_STOPPED);
allUserFilter.addAction(ACTION_USER_REMOVED);
- broadcastDispatcher.registerReceiver(mBroadcastAllReceiver, allUserFilter, mHandler,
- UserHandle.ALL);
+ broadcastDispatcher.registerReceiverWithHandler(mBroadcastAllReceiver, allUserFilter,
+ mHandler, UserHandle.ALL);
mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
try {
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index 0e736dcd11a8..c533755c76da 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -266,7 +266,7 @@ public class ScreenDecorations extends SystemUI implements Tunable {
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_USER_SWITCHED);
- mBroadcastDispatcher.registerReceiver(mIntentReceiver, filter, mHandler);
+ mBroadcastDispatcher.registerReceiverWithHandler(mIntentReceiver, filter, mHandler);
mOverlay.addOnLayoutChangeListener(new OnLayoutChangeListener() {
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt b/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt
index 8cb0cc5db1d3..cedf7c354ccc 100644
--- a/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt
+++ b/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt
@@ -20,6 +20,7 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.IntentFilter
import android.os.Handler
+import android.os.HandlerExecutor
import android.os.Looper
import android.os.Message
import android.os.UserHandle
@@ -32,13 +33,14 @@ import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import java.io.FileDescriptor
import java.io.PrintWriter
+import java.util.concurrent.Executor
import javax.inject.Inject
import javax.inject.Singleton
data class ReceiverData(
val receiver: BroadcastReceiver,
val filter: IntentFilter,
- val handler: Handler,
+ val executor: Executor,
val user: UserHandle
)
@@ -76,24 +78,49 @@ open class BroadcastDispatcher @Inject constructor (
* @param filter A filter to determine what broadcasts should be dispatched to this receiver.
* It will only take into account actions and categories for filtering. It must
* have at least one action.
- * @param handler A handler to dispatch [BroadcastReceiver.onReceive]. By default, it is the
- * main handler. Pass `null` to use the default.
+ * @param handler A handler to dispatch [BroadcastReceiver.onReceive].
* @param user A user handle to determine which broadcast should be dispatched to this receiver.
* By default, it is the current user.
* @throws IllegalArgumentException if the filter has other constraints that are not actions or
* categories or the filter has no actions.
*/
+ @Deprecated(message = "Replacing Handler for Executor in SystemUI",
+ replaceWith = ReplaceWith("registerReceiver(receiver, filter, executor, user)"))
@JvmOverloads
- fun registerReceiver(
+ fun registerReceiverWithHandler(
receiver: BroadcastReceiver,
filter: IntentFilter,
- handler: Handler? = mainHandler,
+ handler: Handler,
user: UserHandle = context.user
) {
+ registerReceiver(receiver, filter, HandlerExecutor(handler), user)
+ }
+
+ /**
+ * Register a receiver for broadcast with the dispatcher
+ *
+ * @param receiver A receiver to dispatch the [Intent]
+ * @param filter A filter to determine what broadcasts should be dispatched to this receiver.
+ * It will only take into account actions and categories for filtering. It must
+ * have at least one action.
+ * @param executor An executor to dispatch [BroadcastReceiver.onReceive]. Pass null to use an
+ * executor in the main thread (default).
+ * @param user A user handle to determine which broadcast should be dispatched to this receiver.
+ * By default, it is the current user.
+ * @throws IllegalArgumentException if the filter has other constraints that are not actions or
+ * categories or the filter has no actions.
+ */
+ @JvmOverloads
+ fun registerReceiver(
+ receiver: BroadcastReceiver,
+ filter: IntentFilter,
+ executor: Executor? = context.mainExecutor,
+ user: UserHandle = context.user
+ ) {
checkFilter(filter)
this.handler
.obtainMessage(MSG_ADD_RECEIVER,
- ReceiverData(receiver, filter, handler ?: mainHandler, user))
+ ReceiverData(receiver, filter, executor ?: context.mainExecutor, user))
.sendToTarget()
}
diff --git a/packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt b/packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt
index b2942bb14c6b..0c631aacab82 100644
--- a/packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt
+++ b/packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt
@@ -193,7 +193,7 @@ class UserBroadcastDispatcher(
it.filter.hasAction(intent.action) &&
it.filter.matchCategories(intent.categories) == null }
?.forEach {
- it.handler.post {
+ it.executor.execute {
if (DEBUG) Log.w(TAG,
"[$index] Dispatching ${intent.action} to ${it.receiver}")
it.receiver.pendingResult = pendingResult
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
index c9faf69cfd6f..4e887262659e 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
@@ -91,7 +91,7 @@ public class DozeScreenBrightness extends BroadcastReceiver implements DozeMachi
if (mDebuggable) {
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_AOD_BRIGHTNESS);
- mBroadcastDispatcher.registerReceiver(this, filter, handler, UserHandle.ALL);
+ mBroadcastDispatcher.registerReceiverWithHandler(this, filter, handler, UserHandle.ALL);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index 59ac329e1983..48750fa5e769 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -233,7 +233,7 @@ public class PowerUI extends SystemUI implements CommandQueue.Callbacks {
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_USER_SWITCHED);
- mBroadcastDispatcher.registerReceiver(this, filter, mHandler);
+ mBroadcastDispatcher.registerReceiverWithHandler(this, filter, mHandler);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
index bbff117c6f81..ad79cadcc12d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
@@ -322,7 +322,7 @@ public class TileLifecycleManager extends BroadcastReceiver implements
filter = new IntentFilter(Intent.ACTION_USER_UNLOCKED);
try {
mUserReceiverRegistered.set(true);
- mBroadcastDispatcher.registerReceiver(this, filter, mHandler, mUser);
+ mBroadcastDispatcher.registerReceiverWithHandler(this, filter, mHandler, mUser);
} catch (Exception ex) {
mUserReceiverRegistered.set(false);
Log.e(TAG, "Could not register unlock receiver", ex);
diff --git a/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java
index 077d2602e43f..9599d77bf65a 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java
@@ -98,7 +98,8 @@ public abstract class CurrentUserTracker {
if (!mReceiverRegistered) {
mCurrentUserId = ActivityManager.getCurrentUser();
IntentFilter filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
- mBroadcastDispatcher.registerReceiver(this, filter, null, UserHandle.ALL);
+ mBroadcastDispatcher.registerReceiver(this, filter, null,
+ UserHandle.ALL);
mReceiverRegistered = true;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index a3b1b5f8360b..a6842badc153 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -366,8 +366,8 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_USER_SWITCHED);
- mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, Handler.getMain(),
- UserHandle.ALL);
+ mBroadcastDispatcher.registerReceiverWithHandler(mBroadcastReceiver, filter,
+ Handler.getMain(), UserHandle.ALL);
notifyNavigationBarScreenOn();
mOverviewProxyService.addCallback(mOverviewProxyListener);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 5b34aa7781c1..00e38f814dff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -179,7 +179,7 @@ public class PhoneStatusBarPolicy
filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
filter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED);
- broadcastDispatcher.registerReceiver(mIntentReceiver, filter, mHandler);
+ broadcastDispatcher.registerReceiverWithHandler(mIntentReceiver, filter, mHandler);
// listen for user / profile change.
try {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index ddacc3aedce0..4f0af9e166c9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -188,7 +188,7 @@ public class Clock extends TextView implements DemoMode, Tunable, CommandQueue.C
// NOTE: This receiver could run before this method returns, as it's not dispatching
// on the main thread and BroadcastDispatcher may not need to register with Context.
// The receiver will return immediately if the view does not have a Handler yet.
- mBroadcastDispatcher.registerReceiver(mIntentReceiver, filter,
+ mBroadcastDispatcher.registerReceiverWithHandler(mIntentReceiver, filter,
Dependency.get(Dependency.TIME_TICK_HANDLER), UserHandle.ALL);
Dependency.get(TunerService.class).addTunable(this, CLOCK_SECONDS,
StatusBarIconController.ICON_BLACKLIST);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
index 2e26711a3578..b4c154aa28cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
@@ -96,7 +96,7 @@ public class DateView extends TextView {
filter.addAction(Intent.ACTION_TIME_CHANGED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
filter.addAction(Intent.ACTION_LOCALE_CHANGED);
- mBroadcastDispatcher.registerReceiver(mIntentReceiver, filter,
+ mBroadcastDispatcher.registerReceiverWithHandler(mIntentReceiver, filter,
Dependency.get(Dependency.TIME_TICK_HANDLER));
updateClock();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
index 570f153a62c0..cb40d7752f53 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
@@ -79,7 +79,8 @@ public class LocationControllerImpl extends BroadcastReceiver implements Locatio
IntentFilter filter = new IntentFilter();
filter.addAction(LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION);
filter.addAction(LocationManager.MODE_CHANGED_ACTION);
- mBroadcastDispatcher.registerReceiver(this, filter, new Handler(bgLooper), UserHandle.ALL);
+ mBroadcastDispatcher.registerReceiverWithHandler(this, filter,
+ new Handler(bgLooper), UserHandle.ALL);
mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
mStatusBarManager
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index f640d039ad31..679fa7e2b016 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -326,7 +326,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
filter.addAction(ConnectivityManager.INET_CONDITION_ACTION);
filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
- mBroadcastDispatcher.registerReceiver(this, filter, mReceiverHandler);
+ mBroadcastDispatcher.registerReceiverWithHandler(this, filter, mReceiverHandler);
mListening = true;
updateMobileControllers();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
index 019ef3bca709..312c4ac75bfa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
@@ -126,7 +126,8 @@ public class SecurityControllerImpl extends CurrentUserTracker implements Securi
IntentFilter filter = new IntentFilter();
filter.addAction(KeyChain.ACTION_TRUST_STORE_CHANGED);
filter.addAction(Intent.ACTION_USER_UNLOCKED);
- broadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, bgHandler, UserHandle.ALL);
+ broadcastDispatcher.registerReceiverWithHandler(mBroadcastReceiver, filter, bgHandler,
+ UserHandle.ALL);
// TODO: re-register network callback on user change.
mConnectivityManager.registerNetworkCallback(REQUEST, mNetworkCallback);
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
index 7758aba52918..31b9952afe94 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
@@ -88,7 +88,7 @@ public class ThemeOverlayController extends SystemUI {
final IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_USER_SWITCHED);
filter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED);
- mBroadcastDispatcher.registerReceiver(new BroadcastReceiver() {
+ mBroadcastDispatcher.registerReceiverWithHandler(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (DEBUG) Log.d(TAG, "Updating overlays for user switch / profile added.");
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index a4ed31d95b2b..112ae6f3758a 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -1008,7 +1008,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
- mBroadcastDispatcher.registerReceiver(this, filter, mWorker);
+ mBroadcastDispatcher.registerReceiverWithHandler(this, filter, mWorker);
}
public void destroy() {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 0c22aaeaafb9..2e0fb3bc850d 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -150,10 +150,10 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
@Test
public void testReceiversRegistered() {
- verify(mBroadcastDispatcher, atLeastOnce()).registerReceiver(
+ verify(mBroadcastDispatcher, atLeastOnce()).registerReceiverWithHandler(
eq(mKeyguardUpdateMonitor.mBroadcastReceiver),
any(IntentFilter.class), any(Handler.class));
- verify(mBroadcastDispatcher, atLeastOnce()).registerReceiver(
+ verify(mBroadcastDispatcher, atLeastOnce()).registerReceiverWithHandler(
eq(mKeyguardUpdateMonitor.mBroadcastAllReceiver),
any(IntentFilter.class), any(Handler.class), eq(UserHandle.ALL));
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
index 42fbf59fef44..22b18373e81d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
@@ -27,6 +27,8 @@ import android.test.suitebuilder.annotation.SmallTest
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.time.FakeSystemClock
import junit.framework.Assert.assertSame
import org.junit.Before
import org.junit.Test
@@ -39,6 +41,7 @@ import org.mockito.Mockito.mock
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
+import java.util.concurrent.Executor
@RunWith(AndroidTestingRunner::class)
@TestableLooper.RunWithLooper
@@ -73,6 +76,8 @@ class BroadcastDispatcherTest : SysuiTestCase() {
@Mock
private lateinit var mockHandler: Handler
+ private lateinit var executor: Executor
+
@Captor
private lateinit var argumentCaptor: ArgumentCaptor<ReceiverData>
@@ -83,6 +88,7 @@ class BroadcastDispatcherTest : SysuiTestCase() {
fun setUp() {
MockitoAnnotations.initMocks(this)
testableLooper = TestableLooper.get(this)
+ executor = FakeExecutor(FakeSystemClock())
broadcastDispatcher = TestBroadcastDispatcher(
mockContext,
@@ -98,8 +104,9 @@ class BroadcastDispatcherTest : SysuiTestCase() {
@Test
fun testAddingReceiverToCorrectUBR() {
- broadcastDispatcher.registerReceiver(broadcastReceiver, intentFilter, mockHandler, user0)
- broadcastDispatcher.registerReceiver(
+ broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
+ mockHandler, user0)
+ broadcastDispatcher.registerReceiverWithHandler(
broadcastReceiverOther, intentFilterOther, mockHandler, user1)
testableLooper.processAllMessages()
@@ -115,9 +122,29 @@ class BroadcastDispatcherTest : SysuiTestCase() {
}
@Test
+ fun testAddingReceiverToCorrectUBR_executor() {
+ broadcastDispatcher.registerReceiver(broadcastReceiver, intentFilter, executor, user0)
+ broadcastDispatcher.registerReceiver(
+ broadcastReceiverOther, intentFilterOther, executor, user1)
+
+ testableLooper.processAllMessages()
+
+ verify(mockUBRUser0).registerReceiver(capture(argumentCaptor))
+
+ assertSame(broadcastReceiver, argumentCaptor.value.receiver)
+ assertSame(intentFilter, argumentCaptor.value.filter)
+
+ verify(mockUBRUser1).registerReceiver(capture(argumentCaptor))
+ assertSame(broadcastReceiverOther, argumentCaptor.value.receiver)
+ assertSame(intentFilterOther, argumentCaptor.value.filter)
+ }
+
+ @Test
fun testRemovingReceiversRemovesFromAllUBR() {
- broadcastDispatcher.registerReceiver(broadcastReceiver, intentFilter, mockHandler, user0)
- broadcastDispatcher.registerReceiver(broadcastReceiver, intentFilter, mockHandler, user1)
+ broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
+ mockHandler, user0)
+ broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
+ mockHandler, user1)
broadcastDispatcher.unregisterReceiver(broadcastReceiver)
@@ -129,8 +156,10 @@ class BroadcastDispatcherTest : SysuiTestCase() {
@Test
fun testRemoveReceiverFromUser() {
- broadcastDispatcher.registerReceiver(broadcastReceiver, intentFilter, mockHandler, user0)
- broadcastDispatcher.registerReceiver(broadcastReceiver, intentFilter, mockHandler, user1)
+ broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
+ mockHandler, user0)
+ broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
+ mockHandler, user1)
broadcastDispatcher.unregisterReceiverForUser(broadcastReceiver, user0)
@@ -143,8 +172,8 @@ class BroadcastDispatcherTest : SysuiTestCase() {
@Test
fun testRegisterCurrentAsActualUser() {
setUserMock(mockContext, user1)
- broadcastDispatcher.registerReceiver(broadcastReceiver, intentFilter, mockHandler,
- UserHandle.CURRENT)
+ broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
+ mockHandler, UserHandle.CURRENT)
testableLooper.processAllMessages()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/broadcast/UserBroadcastDispatcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/broadcast/UserBroadcastDispatcherTest.kt
index 21ed15517752..7821ae29592e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/broadcast/UserBroadcastDispatcherTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/broadcast/UserBroadcastDispatcherTest.kt
@@ -26,6 +26,8 @@ import android.test.suitebuilder.annotation.SmallTest
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.time.FakeSystemClock
import junit.framework.Assert.assertEquals
import junit.framework.Assert.assertFalse
import junit.framework.Assert.assertTrue
@@ -69,8 +71,6 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
@Mock
private lateinit var mockContext: Context
@Mock
- private lateinit var mockHandler: Handler
- @Mock
private lateinit var mPendingResult: BroadcastReceiver.PendingResult
@Captor
@@ -81,12 +81,14 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
private lateinit var intentFilter: IntentFilter
private lateinit var intentFilterOther: IntentFilter
private lateinit var handler: Handler
+ private lateinit var fakeExecutor: FakeExecutor
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
testableLooper = TestableLooper.get(this)
handler = Handler(testableLooper.looper)
+ fakeExecutor = FakeExecutor(FakeSystemClock())
userBroadcastDispatcher = UserBroadcastDispatcher(
mockContext, USER_ID, handler, testableLooper.looper)
@@ -108,7 +110,7 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
intentFilter = IntentFilter(ACTION_1)
userBroadcastDispatcher.registerReceiver(
- ReceiverData(broadcastReceiver, intentFilter, mockHandler, USER_HANDLE))
+ ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE))
testableLooper.processAllMessages()
assertTrue(userBroadcastDispatcher.isRegistered())
@@ -128,7 +130,7 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
intentFilter = IntentFilter(ACTION_1)
userBroadcastDispatcher.registerReceiver(
- ReceiverData(broadcastReceiver, intentFilter, mockHandler, USER_HANDLE))
+ ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE))
testableLooper.processAllMessages()
reset(mockContext)
@@ -151,9 +153,9 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
}
userBroadcastDispatcher.registerReceiver(
- ReceiverData(broadcastReceiver, intentFilter, mockHandler, USER_HANDLE))
+ ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE))
userBroadcastDispatcher.registerReceiver(
- ReceiverData(broadcastReceiverOther, intentFilterOther, mockHandler, USER_HANDLE))
+ ReceiverData(broadcastReceiverOther, intentFilterOther, fakeExecutor, USER_HANDLE))
testableLooper.processAllMessages()
assertTrue(userBroadcastDispatcher.isRegistered())
@@ -179,14 +181,15 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
intentFilterOther = IntentFilter(ACTION_2)
userBroadcastDispatcher.registerReceiver(
- ReceiverData(broadcastReceiver, intentFilter, handler, USER_HANDLE))
+ ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE))
userBroadcastDispatcher.registerReceiver(
- ReceiverData(broadcastReceiverOther, intentFilterOther, handler, USER_HANDLE))
+ ReceiverData(broadcastReceiverOther, intentFilterOther, fakeExecutor, USER_HANDLE))
val intent = Intent(ACTION_2)
userBroadcastDispatcher.onReceive(mockContext, intent)
testableLooper.processAllMessages()
+ fakeExecutor.runAllReady()
verify(broadcastReceiver, never()).onReceive(any(), any())
verify(broadcastReceiverOther).onReceive(mockContext, intent)
@@ -198,14 +201,15 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
intentFilterOther = IntentFilter(ACTION_2)
userBroadcastDispatcher.registerReceiver(
- ReceiverData(broadcastReceiver, intentFilter, handler, USER_HANDLE))
+ ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE))
userBroadcastDispatcher.registerReceiver(
- ReceiverData(broadcastReceiver, intentFilterOther, handler, USER_HANDLE))
+ ReceiverData(broadcastReceiver, intentFilterOther, fakeExecutor, USER_HANDLE))
val intent = Intent(ACTION_2)
userBroadcastDispatcher.onReceive(mockContext, intent)
testableLooper.processAllMessages()
+ fakeExecutor.runAllReady()
verify(broadcastReceiver).onReceive(mockContext, intent)
}
@@ -218,14 +222,15 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
intentFilterOther.addCategory(CATEGORY_2)
userBroadcastDispatcher.registerReceiver(
- ReceiverData(broadcastReceiver, intentFilter, handler, USER_HANDLE))
+ ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE))
userBroadcastDispatcher.registerReceiver(
- ReceiverData(broadcastReceiverOther, intentFilterOther, handler, USER_HANDLE))
+ ReceiverData(broadcastReceiverOther, intentFilterOther, fakeExecutor, USER_HANDLE))
val intent = Intent(ACTION_1)
userBroadcastDispatcher.onReceive(mockContext, intent)
testableLooper.processAllMessages()
+ fakeExecutor.runAllReady()
verify(broadcastReceiver).onReceive(mockContext, intent)
verify(broadcastReceiverOther).onReceive(mockContext, intent)
@@ -235,12 +240,13 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
fun testPendingResult() {
intentFilter = IntentFilter(ACTION_1)
userBroadcastDispatcher.registerReceiver(
- ReceiverData(broadcastReceiver, intentFilter, handler, USER_HANDLE))
+ ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE))
val intent = Intent(ACTION_1)
userBroadcastDispatcher.onReceive(mockContext, intent)
testableLooper.processAllMessages()
+ fakeExecutor.runAllReady()
verify(broadcastReceiver).onReceive(mockContext, intent)
verify(broadcastReceiver).pendingResult = mPendingResult
@@ -250,15 +256,16 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
fun testRemoveReceiverReferences() {
intentFilter = IntentFilter(ACTION_1)
userBroadcastDispatcher.registerReceiver(
- ReceiverData(broadcastReceiver, intentFilter, handler, USER_HANDLE))
+ ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE))
intentFilterOther = IntentFilter(ACTION_1)
intentFilterOther.addAction(ACTION_2)
userBroadcastDispatcher.registerReceiver(
- ReceiverData(broadcastReceiverOther, intentFilterOther, handler, USER_HANDLE))
+ ReceiverData(broadcastReceiverOther, intentFilterOther, fakeExecutor, USER_HANDLE))
userBroadcastDispatcher.unregisterReceiver(broadcastReceiver)
testableLooper.processAllMessages()
+ fakeExecutor.runAllReady()
assertFalse(userBroadcastDispatcher.isReceiverReferenceHeld(broadcastReceiver))
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
index 167f361b341a..548da8e1f2aa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
@@ -110,7 +110,7 @@ public class PowerUITest extends SysuiTestCase {
@Test
public void testReceiverIsRegisteredToDispatcherOnStart() {
mPowerUI.start();
- verify(mBroadcastDispatcher).registerReceiver(
+ verify(mBroadcastDispatcher).registerReceiverWithHandler(
any(BroadcastReceiver.class),
any(IntentFilter.class),
any(Handler.class)); //PowerUI does not call with User
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
index 39afbe0a1a23..8f645b6bd3c8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
@@ -190,7 +190,7 @@ public class NavigationBarFragmentTest extends SysuiBaseFragmentTest {
mFragments.dispatchResume();
processAllMessages();
- verify(mBroadcastDispatcher).registerReceiver(
+ verify(mBroadcastDispatcher).registerReceiverWithHandler(
any(BroadcastReceiver.class),
any(IntentFilter.class),
any(Handler.class),
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 2854665aedb1..80aa6f6c49bc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java
@@ -69,7 +69,7 @@ public class VolumeDialogControllerImplTest extends SysuiTestCase {
@Test
public void testRegisteredWithDispatcher() {
- verify(mBroadcastDispatcher).registerReceiver(any(BroadcastReceiver.class),
+ verify(mBroadcastDispatcher).registerReceiverWithHandler(any(BroadcastReceiver.class),
any(IntentFilter.class),
any(Handler.class)); // VolumeDialogControllerImpl does not call with user
}
diff --git a/packages/Tethering/Android.bp b/packages/Tethering/Android.bp
index 797b713d8614..d297f3f84189 100644
--- a/packages/Tethering/Android.bp
+++ b/packages/Tethering/Android.bp
@@ -123,4 +123,5 @@ android_app {
use_embedded_native_libs: true,
// The permission configuration *must* be included to ensure security of the device
required: ["NetworkPermissionConfig"],
+ apex_available: ["com.android.tethering"],
}
diff --git a/packages/Tethering/common/TetheringLib/Android.bp b/packages/Tethering/common/TetheringLib/Android.bp
index 5785707cb9c5..264ce440f59f 100644
--- a/packages/Tethering/common/TetheringLib/Android.bp
+++ b/packages/Tethering/common/TetheringLib/Android.bp
@@ -47,6 +47,16 @@ java_library {
libs: [
"android_system_stubs_current",
],
+
+ hostdex: true, // for hiddenapi check
+ visibility: [
+ "//frameworks/base/packages/Tethering:__subpackages__",
+ //TODO(b/147200698) remove below lines when the platform is built with stubs
+ "//frameworks/base",
+ "//frameworks/base/services",
+ "//frameworks/base/services/core",
+ ],
+ apex_available: ["com.android.tethering"],
}
filegroup {
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 3bce322a7655..d45a54e0ff28 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -1452,6 +1452,11 @@ public class BackupManagerService extends IBackupManager.Stub {
if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) {
return;
}
+ dumpWithoutCheckingPermission(fd, pw, args);
+ }
+
+ @VisibleForTesting
+ void dumpWithoutCheckingPermission(FileDescriptor fd, PrintWriter pw, String[] args) {
int userId = binderGetCallingUserId();
if (!isUserReadyForBackup(userId)) {
pw.println("Inactive");
@@ -1460,7 +1465,16 @@ public class BackupManagerService extends IBackupManager.Stub {
if (args != null) {
for (String arg : args) {
- if ("users".equals(arg.toLowerCase())) {
+ if ("-h".equals(arg)) {
+ pw.println("'dumpsys backup' optional arguments:");
+ pw.println(" -h : this help text");
+ pw.println(" a[gents] : dump information about defined backup agents");
+ pw.println(" transportclients : dump information about transport clients");
+ pw.println(" transportstats : dump transport statts");
+ pw.println(" users : dump the list of users for which backup service "
+ + "is running");
+ return;
+ } else if ("users".equals(arg.toLowerCase())) {
pw.print(DUMP_RUNNING_USERS_MESSAGE);
for (int i = 0; i < mUserServices.size(); i++) {
pw.print(" " + mUserServices.keyAt(i));
@@ -1471,11 +1485,12 @@ public class BackupManagerService extends IBackupManager.Stub {
}
}
- UserBackupManagerService userBackupManagerService =
- getServiceForUserIfCallerHasPermission(UserHandle.USER_SYSTEM, "dump()");
-
- if (userBackupManagerService != null) {
- userBackupManagerService.dump(fd, pw, args);
+ for (int i = 0; i < mUserServices.size(); i++) {
+ UserBackupManagerService userBackupManagerService =
+ getServiceForUserIfCallerHasPermission(mUserServices.keyAt(i), "dump()");
+ if (userBackupManagerService != null) {
+ userBackupManagerService.dump(fd, pw, args);
+ }
}
}
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
index 064cd060528d..7b95ab526b41 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
@@ -3545,14 +3545,7 @@ public class UserBackupManagerService {
try {
if (args != null) {
for (String arg : args) {
- if ("-h".equals(arg)) {
- pw.println("'dumpsys backup' optional arguments:");
- pw.println(" -h : this help text");
- pw.println(" a[gents] : dump information about defined backup agents");
- pw.println(" users : dump the list of users for which backup service "
- + "is running");
- return;
- } else if ("agents".startsWith(arg)) {
+ if ("agents".startsWith(arg)) {
dumpAgents(pw);
return;
} else if ("transportclients".equals(arg.toLowerCase())) {
@@ -3583,8 +3576,10 @@ public class UserBackupManagerService {
}
private void dumpInternal(PrintWriter pw) {
+ // Add prefix for only non-system users so that system user dumpsys is the same as before
+ String userPrefix = mUserId == UserHandle.USER_SYSTEM ? "" : "User " + mUserId + ":";
synchronized (mQueueLock) {
- pw.println("Backup Manager is " + (mEnabled ? "enabled" : "disabled")
+ pw.println(userPrefix + "Backup Manager is " + (mEnabled ? "enabled" : "disabled")
+ " / " + (!mSetupComplete ? "not " : "") + "setup complete / "
+ (this.mPendingInits.size() == 0 ? "not " : "") + "pending init");
pw.println("Auto-restore is " + (mAutoRestore ? "enabled" : "disabled"));
@@ -3594,13 +3589,13 @@ public class UserBackupManagerService {
+ " (now = " + System.currentTimeMillis() + ')');
pw.println(" next scheduled: " + KeyValueBackupJob.nextScheduled(mUserId));
- pw.println("Transport whitelist:");
+ pw.println(userPrefix + "Transport whitelist:");
for (ComponentName transport : mTransportManager.getTransportWhitelist()) {
pw.print(" ");
pw.println(transport.flattenToShortString());
}
- pw.println("Available transports:");
+ pw.println(userPrefix + "Available transports:");
final String[] transports = listAllTransports();
if (transports != null) {
for (String t : transports) {
@@ -3626,18 +3621,18 @@ public class UserBackupManagerService {
mTransportManager.dumpTransportClients(pw);
- pw.println("Pending init: " + mPendingInits.size());
+ pw.println(userPrefix + "Pending init: " + mPendingInits.size());
for (String s : mPendingInits) {
pw.println(" " + s);
}
- pw.print("Ancestral: ");
+ pw.print(userPrefix + "Ancestral: ");
pw.println(Long.toHexString(mAncestralToken));
- pw.print("Current: ");
+ pw.print(userPrefix + "Current: ");
pw.println(Long.toHexString(mCurrentToken));
int numPackages = mBackupParticipants.size();
- pw.println("Participants:");
+ pw.println(userPrefix + "Participants:");
for (int i = 0; i < numPackages; i++) {
int uid = mBackupParticipants.keyAt(i);
pw.print(" uid: ");
@@ -3648,7 +3643,7 @@ public class UserBackupManagerService {
}
}
- pw.println("Ancestral packages: "
+ pw.println(userPrefix + "Ancestral packages: "
+ (mAncestralPackages == null ? "none" : mAncestralPackages.size()));
if (mAncestralPackages != null) {
for (String pkg : mAncestralPackages) {
@@ -3657,17 +3652,17 @@ public class UserBackupManagerService {
}
Set<String> processedPackages = mProcessedPackagesJournal.getPackagesCopy();
- pw.println("Ever backed up: " + processedPackages.size());
+ pw.println(userPrefix + "Ever backed up: " + processedPackages.size());
for (String pkg : processedPackages) {
pw.println(" " + pkg);
}
- pw.println("Pending key/value backup: " + mPendingBackups.size());
+ pw.println(userPrefix + "Pending key/value backup: " + mPendingBackups.size());
for (BackupRequest req : mPendingBackups.values()) {
pw.println(" " + req);
}
- pw.println("Full backup queue:" + mFullBackupQueue.size());
+ pw.println(userPrefix + "Full backup queue:" + mFullBackupQueue.size());
for (FullBackupEntry entry : mFullBackupQueue) {
pw.print(" ");
pw.print(entry.lastBackup);
diff --git a/services/core/java/com/android/server/notification/OWNERS b/services/core/java/com/android/server/notification/OWNERS
new file mode 100644
index 000000000000..5a19656b36a6
--- /dev/null
+++ b/services/core/java/com/android/server/notification/OWNERS
@@ -0,0 +1,4 @@
+dsandler@android.com
+juliacr@google.com
+beverlyt@google.com
+pixel@google.com
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index a9571d97200c..b26e6c7021c1 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -19380,7 +19380,7 @@ public class PackageManagerService extends IPackageManager.Stub
// PermissionController manages default home directly.
return false;
}
- mPermissionManager.setDefaultHome(currentPackageName, userId, (successful) -> {
+ mPermissionManager.setDefaultHome(packageName, userId, (successful) -> {
if (successful) {
postPreferredActivityChangedBroadcast(userId);
}
diff --git a/services/net/java/android/net/ip/IpClientCallbacks.java b/services/net/java/android/net/ip/IpClientCallbacks.java
index 61cd88aac921..c93e5c5e4759 100644
--- a/services/net/java/android/net/ip/IpClientCallbacks.java
+++ b/services/net/java/android/net/ip/IpClientCallbacks.java
@@ -17,6 +17,7 @@
package android.net.ip;
import android.net.DhcpResults;
+import android.net.DhcpResultsParcelable;
import android.net.Layer2PacketParcelable;
import android.net.LinkProperties;
@@ -69,6 +70,18 @@ public class IpClientCallbacks {
public void onNewDhcpResults(DhcpResults dhcpResults) {}
/**
+ * Callback called when new DHCP results are available.
+ *
+ * <p>This is purely advisory and not an indication of provisioning success or failure. This is
+ * only here for callers that want to expose DHCPv4 results to other APIs
+ * (e.g., WifiInfo#setInetAddress).
+ *
+ * <p>DHCPv4 or static IPv4 configuration failure or success can be determined by whether or not
+ * the passed-in DhcpResults object is null.
+ */
+ public void onNewDhcpResults(DhcpResultsParcelable dhcpResults) {}
+
+ /**
* Indicates that provisioning was successful.
*/
public void onProvisioningSuccess(LinkProperties newLp) {}
diff --git a/services/net/java/android/net/ip/IpClientUtil.java b/services/net/java/android/net/ip/IpClientUtil.java
index 4d60e6239376..7f723b1c232b 100644
--- a/services/net/java/android/net/ip/IpClientUtil.java
+++ b/services/net/java/android/net/ip/IpClientUtil.java
@@ -119,6 +119,7 @@ public class IpClientUtil {
@Override
public void onNewDhcpResults(DhcpResultsParcelable dhcpResults) {
mCb.onNewDhcpResults(fromStableParcelable(dhcpResults));
+ mCb.onNewDhcpResults(dhcpResults);
}
@Override
diff --git a/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java b/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java
index 8632ca4c2898..8b2f15c2babb 100644
--- a/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java
@@ -81,7 +81,10 @@ import org.robolectric.shadows.ShadowLooper;
import org.robolectric.shadows.ShadowPackageManager;
import java.io.File;
+import java.io.FileDescriptor;
import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
import java.util.List;
/**
@@ -1238,13 +1241,49 @@ public class UserBackupManagerServiceTest {
assertThat(service.getAncestralSerialNumber()).isEqualTo(testSerialNumber2);
}
+ /**
+ * Test that {@link UserBackupManagerService#dump()} for system user does not prefix dump with
+ * "User 0:".
+ */
+ @Test
+ public void testDump_forSystemUser_DoesNotHaveUserPrefix() throws Exception {
+ mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
+ UserBackupManagerService service =
+ BackupManagerServiceTestUtils.createUserBackupManagerServiceAndRunTasks(
+ UserHandle.USER_SYSTEM,
+ mContext,
+ mBackupThread,
+ mBaseStateDir,
+ mDataDir,
+ mTransportManager);
+
+ StringWriter dump = new StringWriter();
+ service.dump(new FileDescriptor(), new PrintWriter(dump), new String[0]);
+
+ assertThat(dump.toString()).startsWith("Backup Manager is ");
+ }
+
+ /**
+ * Test that {@link UserBackupManagerService#dump()} for non-system user prefixes dump with
+ * "User <userid>:".
+ */
+ @Test
+ public void testDump_forNonSystemUser_HasUserPrefix() throws Exception {
+ mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
+ UserBackupManagerService service = createUserBackupManagerServiceAndRunTasks();
+
+ StringWriter dump = new StringWriter();
+ service.dump(new FileDescriptor(), new PrintWriter(dump), new String[0]);
+
+ assertThat(dump.toString()).startsWith("User " + USER_ID + ":" + "Backup Manager is ");
+ }
+
private File createTestFile() throws IOException {
File testFile = new File(mContext.getFilesDir(), "test");
testFile.createNewFile();
return testFile;
}
-
/**
* We can't mock the void method {@link #schedule(Context, long, BackupManagerConstants)} so we
* extend {@link ShadowKeyValueBackupJob} and throw an exception at the end of the method.
diff --git a/services/tests/servicestests/src/com/android/server/backup/BackupManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/backup/BackupManagerServiceTest.java
index 2326dfda7e12..d44476ed971d 100644
--- a/services/tests/servicestests/src/com/android/server/backup/BackupManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/backup/BackupManagerServiceTest.java
@@ -27,6 +27,7 @@ import static junit.framework.Assert.fail;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
@@ -59,6 +60,7 @@ import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -83,6 +85,8 @@ public class BackupManagerServiceTest {
@Mock
private UserBackupManagerService mUserBackupManagerService;
@Mock
+ private UserBackupManagerService mNonSystemUserBackupManagerService;
+ @Mock
private Context mContextMock;
@Mock
private PrintWriter mPrintWriterMock;
@@ -105,7 +109,7 @@ public class BackupManagerServiceTest {
mUserServices = new SparseArray<>();
mUserServices.append(UserHandle.USER_SYSTEM, mUserBackupManagerService);
- mUserServices.append(NON_USER_SYSTEM, mUserBackupManagerService);
+ mUserServices.append(NON_USER_SYSTEM, mNonSystemUserBackupManagerService);
when(mUserManagerMock.getUserInfo(UserHandle.USER_SYSTEM)).thenReturn(mUserInfoMock);
when(mUserManagerMock.getUserInfo(NON_USER_SYSTEM)).thenReturn(mUserInfoMock);
@@ -512,6 +516,26 @@ public class BackupManagerServiceTest {
mService.dump(mFileDescriptorStub, mPrintWriterMock, new String[0]);
verifyNoMoreInteractions(mUserBackupManagerService);
+ verifyNoMoreInteractions(mNonSystemUserBackupManagerService);
+ }
+
+ /**
+ * Test that {@link BackupManagerService#dump()} dumps system user information before non-system
+ * user information.
+ */
+
+ @Test
+ public void testDump_systemUserFirst() {
+ String[] args = new String[0];
+ mService.dumpWithoutCheckingPermission(mFileDescriptorStub, mPrintWriterMock, args);
+
+ InOrder inOrder =
+ inOrder(mUserBackupManagerService, mNonSystemUserBackupManagerService);
+ inOrder.verify(mUserBackupManagerService)
+ .dump(mFileDescriptorStub, mPrintWriterMock, args);
+ inOrder.verify(mNonSystemUserBackupManagerService)
+ .dump(mFileDescriptorStub, mPrintWriterMock, args);
+ inOrder.verifyNoMoreInteractions();
}
@Test
diff --git a/wifi/Android.bp b/wifi/Android.bp
index 09d5386dcfc5..180368cbd9f7 100644
--- a/wifi/Android.bp
+++ b/wifi/Android.bp
@@ -67,10 +67,15 @@ java_library {
optimize: {
enabled: false
},
+ hostdex: true, // for hiddenapi check
visibility: [
"//frameworks/base", // TODO(b/140299412) remove once all dependencies are fixed
"//frameworks/opt/net/wifi/service:__subpackages__",
] + test_access_hidden_api_whitelist,
+ apex_available: [
+ "com.android.wifi",
+ "test_com.android.wifi",
+ ],
plugins: ["java_api_finder"],
}