Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 87959cdd authored by Dianne Hackborn's avatar Dianne Hackborn Committed by Android (Google) Code Review
Browse files

Merge "Add new callback for MediaRouter to found out about device changes." into jb-dev

parents c4f4b0f0 632ca417
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -193,6 +193,7 @@ LOCAL_SRC_FILES += \
	location/java/android/location/INetInitiatedListener.aidl \
	media/java/android/media/IAudioService.aidl \
	media/java/android/media/IAudioFocusDispatcher.aidl \
    media/java/android/media/IAudioRoutesObserver.aidl \
	media/java/android/media/IMediaScannerListener.aidl \
	media/java/android/media/IMediaScannerService.aidl \
	media/java/android/media/IRemoteControlClient.aidl \
+18 −0
Original line number Diff line number Diff line
/* Copyright 2012, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

package android.media;

parcelable AudioRoutesInfo;
+71 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.media;

import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;

/**
 * Information available from AudioService about the current routes.
 * @hide
 */
public class AudioRoutesInfo implements Parcelable {
    static final int MAIN_SPEAKER = 0;
    static final int MAIN_HEADSET = 1<<0;
    static final int MAIN_HEADPHONES = 1<<1;
    static final int MAIN_DOCK_SPEAKERS = 1<<2;
    static final int MAIN_HDMI = 1<<3;

    CharSequence mBluetoothName;
    int mMainType = MAIN_SPEAKER;

    public AudioRoutesInfo() {
    }

    public AudioRoutesInfo(AudioRoutesInfo o) {
        mBluetoothName = o.mBluetoothName;
        mMainType = o.mMainType;
    }

    AudioRoutesInfo(Parcel src) {
        mBluetoothName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(src);
        mMainType = src.readInt();
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        TextUtils.writeToParcel(mBluetoothName, dest, flags);
        dest.writeInt(mMainType);
    }

    public static final Parcelable.Creator<AudioRoutesInfo> CREATOR
            = new Parcelable.Creator<AudioRoutesInfo>() {
        public AudioRoutesInfo createFromParcel(Parcel in) {
            return new AudioRoutesInfo(in);
        }

        public AudioRoutesInfo[] newArray(int size) {
            return new AudioRoutesInfo[size];
        }
    };
}
+80 −2
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
@@ -62,6 +63,7 @@ import android.provider.Settings.System;
import android.speech.RecognizerIntent;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.VolumePanel;
@@ -135,10 +137,11 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
    private static final int MSG_RCDISPLAY_UPDATE = 13;
    private static final int MSG_SET_ALL_VOLUMES = 14;
    private static final int MSG_PERSIST_MASTER_VOLUME_MUTE = 15;
    private static final int MSG_REPORT_NEW_ROUTES = 16;
    // messages handled under wakelock, can only be queued, i.e. sent with queueMsgUnderWakeLock(),
    //   and not with sendMsg(..., ..., SENDMSG_QUEUE, ...)
    private static final int MSG_SET_WIRED_DEVICE_CONNECTION_STATE = 16;
    private static final int MSG_SET_A2DP_CONNECTION_STATE = 17;
    private static final int MSG_SET_WIRED_DEVICE_CONNECTION_STATE = 17;
    private static final int MSG_SET_A2DP_CONNECTION_STATE = 18;


    // flags for MSG_PERSIST_VOLUME indicating if current and/or last audible volume should be
@@ -397,6 +400,11 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
    private boolean mBluetoothA2dpEnabled;
    private final Object mBluetoothA2dpEnabledLock = new Object();

    // Monitoring of audio routes.  Protected by mCurAudioRoutes.
    final AudioRoutesInfo mCurAudioRoutes = new AudioRoutesInfo();
    final RemoteCallbackList<IAudioRoutesObserver> mRoutesObservers
            = new RemoteCallbackList<IAudioRoutesObserver>();

    ///////////////////////////////////////////////////////////////////////////
    // Construction
    ///////////////////////////////////////////////////////////////////////////
@@ -3011,6 +3019,26 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
                    onSetA2dpConnectionState((BluetoothDevice)msg.obj, msg.arg1);
                    mMediaEventWakeLock.release();
                    break;

                case MSG_REPORT_NEW_ROUTES: {
                    int N = mRoutesObservers.beginBroadcast();
                    if (N > 0) {
                        AudioRoutesInfo routes;
                        synchronized (mCurAudioRoutes) {
                            routes = new AudioRoutesInfo(mCurAudioRoutes);
                        }
                        while (N > 0) {
                            N--;
                            IAudioRoutesObserver obs = mRoutesObservers.getBroadcastItem(N);
                            try {
                                obs.dispatchAudioRoutesChanged(routes);
                            } catch (RemoteException e) {
                            }
                        }
                    }
                    mRoutesObservers.finishBroadcast();
                    break;
                }
            }
        }
    }
@@ -3127,6 +3155,13 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
                } else {
                    makeA2dpDeviceUnavailableNow(address);
                }
                synchronized (mCurAudioRoutes) {
                    if (mCurAudioRoutes.mBluetoothName != null) {
                        mCurAudioRoutes.mBluetoothName = null;
                        sendMsg(mAudioHandler, MSG_REPORT_NEW_ROUTES,
                                SENDMSG_NOOP, 0, 0, null, 0);
                    }
                }
            } else if (!isConnected && state == BluetoothProfile.STATE_CONNECTED) {
                if (btDevice.isBluetoothDock()) {
                    // this could be a reconnection after a transient disconnection
@@ -3141,6 +3176,14 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
                    }
                }
                makeA2dpDeviceAvailable(address);
                synchronized (mCurAudioRoutes) {
                    String name = btDevice.getAliasName();
                    if (!TextUtils.equals(mCurAudioRoutes.mBluetoothName, name)) {
                        mCurAudioRoutes.mBluetoothName = name;
                        sendMsg(mAudioHandler, MSG_REPORT_NEW_ROUTES,
                                SENDMSG_NOOP, 0, 0, null, 0);
                    }
                }
            }
        }
    }
@@ -3204,20 +3247,43 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
        intent.putExtra("name", name);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);

        int connType = 0;

        if (device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) {
            connType = AudioRoutesInfo.MAIN_HEADSET;
            intent.setAction(Intent.ACTION_HEADSET_PLUG);
            intent.putExtra("microphone", 1);
        } else if (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE) {
            connType = AudioRoutesInfo.MAIN_HEADPHONES;
            intent.setAction(Intent.ACTION_HEADSET_PLUG);
            intent.putExtra("microphone", 0);
        } else if (device == AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET) {
            connType = AudioRoutesInfo.MAIN_DOCK_SPEAKERS;
            intent.setAction(Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG);
        } else if (device == AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET) {
            connType = AudioRoutesInfo.MAIN_DOCK_SPEAKERS;
            intent.setAction(Intent.ACTION_DIGITAL_AUDIO_DOCK_PLUG);
        } else if (device == AudioSystem.DEVICE_OUT_AUX_DIGITAL) {
            connType = AudioRoutesInfo.MAIN_HDMI;
            intent.setAction(Intent.ACTION_HDMI_AUDIO_PLUG);
        }

        synchronized (mCurAudioRoutes) {
            if (connType != 0) {
                int newConn = mCurAudioRoutes.mMainType;
                if (state != 0) {
                    newConn |= connType;
                } else {
                    newConn &= ~connType;
                }
                if (newConn != mCurAudioRoutes.mMainType) {
                    mCurAudioRoutes.mMainType = newConn;
                    sendMsg(mAudioHandler, MSG_REPORT_NEW_ROUTES,
                            SENDMSG_NOOP, 0, 0, null, 0);
                }
            }
        }

        ActivityManagerNative.broadcastStickyIntent(intent, null);
    }

@@ -4795,6 +4861,15 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
        return mRingtonePlayer;
    }

    @Override
    public AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) {
        synchronized (mCurAudioRoutes) {
            AudioRoutesInfo routes = new AudioRoutesInfo(mCurAudioRoutes);
            mRoutesObservers.register(observer);
            return routes;
        }
    }

    @Override
    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
@@ -4803,5 +4878,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
        dumpFocusStack(pw);
        dumpRCStack(pw);
        dumpStreamStates(pw);
        pw.println("\nAudio routes:");
        pw.print("  mMainType=0x"); pw.println(Integer.toHexString(mCurAudioRoutes.mMainType));
        pw.print("  mBluetoothName="); pw.println(mCurAudioRoutes.mBluetoothName);
    }
}
+27 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.media;

import android.media.AudioRoutesInfo;

/**
 * AIDL for the AudioService to report changes in available audio routes.
 * @hide
 */
oneway interface IAudioRoutesObserver {
    void dispatchAudioRoutesChanged(in AudioRoutesInfo newRoutes);
}
Loading