1292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi/* 2292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi * Copyright (C) 2016 The Android Open Source Project 3292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi * 4292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License"); 5292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi * you may not use this file except in compliance with the License. 6292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi * You may obtain a copy of the License at 7292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi * 8292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi * http://www.apache.org/licenses/LICENSE-2.0 9292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi * 10292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi * Unless required by applicable law or agreed to in writing, software 11292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS, 12292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi * See the License for the specific language governing permissions and 14292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi * limitations under the License. 15292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi */ 16292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi 17292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivipackage com.android.server.audio; 18292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi 19292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Triviimport android.annotation.NonNull; 20e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurentimport android.content.Context; 21e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurentimport android.content.pm.PackageManager; 22292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Triviimport android.media.AudioAttributes; 23292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Triviimport android.media.AudioManager; 24292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Triviimport android.media.AudioPlaybackConfiguration; 25292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Triviimport android.media.AudioSystem; 26292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Triviimport android.media.IPlaybackConfigDispatcher; 27292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Triviimport android.media.PlayerBase; 28dce82ab7bfd5ec7c1ef658825c18506a89e567d6Jean-Michel Triviimport android.media.VolumeShaper; 2944a8f53f94808fdc5ac35a249d21ff2ba23e9419Jean-Michel Triviimport android.os.Binder; 30292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Triviimport android.os.IBinder; 31292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Triviimport android.os.RemoteException; 32292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Triviimport android.util.Log; 33292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi 3483271bd70e21d420e1258d2473e7b4594915a48fJean-Michel Triviimport com.android.internal.util.ArrayUtils; 3583271bd70e21d420e1258d2473e7b4594915a48fJean-Michel Trivi 36292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Triviimport java.io.PrintWriter; 37292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Triviimport java.text.DateFormat; 38292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Triviimport java.util.ArrayList; 3956266190e8d74bcf1d5525634f50368efb845676Jean-Michel Triviimport java.util.Collections; 40292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Triviimport java.util.Date; 41292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Triviimport java.util.HashMap; 42292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Triviimport java.util.Iterator; 43292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Triviimport java.util.List; 4499489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Triviimport java.util.Set; 45292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi 46292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi/** 47292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi * Class to receive and dispatch updates from AudioSystem about recording configurations. 48292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi */ 499dc22c227cb5c01136a6aa1b52c7dfa3383c0bd7Jean-Michel Trivipublic final class PlaybackActivityMonitor 5099489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi implements AudioPlaybackConfiguration.PlayerDeathMonitor, PlayerFocusEnforcer { 51292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi 52c2769ab2ac908b4ea344cf22cfe8ff968a906649Jean-Michel Trivi public static final String TAG = "AudioService.PlaybackActivityMonitor"; 530f49f82e9777b7878fbc4566779dbe29191141baJean-Michel Trivi 54c2769ab2ac908b4ea344cf22cfe8ff968a906649Jean-Michel Trivi private static final boolean DEBUG = false; 55c2769ab2ac908b4ea344cf22cfe8ff968a906649Jean-Michel Trivi private static final int VOLUME_SHAPER_SYSTEM_DUCK_ID = 1; 56292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi 57c2769ab2ac908b4ea344cf22cfe8ff968a906649Jean-Michel Trivi private static final VolumeShaper.Configuration DUCK_VSHAPE = 587da0e98219501cb5ab49331878c7b2cdde541497Andy Hung new VolumeShaper.Configuration.Builder() 597da0e98219501cb5ab49331878c7b2cdde541497Andy Hung .setId(VOLUME_SHAPER_SYSTEM_DUCK_ID) 607da0e98219501cb5ab49331878c7b2cdde541497Andy Hung .setCurve(new float[] { 0.f, 1.f } /* times */, 617da0e98219501cb5ab49331878c7b2cdde541497Andy Hung new float[] { 1.f, 0.2f } /* volumes */) 627da0e98219501cb5ab49331878c7b2cdde541497Andy Hung .setOptionFlags(VolumeShaper.Configuration.OPTION_FLAG_CLOCK_TIME) 634c86efa1e3fd8f467f4053b8027a9db12eee584cJean-Michel Trivi .setDuration(MediaFocusControl.getFocusRampTimeMs( 647da0e98219501cb5ab49331878c7b2cdde541497Andy Hung AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, 657da0e98219501cb5ab49331878c7b2cdde541497Andy Hung new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_NOTIFICATION) 667da0e98219501cb5ab49331878c7b2cdde541497Andy Hung .build())) 677da0e98219501cb5ab49331878c7b2cdde541497Andy Hung .build(); 68c2769ab2ac908b4ea344cf22cfe8ff968a906649Jean-Michel Trivi private static final VolumeShaper.Configuration DUCK_ID = 697da0e98219501cb5ab49331878c7b2cdde541497Andy Hung new VolumeShaper.Configuration(VOLUME_SHAPER_SYSTEM_DUCK_ID); 70c2769ab2ac908b4ea344cf22cfe8ff968a906649Jean-Michel Trivi private static final VolumeShaper.Operation PLAY_CREATE_IF_NEEDED = 717da0e98219501cb5ab49331878c7b2cdde541497Andy Hung new VolumeShaper.Operation.Builder(VolumeShaper.Operation.PLAY) 727da0e98219501cb5ab49331878c7b2cdde541497Andy Hung .createIfNeeded() 737da0e98219501cb5ab49331878c7b2cdde541497Andy Hung .build(); 747da0e98219501cb5ab49331878c7b2cdde541497Andy Hung 7583271bd70e21d420e1258d2473e7b4594915a48fJean-Michel Trivi // TODO support VolumeShaper on those players 7683271bd70e21d420e1258d2473e7b4594915a48fJean-Michel Trivi private static final int[] UNDUCKABLE_PLAYER_TYPES = { 7783271bd70e21d420e1258d2473e7b4594915a48fJean-Michel Trivi AudioPlaybackConfiguration.PLAYER_TYPE_AAUDIO, 7883271bd70e21d420e1258d2473e7b4594915a48fJean-Michel Trivi AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL, 7983271bd70e21d420e1258d2473e7b4594915a48fJean-Michel Trivi }; 8083271bd70e21d420e1258d2473e7b4594915a48fJean-Michel Trivi 812e48fb55122ad11f7416a65b04034ef30c3a42f5Jean-Michel Trivi // like a PLAY_CREATE_IF_NEEDED operation but with a skip to the end of the ramp 822e48fb55122ad11f7416a65b04034ef30c3a42f5Jean-Michel Trivi private static final VolumeShaper.Operation PLAY_SKIP_RAMP = 832e48fb55122ad11f7416a65b04034ef30c3a42f5Jean-Michel Trivi new VolumeShaper.Operation.Builder(PLAY_CREATE_IF_NEEDED).setXOffset(1.0f).build(); 842e48fb55122ad11f7416a65b04034ef30c3a42f5Jean-Michel Trivi 857da0e98219501cb5ab49331878c7b2cdde541497Andy Hung private final ArrayList<PlayMonitorClient> mClients = new ArrayList<PlayMonitorClient>(); 86292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi // a public client is one that needs an anonymized version of the playback configurations, we 87292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi // keep track of whether there is at least one to know when we need to create the list of 88292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi // playback configurations that do not contain uid/pid/package name information. 89292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi private boolean mHasPublicClients = false; 90292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi 91292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi private final Object mPlayerLock = new Object(); 927da0e98219501cb5ab49331878c7b2cdde541497Andy Hung private final HashMap<Integer, AudioPlaybackConfiguration> mPlayers = 93292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi new HashMap<Integer, AudioPlaybackConfiguration>(); 94292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi 95e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent private final Context mContext; 96e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent private int mSavedAlarmVolume = -1; 97e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent private final int mMaxAlarmVolume; 98e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent private int mPrivilegedAlarmActiveCount = 0; 99e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent 100e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent PlaybackActivityMonitor(Context context, int maxAlarmVolume) { 101e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent mContext = context; 102e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent mMaxAlarmVolume = maxAlarmVolume; 1039dc22c227cb5c01136a6aa1b52c7dfa3383c0bd7Jean-Michel Trivi PlayMonitorClient.sListenerDeathMonitor = this; 1049dc22c227cb5c01136a6aa1b52c7dfa3383c0bd7Jean-Michel Trivi AudioPlaybackConfiguration.sPlayerDeathMonitor = this; 105292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 106292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi 107292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi //================================================================= 10892ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi private final ArrayList<Integer> mBannedUids = new ArrayList<Integer>(); 10992ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi 11092ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi // see AudioManagerInternal.disableAudioForUid(boolean disable, int uid) 11192ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi public void disableAudioForUid(boolean disable, int uid) { 11292ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi synchronized(mPlayerLock) { 11392ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi final int index = mBannedUids.indexOf(new Integer(uid)); 11492ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi if (index >= 0) { 11592ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi if (!disable) { 116011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi if (DEBUG) { // hidden behind DEBUG, too noisy otherwise 11774a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi sEventLogger.log(new AudioEventLogger.StringEvent("unbanning uid:" + uid)); 118011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi } 11992ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi mBannedUids.remove(index); 12092ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi // nothing else to do, future playback requests from this uid are ok 12192ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi } // no else to handle, uid already present, so disabling again is no-op 12292ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi } else { 12392ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi if (disable) { 12492ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi for (AudioPlaybackConfiguration apc : mPlayers.values()) { 12592ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi checkBanPlayer(apc, uid); 12692ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi } 127011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi if (DEBUG) { // hidden behind DEBUG, too noisy otherwise 12874a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi sEventLogger.log(new AudioEventLogger.StringEvent("banning uid:" + uid)); 129011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi } 13092ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi mBannedUids.add(new Integer(uid)); 13192ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi } // no else to handle, uid already not in list, so enabling again is no-op 13292ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi } 13392ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi } 13492ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi } 13592ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi 13692ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi private boolean checkBanPlayer(@NonNull AudioPlaybackConfiguration apc, int uid) { 13792ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi final boolean toBan = (apc.getClientUid() == uid); 13892ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi if (toBan) { 13992ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi final int piid = apc.getPlayerInterfaceId(); 14092ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi try { 14192ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi Log.v(TAG, "banning player " + piid + " uid:" + uid); 14292ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi apc.getPlayerProxy().pause(); 14392ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi } catch (Exception e) { 14492ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi Log.e(TAG, "error banning player " + piid + " uid:" + uid, e); 14592ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi } 14692ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi } 14792ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi return toBan; 14892ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi } 14992ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi 15092ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi //================================================================= 151292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi // Track players and their states 15244a8f53f94808fdc5ac35a249d21ff2ba23e9419Jean-Michel Trivi // methods playerAttributes, playerEvent, releasePlayer are all oneway calls 153292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi // into AudioService. They trigger synchronous dispatchPlaybackChange() which updates 154292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi // all listeners as oneway calls. 155292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi 15644a8f53f94808fdc5ac35a249d21ff2ba23e9419Jean-Michel Trivi public int trackPlayer(PlayerBase.PlayerIdCard pic) { 15744a8f53f94808fdc5ac35a249d21ff2ba23e9419Jean-Michel Trivi final int newPiid = AudioSystem.newAudioPlayerId(); 15844a8f53f94808fdc5ac35a249d21ff2ba23e9419Jean-Michel Trivi if (DEBUG) { Log.v(TAG, "trackPlayer() new piid=" + newPiid); } 15944a8f53f94808fdc5ac35a249d21ff2ba23e9419Jean-Michel Trivi final AudioPlaybackConfiguration apc = 16044a8f53f94808fdc5ac35a249d21ff2ba23e9419Jean-Michel Trivi new AudioPlaybackConfiguration(pic, newPiid, 16144a8f53f94808fdc5ac35a249d21ff2ba23e9419Jean-Michel Trivi Binder.getCallingUid(), Binder.getCallingPid()); 1629dc22c227cb5c01136a6aa1b52c7dfa3383c0bd7Jean-Michel Trivi apc.init(); 16374a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi sEventLogger.log(new NewPlayerEvent(apc)); 164292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi synchronized(mPlayerLock) { 16544a8f53f94808fdc5ac35a249d21ff2ba23e9419Jean-Michel Trivi mPlayers.put(newPiid, apc); 166292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 16744a8f53f94808fdc5ac35a249d21ff2ba23e9419Jean-Michel Trivi return newPiid; 168292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 169292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi 17046e310b34f73fe87a6dd1e7357b486f1cf7cacbcJean-Michel Trivi public void playerAttributes(int piid, @NonNull AudioAttributes attr, int binderUid) { 171292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi final boolean change; 172292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi synchronized(mPlayerLock) { 173292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi final AudioPlaybackConfiguration apc = mPlayers.get(new Integer(piid)); 17446e310b34f73fe87a6dd1e7357b486f1cf7cacbcJean-Michel Trivi if (checkConfigurationCaller(piid, apc, binderUid)) { 17574a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi sEventLogger.log(new AudioAttrEvent(piid, attr)); 176292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi change = apc.handleAudioAttributesEvent(attr); 17746e310b34f73fe87a6dd1e7357b486f1cf7cacbcJean-Michel Trivi } else { 17846e310b34f73fe87a6dd1e7357b486f1cf7cacbcJean-Michel Trivi Log.e(TAG, "Error updating audio attributes"); 17946e310b34f73fe87a6dd1e7357b486f1cf7cacbcJean-Michel Trivi change = false; 180292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 181292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 182292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi if (change) { 183776a39931499d7d118eba916aba017032cde49a9Jean-Michel Trivi dispatchPlaybackChange(false); 184292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 185292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 186292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi 187d51d398383c99aa0e1c84e46aafa593006d5120dJean-Michel Trivi private static final int FLAGS_FOR_SILENCE_OVERRIDE = 188d51d398383c99aa0e1c84e46aafa593006d5120dJean-Michel Trivi AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY | 189d51d398383c99aa0e1c84e46aafa593006d5120dJean-Michel Trivi AudioAttributes.FLAG_BYPASS_MUTE; 190d51d398383c99aa0e1c84e46aafa593006d5120dJean-Michel Trivi 191e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent private void checkVolumeForPrivilegedAlarm(AudioPlaybackConfiguration apc, int event) { 192e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent if (event == AudioPlaybackConfiguration.PLAYER_STATE_STARTED || 193e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent apc.getPlayerState() == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) { 194d51d398383c99aa0e1c84e46aafa593006d5120dJean-Michel Trivi if ((apc.getAudioAttributes().getAllFlags() & FLAGS_FOR_SILENCE_OVERRIDE) 195d51d398383c99aa0e1c84e46aafa593006d5120dJean-Michel Trivi == FLAGS_FOR_SILENCE_OVERRIDE && 196e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent apc.getAudioAttributes().getUsage() == AudioAttributes.USAGE_ALARM && 197e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent mContext.checkPermission(android.Manifest.permission.MODIFY_PHONE_STATE, 198e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent apc.getClientPid(), apc.getClientUid()) == 199e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent PackageManager.PERMISSION_GRANTED) { 200e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent if (event == AudioPlaybackConfiguration.PLAYER_STATE_STARTED && 201e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent apc.getPlayerState() != AudioPlaybackConfiguration.PLAYER_STATE_STARTED) { 202e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent if (mPrivilegedAlarmActiveCount++ == 0) { 203e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent mSavedAlarmVolume = AudioSystem.getStreamVolumeIndex( 204e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent AudioSystem.STREAM_ALARM, AudioSystem.DEVICE_OUT_SPEAKER); 205e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent AudioSystem.setStreamVolumeIndex(AudioSystem.STREAM_ALARM, 206e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent mMaxAlarmVolume, AudioSystem.DEVICE_OUT_SPEAKER); 207e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent } 208e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent } else if (event != AudioPlaybackConfiguration.PLAYER_STATE_STARTED && 209e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent apc.getPlayerState() == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) { 210e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent if (--mPrivilegedAlarmActiveCount == 0) { 211e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent if (AudioSystem.getStreamVolumeIndex( 212e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent AudioSystem.STREAM_ALARM, AudioSystem.DEVICE_OUT_SPEAKER) == 213e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent mMaxAlarmVolume) { 214e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent AudioSystem.setStreamVolumeIndex(AudioSystem.STREAM_ALARM, 215e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent mSavedAlarmVolume, AudioSystem.DEVICE_OUT_SPEAKER); 216e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent } 217e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent } 218e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent } 219e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent } 220e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent } 221e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent } 222e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent 22346e310b34f73fe87a6dd1e7357b486f1cf7cacbcJean-Michel Trivi public void playerEvent(int piid, int event, int binderUid) { 22444a8f53f94808fdc5ac35a249d21ff2ba23e9419Jean-Michel Trivi if (DEBUG) { Log.v(TAG, String.format("playerEvent(piid=%d, event=%d)", piid, event)); } 225292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi final boolean change; 226292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi synchronized(mPlayerLock) { 227292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi final AudioPlaybackConfiguration apc = mPlayers.get(new Integer(piid)); 228cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi if (apc == null) { 229cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi return; 230cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi } 23174a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi sEventLogger.log(new PlayerEvent(piid, event)); 23292ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi if (event == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) { 23392ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi for (Integer uidInteger: mBannedUids) { 23492ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi if (checkBanPlayer(apc, uidInteger.intValue())) { 23592ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi // player was banned, do not update its state 23674a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi sEventLogger.log(new AudioEventLogger.StringEvent( 237011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi "not starting piid:" + piid + " ,is banned")); 23892ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi return; 23992ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi } 24092ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi } 24192ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi } 242cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi if (apc.getPlayerType() == AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL) { 243cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi // FIXME SoundPool not ready for state reporting 244f1d82761ee0a4a0bb32a565f01127534cc9ab7dbJean-Michel Trivi return; 245f1d82761ee0a4a0bb32a565f01127534cc9ab7dbJean-Michel Trivi } 24646e310b34f73fe87a6dd1e7357b486f1cf7cacbcJean-Michel Trivi if (checkConfigurationCaller(piid, apc, binderUid)) { 247292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi //TODO add generation counter to only update to the latest state 248e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent checkVolumeForPrivilegedAlarm(apc, event); 249292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi change = apc.handleStateEvent(event); 25046e310b34f73fe87a6dd1e7357b486f1cf7cacbcJean-Michel Trivi } else { 25146e310b34f73fe87a6dd1e7357b486f1cf7cacbcJean-Michel Trivi Log.e(TAG, "Error handling event " + event); 25246e310b34f73fe87a6dd1e7357b486f1cf7cacbcJean-Michel Trivi change = false; 253292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 254cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi if (change && event == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) { 255cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi mDuckingManager.checkDuck(apc); 256cafed63e3acfebe1c633433c9e3a6013bb1f47ccJean-Michel Trivi } 257292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 258292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi if (change) { 259776a39931499d7d118eba916aba017032cde49a9Jean-Michel Trivi dispatchPlaybackChange(event == AudioPlaybackConfiguration.PLAYER_STATE_RELEASED); 260292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 261292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 262292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi 2633120059d5bdc52fb5ef2c90d9662562e92cd4df9Jean-Michel Trivi public void playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio, int binderUid) { 2643120059d5bdc52fb5ef2c90d9662562e92cd4df9Jean-Michel Trivi // no check on UID yet because this is only for logging at the moment 26574a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi sEventLogger.log(new PlayerOpPlayAudioEvent(piid, hasOpPlayAudio, binderUid)); 2663120059d5bdc52fb5ef2c90d9662562e92cd4df9Jean-Michel Trivi } 2673120059d5bdc52fb5ef2c90d9662562e92cd4df9Jean-Michel Trivi 26846e310b34f73fe87a6dd1e7357b486f1cf7cacbcJean-Michel Trivi public void releasePlayer(int piid, int binderUid) { 269292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi if (DEBUG) { Log.v(TAG, "releasePlayer() for piid=" + piid); } 2702a28126af931554a8621341149b86cc54773c71aJean-Michel Trivi boolean change = false; 271292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi synchronized(mPlayerLock) { 27246e310b34f73fe87a6dd1e7357b486f1cf7cacbcJean-Michel Trivi final AudioPlaybackConfiguration apc = mPlayers.get(new Integer(piid)); 27346e310b34f73fe87a6dd1e7357b486f1cf7cacbcJean-Michel Trivi if (checkConfigurationCaller(piid, apc, binderUid)) { 27474a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi sEventLogger.log(new AudioEventLogger.StringEvent( 275011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi "releasing player piid:" + piid)); 276292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi mPlayers.remove(new Integer(piid)); 277cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi mDuckingManager.removeReleased(apc); 278e5a351cb9213b59026efd602011a4d9e99c85649Eric Laurent checkVolumeForPrivilegedAlarm(apc, AudioPlaybackConfiguration.PLAYER_STATE_RELEASED); 2792a28126af931554a8621341149b86cc54773c71aJean-Michel Trivi change = apc.handleStateEvent(AudioPlaybackConfiguration.PLAYER_STATE_RELEASED); 280292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 281292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 2822a28126af931554a8621341149b86cc54773c71aJean-Michel Trivi if (change) { 2832a28126af931554a8621341149b86cc54773c71aJean-Michel Trivi dispatchPlaybackChange(true /*iplayerreleased*/); 2842a28126af931554a8621341149b86cc54773c71aJean-Michel Trivi } 285292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 286292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi 2879dc22c227cb5c01136a6aa1b52c7dfa3383c0bd7Jean-Michel Trivi // Implementation of AudioPlaybackConfiguration.PlayerDeathMonitor 2889dc22c227cb5c01136a6aa1b52c7dfa3383c0bd7Jean-Michel Trivi @Override 2899dc22c227cb5c01136a6aa1b52c7dfa3383c0bd7Jean-Michel Trivi public void playerDeath(int piid) { 2909dc22c227cb5c01136a6aa1b52c7dfa3383c0bd7Jean-Michel Trivi releasePlayer(piid, 0); 2919dc22c227cb5c01136a6aa1b52c7dfa3383c0bd7Jean-Michel Trivi } 2929dc22c227cb5c01136a6aa1b52c7dfa3383c0bd7Jean-Michel Trivi 293292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi protected void dump(PrintWriter pw) { 29499489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi // players 295292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi pw.println("\nPlaybackActivityMonitor dump time: " 296292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi + DateFormat.getTimeInstance().format(new Date())); 297292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi synchronized(mPlayerLock) { 298776a39931499d7d118eba916aba017032cde49a9Jean-Michel Trivi pw.println("\n playback listeners:"); 299776a39931499d7d118eba916aba017032cde49a9Jean-Michel Trivi synchronized(mClients) { 300776a39931499d7d118eba916aba017032cde49a9Jean-Michel Trivi for (PlayMonitorClient pmc : mClients) { 301776a39931499d7d118eba916aba017032cde49a9Jean-Michel Trivi pw.print(" " + (pmc.mIsPrivileged ? "(S)" : "(P)") 302776a39931499d7d118eba916aba017032cde49a9Jean-Michel Trivi + pmc.toString()); 303776a39931499d7d118eba916aba017032cde49a9Jean-Michel Trivi } 304776a39931499d7d118eba916aba017032cde49a9Jean-Michel Trivi } 305776a39931499d7d118eba916aba017032cde49a9Jean-Michel Trivi pw.println("\n"); 30656266190e8d74bcf1d5525634f50368efb845676Jean-Michel Trivi // all players 30756266190e8d74bcf1d5525634f50368efb845676Jean-Michel Trivi pw.println("\n players:"); 30856266190e8d74bcf1d5525634f50368efb845676Jean-Michel Trivi final List<Integer> piidIntList = new ArrayList<Integer>(mPlayers.keySet()); 30956266190e8d74bcf1d5525634f50368efb845676Jean-Michel Trivi Collections.sort(piidIntList); 31056266190e8d74bcf1d5525634f50368efb845676Jean-Michel Trivi for (Integer piidInt : piidIntList) { 31156266190e8d74bcf1d5525634f50368efb845676Jean-Michel Trivi final AudioPlaybackConfiguration apc = mPlayers.get(piidInt); 31256266190e8d74bcf1d5525634f50368efb845676Jean-Michel Trivi if (apc != null) { 31356266190e8d74bcf1d5525634f50368efb845676Jean-Michel Trivi apc.dump(pw); 31456266190e8d74bcf1d5525634f50368efb845676Jean-Michel Trivi } 315292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 31699489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi // ducked players 31756266190e8d74bcf1d5525634f50368efb845676Jean-Michel Trivi pw.println("\n ducked players piids:"); 318cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi mDuckingManager.dump(pw); 31962b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi // players muted due to the device ringing or being in a call 32092ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi pw.print("\n muted player piids:"); 32162b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi for (int piid : mMutedPlayers) { 32292ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi pw.print(" " + piid); 32392ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi } 32492ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi pw.println(); 32592ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi // banned players: 32692ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi pw.print("\n banned uids:"); 32792ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi for (int uid : mBannedUids) { 32892ed7bf41235c95b2c71648a631ce7aaa65f8943Jean-Michel Trivi pw.print(" " + uid); 32962b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi } 330776a39931499d7d118eba916aba017032cde49a9Jean-Michel Trivi pw.println("\n"); 331011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi // log 33274a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi sEventLogger.dump(pw); 333292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 334292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 335292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi 33646e310b34f73fe87a6dd1e7357b486f1cf7cacbcJean-Michel Trivi /** 337c2769ab2ac908b4ea344cf22cfe8ff968a906649Jean-Michel Trivi * Check that piid and uid are valid for the given valid configuration. 33846e310b34f73fe87a6dd1e7357b486f1cf7cacbcJean-Michel Trivi * @param piid the piid of the player. 33946e310b34f73fe87a6dd1e7357b486f1cf7cacbcJean-Michel Trivi * @param apc the configuration found for this piid. 34046e310b34f73fe87a6dd1e7357b486f1cf7cacbcJean-Michel Trivi * @param binderUid actual uid of client trying to signal a player state/event/attributes. 341c2769ab2ac908b4ea344cf22cfe8ff968a906649Jean-Michel Trivi * @return true if the call is valid and the change should proceed, false otherwise. Always 342c2769ab2ac908b4ea344cf22cfe8ff968a906649Jean-Michel Trivi * returns false when apc is null. 34346e310b34f73fe87a6dd1e7357b486f1cf7cacbcJean-Michel Trivi */ 34446e310b34f73fe87a6dd1e7357b486f1cf7cacbcJean-Michel Trivi private static boolean checkConfigurationCaller(int piid, 34546e310b34f73fe87a6dd1e7357b486f1cf7cacbcJean-Michel Trivi final AudioPlaybackConfiguration apc, int binderUid) { 34646e310b34f73fe87a6dd1e7357b486f1cf7cacbcJean-Michel Trivi if (apc == null) { 34746e310b34f73fe87a6dd1e7357b486f1cf7cacbcJean-Michel Trivi return false; 34846e310b34f73fe87a6dd1e7357b486f1cf7cacbcJean-Michel Trivi } else if ((binderUid != 0) && (apc.getClientUid() != binderUid)) { 34946e310b34f73fe87a6dd1e7357b486f1cf7cacbcJean-Michel Trivi Log.e(TAG, "Forbidden operation from uid " + binderUid + " for player " + piid); 35046e310b34f73fe87a6dd1e7357b486f1cf7cacbcJean-Michel Trivi return false; 35146e310b34f73fe87a6dd1e7357b486f1cf7cacbcJean-Michel Trivi } 35246e310b34f73fe87a6dd1e7357b486f1cf7cacbcJean-Michel Trivi return true; 35346e310b34f73fe87a6dd1e7357b486f1cf7cacbcJean-Michel Trivi } 35446e310b34f73fe87a6dd1e7357b486f1cf7cacbcJean-Michel Trivi 355776a39931499d7d118eba916aba017032cde49a9Jean-Michel Trivi /** 356776a39931499d7d118eba916aba017032cde49a9Jean-Michel Trivi * Sends new list after update of playback configurations 357776a39931499d7d118eba916aba017032cde49a9Jean-Michel Trivi * @param iplayerReleased indicates if the change was due to a player being released 358776a39931499d7d118eba916aba017032cde49a9Jean-Michel Trivi */ 359776a39931499d7d118eba916aba017032cde49a9Jean-Michel Trivi private void dispatchPlaybackChange(boolean iplayerReleased) { 360292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi synchronized (mClients) { 361292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi // typical use case, nobody is listening, don't do any work 362292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi if (mClients.isEmpty()) { 363292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi return; 364292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 365292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 366292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi if (DEBUG) { Log.v(TAG, "dispatchPlaybackChange to " + mClients.size() + " clients"); } 367292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi final List<AudioPlaybackConfiguration> configsSystem; 368292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi // list of playback configurations for "public consumption". It is only computed if there 369292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi // are non-system playback activity listeners. 370292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi final List<AudioPlaybackConfiguration> configsPublic; 371292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi synchronized (mPlayerLock) { 372292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi if (mPlayers.isEmpty()) { 373292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi return; 374292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 375292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi configsSystem = new ArrayList<AudioPlaybackConfiguration>(mPlayers.values()); 376292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 377292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi synchronized (mClients) { 378292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi // was done at beginning of method, but could have changed 379292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi if (mClients.isEmpty()) { 380292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi return; 381292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 382292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi configsPublic = mHasPublicClients ? anonymizeForPublicConsumption(configsSystem) : null; 383292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi final Iterator<PlayMonitorClient> clientIterator = mClients.iterator(); 384292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi while (clientIterator.hasNext()) { 385292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi final PlayMonitorClient pmc = clientIterator.next(); 386292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi try { 387292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi // do not spam the logs if there are problems communicating with this client 388292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi if (pmc.mErrorCount < PlayMonitorClient.MAX_ERRORS) { 389292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi if (pmc.mIsPrivileged) { 390776a39931499d7d118eba916aba017032cde49a9Jean-Michel Trivi pmc.mDispatcherCb.dispatchPlaybackConfigChange(configsSystem, 391776a39931499d7d118eba916aba017032cde49a9Jean-Michel Trivi iplayerReleased); 392292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } else { 393776a39931499d7d118eba916aba017032cde49a9Jean-Michel Trivi // non-system clients don't have the control interface IPlayer, so 394776a39931499d7d118eba916aba017032cde49a9Jean-Michel Trivi // they don't need to flush commands when a player was released 395776a39931499d7d118eba916aba017032cde49a9Jean-Michel Trivi pmc.mDispatcherCb.dispatchPlaybackConfigChange(configsPublic, false); 396292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 397292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 398292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } catch (RemoteException e) { 399292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi pmc.mErrorCount++; 400292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi Log.e(TAG, "Error (" + pmc.mErrorCount + 401292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi ") trying to dispatch playback config change to " + pmc, e); 402292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 403292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 404292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 405292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 406292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi 407292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi private ArrayList<AudioPlaybackConfiguration> anonymizeForPublicConsumption( 408292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi List<AudioPlaybackConfiguration> sysConfigs) { 409292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi ArrayList<AudioPlaybackConfiguration> publicConfigs = 410292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi new ArrayList<AudioPlaybackConfiguration>(); 41199489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi // only add active anonymized configurations, 412292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi for (AudioPlaybackConfiguration config : sysConfigs) { 413292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi if (config.isActive()) { 414292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi publicConfigs.add(AudioPlaybackConfiguration.anonymizedCopy(config)); 415292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 416292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 417292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi return publicConfigs; 418292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 419292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi 42099489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi 42199489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi //================================================================= 42299489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi // PlayerFocusEnforcer implementation 42362b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi private final ArrayList<Integer> mMutedPlayers = new ArrayList<Integer>(); 424cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi 425cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi private final DuckingManager mDuckingManager = new DuckingManager(); 42699489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi 42799489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi @Override 4289228af6bc20c27b9949df36684f9c06ca9cdb27dJean-Michel Trivi public boolean duckPlayers(FocusRequester winner, FocusRequester loser, boolean forceDuck) { 42999489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi if (DEBUG) { 43099489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi Log.v(TAG, String.format("duckPlayers: uids winner=%d loser=%d", 431cafed63e3acfebe1c633433c9e3a6013bb1f47ccJean-Michel Trivi winner.getClientUid(), loser.getClientUid())); 432cafed63e3acfebe1c633433c9e3a6013bb1f47ccJean-Michel Trivi } 43399489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi synchronized (mPlayerLock) { 43499489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi if (mPlayers.isEmpty()) { 43599489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi return true; 43699489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi } 437cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi // check if this UID needs to be ducked (return false if not), and gather list of 438cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi // eligible players to duck 439cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi final Iterator<AudioPlaybackConfiguration> apcIterator = mPlayers.values().iterator(); 440cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi final ArrayList<AudioPlaybackConfiguration> apcsToDuck = 441cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi new ArrayList<AudioPlaybackConfiguration>(); 442cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi while (apcIterator.hasNext()) { 443cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi final AudioPlaybackConfiguration apc = apcIterator.next(); 44499489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi if (!winner.hasSameUid(apc.getClientUid()) 44599489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi && loser.hasSameUid(apc.getClientUid()) 44699489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi && apc.getPlayerState() == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) 44799489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi { 4489228af6bc20c27b9949df36684f9c06ca9cdb27dJean-Michel Trivi if (!forceDuck && (apc.getAudioAttributes().getContentType() == 4499228af6bc20c27b9949df36684f9c06ca9cdb27dJean-Michel Trivi AudioAttributes.CONTENT_TYPE_SPEECH)) { 45099489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi // the player is speaking, ducking will make the speech unintelligible 45199489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi // so let the app handle it instead 452087b672797b23d6c7451f975ca7f825d64fb1bd9Jean-Michel Trivi Log.v(TAG, "not ducking player " + apc.getPlayerInterfaceId() 453087b672797b23d6c7451f975ca7f825d64fb1bd9Jean-Michel Trivi + " uid:" + apc.getClientUid() + " pid:" + apc.getClientPid() 454087b672797b23d6c7451f975ca7f825d64fb1bd9Jean-Michel Trivi + " - SPEECH"); 45599489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi return false; 45683271bd70e21d420e1258d2473e7b4594915a48fJean-Michel Trivi } else if (ArrayUtils.contains(UNDUCKABLE_PLAYER_TYPES, apc.getPlayerType())) { 457087b672797b23d6c7451f975ca7f825d64fb1bd9Jean-Michel Trivi Log.v(TAG, "not ducking player " + apc.getPlayerInterfaceId() 458087b672797b23d6c7451f975ca7f825d64fb1bd9Jean-Michel Trivi + " uid:" + apc.getClientUid() + " pid:" + apc.getClientPid() 45983271bd70e21d420e1258d2473e7b4594915a48fJean-Michel Trivi + " due to type:" 46083271bd70e21d420e1258d2473e7b4594915a48fJean-Michel Trivi + AudioPlaybackConfiguration.toLogFriendlyPlayerType( 46183271bd70e21d420e1258d2473e7b4594915a48fJean-Michel Trivi apc.getPlayerType())); 462dce82ab7bfd5ec7c1ef658825c18506a89e567d6Jean-Michel Trivi return false; 46399489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi } 464cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi apcsToDuck.add(apc); 46599489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi } 46699489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi } 467cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi // add the players eligible for ducking to the list, and duck them 468cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi // (if apcsToDuck is empty, this will at least mark this uid as ducked, so when 469cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi // players of the same uid start, they will be ducked by DuckingManager.checkDuck()) 470cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi mDuckingManager.duckUid(loser.getClientUid(), apcsToDuck); 47199489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi } 47299489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi return true; 47399489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi } 47499489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi 47599489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi @Override 47699489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi public void unduckPlayers(FocusRequester winner) { 47799489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi if (DEBUG) { Log.v(TAG, "unduckPlayers: uids winner=" + winner.getClientUid()); } 47899489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi synchronized (mPlayerLock) { 479cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi mDuckingManager.unduckUid(winner.getClientUid(), mPlayers); 48099489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi } 48199489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi } 48299489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi 48362b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi @Override 48462b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi public void mutePlayersForCall(int[] usagesToMute) { 48562b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi if (DEBUG) { 48662b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi String log = new String("mutePlayersForCall: usages="); 48762b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi for (int usage : usagesToMute) { log += " " + usage; } 48862b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi Log.v(TAG, log); 48962b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi } 49062b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi synchronized (mPlayerLock) { 49162b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi final Set<Integer> piidSet = mPlayers.keySet(); 49262b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi final Iterator<Integer> piidIterator = piidSet.iterator(); 49362b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi // find which players to mute 49462b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi while (piidIterator.hasNext()) { 49562b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi final Integer piid = piidIterator.next(); 49662b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi final AudioPlaybackConfiguration apc = mPlayers.get(piid); 497bd39cfaf97106bb8b9ea702d8e1cd5965537da16Jean-Michel Trivi if (apc == null) { 498bd39cfaf97106bb8b9ea702d8e1cd5965537da16Jean-Michel Trivi continue; 499bd39cfaf97106bb8b9ea702d8e1cd5965537da16Jean-Michel Trivi } 50062b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi final int playerUsage = apc.getAudioAttributes().getUsage(); 50162b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi boolean mute = false; 50262b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi for (int usageToMute : usagesToMute) { 50362b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi if (playerUsage == usageToMute) { 50462b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi mute = true; 50562b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi break; 50662b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi } 50762b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi } 50862b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi if (mute) { 50962b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi try { 51074a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi sEventLogger.log((new AudioEventLogger.StringEvent("call: muting piid:" 51174a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi + piid + " uid:" + apc.getClientUid())).printLog(TAG)); 51262b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi apc.getPlayerProxy().setVolume(0.0f); 513cafed63e3acfebe1c633433c9e3a6013bb1f47ccJean-Michel Trivi mMutedPlayers.add(new Integer(piid)); 51462b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi } catch (Exception e) { 515952f2341abc398d245f3c0a577ebe1b28f93f368Jean-Michel Trivi Log.e(TAG, "call: error muting player " + piid, e); 51662b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi } 51762b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi } 51862b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi } 51962b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi } 52062b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi } 52162b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi 52262b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi @Override 52362b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi public void unmutePlayersForCall() { 52462b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi if (DEBUG) { 52562b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi Log.v(TAG, "unmutePlayersForCall()"); 52662b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi } 52762b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi synchronized (mPlayerLock) { 52862b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi if (mMutedPlayers.isEmpty()) { 52962b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi return; 53062b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi } 53162b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi for (int piid : mMutedPlayers) { 53262b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi final AudioPlaybackConfiguration apc = mPlayers.get(piid); 53362b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi if (apc != null) { 53462b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi try { 53574a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi sEventLogger.log(new AudioEventLogger.StringEvent("call: unmuting piid:" 53674a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi + piid).printLog(TAG)); 53762b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi apc.getPlayerProxy().setVolume(1.0f); 53862b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi } catch (Exception e) { 539087b672797b23d6c7451f975ca7f825d64fb1bd9Jean-Michel Trivi Log.e(TAG, "call: error unmuting player " + piid + " uid:" 540087b672797b23d6c7451f975ca7f825d64fb1bd9Jean-Michel Trivi + apc.getClientUid(), e); 54162b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi } 54262b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi } 54362b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi } 544579c511765a23211a33a1b2f90010942ada2bccbJean-Michel Trivi mMutedPlayers.clear(); 54562b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi } 54662b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi } 54762b8634f06b32f17eced8020ecd9240f70838124Jean-Michel Trivi 548292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi //================================================================= 549292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi // Track playback activity listeners 550292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi 551292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi void registerPlaybackCallback(IPlaybackConfigDispatcher pcdb, boolean isPrivileged) { 552292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi if (pcdb == null) { 553292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi return; 554292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 555292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi synchronized(mClients) { 556292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi final PlayMonitorClient pmc = new PlayMonitorClient(pcdb, isPrivileged); 557292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi if (pmc.init()) { 558292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi if (!isPrivileged) { 559292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi mHasPublicClients = true; 560292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 561292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi mClients.add(pmc); 562292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 563292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 564292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 565292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi 566292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi void unregisterPlaybackCallback(IPlaybackConfigDispatcher pcdb) { 567292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi if (pcdb == null) { 568292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi return; 569292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 570292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi synchronized(mClients) { 571292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi final Iterator<PlayMonitorClient> clientIterator = mClients.iterator(); 572292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi boolean hasPublicClients = false; 573292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi // iterate over the clients to remove the dispatcher to remove, and reevaluate at 574292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi // the same time if we still have a public client. 575292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi while (clientIterator.hasNext()) { 576292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi PlayMonitorClient pmc = clientIterator.next(); 577292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi if (pcdb.equals(pmc.mDispatcherCb)) { 578292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi pmc.release(); 579292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi clientIterator.remove(); 580292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } else { 581292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi if (!pmc.mIsPrivileged) { 582292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi hasPublicClients = true; 583292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 584292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 585292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 586292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi mHasPublicClients = hasPublicClients; 587292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 588292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 589292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi 59044a8f53f94808fdc5ac35a249d21ff2ba23e9419Jean-Michel Trivi List<AudioPlaybackConfiguration> getActivePlaybackConfigurations(boolean isPrivileged) { 591292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi synchronized(mPlayers) { 59244a8f53f94808fdc5ac35a249d21ff2ba23e9419Jean-Michel Trivi if (isPrivileged) { 59344a8f53f94808fdc5ac35a249d21ff2ba23e9419Jean-Michel Trivi return new ArrayList<AudioPlaybackConfiguration>(mPlayers.values()); 59444a8f53f94808fdc5ac35a249d21ff2ba23e9419Jean-Michel Trivi } else { 59544a8f53f94808fdc5ac35a249d21ff2ba23e9419Jean-Michel Trivi final List<AudioPlaybackConfiguration> configsPublic; 59644a8f53f94808fdc5ac35a249d21ff2ba23e9419Jean-Michel Trivi synchronized (mPlayerLock) { 59744a8f53f94808fdc5ac35a249d21ff2ba23e9419Jean-Michel Trivi configsPublic = anonymizeForPublicConsumption( 59844a8f53f94808fdc5ac35a249d21ff2ba23e9419Jean-Michel Trivi new ArrayList<AudioPlaybackConfiguration>(mPlayers.values())); 59944a8f53f94808fdc5ac35a249d21ff2ba23e9419Jean-Michel Trivi } 60044a8f53f94808fdc5ac35a249d21ff2ba23e9419Jean-Michel Trivi return configsPublic; 60144a8f53f94808fdc5ac35a249d21ff2ba23e9419Jean-Michel Trivi } 602292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 603292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 604292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi 605292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi 606292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi /** 607292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi * Inner class to track clients that want to be notified of playback updates 608292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi */ 609c2769ab2ac908b4ea344cf22cfe8ff968a906649Jean-Michel Trivi private static final class PlayMonitorClient implements IBinder.DeathRecipient { 610292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi 611292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi // can afford to be static because only one PlaybackActivityMonitor ever instantiated 6129dc22c227cb5c01136a6aa1b52c7dfa3383c0bd7Jean-Michel Trivi static PlaybackActivityMonitor sListenerDeathMonitor; 613292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi 614292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi final IPlaybackConfigDispatcher mDispatcherCb; 615292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi final boolean mIsPrivileged; 616292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi 617292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi int mErrorCount = 0; 618292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi // number of errors after which we don't update this client anymore to not spam the logs 619292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi static final int MAX_ERRORS = 5; 620292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi 621292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi PlayMonitorClient(IPlaybackConfigDispatcher pcdb, boolean isPrivileged) { 622292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi mDispatcherCb = pcdb; 623292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi mIsPrivileged = isPrivileged; 624292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 625292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi 626292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi public void binderDied() { 627292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi Log.w(TAG, "client died"); 6289dc22c227cb5c01136a6aa1b52c7dfa3383c0bd7Jean-Michel Trivi sListenerDeathMonitor.unregisterPlaybackCallback(mDispatcherCb); 629292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 630292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi 631292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi boolean init() { 632292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi try { 633292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi mDispatcherCb.asBinder().linkToDeath(this, 0); 634292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi return true; 635292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } catch (RemoteException e) { 636292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi Log.w(TAG, "Could not link to client death", e); 637292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi return false; 638292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 639292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 640292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi 641292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi void release() { 642292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi mDispatcherCb.asBinder().unlinkToDeath(this, 0); 643292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 644292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi } 645cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi 646cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi //================================================================= 647cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi // Class to handle ducking related operations for a given UID 648cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi private static final class DuckingManager { 649cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi private final HashMap<Integer, DuckedApp> mDuckers = new HashMap<Integer, DuckedApp>(); 650cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi 6512e48fb55122ad11f7416a65b04034ef30c3a42f5Jean-Michel Trivi synchronized void duckUid(int uid, ArrayList<AudioPlaybackConfiguration> apcsToDuck) { 6522e48fb55122ad11f7416a65b04034ef30c3a42f5Jean-Michel Trivi if (DEBUG) { Log.v(TAG, "DuckingManager: duckUid() uid:"+ uid); } 653cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi if (!mDuckers.containsKey(uid)) { 654cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi mDuckers.put(uid, new DuckedApp(uid)); 655cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi } 656cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi final DuckedApp da = mDuckers.get(uid); 657cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi for (AudioPlaybackConfiguration apc : apcsToDuck) { 6582e48fb55122ad11f7416a65b04034ef30c3a42f5Jean-Michel Trivi da.addDuck(apc, false /*skipRamp*/); 659cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi } 660cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi } 661cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi 6622e48fb55122ad11f7416a65b04034ef30c3a42f5Jean-Michel Trivi synchronized void unduckUid(int uid, HashMap<Integer, AudioPlaybackConfiguration> players) { 6632e48fb55122ad11f7416a65b04034ef30c3a42f5Jean-Michel Trivi if (DEBUG) { Log.v(TAG, "DuckingManager: unduckUid() uid:"+ uid); } 664cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi final DuckedApp da = mDuckers.remove(uid); 665cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi if (da == null) { 666cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi return; 667cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi } 668cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi da.removeUnduckAll(players); 669cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi } 670cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi 671cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi // pre-condition: apc.getPlayerState() == AudioPlaybackConfiguration.PLAYER_STATE_STARTED 6722e48fb55122ad11f7416a65b04034ef30c3a42f5Jean-Michel Trivi synchronized void checkDuck(@NonNull AudioPlaybackConfiguration apc) { 6732e48fb55122ad11f7416a65b04034ef30c3a42f5Jean-Michel Trivi if (DEBUG) { Log.v(TAG, "DuckingManager: checkDuck() player piid:" 6742e48fb55122ad11f7416a65b04034ef30c3a42f5Jean-Michel Trivi + apc.getPlayerInterfaceId()+ " uid:"+ apc.getClientUid()); } 675cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi final DuckedApp da = mDuckers.get(apc.getClientUid()); 676cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi if (da == null) { 677cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi return; 678cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi } 6792e48fb55122ad11f7416a65b04034ef30c3a42f5Jean-Michel Trivi da.addDuck(apc, true /*skipRamp*/); 680cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi } 681cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi 6822e48fb55122ad11f7416a65b04034ef30c3a42f5Jean-Michel Trivi synchronized void dump(PrintWriter pw) { 683cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi for (DuckedApp da : mDuckers.values()) { 684cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi da.dump(pw); 685cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi } 686cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi } 687cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi 6882e48fb55122ad11f7416a65b04034ef30c3a42f5Jean-Michel Trivi synchronized void removeReleased(@NonNull AudioPlaybackConfiguration apc) { 6892e48fb55122ad11f7416a65b04034ef30c3a42f5Jean-Michel Trivi final int uid = apc.getClientUid(); 6902e48fb55122ad11f7416a65b04034ef30c3a42f5Jean-Michel Trivi if (DEBUG) { Log.v(TAG, "DuckingManager: removedReleased() player piid: " 6912e48fb55122ad11f7416a65b04034ef30c3a42f5Jean-Michel Trivi + apc.getPlayerInterfaceId() + " uid:" + uid); } 6922e48fb55122ad11f7416a65b04034ef30c3a42f5Jean-Michel Trivi final DuckedApp da = mDuckers.get(uid); 693cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi if (da == null) { 694cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi return; 695cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi } 696cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi da.removeReleased(apc); 697cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi } 698cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi 699cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi private static final class DuckedApp { 700cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi private final int mUid; 701cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi private final ArrayList<Integer> mDuckedPlayers = new ArrayList<Integer>(); 702cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi 703cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi DuckedApp(int uid) { 704cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi mUid = uid; 705cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi } 706cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi 707cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi void dump(PrintWriter pw) { 708cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi pw.print("\t uid:" + mUid + " piids:"); 709cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi for (int piid : mDuckedPlayers) { 710cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi pw.print(" " + piid); 711cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi } 712cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi pw.println(""); 713cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi } 714cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi 715cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi // pre-conditions: 716cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi // * apc != null 717cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi // * apc.getPlayerState() == AudioPlaybackConfiguration.PLAYER_STATE_STARTED 7182e48fb55122ad11f7416a65b04034ef30c3a42f5Jean-Michel Trivi void addDuck(@NonNull AudioPlaybackConfiguration apc, boolean skipRamp) { 719cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi final int piid = new Integer(apc.getPlayerInterfaceId()); 720cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi if (mDuckedPlayers.contains(piid)) { 7212e48fb55122ad11f7416a65b04034ef30c3a42f5Jean-Michel Trivi if (DEBUG) { Log.v(TAG, "player piid:" + piid + " already ducked"); } 722cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi return; 723cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi } 724cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi try { 72574a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi sEventLogger.log((new DuckEvent(apc, skipRamp)).printLog(TAG)); 726cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi apc.getPlayerProxy().applyVolumeShaper( 727cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi DUCK_VSHAPE, 7282e48fb55122ad11f7416a65b04034ef30c3a42f5Jean-Michel Trivi skipRamp ? PLAY_SKIP_RAMP : PLAY_CREATE_IF_NEEDED); 729cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi mDuckedPlayers.add(piid); 730cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi } catch (Exception e) { 7312e48fb55122ad11f7416a65b04034ef30c3a42f5Jean-Michel Trivi Log.e(TAG, "Error ducking player piid:" + piid + " uid:" + mUid, e); 732cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi } 733cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi } 734cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi 735cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi void removeUnduckAll(HashMap<Integer, AudioPlaybackConfiguration> players) { 736cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi for (int piid : mDuckedPlayers) { 737cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi final AudioPlaybackConfiguration apc = players.get(piid); 738cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi if (apc != null) { 739cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi try { 74074a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi sEventLogger.log((new AudioEventLogger.StringEvent("unducking piid:" 74174a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi + piid)).printLog(TAG)); 742cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi apc.getPlayerProxy().applyVolumeShaper( 743cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi DUCK_ID, 744cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi VolumeShaper.Operation.REVERSE); 745cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi } catch (Exception e) { 7462e48fb55122ad11f7416a65b04034ef30c3a42f5Jean-Michel Trivi Log.e(TAG, "Error unducking player piid:" + piid + " uid:" + mUid, e); 747cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi } 748cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi } else { 749cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi // this piid was in the list of ducked players, but wasn't found 750cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi if (DEBUG) { 7512e48fb55122ad11f7416a65b04034ef30c3a42f5Jean-Michel Trivi Log.v(TAG, "Error unducking player piid:" + piid 7522e48fb55122ad11f7416a65b04034ef30c3a42f5Jean-Michel Trivi + ", player not found for uid " + mUid); 753cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi } 754cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi } 755cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi } 756cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi mDuckedPlayers.clear(); 757cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi } 758cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi 759cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi void removeReleased(@NonNull AudioPlaybackConfiguration apc) { 760cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi mDuckedPlayers.remove(new Integer(apc.getPlayerInterfaceId())); 761cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi } 762cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi } 763cb84fc010998462b222fa5f784bcc54c9a829b36Jean-Michel Trivi } 764011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi 765011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi //================================================================= 766011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi // For logging 767011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi private final static class PlayerEvent extends AudioEventLogger.Event { 768011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi // only keeping the player interface ID as it uniquely identifies the player in the event 769011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi final int mPlayerIId; 770011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi final int mState; 771011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi 772011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi PlayerEvent(int piid, int state) { 773011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi mPlayerIId = piid; 774011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi mState = state; 775011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi } 776011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi 777011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi @Override 778011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi public String eventToString() { 7793120059d5bdc52fb5ef2c90d9662562e92cd4df9Jean-Michel Trivi return new StringBuilder("player piid:").append(mPlayerIId).append(" state:") 7803120059d5bdc52fb5ef2c90d9662562e92cd4df9Jean-Michel Trivi .append(AudioPlaybackConfiguration.toLogFriendlyPlayerState(mState)).toString(); 7813120059d5bdc52fb5ef2c90d9662562e92cd4df9Jean-Michel Trivi } 7823120059d5bdc52fb5ef2c90d9662562e92cd4df9Jean-Michel Trivi } 7833120059d5bdc52fb5ef2c90d9662562e92cd4df9Jean-Michel Trivi 7843120059d5bdc52fb5ef2c90d9662562e92cd4df9Jean-Michel Trivi private final static class PlayerOpPlayAudioEvent extends AudioEventLogger.Event { 7853120059d5bdc52fb5ef2c90d9662562e92cd4df9Jean-Michel Trivi // only keeping the player interface ID as it uniquely identifies the player in the event 7863120059d5bdc52fb5ef2c90d9662562e92cd4df9Jean-Michel Trivi final int mPlayerIId; 7873120059d5bdc52fb5ef2c90d9662562e92cd4df9Jean-Michel Trivi final boolean mHasOp; 7883120059d5bdc52fb5ef2c90d9662562e92cd4df9Jean-Michel Trivi final int mUid; 7893120059d5bdc52fb5ef2c90d9662562e92cd4df9Jean-Michel Trivi 7903120059d5bdc52fb5ef2c90d9662562e92cd4df9Jean-Michel Trivi PlayerOpPlayAudioEvent(int piid, boolean hasOp, int uid) { 7913120059d5bdc52fb5ef2c90d9662562e92cd4df9Jean-Michel Trivi mPlayerIId = piid; 7923120059d5bdc52fb5ef2c90d9662562e92cd4df9Jean-Michel Trivi mHasOp = hasOp; 7933120059d5bdc52fb5ef2c90d9662562e92cd4df9Jean-Michel Trivi mUid = uid; 7943120059d5bdc52fb5ef2c90d9662562e92cd4df9Jean-Michel Trivi } 7953120059d5bdc52fb5ef2c90d9662562e92cd4df9Jean-Michel Trivi 7963120059d5bdc52fb5ef2c90d9662562e92cd4df9Jean-Michel Trivi @Override 7973120059d5bdc52fb5ef2c90d9662562e92cd4df9Jean-Michel Trivi public String eventToString() { 7983120059d5bdc52fb5ef2c90d9662562e92cd4df9Jean-Michel Trivi return new StringBuilder("player piid:").append(mPlayerIId) 7993120059d5bdc52fb5ef2c90d9662562e92cd4df9Jean-Michel Trivi .append(" has OP_PLAY_AUDIO:").append(mHasOp) 8003120059d5bdc52fb5ef2c90d9662562e92cd4df9Jean-Michel Trivi .append(" in uid:").append(mUid).toString(); 801011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi } 802011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi } 803011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi 804011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi private final static class NewPlayerEvent extends AudioEventLogger.Event { 805011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi private final int mPlayerIId; 806011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi private final int mPlayerType; 807011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi private final int mClientUid; 808011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi private final int mClientPid; 809011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi private final AudioAttributes mPlayerAttr; 810011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi 811011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi NewPlayerEvent(AudioPlaybackConfiguration apc) { 812011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi mPlayerIId = apc.getPlayerInterfaceId(); 813011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi mPlayerType = apc.getPlayerType(); 814011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi mClientUid = apc.getClientUid(); 815011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi mClientPid = apc.getClientPid(); 816011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi mPlayerAttr = apc.getAudioAttributes(); 817011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi } 818011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi 819011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi @Override 820011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi public String eventToString() { 821011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi return new String("new player piid:" + mPlayerIId + " uid/pid:" + mClientUid + "/" 822011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi + mClientPid + " type:" 823011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi + AudioPlaybackConfiguration.toLogFriendlyPlayerType(mPlayerType) 824011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi + " attr:" + mPlayerAttr); 825011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi } 826011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi } 827011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi 82874a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi private static final class DuckEvent extends AudioEventLogger.Event { 82974a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi private final int mPlayerIId; 83074a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi private final boolean mSkipRamp; 83174a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi private final int mClientUid; 83274a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi private final int mClientPid; 83374a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi 83474a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi DuckEvent(@NonNull AudioPlaybackConfiguration apc, boolean skipRamp) { 83574a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi mPlayerIId = apc.getPlayerInterfaceId(); 83674a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi mSkipRamp = skipRamp; 83774a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi mClientUid = apc.getClientUid(); 83874a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi mClientPid = apc.getClientPid(); 83974a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi } 84074a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi 84174a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi @Override 84274a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi public String eventToString() { 84374a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi return new StringBuilder("ducking player piid:").append(mPlayerIId) 84474a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi .append(" uid/pid:").append(mClientUid).append("/").append(mClientPid) 84574a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi .append(" skip ramp:").append(mSkipRamp).toString(); 84674a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi } 84774a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi } 84874a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi 84974a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi private static final class AudioAttrEvent extends AudioEventLogger.Event { 850011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi private final int mPlayerIId; 851011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi private final AudioAttributes mPlayerAttr; 852011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi 853011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi AudioAttrEvent(int piid, AudioAttributes attr) { 854011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi mPlayerIId = piid; 855011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi mPlayerAttr = attr; 856011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi } 857011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi 858011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi @Override 859011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi public String eventToString() { 860011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi return new String("player piid:" + mPlayerIId + " new AudioAttributes:" + mPlayerAttr); 861011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi } 862011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi } 863011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi 86474a5596a8aeb4c112a6c024e9613d58ba662a5b5Jean-Michel Trivi private static final AudioEventLogger sEventLogger = new AudioEventLogger(100, 865011f39e7c7a16424260310fb9f580c727b72e8d8Jean-Michel Trivi "playback activity as reported through PlayerBase"); 866292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi} 867