Broadcast device audio connection intents
To current user and its profile group. Test: atest AudioDeviceBrokerTest Bug: 172129045 Bug: 163357045 Change-Id: Id523a63590f38aec118827c66195f3ba5afd94d1
This commit is contained in:
@@ -154,6 +154,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
mPreferredDeviceforComm = null;
|
||||
initCommunicationStrategyId();
|
||||
|
||||
mSystemServer.registerUserStartedReceiver(mContext);
|
||||
}
|
||||
|
||||
/*package*/ Context getContext() {
|
||||
@@ -993,6 +995,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
}
|
||||
}
|
||||
|
||||
/*package*/ void broadcastStickyIntentToCurrentProfileGroup(Intent intent) {
|
||||
mSystemServer.broadcastStickyIntentToCurrentProfileGroup(intent);
|
||||
}
|
||||
|
||||
/*package*/ void dump(PrintWriter pw, String prefix) {
|
||||
if (mBrokerHandler != null) {
|
||||
pw.println(prefix + "Message handler (watch for unhandled messages):");
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
package com.android.server.audio;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.ActivityManager;
|
||||
import android.bluetooth.BluetoothA2dp;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
@@ -37,7 +36,6 @@ import android.media.MediaMetrics;
|
||||
import android.os.Binder;
|
||||
import android.os.RemoteCallbackList;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
@@ -1270,7 +1268,7 @@ public class AudioDeviceInventory {
|
||||
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
ActivityManager.broadcastStickyIntent(intent, UserHandle.USER_CURRENT);
|
||||
mDeviceBroker.broadcastStickyIntentToCurrentProfileGroup(intent);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
|
||||
@@ -5566,7 +5566,9 @@ public class AudioService extends IAudioService.Stub
|
||||
profile, suppressNoisyIntent, a2dpVolume);
|
||||
}
|
||||
|
||||
/*package*/ void setMusicMute(boolean mute) {
|
||||
/** only public for mocking/spying, do not call outside of AudioService */
|
||||
@VisibleForTesting
|
||||
public void setMusicMute(boolean mute) {
|
||||
mStreamStates[AudioSystem.STREAM_MUSIC].muteInternally(mute);
|
||||
}
|
||||
|
||||
@@ -7046,7 +7048,9 @@ public class AudioService extends IAudioService.Stub
|
||||
}
|
||||
}
|
||||
|
||||
/*package*/ void checkMusicActive(int deviceType, String caller) {
|
||||
/** only public for mocking/spying, do not call outside of AudioService */
|
||||
@VisibleForTesting
|
||||
public void checkMusicActive(int deviceType, String caller) {
|
||||
if (mSafeMediaVolumeDevices.contains(deviceType)) {
|
||||
sendMsg(mAudioHandler,
|
||||
MSG_CHECK_MUSIC_ACTIVE,
|
||||
|
||||
@@ -18,11 +18,20 @@ package com.android.server.audio;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityManagerInternal;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Binder;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.server.LocalServices;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -82,4 +91,58 @@ public class SystemServerAdapter {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send sticky broadcast to current user's profile group (including current user)
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public void broadcastStickyIntentToCurrentProfileGroup(Intent intent) {
|
||||
int[] profileIds = LocalServices.getService(
|
||||
ActivityManagerInternal.class).getCurrentProfileIds();
|
||||
for (int userId : profileIds) {
|
||||
ActivityManager.broadcastStickyIntent(intent, userId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast sticky intents when a profile is started. This is needed because newly created
|
||||
* profiles would not receive the intents until the next state change.
|
||||
*/
|
||||
/*package*/ void registerUserStartedReceiver(Context context) {
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(Intent.ACTION_USER_STARTED);
|
||||
context.registerReceiverAsUser(new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (Intent.ACTION_USER_STARTED.equals(intent.getAction())) {
|
||||
final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
|
||||
UserHandle.USER_NULL);
|
||||
if (userId == UserHandle.USER_NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
UserManager userManager = context.getSystemService(UserManager.class);
|
||||
final UserInfo profileParent = userManager.getProfileParent(userId);
|
||||
if (profileParent == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// get sticky intents from parent and broadcast them to the started profile
|
||||
broadcastProfileParentStickyIntent(context, AudioManager.ACTION_HDMI_AUDIO_PLUG,
|
||||
userId, profileParent.id);
|
||||
broadcastProfileParentStickyIntent(context, AudioManager.ACTION_HEADSET_PLUG,
|
||||
userId, profileParent.id);
|
||||
}
|
||||
}
|
||||
}, UserHandle.ALL, filter, null, null);
|
||||
}
|
||||
|
||||
private void broadcastProfileParentStickyIntent(Context context, String intentAction,
|
||||
int profileId, int parentId) {
|
||||
Intent intent = context.registerReceiverAsUser(/*receiver*/ null, UserHandle.of(parentId),
|
||||
new IntentFilter(intentAction), /*broadcastPermission*/ null, /*scheduler*/ null);
|
||||
if (intent != null) {
|
||||
ActivityManager.broadcastStickyIntent(intent, profileId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.android.server.audio;
|
||||
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.anyInt;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
@@ -27,6 +28,7 @@ import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioSystem;
|
||||
import android.util.Log;
|
||||
@@ -58,7 +60,7 @@ public class AudioDeviceBrokerTest {
|
||||
@Mock private AudioService mMockAudioService;
|
||||
@Spy private AudioDeviceInventory mSpyDevInventory;
|
||||
@Spy private AudioSystemAdapter mSpyAudioSystem;
|
||||
private SystemServerAdapter mSystemServer;
|
||||
@Spy private SystemServerAdapter mSpySystemServer;
|
||||
|
||||
private BluetoothDevice mFakeBtDevice;
|
||||
|
||||
@@ -69,9 +71,9 @@ public class AudioDeviceBrokerTest {
|
||||
mMockAudioService = mock(AudioService.class);
|
||||
mSpyAudioSystem = spy(new NoOpAudioSystemAdapter());
|
||||
mSpyDevInventory = spy(new AudioDeviceInventory(mSpyAudioSystem));
|
||||
mSystemServer = new NoOpSystemServerAdapter();
|
||||
mSpySystemServer = spy(new NoOpSystemServerAdapter());
|
||||
mAudioDeviceBroker = new AudioDeviceBroker(mContext, mMockAudioService, mSpyDevInventory,
|
||||
mSystemServer);
|
||||
mSpySystemServer);
|
||||
mSpyDevInventory.setDeviceBroker(mAudioDeviceBroker);
|
||||
|
||||
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
||||
@@ -172,6 +174,30 @@ public class AudioDeviceBrokerTest {
|
||||
true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that device wired state intents are broadcasted on connection state change
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testSetWiredDeviceConnectionState() throws Exception {
|
||||
Log.i(TAG, "starting postSetWiredDeviceConnectionState");
|
||||
|
||||
final String address = "testAddress";
|
||||
final String name = "testName";
|
||||
final String caller = "testCaller";
|
||||
|
||||
doNothing().when(mSpySystemServer).broadcastStickyIntentToCurrentProfileGroup(
|
||||
any(Intent.class));
|
||||
|
||||
mSpyDevInventory.setWiredDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADSET,
|
||||
AudioService.CONNECTION_STATE_CONNECTED, address, name, caller);
|
||||
Thread.sleep(MAX_MESSAGE_HANDLING_DELAY_MS);
|
||||
|
||||
// Verify that the sticky intent is broadcasted
|
||||
verify(mSpySystemServer, times(1)).broadcastStickyIntentToCurrentProfileGroup(
|
||||
any(Intent.class));
|
||||
}
|
||||
|
||||
private void doTestConnectionDisconnectionReconnection(int delayAfterDisconnection,
|
||||
boolean mockMediaPlayback, boolean guaranteeSingleConnection) throws Exception {
|
||||
when(mMockAudioService.getDeviceForStream(AudioManager.STREAM_MUSIC))
|
||||
|
||||
Reference in New Issue
Block a user