Add isAutomotiveController and isAutoCompanionController

Issue: androidx/media#561
Issue: androidx/media#644
Issue: androidx/media#645
PiperOrigin-RevId: 568948230
This commit is contained in:
bachinger 2023-09-27 13:42:47 -07:00 committed by Copybara-Service
parent 99086b4007
commit 0b0d02c3e4
3 changed files with 296 additions and 2 deletions

View File

@ -818,6 +818,33 @@ public class MediaSession {
return impl.getMediaNotificationControllerInfo();
}
/**
* Returns whether the given {@link ControllerInfo} belongs to an Automotive OS controller.
*
* <p>Note: This is not a security validation.
*
* @param controllerInfo The controller info of the connected controller.
* @return True if the controller into belongs to a connected Automotive OS controller.
*/
@UnstableApi
public final boolean isAutomotiveController(ControllerInfo controllerInfo) {
return impl.isAutomotiveController(controllerInfo);
}
/**
* Returns whether the given {@link ControllerInfo} belongs to an Android Auto companion app
* controller.
*
* <p>Note: This is not a security validation.
*
* @param controllerInfo The controller info of the connected controller.
* @return True if the controller into belongs to a connected Auto companion client app.
*/
@UnstableApi
public final boolean isAutoCompanionController(ControllerInfo controllerInfo) {
return impl.isAutoCompanionController(controllerInfo);
}
/**
* Sets the custom layout for the given Media3 controller.
*

View File

@ -86,6 +86,10 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/* package */ class MediaSessionImpl {
private static final String ANDROID_AUTOMOTIVE_LAUNCHER_PACKAGE_NAME =
"com.android.car.carlauncher";
private static final String ANDROID_AUTOMOTIVE_MEDIA_PACKAGE_NAME = "com.android.car.media";
private static final String ANDROID_AUTO_PACKAGE_NAME = "com.google.android.projection.gearhead";
private static final String SYSTEM_UI_PACKAGE_NAME = "com.android.systemui";
private static final String WRONG_THREAD_ERROR_MESSAGE =
"Player callback method is called from a wrong thread. "
@ -388,14 +392,37 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
*/
public boolean isMediaNotificationController(MediaSession.ControllerInfo controllerInfo) {
return Objects.equals(controllerInfo.getPackageName(), context.getPackageName())
&& controllerInfo.getControllerVersion()
!= ControllerInfo.LEGACY_CONTROLLER_INTERFACE_VERSION
&& controllerInfo.getControllerVersion() != ControllerInfo.LEGACY_CONTROLLER_VERSION
&& controllerInfo
.getConnectionHints()
.getBoolean(
MediaNotificationManager.KEY_MEDIA_NOTIFICATION_MANAGER, /* defaultValue= */ false);
}
/**
* Returns whether the given {@link ControllerInfo} belongs to an Automotive OS controller.
*
* @param controllerInfo The controller info.
* @return Whether the given controller info belongs to an Automotive OS controller.
*/
public boolean isAutomotiveController(ControllerInfo controllerInfo) {
return controllerInfo.getControllerVersion() == ControllerInfo.LEGACY_CONTROLLER_VERSION
&& (controllerInfo.getPackageName().equals(ANDROID_AUTOMOTIVE_MEDIA_PACKAGE_NAME)
|| controllerInfo.getPackageName().equals(ANDROID_AUTOMOTIVE_LAUNCHER_PACKAGE_NAME));
}
/**
* Returns whether the given {@link ControllerInfo} belongs to an Android Auto companion app
* controller.
*
* @param controllerInfo The controller info.
* @return Whether the given controller info belongs to an Android Auto companion app controller.
*/
public boolean isAutoCompanionController(ControllerInfo controllerInfo) {
return controllerInfo.getControllerVersion() == ControllerInfo.LEGACY_CONTROLLER_VERSION
&& controllerInfo.getPackageName().equals(ANDROID_AUTO_PACKAGE_NAME);
}
/**
* Returns the {@link ControllerInfo} of the system UI notification controller, or {@code null} if
* the System UI controller is not connected.

View File

@ -0,0 +1,240 @@
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.media3.session;
import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static com.google.common.truth.Truth.assertThat;
import android.os.Bundle;
import androidx.media.MediaSessionManager;
import androidx.media3.common.MediaLibraryInfo;
import androidx.media3.test.utils.TestExoPlayerBuilder;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Tests for {@link MediaSession}. */
@RunWith(AndroidJUnit4.class)
public class MediaSessionUnitTest { // Avoid naming collision with session_current
private MediaSession session;
@Before
public void setUp() {
session =
new MediaSession.Builder(
getApplicationContext(), new TestExoPlayerBuilder(getApplicationContext()).build())
.build();
}
@After
public void tearDown() {
session.release();
}
@Test
public void isAutomotiveController_automotiveLauncher_returnsTrue() {
MediaSessionManager.RemoteUserInfo remoteUserInfo =
new MediaSessionManager.RemoteUserInfo(
/* packageName= */ "com.android.car.carlauncher",
/* pid= */ MediaSessionManager.RemoteUserInfo.UNKNOWN_PID,
/* uid= */ MediaSessionManager.RemoteUserInfo.UNKNOWN_UID);
assertThat(session.isAutomotiveController(createMinimalLegacyControllerInfo(remoteUserInfo)))
.isTrue();
}
@Test
public void isAutomotiveController_automotiveMedia_returnsTrue() {
MediaSessionManager.RemoteUserInfo remoteUserInfo =
new MediaSessionManager.RemoteUserInfo(
/* packageName= */ "com.android.car.media",
/* pid= */ MediaSessionManager.RemoteUserInfo.UNKNOWN_PID,
/* uid= */ MediaSessionManager.RemoteUserInfo.UNKNOWN_UID);
assertThat(session.isAutomotiveController(createMinimalLegacyControllerInfo(remoteUserInfo)))
.isTrue();
}
@Test
public void isAutomotiveController_automotiveMediaMedia3Version_returnsFalse() {
MediaSessionManager.RemoteUserInfo remoteUserInfo =
new MediaSessionManager.RemoteUserInfo(
/* packageName= */ "com.android.car.media",
/* pid= */ MediaSessionManager.RemoteUserInfo.UNKNOWN_PID,
/* uid= */ MediaSessionManager.RemoteUserInfo.UNKNOWN_UID);
MediaSession.ControllerInfo controllerInfo =
new MediaSession.ControllerInfo(
remoteUserInfo,
MediaLibraryInfo.VERSION_INT,
MediaControllerStub.VERSION_INT,
/* trusted= */ false,
/* cb= */ null,
/* connectionHints= */ Bundle.EMPTY);
assertThat(session.isAutomotiveController(controllerInfo)).isFalse();
}
@Test
public void isAutomotiveController_randomPackageName_returnsFalse() {
MediaSessionManager.RemoteUserInfo remoteUserInfo =
new MediaSessionManager.RemoteUserInfo(
/* packageName= */ "another.package",
/* pid= */ MediaSessionManager.RemoteUserInfo.UNKNOWN_PID,
/* uid= */ MediaSessionManager.RemoteUserInfo.UNKNOWN_UID);
assertThat(session.isAutoCompanionController(createMinimalLegacyControllerInfo(remoteUserInfo)))
.isFalse();
}
@Test
public void isAutoCompanionController_companionController_returnsTrue() {
MediaSessionManager.RemoteUserInfo remoteUserInfo =
new MediaSessionManager.RemoteUserInfo(
/* packageName= */ "com.google.android.projection.gearhead",
/* pid= */ MediaSessionManager.RemoteUserInfo.UNKNOWN_PID,
/* uid= */ MediaSessionManager.RemoteUserInfo.UNKNOWN_UID);
assertThat(session.isAutoCompanionController(createMinimalLegacyControllerInfo(remoteUserInfo)))
.isTrue();
}
@Test
public void isAutoCompanionController_randomPackage_returnsFalse() {
MediaSessionManager.RemoteUserInfo remoteUserInfo =
new MediaSessionManager.RemoteUserInfo(
/* packageName= */ "some.package",
/* pid= */ MediaSessionManager.RemoteUserInfo.UNKNOWN_PID,
/* uid= */ MediaSessionManager.RemoteUserInfo.UNKNOWN_UID);
assertThat(session.isAutoCompanionController(createMinimalLegacyControllerInfo(remoteUserInfo)))
.isFalse();
}
@Test
public void isAutoCompanionController_media3version_returnsFalse() {
MediaSessionManager.RemoteUserInfo remoteUserInfo =
new MediaSessionManager.RemoteUserInfo(
/* packageName= */ "com.google.android.projection.gearhead",
/* pid= */ MediaSessionManager.RemoteUserInfo.UNKNOWN_PID,
/* uid= */ MediaSessionManager.RemoteUserInfo.UNKNOWN_UID);
MediaSession.ControllerInfo controllerInfo =
new MediaSession.ControllerInfo(
remoteUserInfo,
MediaLibraryInfo.VERSION_INT,
MediaControllerStub.VERSION_INT,
/* trusted= */ false,
/* cb= */ null,
/* connectionHints= */ Bundle.EMPTY);
assertThat(session.isAutoCompanionController(controllerInfo)).isFalse();
}
@Test
public void isMediaNotificationController_applicationPackage_returnsTrue() {
MediaSessionManager.RemoteUserInfo remoteUserInfo =
new MediaSessionManager.RemoteUserInfo(
getApplicationContext().getPackageName(),
/* pid= */ MediaSessionManager.RemoteUserInfo.UNKNOWN_PID,
/* uid= */ MediaSessionManager.RemoteUserInfo.UNKNOWN_UID);
Bundle connectionHints = new Bundle();
connectionHints.putBoolean(MediaNotificationManager.KEY_MEDIA_NOTIFICATION_MANAGER, true);
MediaSession.ControllerInfo controllerInfo =
new MediaSession.ControllerInfo(
remoteUserInfo,
MediaLibraryInfo.VERSION_INT,
MediaControllerStub.VERSION_INT,
/* trusted= */ false,
/* cb= */ null,
connectionHints);
assertThat(session.isMediaNotificationController(controllerInfo)).isTrue();
}
@Test
public void isMediaNotificationController_randomPackage_returnsFalse() {
MediaSessionManager.RemoteUserInfo remoteUserInfo =
new MediaSessionManager.RemoteUserInfo(
/* packageName= */ "some.package",
/* pid= */ MediaSessionManager.RemoteUserInfo.UNKNOWN_PID,
/* uid= */ MediaSessionManager.RemoteUserInfo.UNKNOWN_UID);
Bundle connectionHints = new Bundle();
connectionHints.putBoolean(MediaNotificationManager.KEY_MEDIA_NOTIFICATION_MANAGER, true);
MediaSession.ControllerInfo controllerInfo =
new MediaSession.ControllerInfo(
remoteUserInfo,
MediaLibraryInfo.VERSION_INT,
MediaControllerStub.VERSION_INT,
/* trusted= */ false,
/* cb= */ null,
connectionHints);
assertThat(session.isMediaNotificationController(controllerInfo)).isFalse();
}
@Test
public void isMediaNotificationController_applicationPackageMissingBundle_returnsFalse() {
MediaSessionManager.RemoteUserInfo remoteUserInfo =
new MediaSessionManager.RemoteUserInfo(
getApplicationContext().getPackageName(),
/* pid= */ MediaSessionManager.RemoteUserInfo.UNKNOWN_PID,
/* uid= */ MediaSessionManager.RemoteUserInfo.UNKNOWN_UID);
MediaSession.ControllerInfo controllerInfo =
new MediaSession.ControllerInfo(
remoteUserInfo,
MediaLibraryInfo.VERSION_INT,
MediaControllerStub.VERSION_INT,
/* trusted= */ false,
/* cb= */ null,
/* connectionHints= */ Bundle.EMPTY);
assertThat(session.isMediaNotificationController(controllerInfo)).isFalse();
}
@Test
public void isMediaNotificationController_applicationPackageLegacyVersion_returnsFalse() {
MediaSessionManager.RemoteUserInfo remoteUserInfo =
new MediaSessionManager.RemoteUserInfo(
getApplicationContext().getPackageName(),
/* pid= */ MediaSessionManager.RemoteUserInfo.UNKNOWN_PID,
/* uid= */ MediaSessionManager.RemoteUserInfo.UNKNOWN_UID);
Bundle connectionHints = new Bundle();
connectionHints.putBoolean(MediaNotificationManager.KEY_MEDIA_NOTIFICATION_MANAGER, true);
MediaSession.ControllerInfo controllerInfo =
new MediaSession.ControllerInfo(
remoteUserInfo,
MediaSession.ControllerInfo.LEGACY_CONTROLLER_VERSION,
MediaSession.ControllerInfo.LEGACY_CONTROLLER_INTERFACE_VERSION,
/* trusted= */ false,
/* cb= */ null,
connectionHints);
assertThat(session.isMediaNotificationController(controllerInfo)).isFalse();
}
private static MediaSession.ControllerInfo createMinimalLegacyControllerInfo(
MediaSessionManager.RemoteUserInfo remoteUserInfo) {
return new MediaSession.ControllerInfo(
remoteUserInfo,
MediaSession.ControllerInfo.LEGACY_CONTROLLER_VERSION,
MediaSession.ControllerInfo.LEGACY_CONTROLLER_INTERFACE_VERSION,
/* trusted= */ false,
/* cb= */ null,
/* connectionHints= */ Bundle.EMPTY);
}
}