Add implicit grants to NLSes
So they can query packages they are receiving notifications from without needing to hold QUERY_ALL_PACKAGES. Test: NotificationListenersTest, manual with test app Fixes: 184736797 Change-Id: I8071d5a03515cc05cbd3f8598997e6236d306052
This commit is contained in:
@@ -494,7 +494,7 @@ public class NotificationManagerService extends SystemService {
|
|||||||
private ActivityManagerInternal mAmi;
|
private ActivityManagerInternal mAmi;
|
||||||
private IPackageManager mPackageManager;
|
private IPackageManager mPackageManager;
|
||||||
private PackageManager mPackageManagerClient;
|
private PackageManager mPackageManagerClient;
|
||||||
private PackageManagerInternal mPackageManagerInternal;
|
PackageManagerInternal mPackageManagerInternal;
|
||||||
private PermissionPolicyInternal mPermissionPolicyInternal;
|
private PermissionPolicyInternal mPermissionPolicyInternal;
|
||||||
AudioManager mAudioManager;
|
AudioManager mAudioManager;
|
||||||
AudioManagerInternal mAudioManagerInternal;
|
AudioManagerInternal mAudioManagerInternal;
|
||||||
@@ -9779,7 +9779,7 @@ public class NotificationManagerService extends SystemService {
|
|||||||
* notifications visible to the given listener.
|
* notifications visible to the given listener.
|
||||||
*/
|
*/
|
||||||
@GuardedBy("mNotificationLock")
|
@GuardedBy("mNotificationLock")
|
||||||
private NotificationRankingUpdate makeRankingUpdateLocked(ManagedServiceInfo info) {
|
NotificationRankingUpdate makeRankingUpdateLocked(ManagedServiceInfo info) {
|
||||||
final int N = mNotificationList.size();
|
final int N = mNotificationList.size();
|
||||||
final ArrayList<NotificationListenerService.Ranking> rankings = new ArrayList<>();
|
final ArrayList<NotificationListenerService.Ranking> rankings = new ArrayList<>();
|
||||||
|
|
||||||
@@ -10924,12 +10924,17 @@ public class NotificationManagerService extends SystemService {
|
|||||||
info, oldSbnLightClone, update, null, REASON_USER_STOPPED));
|
info, oldSbnLightClone, update, null, REASON_USER_STOPPED));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grant access before listener is notified
|
// Grant access before listener is notified
|
||||||
final int targetUserId = (info.userid == UserHandle.USER_ALL)
|
final int targetUserId = (info.userid == UserHandle.USER_ALL)
|
||||||
? UserHandle.USER_SYSTEM : info.userid;
|
? UserHandle.USER_SYSTEM : info.userid;
|
||||||
updateUriPermissions(r, old, info.component.getPackageName(), targetUserId);
|
updateUriPermissions(r, old, info.component.getPackageName(), targetUserId);
|
||||||
|
|
||||||
|
mPackageManagerInternal.grantImplicitAccess(
|
||||||
|
targetUserId, null /* intent */,
|
||||||
|
UserHandle.getAppId(info.uid),
|
||||||
|
sbn.getUid(),
|
||||||
|
false /* direct */, false /* retainOnUpdate */);
|
||||||
|
|
||||||
final StatusBarNotification sbnToPost = trimCache.ForListener(info);
|
final StatusBarNotification sbnToPost = trimCache.ForListener(info);
|
||||||
mHandler.post(() -> notifyPosted(info, sbnToPost, update));
|
mHandler.post(() -> notifyPosted(info, sbnToPost, update));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import static junit.framework.Assert.assertFalse;
|
|||||||
import static junit.framework.Assert.assertTrue;
|
import static junit.framework.Assert.assertTrue;
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.ArgumentMatchers.nullable;
|
import static org.mockito.ArgumentMatchers.nullable;
|
||||||
import static org.mockito.Mockito.atLeast;
|
import static org.mockito.Mockito.atLeast;
|
||||||
@@ -40,16 +41,23 @@ import static org.mockito.Mockito.verify;
|
|||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.app.INotificationManager;
|
import android.app.INotificationManager;
|
||||||
|
import android.app.Notification;
|
||||||
|
import android.app.NotificationChannel;
|
||||||
|
import android.app.NotificationManager;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.pm.IPackageManager;
|
import android.content.pm.IPackageManager;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ServiceInfo;
|
import android.content.pm.ServiceInfo;
|
||||||
import android.content.pm.VersionedPackage;
|
import android.content.pm.VersionedPackage;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.os.IInterface;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.service.notification.NotificationListenerFilter;
|
import android.service.notification.NotificationListenerFilter;
|
||||||
import android.service.notification.NotificationListenerService;
|
import android.service.notification.NotificationListenerService;
|
||||||
import android.service.notification.NotificationStats;
|
import android.service.notification.NotificationStats;
|
||||||
|
import android.service.notification.NotificationRankingUpdate;
|
||||||
import android.service.notification.StatusBarNotification;
|
import android.service.notification.StatusBarNotification;
|
||||||
import android.testing.TestableContext;
|
import android.testing.TestableContext;
|
||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
@@ -60,6 +68,8 @@ import android.util.Xml;
|
|||||||
|
|
||||||
import com.android.server.UiServiceTestCase;
|
import com.android.server.UiServiceTestCase;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
@@ -457,4 +467,34 @@ public class NotificationListenersTest extends UiServiceTestCase {
|
|||||||
mListeners.notifyRemovedLocked(r, 0, rs);
|
mListeners.notifyRemovedLocked(r, 0, rs);
|
||||||
verify(r, never()).getSbn();
|
verify(r, never()).getSbn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testImplicitGrant() {
|
||||||
|
String pkg = "pkg";
|
||||||
|
int uid = 9;
|
||||||
|
NotificationChannel channel = new NotificationChannel("id", "name",
|
||||||
|
NotificationManager.IMPORTANCE_HIGH);
|
||||||
|
Notification.Builder nb = new Notification.Builder(mContext, channel.getId())
|
||||||
|
.setContentTitle("foo")
|
||||||
|
.setSmallIcon(android.R.drawable.sym_def_app_icon)
|
||||||
|
.setTimeoutAfter(1);
|
||||||
|
|
||||||
|
StatusBarNotification sbn = new StatusBarNotification(pkg, pkg, 8, "tag", uid, 0,
|
||||||
|
nb.build(), UserHandle.getUserHandleForUid(uid), null, 0);
|
||||||
|
NotificationRecord r = new NotificationRecord(mContext, sbn, channel);
|
||||||
|
|
||||||
|
ManagedServices.ManagedServiceInfo info = mListeners.new ManagedServiceInfo(
|
||||||
|
null, new ComponentName("a", "a"), sbn.getUserId(), false, null, 33, 33);
|
||||||
|
List<ManagedServices.ManagedServiceInfo> services = ImmutableList.of(info);
|
||||||
|
when(mListeners.getServices()).thenReturn(services);
|
||||||
|
|
||||||
|
when(mNm.isVisibleToListener(any(), anyInt(), any())).thenReturn(true);
|
||||||
|
when(mNm.makeRankingUpdateLocked(info)).thenReturn(mock(NotificationRankingUpdate.class));
|
||||||
|
mNm.mPackageManagerInternal = mPmi;
|
||||||
|
|
||||||
|
mListeners.notifyPostedLocked(r, null);
|
||||||
|
|
||||||
|
verify(mPmi).grantImplicitAccess(sbn.getUserId(), null, UserHandle.getAppId(33),
|
||||||
|
sbn.getUid(), false, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user