TransportMediatorJellybeanMR2.java revision c76d76a0d92a9dca5c91c68b86666d403ac0fd3c
1d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn/*
2d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn * Copyright (C) 2013 The Android Open Source Project
3d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn *
4d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
5d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn * you may not use this file except in compliance with the License.
6d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn * You may obtain a copy of the License at
7d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn *
8d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
9d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn *
10d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn * Unless required by applicable law or agreed to in writing, software
11d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
12d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn * See the License for the specific language governing permissions and
14d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn * limitations under the License.
15d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn */
16d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn
17d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackbornpackage android.support.v4.media;
18d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn
19d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackbornimport android.app.PendingIntent;
20d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackbornimport android.content.BroadcastReceiver;
21d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackbornimport android.content.Context;
22d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackbornimport android.content.Intent;
23d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackbornimport android.content.IntentFilter;
24d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackbornimport android.media.AudioManager;
25d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackbornimport android.media.RemoteControlClient;
26c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackbornimport android.os.SystemClock;
27d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackbornimport android.util.Log;
28c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackbornimport android.view.InputDevice;
29c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackbornimport android.view.KeyCharacterMap;
30d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackbornimport android.view.KeyEvent;
31d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackbornimport android.view.View;
32d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackbornimport android.view.ViewTreeObserver;
33d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn
34d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackbornpublic class TransportControllerJellybeanMR2 {
35d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    final Context mContext;
36d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    final AudioManager mAudioManager;
37d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    final View mTargetView;
38c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn    final TransportCallback mTransportCallback;
39d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    final String mReceiverAction;
40d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    final IntentFilter mReceiverFilter;
41d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    final Intent mIntent;
42d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    final ViewTreeObserver.OnWindowAttachListener mWindowAttachListener =
43d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            new ViewTreeObserver.OnWindowAttachListener() {
44d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                @Override
45d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                public void onWindowAttached() {
46d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                    windowAttached();
47d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                }
48d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                @Override
49d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                public void onWindowDetached() {
50d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                    windowDetached();
51d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                }
52d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            };
53d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    final ViewTreeObserver.OnWindowFocusChangeListener mWindowFocusListener =
54d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            new ViewTreeObserver.OnWindowFocusChangeListener() {
55d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                @Override
56d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                public void onWindowFocusChanged(boolean hasFocus) {
57d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                    if (hasFocus) gainFocus();
58d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                    else loseFocus();
59d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                }
60d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            };
61d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    final BroadcastReceiver mMediaButtonReceiver = new BroadcastReceiver() {
62d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        @Override
63d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        public void onReceive(Context context, Intent intent) {
64d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            try {
65d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                KeyEvent event = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
66c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn                mTransportCallback.handleKey(event);
67d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            } catch (ClassCastException e) {
68d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                Log.w("TransportController", e);
69d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            }
70d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        }
71d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    };
72c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn    AudioManager.OnAudioFocusChangeListener mAudioFocusChangeListener
73c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn            = new AudioManager.OnAudioFocusChangeListener() {
74c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn        @Override
75c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn        public void onAudioFocusChange(int focusChange) {
76c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn            mTransportCallback.handleAudioFocusChange(focusChange);
77c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn        }
78c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn    };
79d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn
80d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    PendingIntent mPendingIntent;
81d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    RemoteControlClient mRemoteControl;
82d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    boolean mFocused;
83c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn    int mPlayState = 0;
84c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn    boolean mAudioFocused;
85d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn
86c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn    public interface TransportCallback {
87d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        public void handleKey(KeyEvent key);
88c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn        public void handleAudioFocusChange(int focusChange);
89d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    }
90d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn
91d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    public TransportControllerJellybeanMR2(Context context, AudioManager audioManager,
92c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn            View view, TransportCallback transportCallback) {
93d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mContext = context;
94d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mAudioManager = audioManager;
95d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mTargetView = view;
96c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn        mTransportCallback = transportCallback;
97d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mReceiverAction = context.getPackageName() + ":transport:" + System.identityHashCode(this);
98d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mIntent = new Intent(mReceiverAction);
99d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mIntent.setPackage(context.getPackageName());
100d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mReceiverFilter = new IntentFilter();
101d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mReceiverFilter.addAction(mReceiverAction);
102d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mTargetView.getViewTreeObserver().addOnWindowAttachListener(mWindowAttachListener);
103d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mTargetView.getViewTreeObserver().addOnWindowFocusChangeListener(mWindowFocusListener);
104d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    }
105d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn
106d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    public Object getRemoteControlClient() {
107d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        return mRemoteControl;
108d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    }
109d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn
110d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    public void destroy() {
111d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        windowDetached();
112d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mTargetView.getViewTreeObserver().removeOnWindowAttachListener(mWindowAttachListener);
113d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mTargetView.getViewTreeObserver().removeOnWindowFocusChangeListener(mWindowFocusListener);
114d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    }
115d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn
116d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    void windowAttached() {
117d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mContext.registerReceiver(mMediaButtonReceiver, mReceiverFilter);
118d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mPendingIntent = PendingIntent.getBroadcast(mContext, 0, mIntent,
119d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                PendingIntent.FLAG_CANCEL_CURRENT);
120d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mRemoteControl = new RemoteControlClient(mPendingIntent);
121d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    }
122d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn
123d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    void gainFocus() {
124d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        if (!mFocused) {
125d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            mFocused = true;
126d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            mAudioManager.registerMediaButtonEventReceiver(mPendingIntent);
127d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            mAudioManager.registerRemoteControlClient(mRemoteControl);
128c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn            if (mPlayState == RemoteControlClient.PLAYSTATE_PLAYING) {
129c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn                takeAudioFocus();
130c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn            }
131c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn        }
132c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn    }
133c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn
134c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn    void takeAudioFocus() {
135c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn        if (!mAudioFocused) {
136c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn            mAudioFocused = true;
137c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn            mAudioManager.requestAudioFocus(mAudioFocusChangeListener,
138c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn                    AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
139c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn        }
140c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn    }
141c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn
142c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn    public void startPlaying() {
143c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn        if (mPlayState != RemoteControlClient.PLAYSTATE_PLAYING) {
144c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn            mPlayState = RemoteControlClient.PLAYSTATE_PLAYING;
145c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn            mRemoteControl.setPlaybackState(RemoteControlClient.PLAYSTATE_PLAYING);
146c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn        }
147c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn        if (mFocused) {
148c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn            takeAudioFocus();
149c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn        }
150c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn    }
151c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn
152c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn    public void pausePlaying() {
153c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn        if (mPlayState == RemoteControlClient.PLAYSTATE_PLAYING) {
154c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn            mPlayState = RemoteControlClient.PLAYSTATE_PAUSED;
155c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn            mRemoteControl.setPlaybackState(RemoteControlClient.PLAYSTATE_PAUSED);
156c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn        }
157c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn    }
158c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn
159c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn    public void stopPlaying() {
160c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn        if (mPlayState != RemoteControlClient.PLAYSTATE_STOPPED) {
161c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn            mPlayState = RemoteControlClient.PLAYSTATE_STOPPED;
162c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn            mRemoteControl.setPlaybackState(RemoteControlClient.PLAYSTATE_STOPPED);
163c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn        }
164c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn        dropAudioFocus();
165c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn    }
166c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn
167c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn    void handleAudioFocusChange(int focusChange) {
168c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn        int keyCode = 0;
169c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn        switch (focusChange) {
170c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn            case AudioManager.AUDIOFOCUS_GAIN:
171c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn                keyCode = KeyEvent.KEYCODE_MEDIA_PLAY;
172c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn                break;
173c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn            case AudioManager.AUDIOFOCUS_LOSS:
174c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn                keyCode = KeyEvent.KEYCODE_MEDIA_STOP;
175c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn                break;
176c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn            case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
177c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn            case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
178c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn                keyCode = KeyEvent.KEYCODE_MEDIA_PAUSE;
179c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn                break;
180c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn        }
181c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn        if (keyCode != 0) {
182c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn            final long now = SystemClock.uptimeMillis();
183c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn            mTransportCallback.handleKey(new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keyCode, 0, 0,
184c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn                    KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD));
185c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn            mTransportCallback.handleKey(new KeyEvent(now, now, KeyEvent.ACTION_UP, keyCode, 0, 0,
186c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn                    KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD));
187c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn        }
188c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn    }
189c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn
190c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn    void dropAudioFocus() {
191c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn        if (mAudioFocused) {
192c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn            mAudioFocused = false;
193c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn            mAudioManager.abandonAudioFocus(mAudioFocusChangeListener);
194d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        }
195d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    }
196d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn
197d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    void loseFocus() {
198c76d76a0d92a9dca5c91c68b86666d403ac0fd3cDianne Hackborn        dropAudioFocus();
199d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        if (mFocused) {
200d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            mFocused = false;
201d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            mAudioManager.unregisterRemoteControlClient(mRemoteControl);
202d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            mAudioManager.unregisterMediaButtonEventReceiver(mPendingIntent);
203d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        }
204d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    }
205d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn
206d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    void windowDetached() {
207d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        loseFocus();
208d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        if (mPendingIntent != null) {
209d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            mContext.unregisterReceiver(mMediaButtonReceiver);
210d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            mPendingIntent.cancel();
211d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            mPendingIntent = null;
212d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            mRemoteControl = null;
213d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        }
214d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    }
215d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn}
216