1 package com.android.car.media;
2 
3 import static android.car.media.CarMediaIntents.EXTRA_MEDIA_COMPONENT;
4 import static android.car.media.CarMediaManager.MEDIA_SOURCE_MODE_BROWSE;
5 
6 import android.car.Car;
7 import android.car.media.CarMediaIntents;
8 import android.content.ComponentName;
9 import android.content.Intent;
10 import android.content.res.Resources;
11 import android.os.Bundle;
12 import android.util.Log;
13 
14 import androidx.annotation.Nullable;
15 import androidx.fragment.app.FragmentActivity;
16 
17 import com.android.car.media.common.source.MediaSource;
18 import com.android.car.media.common.source.MediaSourceViewModel;
19 
20 import java.util.Arrays;
21 import java.util.HashSet;
22 import java.util.Set;
23 
24 /**
25  * A trampoline activity that handles the {@link Car#CAR_INTENT_ACTION_MEDIA_TEMPLATE} implicit
26  * intent, and fires up either the Media Center's {@link MediaActivity}, or the specialized
27  * application if the selected media source is custom (e.g. the Radio app).
28  */
29 public class MediaDispatcherActivity extends FragmentActivity {
30 
31     private static final String TAG = "MediaDispatcherActivity";
32     private static Set<String> sCustomMediaComponents = null;
33 
isCustomMediaSource(Resources res, @Nullable MediaSource source)34     static boolean isCustomMediaSource(Resources res, @Nullable MediaSource source) {
35         if (sCustomMediaComponents == null) {
36             sCustomMediaComponents = new HashSet<>();
37             sCustomMediaComponents.addAll(
38                     Arrays.asList(res.getStringArray(R.array.custom_media_packages)));
39         }
40 
41         return (source != null)
42                 && sCustomMediaComponents.contains(
43                         source.getBrowseServiceComponentName().flattenToString());
44     }
45 
46     @Override
onCreate(Bundle savedInstanceState)47     protected void onCreate(Bundle savedInstanceState) {
48         super.onCreate(savedInstanceState);
49 
50         Intent intent = getIntent();
51         String action = null;
52         String componentName = null;
53         if (intent != null) {
54             action = intent.getAction();
55             componentName = intent.getStringExtra(EXTRA_MEDIA_COMPONENT);
56         }
57 
58         if (Log.isLoggable(TAG, Log.INFO)) {
59             Log.i(TAG, "onCreate action: " + action + " component: " + componentName);
60         }
61 
62         MediaSource mediaSrc = null;
63         if (CarMediaIntents.ACTION_MEDIA_TEMPLATE.equals(action)) {
64             if (componentName != null) {
65                 ComponentName mediaSrcComp = ComponentName.unflattenFromString(componentName);
66                 if (mediaSrcComp != null) {
67                     mediaSrc = MediaSource.create(this, mediaSrcComp);
68                 }
69             }
70         }
71 
72         // Retrieve the current source if none was set. However, do NOT set it and rely on setting
73         // the EXTRA_MEDIA_COMPONENT on the intent launched below. This avoids source notifications
74         // as well as extra trips back here, all of which would be useless.
75         if (mediaSrc == null) {
76             MediaSourceViewModel mediaSrcVM = MediaSourceViewModel.get(getApplication(),
77                     MEDIA_SOURCE_MODE_BROWSE);
78             mediaSrc = mediaSrcVM.getPrimaryMediaSource().getValue();
79         }
80 
81         Intent newIntent = null;
82         if ((mediaSrc != null) && isCustomMediaSource(getResources(), mediaSrc)) {
83             // Launch custom app (e.g. Radio)
84             String srcPackage = mediaSrc.getPackageName();
85             newIntent = getPackageManager().getLaunchIntentForPackage(srcPackage);
86             if (Log.isLoggable(TAG, Log.DEBUG)) {
87                 Log.d(TAG, "Getting launch intent for package : " + srcPackage + (newIntent != null
88                         ? " succeeded" : " failed"));
89             }
90         }
91         if (newIntent == null) {
92             // Launch media center
93             newIntent = new Intent(this, MediaActivity.class);
94         }
95 
96         // Add the selected media source to the intent so the launched activity gets it right away
97         if (mediaSrc != null) {
98             newIntent.putExtra(EXTRA_MEDIA_COMPONENT,
99                     mediaSrc.getBrowseServiceComponentName().flattenToString());
100         }
101 
102         newIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
103         startActivity(newIntent);
104         finish();
105     }
106 }
107