/* * Copyright 2022 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.mediarouter.app; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.media.MediaRouter2; import android.os.Build; import android.provider.Settings; import androidx.annotation.DoNotInline; import androidx.annotation.NonNull; import androidx.annotation.RequiresApi; import java.util.List; /** * Provides an utility method to show the system's output switcher dialog. * * @see Media Routing */ public final class SystemOutputSwitcherDialogController { /** System ui service package name. */ private static final String PACKAGE_NAME_SYSTEM_UI = "com.android.systemui"; /** Output switcher dialog intent action in Android S. **/ private static final String OUTPUT_SWITCHER_INTENT_ACTION_ANDROID_S = "com.android.systemui.action.LAUNCH_MEDIA_OUTPUT_DIALOG"; /** Output switcher dialog intent action in Android R. **/ private static final String OUTPUT_SWITCHER_INTENT_ACTION_ANDROID_R = "com.android.settings.panel.action.MEDIA_OUTPUT"; /** A package name key for output switcher intent in Android S. */ private static final String OUTPUT_SWITCHER_INTENT_KEY_PACKAGE_NAME_ANDROID_S = "package_name"; /** A package name key for output switcher intent in Android R. */ private static final String OUTPUT_SWITCHER_INTENT_KEY_PACKAGE_NAME_ANDROID_R = "com.android.settings.panel.extra.PACKAGE_NAME"; private SystemOutputSwitcherDialogController() { // Private to prevent new instances. } /** * Shows the system output switcher dialog. * *
The appearance and precise behaviour of the system output switcher dialog * may vary across different devices, OS versions, and form factors, * but the basic functionality stays the same. * *
See
*
* Output Switcher documentation for more details.
*
* @param context Android context
* @return {@code true} if the dialog was shown successfully and {@code false} otherwise
*/
public static boolean showDialog(@NonNull Context context) {
boolean result = false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
result = showDialogForAndroidUAndAbove(context);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
result = showDialogForAndroidSAndT(context)
// The intent action and related string constants are changed in S,
// however they are not public API yet. Try opening the output switcher with the
// old constants for devices that have prior version of the constants.
|| showDialogForAndroidR(context);
} else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.R) {
result = showDialogForAndroidR(context);
}
if (result) {
return true;
}
if (isRunningOnWear(context) && showBluetoothSettingsFragment(context)) {
return true;
}
return false;
}
private static boolean showDialogForAndroidUAndAbove(@NonNull Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
MediaRouter2 mediaRouter2 = Api30Impl.getInstance(context);
if (Build.VERSION.SDK_INT >= 34) {
return Api34Impl.showSystemOutputSwitcher(mediaRouter2);
}
}
return false;
}
private static boolean showDialogForAndroidSAndT(@NonNull Context context) {
Intent intent = new Intent()
.setAction(OUTPUT_SWITCHER_INTENT_ACTION_ANDROID_S)
.setPackage(PACKAGE_NAME_SYSTEM_UI)
.putExtra(OUTPUT_SWITCHER_INTENT_KEY_PACKAGE_NAME_ANDROID_S,
context.getPackageName());
PackageManager packageManager = context.getPackageManager();
List