Merge "Clear calling identity before verifying listeners" into oc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
43dd3ba3c4
@@ -2695,7 +2695,9 @@ public class NotificationManagerService extends SystemService {
|
||||
Preconditions.checkNotNull(channel);
|
||||
|
||||
ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);
|
||||
checkHasCompanionDevice(info);
|
||||
if (!hasCompanionDevice(info)) {
|
||||
throw new SecurityException(info + " does not have access");
|
||||
}
|
||||
|
||||
int uid = mPackageManager.getPackageUid(pkg, 0, info.userid);
|
||||
updateNotificationChannelInt(pkg, uid, channel, true);
|
||||
@@ -2705,7 +2707,9 @@ public class NotificationManagerService extends SystemService {
|
||||
public ParceledListSlice<NotificationChannel> getNotificationChannelsFromPrivilegedListener(
|
||||
INotificationListener token, String pkg) throws RemoteException {
|
||||
ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);
|
||||
checkHasCompanionDevice(info);
|
||||
if (!hasCompanionDevice(info)) {
|
||||
throw new SecurityException(info + " does not have access");
|
||||
}
|
||||
|
||||
int uid = mPackageManager.getPackageUid(pkg, 0, info.userid);
|
||||
return mRankingHelper.getNotificationChannels(pkg, uid, false /* includeDeleted */);
|
||||
@@ -2716,7 +2720,9 @@ public class NotificationManagerService extends SystemService {
|
||||
getNotificationChannelGroupsFromPrivilegedListener(
|
||||
INotificationListener token, String pkg) throws RemoteException {
|
||||
ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);
|
||||
checkHasCompanionDevice(info);
|
||||
if (!hasCompanionDevice(info)) {
|
||||
throw new SecurityException(info + " does not have access");
|
||||
}
|
||||
|
||||
List<NotificationChannelGroup> groups = new ArrayList<>();
|
||||
int uid = mPackageManager.getPackageUid(pkg, 0, info.userid);
|
||||
@@ -4655,15 +4661,28 @@ public class NotificationManagerService extends SystemService {
|
||||
channels, overridePeople, snoozeCriteria, showBadge);
|
||||
}
|
||||
|
||||
private void checkHasCompanionDevice(ManagedServiceInfo info) throws RemoteException {
|
||||
boolean hasCompanionDevice(ManagedServiceInfo info) {
|
||||
if (mCompanionManager == null) {
|
||||
mCompanionManager = ICompanionDeviceManager.Stub.asInterface(
|
||||
ServiceManager.getService(Context.COMPANION_DEVICE_SERVICE));
|
||||
}
|
||||
if (ArrayUtils.isEmpty(mCompanionManager.getAssociations(
|
||||
info.component.getPackageName(), info.userid))) {
|
||||
throw new SecurityException("Disallowed call from " + info.component);
|
||||
long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
List<String> associations = mCompanionManager.getAssociations(
|
||||
info.component.getPackageName(), info.userid);
|
||||
if (!ArrayUtils.isEmpty(associations)) {
|
||||
return true;
|
||||
}
|
||||
} catch (SecurityException se) {
|
||||
// Not a privileged listener
|
||||
} catch (RemoteException re) {
|
||||
Slog.e(TAG, "Cannot reach companion device service", re);
|
||||
} catch (Exception e) {
|
||||
Slog.e(TAG, "Cannot verify listener " + info, e);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isVisibleToListener(StatusBarNotification sbn, ManagedServiceInfo listener) {
|
||||
@@ -4996,23 +5015,19 @@ public class NotificationManagerService extends SystemService {
|
||||
return;
|
||||
}
|
||||
for (final ManagedServiceInfo serviceInfo : getServices()) {
|
||||
if (!serviceInfo.isEnabledForCurrentProfiles()) {
|
||||
if (!serviceInfo.enabledAndUserMatches(UserHandle.getCallingUserId())) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
checkHasCompanionDevice(serviceInfo);
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
notifyNotificationChannelChanged(serviceInfo, pkg, channel,
|
||||
modificationType);
|
||||
}
|
||||
});
|
||||
} catch (SecurityException se) {
|
||||
// Not a privileged listener; do not notify
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Cannot reach companion device service", e);
|
||||
if (!hasCompanionDevice(serviceInfo)) {
|
||||
continue;
|
||||
}
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
notifyNotificationChannelChanged(serviceInfo, pkg, channel,
|
||||
modificationType);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5022,23 +5037,19 @@ public class NotificationManagerService extends SystemService {
|
||||
return;
|
||||
}
|
||||
for (final ManagedServiceInfo serviceInfo : getServices()) {
|
||||
if (!serviceInfo.isEnabledForCurrentProfiles()) {
|
||||
if (!serviceInfo.enabledAndUserMatches(UserHandle.getCallingUserId())) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
checkHasCompanionDevice(serviceInfo);
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
notifyNotificationChannelGroupChanged(serviceInfo, pkg, group,
|
||||
modificationType);
|
||||
}
|
||||
});
|
||||
} catch (SecurityException se) {
|
||||
// Not a privileged listener; do not notify
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Cannot reach companion device service", e);
|
||||
if (!hasCompanionDevice(serviceInfo)) {
|
||||
continue;
|
||||
}
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
notifyNotificationChannelGroupChanged(serviceInfo, pkg, group,
|
||||
modificationType);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -59,10 +59,11 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import com.android.server.lights.Light;
|
||||
import com.android.server.lights.LightsManager;
|
||||
@@ -74,20 +75,21 @@ public class NotificationManagerServiceTest {
|
||||
private NotificationManagerService mNotificationManagerService;
|
||||
private INotificationManager mBinderService;
|
||||
private NotificationManagerInternal mInternalService;
|
||||
private IPackageManager mPackageManager = mock(IPackageManager.class);
|
||||
private final PackageManager mPackageManagerClient = mock(PackageManager.class);
|
||||
@Mock
|
||||
private IPackageManager mPackageManager;
|
||||
@Mock
|
||||
private PackageManager mPackageManagerClient;
|
||||
private Context mContext = InstrumentationRegistry.getTargetContext();
|
||||
private final String PKG = mContext.getPackageName();
|
||||
private TestableLooper mTestableLooper;
|
||||
private final RankingHelper mRankingHelper = mock(RankingHelper.class);
|
||||
@Mock
|
||||
private RankingHelper mRankingHelper;
|
||||
private NotificationChannel mTestNotificationChannel = new NotificationChannel(
|
||||
TEST_CHANNEL_ID, TEST_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT);
|
||||
private NotificationManagerService.NotificationListeners mNotificationListeners =
|
||||
mock(NotificationManagerService.NotificationListeners.class);
|
||||
private ManagedServices.ManagedServiceInfo mListener =
|
||||
mNotificationListeners.new ManagedServiceInfo(
|
||||
null, new ComponentName(PKG, "test_class"), uid, true, null, 0);
|
||||
private ICompanionDeviceManager mCompanionMgr = mock(ICompanionDeviceManager.class);
|
||||
@Mock
|
||||
private NotificationManagerService.NotificationListeners mNotificationListeners;
|
||||
private ManagedServices.ManagedServiceInfo mListener;
|
||||
@Mock private ICompanionDeviceManager mCompanionMgr;
|
||||
|
||||
// Use a Testable subclass so we can simulate calls from the system without failing.
|
||||
private static class TestableNotificationManagerService extends NotificationManagerService {
|
||||
@@ -102,6 +104,7 @@ public class NotificationManagerServiceTest {
|
||||
@Before
|
||||
@UiThreadTest
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mNotificationManagerService = new TestableNotificationManagerService(mContext);
|
||||
|
||||
// MockPackageManager - default returns ApplicationInfo with matching calling UID
|
||||
@@ -116,6 +119,8 @@ public class NotificationManagerServiceTest {
|
||||
// Use this testable looper.
|
||||
mTestableLooper = new TestableLooper(false);
|
||||
|
||||
mListener = mNotificationListeners.new ManagedServiceInfo(
|
||||
null, new ComponentName(PKG, "test_class"), uid, true, null, 0);
|
||||
when(mNotificationListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
|
||||
mNotificationManagerService.init(mTestableLooper.getLooper(), mPackageManager,
|
||||
mPackageManagerClient, mockLightsManager, mNotificationListeners, mCompanionMgr);
|
||||
@@ -631,4 +636,12 @@ public class NotificationManagerServiceTest {
|
||||
|
||||
verify(mRankingHelper, never()).getNotificationChannelGroups(anyString(), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testHasCompanionDevice_failure() throws Exception {
|
||||
when(mCompanionMgr.getAssociations(anyString(), anyInt())).thenThrow(
|
||||
new IllegalArgumentException());
|
||||
mNotificationManagerService.hasCompanionDevice(mListener);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user