TransportMediatorJellybeanMR2.java revision d3a70800e5f2cc2855d53ebea82fb7568affe02a
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;
26d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackbornimport android.util.Log;
27d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackbornimport android.view.KeyEvent;
28d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackbornimport android.view.View;
29d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackbornimport android.view.ViewTreeObserver;
30d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn
31d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackbornpublic class TransportControllerJellybeanMR2 {
32d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    final Context mContext;
33d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    final AudioManager mAudioManager;
34d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    final View mTargetView;
35d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    final KeyCallback mKeyCallback;
36d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    final String mReceiverAction;
37d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    final IntentFilter mReceiverFilter;
38d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    final Intent mIntent;
39d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    final ViewTreeObserver.OnWindowAttachListener mWindowAttachListener =
40d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            new ViewTreeObserver.OnWindowAttachListener() {
41d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                @Override
42d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                public void onWindowAttached() {
43d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                    windowAttached();
44d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                }
45d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                @Override
46d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                public void onWindowDetached() {
47d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                    windowDetached();
48d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                }
49d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            };
50d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    final ViewTreeObserver.OnWindowFocusChangeListener mWindowFocusListener =
51d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            new ViewTreeObserver.OnWindowFocusChangeListener() {
52d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                @Override
53d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                public void onWindowFocusChanged(boolean hasFocus) {
54d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                    if (hasFocus) gainFocus();
55d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                    else loseFocus();
56d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                }
57d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            };
58d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    final BroadcastReceiver mMediaButtonReceiver = new BroadcastReceiver() {
59d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        @Override
60d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        public void onReceive(Context context, Intent intent) {
61d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            try {
62d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                KeyEvent event = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
63d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                mKeyCallback.handleKey(event);
64d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            } catch (ClassCastException e) {
65d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                Log.w("TransportController", e);
66d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            }
67d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        }
68d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    };
69d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn
70d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    PendingIntent mPendingIntent;
71d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    RemoteControlClient mRemoteControl;
72d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    boolean mFocused;
73d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn
74d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    public interface KeyCallback {
75d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        public void handleKey(KeyEvent key);
76d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    }
77d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn
78d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    public TransportControllerJellybeanMR2(Context context, AudioManager audioManager,
79d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            View view, KeyCallback keyCallback) {
80d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mContext = context;
81d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mAudioManager = audioManager;
82d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mTargetView = view;
83d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mKeyCallback = keyCallback;
84d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mReceiverAction = context.getPackageName() + ":transport:" + System.identityHashCode(this);
85d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mIntent = new Intent(mReceiverAction);
86d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mIntent.setPackage(context.getPackageName());
87d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mReceiverFilter = new IntentFilter();
88d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mReceiverFilter.addAction(mReceiverAction);
89d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mTargetView.getViewTreeObserver().addOnWindowAttachListener(mWindowAttachListener);
90d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mTargetView.getViewTreeObserver().addOnWindowFocusChangeListener(mWindowFocusListener);
91d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    }
92d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn
93d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    public Object getRemoteControlClient() {
94d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        return mRemoteControl;
95d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    }
96d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn
97d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    public void destroy() {
98d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        windowDetached();
99d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mTargetView.getViewTreeObserver().removeOnWindowAttachListener(mWindowAttachListener);
100d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mTargetView.getViewTreeObserver().removeOnWindowFocusChangeListener(mWindowFocusListener);
101d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    }
102d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn
103d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    void windowAttached() {
104d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mContext.registerReceiver(mMediaButtonReceiver, mReceiverFilter);
105d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mPendingIntent = PendingIntent.getBroadcast(mContext, 0, mIntent,
106d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn                PendingIntent.FLAG_CANCEL_CURRENT);
107d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        mRemoteControl = new RemoteControlClient(mPendingIntent);
108d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    }
109d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn
110d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    void gainFocus() {
111d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        if (!mFocused) {
112d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            mFocused = true;
113d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            mAudioManager.registerMediaButtonEventReceiver(mPendingIntent);
114d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            mAudioManager.registerRemoteControlClient(mRemoteControl);
115d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        }
116d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    }
117d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn
118d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    void loseFocus() {
119d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        if (mFocused) {
120d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            mFocused = false;
121d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            mAudioManager.unregisterRemoteControlClient(mRemoteControl);
122d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            mAudioManager.unregisterMediaButtonEventReceiver(mPendingIntent);
123d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        }
124d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    }
125d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn
126d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    void windowDetached() {
127d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        loseFocus();
128d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        if (mPendingIntent != null) {
129d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            mContext.unregisterReceiver(mMediaButtonReceiver);
130d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            mPendingIntent.cancel();
131d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            mPendingIntent = null;
132d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn            mRemoteControl = null;
133d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn        }
134d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn    }
135d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn}
136