Merge "Disable sending tuner callback to non current user" into udc-dev

This commit is contained in:
Weilin Xu
2023-04-26 15:26:53 +00:00
committed by Android (Google) Code Review
8 changed files with 135 additions and 16 deletions

View File

@@ -58,7 +58,7 @@ public final class RadioServiceUserControllerTest extends ExtendedRadioMockitoTe
}
@Test
public void isCurrentUser_forCurrentUser_returnsFalse() {
public void isCurrentOrSystemUser_forCurrentUser_returnsFalse() {
when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1);
assertWithMessage("Current user")
@@ -66,7 +66,7 @@ public final class RadioServiceUserControllerTest extends ExtendedRadioMockitoTe
}
@Test
public void isCurrentUser_forNonCurrentUser_returnsFalse() {
public void isCurrentOrSystemUser_forNonCurrentUser_returnsFalse() {
when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_2);
assertWithMessage("Non-current user")
@@ -74,7 +74,8 @@ public final class RadioServiceUserControllerTest extends ExtendedRadioMockitoTe
}
@Test
public void isCurrentUser_forSystemUser_returnsTrue() {
public void isCurrentOrSystemUser_forSystemUser_returnsTrue() {
when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1);
when(mUserHandleMock.getIdentifier()).thenReturn(UserHandle.USER_SYSTEM);
assertWithMessage("System user")
@@ -82,10 +83,26 @@ public final class RadioServiceUserControllerTest extends ExtendedRadioMockitoTe
}
@Test
public void isCurrentUser_withActivityManagerFails_returnsFalse() {
doThrow(new RuntimeException()).when(() -> ActivityManager.getCurrentUser());
public void isCurrentOrSystemUser_withActivityManagerFailure_returnsFalse() {
when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1);
doThrow(new RuntimeException()).when(ActivityManager::getCurrentUser);
assertWithMessage("User when activity manager fails")
.that(RadioServiceUserController.isCurrentOrSystemUser()).isFalse();
}
@Test
public void getCurrentUser() {
assertWithMessage("Current user")
.that(RadioServiceUserController.getCurrentUser()).isEqualTo(USER_ID_1);
}
@Test
public void getCurrentUser_withActivityManagerFailure_returnsUserNull() {
when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1);
doThrow(new RuntimeException()).when(ActivityManager::getCurrentUser);
assertWithMessage("Current user when activity manager fails")
.that(RadioServiceUserController.getCurrentUser()).isEqualTo(UserHandle.USER_NULL);
}
}

View File

@@ -47,9 +47,11 @@ import android.hardware.radio.ProgramList;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
import android.hardware.radio.RadioTuner;
import android.os.Binder;
import android.os.ParcelableException;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -73,6 +75,8 @@ import java.util.Set;
*/
public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
private static final int USER_ID_1 = 11;
private static final int USER_ID_2 = 12;
private static final VerificationWithTimeout CALLBACK_TIMEOUT =
timeout(/* millis= */ 200);
private static final int SIGNAL_QUALITY = 90;
@@ -109,7 +113,10 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
SIGNAL_QUALITY);
// Mocks
@Mock private IBroadcastRadio mBroadcastRadioMock;
@Mock
private UserHandle mUserHandleMock;
@Mock
private IBroadcastRadio mBroadcastRadioMock;
private android.hardware.radio.ITunerCallback[] mAidlTunerCallbackMocks;
// RadioModule under test
@@ -124,14 +131,18 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
@Override
protected void initializeSession(StaticMockitoSessionBuilder builder) {
builder.spyStatic(RadioServiceUserController.class).spyStatic(CompatChanges.class);
builder.spyStatic(RadioServiceUserController.class).spyStatic(CompatChanges.class)
.spyStatic(Binder.class);
}
@Before
public void setup() throws Exception {
when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1);
doReturn(true).when(() -> CompatChanges.isChangeEnabled(
eq(ConversionUtils.RADIO_U_VERSION_REQUIRED), anyInt()));
doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
doReturn(USER_ID_1).when(() -> RadioServiceUserController.getCurrentUser());
doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle());
mRadioModule = new RadioModule(mBroadcastRadioMock,
AidlTestUtils.makeDefaultModuleProperties());
@@ -420,6 +431,21 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
.onCurrentProgramInfoChanged(tuneInfo);
}
@Test
public void tune_forSystemUser() throws Exception {
when(mUserHandleMock.getIdentifier()).thenReturn(UserHandle.USER_SYSTEM);
doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle());
doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
ProgramSelector initialSel = AidlTestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]);
RadioManager.ProgramInfo tuneInfo =
AidlTestUtils.makeProgramInfo(initialSel, SIGNAL_QUALITY);
openAidlClients(/* numClients= */ 1);
mTunerSessions[0].tune(initialSel);
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onCurrentProgramInfoChanged(tuneInfo);
}
@Test
public void tune_withUnknownErrorFromHal_fails() throws Exception {
openAidlClients(/* numClients= */ 1);
@@ -1135,6 +1161,19 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
.that(thrown).hasMessageThat().contains(exceptionMessage);
}
@Test
public void onCurrentProgramInfoChanged_withNoncurrentUser_doesNotInvokeCallback()
throws Exception {
openAidlClients(1);
doReturn(USER_ID_2).when(() -> RadioServiceUserController.getCurrentUser());
mHalTunerCallback.onCurrentProgramInfoChanged(AidlTestUtils.makeHalProgramInfo(
AidlTestUtils.makeHalFmSelector(/* freq= */ 97300), SIGNAL_QUALITY));
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0))
.onCurrentProgramInfoChanged(any());
}
@Test
public void onAntennaStateChange_forTunerCallback() throws Exception {
int numSessions = 3;

View File

@@ -46,8 +46,10 @@ import android.hardware.radio.ProgramList;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
import android.hardware.radio.RadioTuner;
import android.os.Binder;
import android.os.ParcelableException;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -74,6 +76,8 @@ import java.util.Map;
@RunWith(MockitoJUnitRunner.class)
public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
private static final int USER_ID_1 = 11;
private static final int USER_ID_2 = 12;
private static final VerificationWithTimeout CALLBACK_TIMEOUT =
timeout(/* millis= */ 200);
private static final int SIGNAL_QUALITY = 1;
@@ -94,18 +98,25 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
private ProgramInfo mHalCurrentInfo;
private TunerSession[] mTunerSessions;
@Mock private IBroadcastRadio mBroadcastRadioMock;
@Mock ITunerSession mHalTunerSessionMock;
@Mock
private UserHandle mUserHandleMock;
@Mock
private IBroadcastRadio mBroadcastRadioMock;
@Mock
ITunerSession mHalTunerSessionMock;
private android.hardware.radio.ITunerCallback[] mAidlTunerCallbackMocks;
@Override
protected void initializeSession(StaticMockitoSessionBuilder builder) {
builder.spyStatic(RadioServiceUserController.class);
builder.spyStatic(RadioServiceUserController.class).spyStatic(Binder.class);
}
@Before
public void setup() throws Exception {
when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1);
doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle());
doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
doReturn(USER_ID_1).when(() -> RadioServiceUserController.getCurrentUser());
mRadioModule = new RadioModule(mBroadcastRadioMock,
TestUtils.makeDefaultModuleProperties());
@@ -386,6 +397,20 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
.that(thrown).hasMessageThat().contains(Result.toString(Result.UNKNOWN_ERROR));
}
@Test
public void tune_forSystemUser() throws Exception {
when(mUserHandleMock.getIdentifier()).thenReturn(UserHandle.USER_SYSTEM);
doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle());
doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
ProgramSelector initialSel = TestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]);
RadioManager.ProgramInfo tuneInfo = TestUtils.makeProgramInfo(initialSel, SIGNAL_QUALITY);
openAidlClients(/* numClients= */ 1);
mTunerSessions[0].tune(initialSel);
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onCurrentProgramInfoChanged(tuneInfo);
}
@Test
public void step_withDirectionUp() throws Exception {
long initFreq = AM_FM_FREQUENCY_LIST[1];
@@ -857,6 +882,19 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
.that(thrown).hasMessageThat().contains(exceptionMessage);
}
@Test
public void onCurrentProgramInfoChanged_withNoncurrentUser_doesNotInvokeCallback()
throws Exception {
openAidlClients(1);
doReturn(USER_ID_2).when(() -> RadioServiceUserController.getCurrentUser());
mHalTunerCallback.onCurrentProgramInfoChanged(TestUtils.makeHalProgramInfo(
TestUtils.makeHalFmSelector(/* freq= */ 97300), SIGNAL_QUALITY));
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0))
.onCurrentProgramInfoChanged(any());
}
@Test
public void onConfigFlagUpdated_forTunerCallback() throws Exception {
int numSessions = 3;

View File

@@ -39,18 +39,24 @@ public final class RadioServiceUserController {
*/
public static boolean isCurrentOrSystemUser() {
int callingUser = Binder.getCallingUserHandle().getIdentifier();
return callingUser == getCurrentUser() || callingUser == UserHandle.USER_SYSTEM;
}
/**
* Get current foreground user for Broadcast Radio Service
*
* @return foreground user id.
*/
public static int getCurrentUser() {
final long identity = Binder.clearCallingIdentity();
int userId = UserHandle.USER_NULL;
try {
int currentUser = ActivityManager.getCurrentUser();
if (callingUser != currentUser && callingUser != UserHandle.USER_SYSTEM) {
return false;
}
return true;
userId = ActivityManager.getCurrentUser();
} catch (RuntimeException e) {
// Activity manager not running, nothing we can do assume user 0.
} finally {
Binder.restoreCallingIdentity(identity);
}
return false;
return userId;
}
}

View File

@@ -36,11 +36,13 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.ArraySet;
import android.util.IndentingPrintWriter;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.broadcastradio.RadioServiceUserController;
import com.android.server.utils.Slogf;
import java.util.ArrayList;
@@ -419,8 +421,13 @@ final class RadioModule {
@GuardedBy("mLock")
private void fanoutAidlCallbackLocked(AidlCallbackRunnable runnable) {
int currentUserId = RadioServiceUserController.getCurrentUser();
List<TunerSession> deadSessions = null;
for (int i = 0; i < mAidlTunerSessions.size(); i++) {
if (mAidlTunerSessions.valueAt(i).mUserId != currentUserId
&& mAidlTunerSessions.valueAt(i).mUserId != UserHandle.USER_SYSTEM) {
continue;
}
try {
runnable.run(mAidlTunerSessions.valueAt(i).mCallback,
mAidlTunerSessions.valueAt(i).getUid());

View File

@@ -46,6 +46,7 @@ final class TunerSession extends ITuner.Stub {
private final RadioLogger mLogger;
private final RadioModule mModule;
final int mUserId;
final android.hardware.radio.ITunerCallback mCallback;
private final int mUid;
private final IBroadcastRadio mService;
@@ -65,6 +66,7 @@ final class TunerSession extends ITuner.Stub {
android.hardware.radio.ITunerCallback callback) {
mModule = Objects.requireNonNull(radioModule, "radioModule cannot be null");
mService = Objects.requireNonNull(service, "service cannot be null");
mUserId = Binder.getCallingUserHandle().getIdentifier();
mCallback = Objects.requireNonNull(callback, "callback cannot be null");
mUid = Binder.getCallingUid();
mLogger = new RadioLogger(TAG, TUNER_EVENT_LOGGER_QUEUE_SIZE);

View File

@@ -38,12 +38,14 @@ import android.os.DeadObjectException;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.IndentingPrintWriter;
import android.util.MutableInt;
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.broadcastradio.RadioServiceUserController;
import java.util.ArrayList;
import java.util.HashSet;
@@ -374,8 +376,13 @@ final class RadioModule {
@GuardedBy("mLock")
private void fanoutAidlCallbackLocked(AidlCallbackRunnable runnable) {
int currentUserId = RadioServiceUserController.getCurrentUser();
List<TunerSession> deadSessions = null;
for (TunerSession tunerSession : mAidlTunerSessions) {
if (tunerSession.mUserId != currentUserId && tunerSession.mUserId
!= UserHandle.USER_SYSTEM) {
continue;
}
try {
runnable.run(tunerSession.mCallback);
} catch (DeadObjectException ex) {

View File

@@ -26,6 +26,7 @@ import android.hardware.radio.ITuner;
import android.hardware.radio.ProgramList;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
import android.os.Binder;
import android.os.RemoteException;
import android.util.ArrayMap;
import android.util.IndentingPrintWriter;
@@ -52,6 +53,7 @@ class TunerSession extends ITuner.Stub {
private final RadioModule mModule;
private final ITunerSession mHwSession;
final int mUserId;
final android.hardware.radio.ITunerCallback mCallback;
@GuardedBy("mLock")
@@ -68,6 +70,7 @@ class TunerSession extends ITuner.Stub {
@NonNull android.hardware.radio.ITunerCallback callback) {
mModule = Objects.requireNonNull(module);
mHwSession = Objects.requireNonNull(hwSession);
mUserId = Binder.getCallingUserHandle().getIdentifier();
mCallback = Objects.requireNonNull(callback);
mEventLogger = new RadioEventLogger(TAG, TUNER_EVENT_LOGGER_QUEUE_SIZE);
}