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