164b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer/*
264b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer * Copyright (C) 2016 The Android Open Source Project
364b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer *
464b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer * Licensed under the Apache License, Version 2.0 (the "License");
564b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer * you may not use this file except in compliance with the License.
664b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer * You may obtain a copy of the License at
764b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer *
864b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer *      http://www.apache.org/licenses/LICENSE-2.0
964b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer *
1064b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer * Unless required by applicable law or agreed to in writing, software
1164b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer * distributed under the License is distributed on an "AS IS" BASIS,
1264b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1364b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer * See the License for the specific language governing permissions and
1464b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer * limitations under the License.
1564b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer */
1664b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyerpackage com.android.car.media;
1764b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
1864b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyerimport android.content.ComponentName;
1964b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyerimport android.content.Intent;
2064b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyerimport android.os.Bundle;
2164b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyerimport android.provider.MediaStore;
2264b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyerimport android.util.Log;
235cb58af61618d6c457685a5feba630540f25567cSrinivas Visvanathanimport com.android.car.app.CarDrawerActivity;
245cb58af61618d6c457685a5feba630540f25567cSrinivas Visvanathanimport com.android.car.app.CarDrawerAdapter;
255cb58af61618d6c457685a5feba630540f25567cSrinivas Visvanathanimport com.android.car.media.drawer.MediaDrawerController;
265cb58af61618d6c457685a5feba630540f25567cSrinivas Visvanathan
2764b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer/**
2864b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer * This activity controls the UI of media. It also updates the connection status for the media app
295cb58af61618d6c457685a5feba630540f25567cSrinivas Visvanathan * by broadcast. Drawer menu is controlled by {@link MediaDrawerController}.
3064b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer */
31349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chenpublic class MediaActivity extends CarDrawerActivity
32349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen        implements MediaPlaybackFragment.PlayQueueRevealer {
3364b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    private static final String ACTION_MEDIA_APP_STATE_CHANGE
3464b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer            = "android.intent.action.MEDIA_APP_STATE_CHANGE";
3564b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    private static final String EXTRA_MEDIA_APP_FOREGROUND
3664b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer            = "android.intent.action.MEDIA_APP_STATE";
3764b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
3864b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    private static final String TAG = "MediaActivity";
3964b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
4064b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    /**
4164b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer     * Whether or not {@link #onStart()} has been called.
4264b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer     */
4364b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    private boolean mIsStarted;
4464b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
4564b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    /**
4664b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer     * {@code true} if there was a request to change the content fragment of this Activity when
4764b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer     * it is not started. Then, when onStart() is called, the content fragment will be added.
4864b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer     *
4964b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer     * <p>This prevents a bug where the content fragment is added when the app is not running,
5064b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer     * causing a StateLossException.
5164b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer     */
5264b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    private boolean mContentFragmentChangeQueued;
5364b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
545cb58af61618d6c457685a5feba630540f25567cSrinivas Visvanathan    private MediaDrawerController mDrawerController;
5564b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    private MediaPlaybackFragment mMediaPlaybackFragment;
5664b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
5764b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    @Override
5864b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    protected void onStart() {
5964b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        super.onStart();
6064b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        Intent i = new Intent(ACTION_MEDIA_APP_STATE_CHANGE);
6164b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        i.putExtra(EXTRA_MEDIA_APP_FOREGROUND, true);
625cb58af61618d6c457685a5feba630540f25567cSrinivas Visvanathan        sendBroadcast(i);
6364b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
6464b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        mIsStarted = true;
6564b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
6664b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        if (mContentFragmentChangeQueued) {
6764b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer            if (Log.isLoggable(TAG, Log.DEBUG)) {
6864b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer                Log.d(TAG, "Content fragment queued. Attaching now.");
6964b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer            }
70349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen            showMediaPlaybackFragment();
7164b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer            mContentFragmentChangeQueued = false;
7264b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        }
7364b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    }
7464b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
7564b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    @Override
7664b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    protected void onStop() {
7764b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        super.onStop();
7864b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        Intent i = new Intent(ACTION_MEDIA_APP_STATE_CHANGE);
7964b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        i.putExtra(EXTRA_MEDIA_APP_FOREGROUND, false);
805cb58af61618d6c457685a5feba630540f25567cSrinivas Visvanathan        sendBroadcast(i);
8164b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
8264b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        mIsStarted = false;
8364b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    }
8464b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
8564b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    @Override
8664b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    protected void onCreate(Bundle savedInstanceState) {
87349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen        // The drawer must be initialized before the super call because CarDrawerActivity.onCreate
88349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen        // looks up the rootAdapter from its subclasses. The MediaDrawerController provides the
89349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen        // root adapter.
905cb58af61618d6c457685a5feba630540f25567cSrinivas Visvanathan        mDrawerController = new MediaDrawerController(this);
91349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen
9264b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        super.onCreate(savedInstanceState);
935cb58af61618d6c457685a5feba630540f25567cSrinivas Visvanathan
945cb58af61618d6c457685a5feba630540f25567cSrinivas Visvanathan        setMainContent(R.layout.media_activity);
955cb58af61618d6c457685a5feba630540f25567cSrinivas Visvanathan        MediaManager.getInstance(this).addListener(mListener);
9664b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    }
9764b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
9864b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    @Override
9964b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    public void onDestroy() {
10064b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        super.onDestroy();
10164b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        // Send the broadcast to let the current connected media app know it is disconnected now.
10264b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        sendMediaConnectionStatusBroadcast(
1035cb58af61618d6c457685a5feba630540f25567cSrinivas Visvanathan                MediaManager.getInstance(this).getCurrentComponent(),
10464b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer                MediaConstants.MEDIA_DISCONNECTED);
1055cb58af61618d6c457685a5feba630540f25567cSrinivas Visvanathan        mDrawerController.cleanup();
1065cb58af61618d6c457685a5feba630540f25567cSrinivas Visvanathan        MediaManager.getInstance(this).removeListener(mListener);
107349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen        mMediaPlaybackFragment = null;
1085cb58af61618d6c457685a5feba630540f25567cSrinivas Visvanathan    }
1095cb58af61618d6c457685a5feba630540f25567cSrinivas Visvanathan
1105cb58af61618d6c457685a5feba630540f25567cSrinivas Visvanathan    @Override
1115cb58af61618d6c457685a5feba630540f25567cSrinivas Visvanathan    protected CarDrawerAdapter getRootAdapter() {
1125cb58af61618d6c457685a5feba630540f25567cSrinivas Visvanathan        return mDrawerController.getRootAdapter();
11364b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    }
11464b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
11564b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    @Override
11664b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    public void onResumeFragments() {
11764b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        if (Log.isLoggable(TAG, Log.DEBUG)) {
11864b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer            Log.d(TAG, "onResumeFragments");
11964b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        }
12064b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
12164b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        super.onResumeFragments();
12264b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        handleIntent(getIntent());
12364b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    }
12464b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
12564b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    @Override
12664b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    protected void onNewIntent(Intent intent) {
12764b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        super.onNewIntent(intent);
12864b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        if (Log.isLoggable(TAG, Log.VERBOSE)) {
12964b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer            Log.v(TAG, "onNewIntent(); intent: " + (intent == null ? "<< NULL >>" : intent));
13064b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        }
13164b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
13264b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        setIntent(intent);
1335cb58af61618d6c457685a5feba630540f25567cSrinivas Visvanathan        closeDrawer();
13464b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    }
13564b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
13664b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    @Override
13764b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    public void onBackPressed() {
138349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen        if (mMediaPlaybackFragment != null) {
13964b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer            mMediaPlaybackFragment.closeOverflowMenu();
14064b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        }
14164b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        super.onBackPressed();
14264b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    }
14364b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
14464b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    private void handleIntent(Intent intent) {
14564b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        Bundle extras = null;
14664b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        if (intent != null) {
14764b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer            extras = intent.getExtras();
14864b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        }
14964b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
15064b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        // If the intent has a media component name set, connect to it directly
15164b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        if (extras != null && extras.containsKey(MediaManager.KEY_MEDIA_PACKAGE) &&
15264b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer                extras.containsKey(MediaManager.KEY_MEDIA_CLASS)) {
15364b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer            if (Log.isLoggable(TAG, Log.DEBUG)) {
15464b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer                Log.d(TAG, "Media component in intent.");
15564b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer            }
15664b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
15764b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer            ComponentName component = new ComponentName(
15864b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer                    intent.getStringExtra(MediaManager.KEY_MEDIA_PACKAGE),
15964b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer                    intent.getStringExtra(MediaManager.KEY_MEDIA_CLASS)
16064b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer            );
1615cb58af61618d6c457685a5feba630540f25567cSrinivas Visvanathan            MediaManager.getInstance(this).setMediaClientComponent(component);
16264b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        } else {
16364b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer            if (Log.isLoggable(TAG, Log.DEBUG)) {
16464b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer                Log.d(TAG, "Launching most recent / default component.");
16564b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer            }
16664b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
16764b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer            // Set it to the default GPM component.
1685cb58af61618d6c457685a5feba630540f25567cSrinivas Visvanathan            MediaManager.getInstance(this).connectToMostRecentMediaComponent(
1695cb58af61618d6c457685a5feba630540f25567cSrinivas Visvanathan                    new CarClientServiceAdapter(getPackageManager()));
17064b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        }
17164b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
17264b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        if (isSearchIntent(intent)) {
1735cb58af61618d6c457685a5feba630540f25567cSrinivas Visvanathan            MediaManager.getInstance(this).processSearchIntent(intent);
17464b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer            setIntent(null);
17564b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        }
17664b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    }
17764b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
178349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen    /**
179349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen     * Returns {@code true} if the given intent is one that contains a search query for the
180349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen     * attached media application.
181349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen     */
18264b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    private boolean isSearchIntent(Intent intent) {
18364b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        return (intent != null && intent.getAction() != null &&
18464b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer                intent.getAction().equals(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH));
18564b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    }
18664b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
187349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen    private void sendMediaConnectionStatusBroadcast(ComponentName componentName,
188349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen            String connectionStatus) {
189349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen        // There will be no current component if no media app has been chosen before.
19064b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        if (componentName == null) {
19164b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer            return;
19264b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        }
19364b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
19464b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        Intent intent = new Intent(MediaConstants.ACTION_MEDIA_STATUS);
19564b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        intent.setPackage(componentName.getPackageName());
19664b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        intent.putExtra(MediaConstants.MEDIA_CONNECTION_STATUS, connectionStatus);
1975cb58af61618d6c457685a5feba630540f25567cSrinivas Visvanathan        sendBroadcast(intent);
19864b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    }
19964b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
200349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen    private void showMediaPlaybackFragment() {
201349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen        // If the fragment has already been created, then it has been attached already.
202349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen        if (mMediaPlaybackFragment != null) {
203349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen            return;
20464b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        }
20564b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
206349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen        mMediaPlaybackFragment = new MediaPlaybackFragment();
207349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen        mMediaPlaybackFragment.setPlayQueueRevealer(this);
208349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen
209349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen       getSupportFragmentManager().beginTransaction()
210349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen                .replace(R.id.fragment_container, mMediaPlaybackFragment)
211349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen                .commit();
21264b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    }
21364b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
214349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen    @Override
215349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen    public void showPlayQueue() {
2165f33f82fb1a5907fbd8bd286dcdaa689d2d192d6Anthony Chen        mDrawerController.showPlayQueue();
217349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen    }
21864b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
219349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen    private final MediaManager.Listener mListener = new MediaManager.Listener() {
22064b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        @Override
22164b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        public void onMediaAppChanged(ComponentName componentName) {
22264b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer            sendMediaConnectionStatusBroadcast(componentName, MediaConstants.MEDIA_CONNECTED);
22364b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
22464b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer            // Since this callback happens asynchronously, ensure that the Activity has been
22564b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer            // started before changing fragments. Otherwise, the attach fragment will throw
22664b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer            // an IllegalStateException due to Fragment's checkStateLoss.
22764b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer            if (mIsStarted) {
22864b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer                if (Log.isLoggable(TAG, Log.DEBUG)) {
22964b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer                    Log.d(TAG, "onMediaAppChanged: attaching content fragment");
23064b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer                }
231349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen                showMediaPlaybackFragment();
23264b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer            } else {
23364b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer                if (Log.isLoggable(TAG, Log.DEBUG)) {
23464b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer                    Log.d(TAG, "onMediaAppChanged: queuing content fragment change");
23564b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer                }
23664b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer                mContentFragmentChangeQueued = true;
23764b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer            }
23864b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        }
23964b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer
24064b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        @Override
24164b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer        public void onStatusMessageChanged(String msg) {}
24264b173f33aa2d98ea00b9113b52e6f8cb35589adRakesh Iyer    };
243349880a1749d601dea9f20106b3dd09ee47f8eb9Anthony Chen}
244