summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-01-24 18:08:31 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-01-24 18:08:31 +0000
commitb4e3fdfeea81b20fb5ef7ddcda4615cba0a9db13 (patch)
tree8ecdae832d752b35d251819098b7153076b66903
parentfbdca2eaca667dd17682d3fb306a5971dff4dc0a (diff)
parentcbedf08fcd8cc379a23d6caecef74598480500b8 (diff)
downloadbase-b4e3fdfeea81b20fb5ef7ddcda4615cba0a9db13.tar.gz
Merge cherrypicks of ['ag/20272083', 'ag/20346940', 'ag/20082616', 'ag/20482625'] into sc-platform-release.android-platform-12.0.0_r17
Change-Id: I6eaca2b132fa037deeac34546ea3dea4cf31cdfd
-rw-r--r--core/java/android/os/WorkSource.java2
-rw-r--r--media/java/android/media/session/ISession.aidl2
-rw-r--r--media/java/android/media/session/MediaSession.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java18
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt73
-rw-r--r--services/core/java/com/android/server/media/MediaButtonReceiverHolder.java61
-rw-r--r--services/core/java/com/android/server/media/MediaSessionRecord.java14
-rw-r--r--services/core/java/com/android/server/media/MediaSessionService.java6
8 files changed, 142 insertions, 36 deletions
diff --git a/core/java/android/os/WorkSource.java b/core/java/android/os/WorkSource.java
index 6588b5748d09..cc7cf241e3c9 100644
--- a/core/java/android/os/WorkSource.java
+++ b/core/java/android/os/WorkSource.java
@@ -128,7 +128,7 @@ public class WorkSource implements Parcelable {
mNames = in.createStringArray();
int numChains = in.readInt();
- if (numChains > 0) {
+ if (numChains >= 0) {
mChains = new ArrayList<>(numChains);
in.readParcelableList(mChains, WorkChain.class.getClassLoader());
} else {
diff --git a/media/java/android/media/session/ISession.aidl b/media/java/android/media/session/ISession.aidl
index 9bf126b7a875..31fb8d03c4a0 100644
--- a/media/java/android/media/session/ISession.aidl
+++ b/media/java/android/media/session/ISession.aidl
@@ -35,7 +35,7 @@ interface ISession {
ISessionController getController();
void setFlags(int flags);
void setActive(boolean active);
- void setMediaButtonReceiver(in PendingIntent mbr, String sessionPackageName);
+ void setMediaButtonReceiver(in PendingIntent mbr);
void setMediaButtonBroadcastReceiver(in ComponentName broadcastReceiver);
void setLaunchPendingIntent(in PendingIntent pi);
void destroySession();
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index 20fa53d3ec32..24118b086c24 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -286,7 +286,7 @@ public final class MediaSession {
@Deprecated
public void setMediaButtonReceiver(@Nullable PendingIntent mbr) {
try {
- mBinder.setMediaButtonReceiver(mbr, mContext.getPackageName());
+ mBinder.setMediaButtonReceiver(mbr);
} catch (RemoteException e) {
Log.wtf(TAG, "Failure in setMediaButtonReceiver.", e);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
index 18d6e646b007..dc9f2ce69f9d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
@@ -41,6 +41,7 @@ import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.phone.StatusIconContainer;
import com.android.systemui.statusbar.policy.Clock;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.VariableDateViewController;
import com.android.systemui.util.ViewController;
@@ -71,6 +72,7 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
private final PrivacyDialogController mPrivacyDialogController;
private final QSExpansionPathInterpolator mQSExpansionPathInterpolator;
private final FeatureFlags mFeatureFlags;
+ private final DeviceProvisionedController mDeviceProvisionedController;
private final VariableDateViewController mVariableDateViewControllerDateView;
private final VariableDateViewController mVariableDateViewControllerClockDateView;
@@ -79,6 +81,7 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
private boolean mMicCameraIndicatorsEnabled;
private boolean mLocationIndicatorsEnabled;
private boolean mPrivacyChipLogged;
+ private volatile boolean mDeviceProvisioned;
private final String mCameraSlot;
private final String mMicSlot;
private final String mLocationSlot;
@@ -119,6 +122,7 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
@Override
public void onClick(View v) {
if (v == mPrivacyChip) {
+ if (!mDeviceProvisioned) return;
// If the privacy chip is visible, it means there were some indicators
mUiEventLogger.log(PrivacyChipEvent.ONGOING_INDICATORS_CHIP_CLICK);
mPrivacyDialogController.showDialog(getContext());
@@ -126,6 +130,14 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
}
};
+ private DeviceProvisionedController.DeviceProvisionedListener mDeviceProvisionedListener =
+ new DeviceProvisionedController.DeviceProvisionedListener() {
+ @Override
+ public void onDeviceProvisionedChanged() {
+ mDeviceProvisioned = mDeviceProvisionedController.isDeviceProvisioned();
+ }
+ };
+
@Inject
QuickStatusBarHeaderController(QuickStatusBarHeader view,
PrivacyItemController privacyItemController,
@@ -139,7 +151,8 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
PrivacyDialogController privacyDialogController,
QSExpansionPathInterpolator qsExpansionPathInterpolator,
FeatureFlags featureFlags,
- VariableDateViewController.Factory variableDateViewControllerFactory) {
+ VariableDateViewController.Factory variableDateViewControllerFactory,
+ DeviceProvisionedController deviceProvisionedController) {
super(view);
mPrivacyItemController = privacyItemController;
mActivityStarter = activityStarter;
@@ -151,6 +164,7 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
mPrivacyDialogController = privacyDialogController;
mQSExpansionPathInterpolator = qsExpansionPathInterpolator;
mFeatureFlags = featureFlags;
+ mDeviceProvisionedController = deviceProvisionedController;
mQSCarrierGroupController = qsCarrierGroupControllerBuilder
.setQSCarrierGroup(mView.findViewById(R.id.carrier_group))
@@ -182,6 +196,7 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
@Override
protected void onViewAttached() {
+ mDeviceProvisionedController.addCallback(mDeviceProvisionedListener);
mPrivacyChip.setOnClickListener(mOnClickListener);
mMicCameraIndicatorsEnabled = mPrivacyItemController.getMicCameraAvailable();
@@ -224,6 +239,7 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
@Override
protected void onViewDetached() {
mColorExtractor.removeOnColorsChangedListener(mOnColorsChangedListener);
+ mDeviceProvisionedController.removeCallback(mDeviceProvisionedListener);
mPrivacyChip.setOnClickListener(null);
mStatusBarIconController.removeIconGroup(mIconManager);
mQSCarrierGroupController.setOnSingleCarrierChangedListener(null);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt
index 8b7e20ed0e5a..552f60d252bc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt
@@ -36,6 +36,7 @@ import com.android.systemui.statusbar.FeatureFlags
import com.android.systemui.statusbar.phone.StatusBarIconController
import com.android.systemui.statusbar.phone.StatusIconContainer
import com.android.systemui.statusbar.policy.Clock
+import com.android.systemui.statusbar.policy.DeviceProvisionedController
import com.android.systemui.statusbar.policy.VariableDateView
import com.android.systemui.statusbar.policy.VariableDateViewController
import com.android.systemui.util.mockito.any
@@ -50,6 +51,7 @@ import org.mockito.Answers
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
import org.mockito.Mockito.`when`
+import org.mockito.Mockito.never
import org.mockito.Mockito.reset
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@@ -103,6 +105,7 @@ class QuickStatusBarHeaderControllerTest : SysuiTestCase() {
@Mock
private lateinit var featureFlags: FeatureFlags
+ private lateinit var deviceProvisionedController: FakeDeviceProvisionedController
private val qsExpansionPathInterpolator = QSExpansionPathInterpolator()
private lateinit var controller: QuickStatusBarHeaderController
@@ -123,6 +126,9 @@ class QuickStatusBarHeaderControllerTest : SysuiTestCase() {
`when`(view.isAttachedToWindow).thenReturn(true)
`when`(view.context).thenReturn(context)
+ deviceProvisionedController = FakeDeviceProvisionedController()
+ deviceProvisionedController.provisioned = true
+
cameraSlotName = mContext.resources.getString(
com.android.internal.R.string.status_bar_camera)
microphoneSlotName = mContext.resources.getString(
@@ -144,7 +150,8 @@ class QuickStatusBarHeaderControllerTest : SysuiTestCase() {
privacyDialogController,
qsExpansionPathInterpolator,
featureFlags,
- variableDateViewControllerFactory
+ variableDateViewControllerFactory,
+ deviceProvisionedController
)
}
@@ -279,6 +286,34 @@ class QuickStatusBarHeaderControllerTest : SysuiTestCase() {
verify(view).setIsSingleCarrier(false)
}
+ @Test
+ fun testDeviceNotProvisionedBeforeInit_clickOnChipDoesntShowDialog() {
+ deviceProvisionedController.provisioned = false
+ controller.init()
+
+ val captor = argumentCaptor<View.OnClickListener>()
+ verify(privacyChip).setOnClickListener(capture(captor))
+
+ captor.value.onClick(privacyChip)
+
+ verify(privacyDialogController, never()).showDialog(any(Context::class.java))
+ }
+
+ @Test
+ fun testDeviceNotProvisionedBeforeInit_provisionedAfter_clickOnChipDoesntShowDialog() {
+ deviceProvisionedController.provisioned = false
+ controller.init()
+
+ deviceProvisionedController.provisioned = true
+
+ val captor = argumentCaptor<View.OnClickListener>()
+ verify(privacyChip).setOnClickListener(capture(captor))
+
+ captor.value.onClick(privacyChip)
+
+ verify(privacyDialogController).showDialog(any(Context::class.java))
+ }
+
private fun stubViews() {
`when`(view.findViewById<View>(anyInt())).thenReturn(mockView)
`when`(view.findViewById<QSCarrierGroup>(R.id.carrier_group)).thenReturn(qsCarrierGroup)
@@ -293,4 +328,40 @@ class QuickStatusBarHeaderControllerTest : SysuiTestCase() {
`when`(privacyItemController.micCameraAvailable).thenReturn(micCamera)
`when`(privacyItemController.locationAvailable).thenReturn(location)
}
+
+ // We only care about device provisioned
+ class FakeDeviceProvisionedController : DeviceProvisionedController {
+ val callbacks = mutableSetOf<DeviceProvisionedController.DeviceProvisionedListener>()
+ var provisioned = false
+ set(value) {
+ if (field != value) {
+ field = value
+ callbacks.forEach { it.onDeviceProvisionedChanged() }
+ }
+ }
+
+ override fun addCallback(listener: DeviceProvisionedController.DeviceProvisionedListener) {
+ if (callbacks.add(listener)) {
+ listener.onDeviceProvisionedChanged()
+ }
+ }
+
+ override fun removeCallback(
+ listener: DeviceProvisionedController.DeviceProvisionedListener
+ ) {
+ callbacks.remove(listener)
+ }
+
+ override fun isDeviceProvisioned(): Boolean {
+ return provisioned
+ }
+
+ override fun isUserSetup(currentUser: Int): Boolean {
+ return true
+ }
+
+ override fun getCurrentUser(): Int {
+ return 0
+ }
+ }
}
diff --git a/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java b/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java
index 9a190316f4eb..c5fb5270f841 100644
--- a/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java
+++ b/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java
@@ -18,6 +18,7 @@ package com.android.server.media;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.BroadcastOptions;
import android.app.PendingIntent;
import android.content.ComponentName;
@@ -37,6 +38,7 @@ import android.view.KeyEvent;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Collections;
import java.util.List;
/**
@@ -102,15 +104,19 @@ final class MediaButtonReceiverHolder {
}
/**
- * Creates a new instance.
+ * Creates a new instance from a {@link PendingIntent}.
+ *
+ * <p>This method assumes the session package name has been validated and effectively belongs to
+ * the media session's owner.
*
- * @param context context
* @param userId userId
- * @param pendingIntent pending intent
- * @return Can be {@code null} if pending intent was null.
+ * @param pendingIntent pending intent that will receive media button events
+ * @param sessionPackageName package name of media session owner
+ * @return {@link MediaButtonReceiverHolder} instance or {@code null} if pending intent was
+ * null.
*/
- public static MediaButtonReceiverHolder create(Context context, int userId,
- PendingIntent pendingIntent, String sessionPackageName) {
+ public static MediaButtonReceiverHolder create(
+ int userId, @Nullable PendingIntent pendingIntent, String sessionPackageName) {
if (pendingIntent == null) {
return null;
}
@@ -312,7 +318,7 @@ final class MediaButtonReceiverHolder {
}
private static ComponentName getComponentName(PendingIntent pendingIntent, int componentType) {
- List<ResolveInfo> resolveInfos = null;
+ List<ResolveInfo> resolveInfos = Collections.emptyList();
switch (componentType) {
case COMPONENT_TYPE_ACTIVITY:
resolveInfos = pendingIntent.queryIntentComponents(
@@ -330,32 +336,37 @@ final class MediaButtonReceiverHolder {
PACKAGE_MANAGER_COMMON_FLAGS | PackageManager.GET_RECEIVERS);
break;
}
- if (resolveInfos != null && !resolveInfos.isEmpty()) {
- return createComponentName(resolveInfos.get(0));
+
+ for (ResolveInfo resolveInfo : resolveInfos) {
+ ComponentInfo componentInfo = getComponentInfo(resolveInfo);
+ if (componentInfo != null && TextUtils.equals(componentInfo.packageName,
+ pendingIntent.getCreatorPackage())
+ && componentInfo.packageName != null && componentInfo.name != null) {
+ return new ComponentName(componentInfo.packageName, componentInfo.name);
+ }
}
+
return null;
}
- private static ComponentName createComponentName(ResolveInfo resolveInfo) {
- if (resolveInfo == null) {
- return null;
- }
- ComponentInfo componentInfo;
+ /**
+ * Retrieves the {@link ComponentInfo} from a {@link ResolveInfo} instance. Similar to {@link
+ * ResolveInfo#getComponentInfo()}, but returns {@code null} if this {@link ResolveInfo} points
+ * to a content provider.
+ *
+ * @param resolveInfo Where to extract the {@link ComponentInfo} from.
+ * @return Either a non-null {@link ResolveInfo#activityInfo} or {@link
+ * ResolveInfo#serviceInfo}. Otherwise {@code null} if {@link ResolveInfo#providerInfo} is
+ * not {@code null}.
+ */
+ private static ComponentInfo getComponentInfo(@NonNull ResolveInfo resolveInfo) {
// Code borrowed from ResolveInfo#getComponentInfo().
if (resolveInfo.activityInfo != null) {
- componentInfo = resolveInfo.activityInfo;
+ return resolveInfo.activityInfo;
} else if (resolveInfo.serviceInfo != null) {
- componentInfo = resolveInfo.serviceInfo;
+ return resolveInfo.serviceInfo;
} else {
- // We're not interested in content provider.
- return null;
- }
- // Code borrowed from ComponentInfo#getComponentName().
- try {
- return new ComponentName(componentInfo.packageName, componentInfo.name);
- } catch (IllegalArgumentException | NullPointerException e) {
- // This may be happen if resolveActivity() end up with matching multiple activities.
- // see PackageManager#resolveActivity().
+ // We're not interested in content providers.
return null;
}
}
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 4822d6a62ac7..9bbcec98ef71 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -53,6 +53,7 @@ import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.SystemClock;
import android.text.TextUtils;
+import android.util.EventLog;
import android.util.Log;
import android.view.KeyEvent;
@@ -932,8 +933,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
}
@Override
- public void setMediaButtonReceiver(PendingIntent pi, String sessionPackageName)
- throws RemoteException {
+ public void setMediaButtonReceiver(PendingIntent pi) throws RemoteException {
final long token = Binder.clearCallingIdentity();
try {
if ((mPolicies & MediaSessionPolicyProvider.SESSION_POLICY_IGNORE_BUTTON_RECEIVER)
@@ -941,7 +941,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
return;
}
mMediaButtonReceiverHolder =
- MediaButtonReceiverHolder.create(mContext, mUserId, pi, sessionPackageName);
+ MediaButtonReceiverHolder.create(mUserId, pi, mPackageName);
mService.onMediaButtonReceiverChanged(MediaSessionRecord.this);
} finally {
Binder.restoreCallingIdentity(token);
@@ -952,6 +952,14 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
public void setMediaButtonBroadcastReceiver(ComponentName receiver) throws RemoteException {
final long token = Binder.clearCallingIdentity();
try {
+ //mPackageName has been verified in MediaSessionService.enforcePackageName().
+ if (receiver != null && !TextUtils.equals(
+ mPackageName, receiver.getPackageName())) {
+ EventLog.writeEvent(0x534e4554, "238177121", -1, ""); // SafetyNet logging.
+ throw new IllegalArgumentException("receiver does not belong to "
+ + "package name provided to MediaSessionRecord. Pkg = " + mPackageName
+ + ", Receiver Pkg = " + receiver.getPackageName());
+ }
if ((mPolicies & MediaSessionPolicyProvider.SESSION_POLICY_IGNORE_BUTTON_RECEIVER)
!= 0) {
return;
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index b477ea353c25..52f97574a03b 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -2229,9 +2229,9 @@ public class MediaSessionService extends SystemService implements Monitor {
PendingIntent pi = mCustomMediaKeyDispatcher.getMediaButtonReceiver(keyEvent,
uid, asSystemService);
if (pi != null) {
- mediaButtonReceiverHolder = MediaButtonReceiverHolder.create(mContext,
- mCurrentFullUserRecord.mFullUserId, pi,
- /* sessionPackageName= */ "");
+ mediaButtonReceiverHolder =
+ MediaButtonReceiverHolder.create(
+ mCurrentFullUserRecord.mFullUserId, pi, "");
}
}
}