Skip to content

Commit

Permalink
Add isAutomotiveController and isAutoCompanionController
Browse files Browse the repository at this point in the history
Issue: #561
Issue: #644
Issue: #645
PiperOrigin-RevId: 568948230
  • Loading branch information
marcbaechinger authored and copybara-github committed Sep 27, 2023
1 parent 99086b4 commit 0b0d02c
Show file tree
Hide file tree
Showing 3 changed files with 296 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -818,6 +818,33 @@ public ControllerInfo getMediaNotificationControllerInfo() {
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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@

/* 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. "
Expand Down Expand Up @@ -388,14 +392,37 @@ protected boolean isSystemUiController(@Nullable MediaSession.ControllerInfo con
*/
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.
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
}

0 comments on commit 0b0d02c

Please sign in to comment.