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

Commit 7c0b8a93 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 8429780 from 4c56b899 to tm-d1-release

Change-Id: Id531cd47cf94dc21a13905a425f9a750a570f1d7
parents eec20ec4 4c56b899
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -542,9 +542,9 @@ public class CallAudioManager extends CallsManagerListenerBase {
        mCallAudioModeStateMachine.dump(pw);
        pw.decreaseIndent();

        pw.println("CallAudioRouteStateMachine pending messages:");
        pw.println("CallAudioRouteStateMachine:");
        pw.increaseIndent();
        mCallAudioRouteStateMachine.dumpPendingMessages(pw);
        mCallAudioRouteStateMachine.dump(pw);
        pw.decreaseIndent();

        pw.println("BluetoothDeviceManager:");
+15 −4
Original line number Diff line number Diff line
@@ -411,6 +411,8 @@ public class CallAudioRouteStateMachine extends StateMachine {
                        Log.w(this, "Ignoring switch to headset command. Not available.");
                    }
                    return HANDLED;
                case CONNECT_DOCK:
                    // fall through; we want to switch to speaker mode when docked and in a call.
                case SWITCH_SPEAKER:
                case USER_SWITCH_SPEAKER:
                    setSpeakerphoneOn(true);
@@ -486,6 +488,8 @@ public class CallAudioRouteStateMachine extends StateMachine {
                        Log.w(this, "Ignoring switch to headset command. Not available.");
                    }
                    return HANDLED;
                case CONNECT_DOCK:
                    // fall through; we want to go to the quiescent speaker route when out of a call
                case SWITCH_SPEAKER:
                case USER_SWITCH_SPEAKER:
                    transitionTo(mQuiescentSpeakerRoute);
@@ -537,10 +541,6 @@ public class CallAudioRouteStateMachine extends StateMachine {
                case BT_AUDIO_DISCONNECTED:
                    // This may be sent as a confirmation by the BT stack after switch off BT.
                    return HANDLED;
                case CONNECT_DOCK:
                    setSpeakerphoneOn(true);
                    sendInternalMessage(SWITCH_SPEAKER);
                    return HANDLED;
                case DISCONNECT_DOCK:
                    // Nothing to do here
                    return HANDLED;
@@ -1273,6 +1273,8 @@ public class CallAudioRouteStateMachine extends StateMachine {
                case SPEAKER_ON:
                    // Nothing to do
                    return HANDLED;
                case DISCONNECT_DOCK:
                    // Fall-through; same as if speaker goes off, we want to switch baseline.
                case SPEAKER_OFF:
                    sendInternalMessage(SWITCH_BASELINE_ROUTE, INCLUDE_BLUETOOTH_IN_BASELINE);
                    return HANDLED;
@@ -1619,6 +1621,15 @@ public class CallAudioRouteStateMachine extends StateMachine {
        quitNow();
    }

    public void dump(IndentingPrintWriter pw) {
        pw.print("Current state: ");
        pw.println(getCurrentState().getName());
        pw.println("Pending messages:");
        pw.increaseIndent();
        dumpPendingMessages(pw);
        pw.decreaseIndent();
    }

    public void dumpPendingMessages(IndentingPrintWriter pw) {
        getHandler().getLooper().dump(pw::println, "");
    }
+6 −1
Original line number Diff line number Diff line
@@ -29,7 +29,12 @@ import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/** Listens for and caches car dock state. */
/**
 * Listens for and caches car dock state.
 * Testing; you can enable/disable dock with adb commands:
 *   adb shell dumpsys DockObserver set state 3
 *   adb shell dumpsys DockObserver set state 0
 */
@VisibleForTesting
public class DockManager {
    @VisibleForTesting
+68 −67
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import com.android.internal.annotations.VisibleForTesting;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Play a call-related tone (ringback, busy signal, etc.) either through ToneGenerator, or using a
@@ -186,7 +187,7 @@ public class InCallTonePlayer extends Thread {
     * when we need focus and when it can be release. This should only be manipulated from the main
     * thread.
     */
    private static int sTonesPlaying = 0;
    private static AtomicInteger sTonesPlaying = new AtomicInteger(0);

    private final CallAudioManager mCallAudioManager;
    private final CallAudioRoutePeripheralAdapter mCallAudioRoutePeripheralAdapter;
@@ -212,6 +213,12 @@ public class InCallTonePlayer extends Thread {
    private final MediaPlayerFactory mMediaPlayerFactory;
    private final AudioManagerAdapter mAudioManagerAdapter;

    /**
     * Latch used for awaiting on playback, which may be interrupted if the tone is stopped from
     * outside the playback.
     */
    private final CountDownLatch mPlaybackLatch = new CountDownLatch(1);

    /**
     * Initializes the tone player. Private; use the {@link Factory} to create tone players.
     *
@@ -388,26 +395,21 @@ public class InCallTonePlayer extends Thread {
            }

            Log.i(this, "playToneGeneratorTone: toneType=%d", toneType);
            // TODO: Certain CDMA tones need to check the ringer-volume state before
            // playing. See CallNotifier.InCallTonePlayer.

            // TODO: Some tones play through the end of a call so we need to inform
            // CallAudioManager that we want focus the same way that Ringer does.

            synchronized (this) {
                if (mState != STATE_STOPPED) {
            mState = STATE_ON;
            toneGenerator.startTone(toneType);
            try {
                Log.v(this, "Starting tone %d...waiting for %d ms.", mToneId,
                        toneLengthMillis + TIMEOUT_BUFFER_MILLIS);
                        wait(toneLengthMillis + TIMEOUT_BUFFER_MILLIS);
                    } catch (InterruptedException e) {
                        Log.w(this, "wait interrupted", e);
                    }
                if (mPlaybackLatch.await(toneLengthMillis + TIMEOUT_BUFFER_MILLIS,
                        TimeUnit.MILLISECONDS)) {
                    Log.i(this, "playToneGeneratorTone: tone playback stopped.");
                }
            } catch (InterruptedException e) {
                Log.w(this, "playToneGeneratorTone: wait interrupted", e);
            }
            mState = STATE_OFF;
            // Redundant; don't want anyone re-using at this point.
            mState = STATE_STOPPED;
        } finally {
            if (toneGenerator != null) {
                toneGenerator.release();
@@ -421,10 +423,7 @@ public class InCallTonePlayer extends Thread {
     * @param toneResourceId The resource ID of the tone to play.
     */
    private void playMediaTone(int stream, int toneResourceId) {
        synchronized (this) {
            if (mState != STATE_STOPPED) {
        mState = STATE_ON;
            }
        Log.i(this, "playMediaTone: toneResourceId=%d", toneResourceId);
        AudioAttributes attributes = new AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
@@ -434,32 +433,32 @@ public class InCallTonePlayer extends Thread {
        mToneMediaPlayer = mMediaPlayerFactory.get(toneResourceId, attributes);
        mToneMediaPlayer.setLooping(false);
        int durationMillis = mToneMediaPlayer.getDuration();
            final CountDownLatch toneLatch = new CountDownLatch(1);
        mToneMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                Log.i(InCallTonePlayer.this, "playMediaTone: toneResourceId=%d completed.",
                        toneResourceId);
                    synchronized (InCallTonePlayer.this) {
                        mState = STATE_OFF;
                    }
                    mToneMediaPlayer.release();
                    mToneMediaPlayer = null;
                    toneLatch.countDown();
                mPlaybackLatch.countDown();
            }
        });
            mToneMediaPlayer.start();

        try {
            mToneMediaPlayer.start();
            // Wait for the tone to stop playing; timeout at 2x the length of the file just to
                // be on the safe side.
                toneLatch.await(durationMillis * 2, TimeUnit.MILLISECONDS);
            // be on the safe side.  Playback can also be stopped via stopTone().
            if (mPlaybackLatch.await(durationMillis * 2, TimeUnit.MILLISECONDS)) {
                Log.i(this, "playMediaTone: tone playback stopped.");
            }
        } catch (InterruptedException ie) {
            Log.e(this, ie, "playMediaTone: tone playback interrupted.");
        } finally {
            // Redundant; don't want anyone re-using at this point.
            mState = STATE_STOPPED;
            mToneMediaPlayer.release();
            mToneMediaPlayer = null;
        }
    }

    }

    @VisibleForTesting
    public boolean startTone() {
        // Skip playing the end call tone if the volume is silenced.
@@ -468,8 +467,12 @@ public class InCallTonePlayer extends Thread {
            return false;
        }

        sTonesPlaying++;
        if (sTonesPlaying == 1) {
        // Tone already done; don't allow re-used
        if (mState == STATE_STOPPED) {
            return false;
        }

        if (sTonesPlaying.incrementAndGet() == 1) {
            mCallAudioManager.setIsTonePlaying(true);
        }

@@ -494,18 +497,17 @@ public class InCallTonePlayer extends Thread {
     */
    @VisibleForTesting
    public void stopTone() {
        synchronized (this) {
        if (mState == STATE_ON) {
                Log.d(this, "Stopping the tone %d.", mToneId);
                notify();
            Log.i(this, "stopTone: Stopping the tone %d.", mToneId);
            // Notify the playback to end early.
            mPlaybackLatch.countDown();
        }
        mState = STATE_STOPPED;
    }
    }

    @VisibleForTesting
    public void cleanup() {
        sTonesPlaying = 0;
        sTonesPlaying.set(0);
    }

    private void cleanUpTonePlayer() {
@@ -514,12 +516,11 @@ public class InCallTonePlayer extends Thread {
        mMainThreadHandler.post(new Runnable("ICTP.cUTP", mLock) {
            @Override
            public void loggedRun() {
                if (sTonesPlaying == 0) {
                    Log.wtf(InCallTonePlayer.this,
                            "cleanUpTonePlayer(): Over-releasing focus for tone player.");
                } else if (--sTonesPlaying == 0) {
                int newToneCount = sTonesPlaying.updateAndGet( t -> Math.min(0, t--));

                if (newToneCount == 0) {
                    Log.i(InCallTonePlayer.this,
                            "cleanUpTonePlayer(): tonesPlaying=%d, tone completed", sTonesPlaying);
                            "cleanUpTonePlayer(): tonesPlaying=%d, tone completed", newToneCount);
                    if (mCallAudioManager != null) {
                        mCallAudioManager.setIsTonePlaying(false);
                    } else {
@@ -528,7 +529,7 @@ public class InCallTonePlayer extends Thread {
                    }
                } else {
                    Log.i(InCallTonePlayer.this,
                            "cleanUpTonePlayer(): tonesPlaying=%d; still playing", sTonesPlaying);
                            "cleanUpTonePlayer(): tonesPlaying=%d; still playing", newToneCount);
                }
            }
        }.prepare());
+47 −1
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telephony.CarrierConfigManager;
import android.telephony.PhoneNumberUtils;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
@@ -1413,7 +1414,7 @@ public class PhoneAccountRegistrar {

        public final UserHandle userHandle;

        public final PhoneAccountHandle phoneAccountHandle;
        public PhoneAccountHandle phoneAccountHandle;

        public final String groupId;

@@ -1555,6 +1556,7 @@ public class PhoneAccountRegistrar {
            XmlPullParser parser = Xml.resolvePullParser(is);
            parser.nextTag();
            mState = readFromXml(parser, mContext);
            migratePhoneAccountHandle(mState);
            versionChanged = mState.versionNumber < EXPECTED_STATE_VERSION;

        } catch (IOException | XmlPullParserException e) {
@@ -1599,6 +1601,50 @@ public class PhoneAccountRegistrar {
        return s != null ? s : new State();
    }

    /**
     * Try to migrate the ID of default phone account handle from IccId to SubId.
     */
    @VisibleForTesting
    public void migratePhoneAccountHandle(State state) {
        if (mSubscriptionManager == null) {
            return;
        }
        // Use getAllSubscirptionInfoList() to get the mapping between iccId and subId
        // from the subscription database
        List<SubscriptionInfo> subscriptionInfos = mSubscriptionManager
                .getAllSubscriptionInfoList();
        Map<UserHandle, DefaultPhoneAccountHandle> defaultPhoneAccountHandles
                = state.defaultOutgoingAccountHandles;
        for (Map.Entry<UserHandle, DefaultPhoneAccountHandle> entry
                : defaultPhoneAccountHandles.entrySet()) {
            DefaultPhoneAccountHandle defaultPhoneAccountHandle = entry.getValue();

            // Migrate Telephony PhoneAccountHandle only
            String telephonyComponentName =
                    "com.android.phone/com.android.services.telephony.TelephonyConnectionService";
            if (!defaultPhoneAccountHandle.phoneAccountHandle.getComponentName()
                    .flattenToString().equals(telephonyComponentName)) {
                continue;
            }
            // Migrate from IccId to SubId
            for (SubscriptionInfo subscriptionInfo : subscriptionInfos) {
                String phoneAccountHandleId = defaultPhoneAccountHandle.phoneAccountHandle.getId();
                // Some phone account handle would store phone account handle id with the IccId
                // string plus "F", and the getIccId() returns IccId string itself without "F",
                // so here need to use "startsWith" to match.
                if (phoneAccountHandleId != null && phoneAccountHandleId.startsWith(
                        subscriptionInfo.getIccId())) {
                    Log.i(this, "Found subscription ID to migrate: "
                            + subscriptionInfo.getSubscriptionId());
                    defaultPhoneAccountHandle.phoneAccountHandle = new PhoneAccountHandle(
                            defaultPhoneAccountHandle.phoneAccountHandle.getComponentName(),
                                    Integer.toString(subscriptionInfo.getSubscriptionId()));
                    break;
                }
            }
        }
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // XML serialization
Loading