Remove BluetoothPhoneService.
Service moved to telecom.
Bug:17475562
Change-Id: I20d20b00f8f7caedd5ba59245c06fd369534857b
diff --git a/src/com/android/phone/BluetoothPhoneService.java b/src/com/android/phone/BluetoothPhoneService.java
deleted file mode 100644
index 653d671..0000000
--- a/src/com/android/phone/BluetoothPhoneService.java
+++ /dev/null
@@ -1,982 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone;
-
-import android.app.Service;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothHeadset;
-import android.bluetooth.BluetoothProfile;
-import android.bluetooth.IBluetoothHeadsetPhone;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.PowerManager.WakeLock;
-import android.os.SystemProperties;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.ServiceState;
-import android.util.Log;
-
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.telephony.CallManager;
-
-import com.android.phone.CallGatewayManager.RawGatewayInfo;
-
-import java.io.IOException;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Bluetooth headset manager for the Phone app.
- * @hide
- */
-public class BluetoothPhoneService extends Service {
- private static final String TAG = "BluetoothPhoneService";
- private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 1)
- && (SystemProperties.getInt("ro.debuggable", 0) == 1);
- private static final boolean VDBG = (PhoneGlobals.DBG_LEVEL >= 2); // even more logging
-
- private static final String MODIFY_PHONE_STATE = android.Manifest.permission.MODIFY_PHONE_STATE;
-
- private BluetoothAdapter mAdapter;
- private CallManager mCM;
- private CallGatewayManager mCallGatewayManager;
-
- private BluetoothHeadset mBluetoothHeadset;
-
- private PowerManager mPowerManager;
-
- private WakeLock mStartCallWakeLock; // held while waiting for the intent to start call
-
- private PhoneConstants.State mPhoneState = PhoneConstants.State.IDLE;
- CdmaPhoneCallState.PhoneCallState mCdmaThreeWayCallState =
- CdmaPhoneCallState.PhoneCallState.IDLE;
-
- private Call.State mForegroundCallState;
- private Call.State mRingingCallState;
- private CallNumber mRingNumber;
- // number of active calls
- int mNumActive;
- // number of background (held) calls
- int mNumHeld;
-
- long mBgndEarliestConnectionTime = 0;
-
- // CDMA specific flag used in context with BT devices having display capabilities
- // to show which Caller is active. This state might not be always true as in CDMA
- // networks if a caller drops off no update is provided to the Phone.
- // This flag is just used as a toggle to provide a update to the BT device to specify
- // which caller is active.
- private boolean mCdmaIsSecondCallActive = false;
- private boolean mCdmaCallsSwapped = false;
-
- private long[] mClccTimestamps; // Timestamps associated with each clcc index
- private boolean[] mClccUsed; // Is this clcc index in use
-
- private static final int GSM_MAX_CONNECTIONS = 6; // Max connections allowed by GSM
- private static final int CDMA_MAX_CONNECTIONS = 2; // Max connections allowed by CDMA
- private IntentFilter mIntentFilter;
-
- private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
- if (VDBG) Log.d(TAG, "Received BLUETOOTH_STATE_CHANGED_ACTION state:" + state);
- if(state == BluetoothAdapter.STATE_ON) {
- if (DBG) Log.d(TAG, "Bluetooth Turned ON, query phone state");
- Message msg = Message.obtain(mHandler, QUERY_PHONE_STATE);
- mHandler.sendMessage(msg);
- }
- }
- };
-
- @Override
- public void onCreate() {
- super.onCreate();
- mCM = CallManager.getInstance();
- mAdapter = BluetoothAdapter.getDefaultAdapter();
- if (mAdapter == null) {
- if (VDBG) Log.d(TAG, "mAdapter null");
- return;
- }
- mCallGatewayManager = CallGatewayManager.getInstance();
-
- mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
- mStartCallWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
- TAG + ":StartCall");
- mStartCallWakeLock.setReferenceCounted(false);
-
- mAdapter.getProfileProxy(this, mProfileListener, BluetoothProfile.HEADSET);
-
- mForegroundCallState = Call.State.IDLE;
- mRingingCallState = Call.State.IDLE;
- mNumActive = 0;
- mNumHeld = 0;
- mRingNumber = new CallNumber("", 0);;
-
- handlePreciseCallStateChange(null);
-
- if(VDBG) Log.d(TAG, "onCreate register for updates");
- // register for updates
- mCM.registerForPreciseCallStateChanged(mHandler, PRECISE_CALL_STATE_CHANGED, null);
- mCM.registerForCallWaiting(mHandler, PHONE_CDMA_CALL_WAITING, null);
- mCM.registerForDisconnect(mHandler, PHONE_ON_DISCONNECT, null);
-
- mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
- this.registerReceiver(mReceiver, mIntentFilter);
- // TODO(BT) registerForIncomingRing?
- mClccTimestamps = new long[GSM_MAX_CONNECTIONS];
- mClccUsed = new boolean[GSM_MAX_CONNECTIONS];
- for (int i = 0; i < GSM_MAX_CONNECTIONS; i++) {
- mClccUsed[i] = false;
- }
- }
-
- @Override
- public void onStart(Intent intent, int startId) {
- if (mAdapter == null) {
- Log.w(TAG, "Stopping Bluetooth BluetoothPhoneService Service: device does not have BT");
- stopSelf();
- }
- if (VDBG) Log.d(TAG, "BluetoothPhoneService started");
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- if (DBG) log("Stopping Bluetooth BluetoothPhoneService Service");
- this.unregisterReceiver(mReceiver);
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- return mBinder;
- }
-
- private static final int PRECISE_CALL_STATE_CHANGED = 1;
- private static final int PHONE_CDMA_CALL_WAITING = 2;
- private static final int LIST_CURRENT_CALLS = 3;
- private static final int QUERY_PHONE_STATE = 4;
- private static final int CDMA_SWAP_SECOND_CALL_STATE = 5;
- private static final int CDMA_SET_SECOND_CALL_STATE = 6;
- private static final int PHONE_ON_DISCONNECT = 7;
-
- private Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- if (VDBG) Log.d(TAG, "handleMessage: " + msg.what);
- switch(msg.what) {
- case PRECISE_CALL_STATE_CHANGED:
- case PHONE_CDMA_CALL_WAITING:
- case PHONE_ON_DISCONNECT:
- Connection connection = null;
- if (((AsyncResult) msg.obj).result instanceof Connection) {
- connection = (Connection) ((AsyncResult) msg.obj).result;
- }
- handlePreciseCallStateChange(connection);
- break;
- case LIST_CURRENT_CALLS:
- handleListCurrentCalls();
- break;
- case QUERY_PHONE_STATE:
- handleQueryPhoneState();
- break;
- case CDMA_SWAP_SECOND_CALL_STATE:
- handleCdmaSwapSecondCallState();
- break;
- case CDMA_SET_SECOND_CALL_STATE:
- handleCdmaSetSecondCallState((Boolean) msg.obj);
- break;
- }
- }
- };
-
- private void updateBtPhoneStateAfterRadioTechnologyChange() {
- if(VDBG) Log.d(TAG, "updateBtPhoneStateAfterRadioTechnologyChange...");
-
- //Unregister all events from the old obsolete phone
- mCM.unregisterForPreciseCallStateChanged(mHandler);
- mCM.unregisterForCallWaiting(mHandler);
-
- //Register all events new to the new active phone
- mCM.registerForPreciseCallStateChanged(mHandler,
- PRECISE_CALL_STATE_CHANGED, null);
- mCM.registerForCallWaiting(mHandler,
- PHONE_CDMA_CALL_WAITING, null);
- }
-
- private void handlePreciseCallStateChange(Connection connection) {
- // get foreground call state
- int oldNumActive = mNumActive;
- int oldNumHeld = mNumHeld;
- Call.State oldRingingCallState = mRingingCallState;
- Call.State oldForegroundCallState = mForegroundCallState;
- CallNumber oldRingNumber = mRingNumber;
-
- Call foregroundCall = mCM.getActiveFgCall();
-
- if (VDBG)
- Log.d(TAG, " handlePreciseCallStateChange: foreground: " + foregroundCall +
- " background: " + mCM.getFirstActiveBgCall() + " ringing: " +
- mCM.getFirstActiveRingingCall());
-
- mForegroundCallState = foregroundCall.getState();
- /* if in transition, do not update */
- if (mForegroundCallState == Call.State.DISCONNECTING)
- {
- Log.d(TAG, "handlePreciseCallStateChange. Call disconnecting, wait before update");
- return;
- }
- else
- mNumActive = (mForegroundCallState == Call.State.ACTIVE) ? 1 : 0;
-
- Call ringingCall = mCM.getFirstActiveRingingCall();
- mRingingCallState = ringingCall.getState();
- mRingNumber = getCallNumber(connection, ringingCall);
-
- if (mCM.getDefaultPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
- mNumHeld = getNumHeldCdma();
- PhoneGlobals app = PhoneGlobals.getInstance();
- if (app.cdmaPhoneCallState != null) {
- CdmaPhoneCallState.PhoneCallState currCdmaThreeWayCallState =
- app.cdmaPhoneCallState.getCurrentCallState();
- CdmaPhoneCallState.PhoneCallState prevCdmaThreeWayCallState =
- app.cdmaPhoneCallState.getPreviousCallState();
-
- log("CDMA call state: " + currCdmaThreeWayCallState + " prev state:" +
- prevCdmaThreeWayCallState);
-
- if ((mBluetoothHeadset != null) &&
- (mCdmaThreeWayCallState != currCdmaThreeWayCallState)) {
- // In CDMA, the network does not provide any feedback
- // to the phone when the 2nd MO call goes through the
- // stages of DIALING > ALERTING -> ACTIVE we fake the
- // sequence
- log("CDMA 3way call state change. mNumActive: " + mNumActive +
- " mNumHeld: " + mNumHeld + " IsThreeWayCallOrigStateDialing: " +
- app.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing());
- if ((currCdmaThreeWayCallState ==
- CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE)
- && app.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing()) {
- // Mimic dialing, put the call on hold, alerting
- mBluetoothHeadset.phoneStateChanged(0, mNumHeld,
- convertCallState(Call.State.IDLE, Call.State.DIALING),
- mRingNumber.mNumber, mRingNumber.mType);
-
- mBluetoothHeadset.phoneStateChanged(0, mNumHeld,
- convertCallState(Call.State.IDLE, Call.State.ALERTING),
- mRingNumber.mNumber, mRingNumber.mType);
-
- }
-
- // In CDMA, the network does not provide any feedback to
- // the phone when a user merges a 3way call or swaps
- // between two calls we need to send a CIEV response
- // indicating that a call state got changed which should
- // trigger a CLCC update request from the BT client.
- if (currCdmaThreeWayCallState ==
- CdmaPhoneCallState.PhoneCallState.CONF_CALL &&
- prevCdmaThreeWayCallState ==
- CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
- log("CDMA 3way conf call. mNumActive: " + mNumActive +
- " mNumHeld: " + mNumHeld);
- mBluetoothHeadset.phoneStateChanged(mNumActive, mNumHeld,
- convertCallState(Call.State.IDLE, mForegroundCallState),
- mRingNumber.mNumber, mRingNumber.mType);
- }
- }
- mCdmaThreeWayCallState = currCdmaThreeWayCallState;
- }
- } else {
- mNumHeld = getNumHeldUmts();
- }
-
- boolean callsSwitched = false;
- if (mCM.getDefaultPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA &&
- mCdmaThreeWayCallState == CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
- callsSwitched = mCdmaCallsSwapped;
- } else {
- Call backgroundCall = mCM.getFirstActiveBgCall();
- callsSwitched =
- (mNumHeld == 1 && ! (backgroundCall.getEarliestConnectTime() ==
- mBgndEarliestConnectionTime));
- mBgndEarliestConnectionTime = backgroundCall.getEarliestConnectTime();
- }
-
- if (mNumActive != oldNumActive || mNumHeld != oldNumHeld ||
- mRingingCallState != oldRingingCallState ||
- mForegroundCallState != oldForegroundCallState ||
- !mRingNumber.equalTo(oldRingNumber) ||
- callsSwitched) {
- if (mBluetoothHeadset != null) {
- mBluetoothHeadset.phoneStateChanged(mNumActive, mNumHeld,
- convertCallState(mRingingCallState, mForegroundCallState),
- mRingNumber.mNumber, mRingNumber.mType);
- }
- }
- }
-
- private void handleListCurrentCalls() {
- Phone phone = mCM.getDefaultPhone();
- int phoneType = phone.getPhoneType();
-
- // TODO(BT) handle virtual call
-
- if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
- listCurrentCallsCdma();
- } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
- listCurrentCallsGsm();
- } else {
- Log.e(TAG, "Unexpected phone type: " + phoneType);
- }
- // end the result
- // when index is 0, other parameter does not matter
- if (mBluetoothHeadset != null) {
- mBluetoothHeadset.clccResponse(0, 0, 0, 0, false, "", 0);
- }
- }
-
- private void handleQueryPhoneState() {
- if (mBluetoothHeadset != null) {
- mBluetoothHeadset.phoneStateChanged(mNumActive, mNumHeld,
- convertCallState(mRingingCallState, mForegroundCallState),
- mRingNumber.mNumber, mRingNumber.mType);
- }
- }
-
- private int getNumHeldUmts() {
- int countHeld = 0;
- List<Call> heldCalls = mCM.getBackgroundCalls();
-
- for (Call call : heldCalls) {
- if (call.getState() == Call.State.HOLDING) {
- countHeld++;
- }
- }
- return countHeld;
- }
-
- private int getNumHeldCdma() {
- int numHeld = 0;
- PhoneGlobals app = PhoneGlobals.getInstance();
- if (app.cdmaPhoneCallState != null) {
- CdmaPhoneCallState.PhoneCallState curr3WayCallState =
- app.cdmaPhoneCallState.getCurrentCallState();
- CdmaPhoneCallState.PhoneCallState prev3WayCallState =
- app.cdmaPhoneCallState.getPreviousCallState();
-
- log("CDMA call state: " + curr3WayCallState + " prev state:" +
- prev3WayCallState);
- if (curr3WayCallState == CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
- if (prev3WayCallState == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
- numHeld = 0; //0: no calls held, as now *both* the caller are active
- } else {
- numHeld = 1; //1: held call and active call, as on answering a
- // Call Waiting, one of the caller *is* put on hold
- }
- } else if (curr3WayCallState == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
- numHeld = 1; //1: held call and active call, as on make a 3 Way Call
- // the first caller *is* put on hold
- } else {
- numHeld = 0; //0: no calls held as this is a SINGLE_ACTIVE call
- }
- }
- return numHeld;
- }
-
- private CallNumber getCallNumber(Connection connection, Call call) {
- String number = null;
- int type = 128;
- // find phone number and type
- if (connection == null) {
- connection = call.getEarliestConnection();
- if (connection == null) {
- Log.e(TAG, "Could not get a handle on Connection object for the call");
- }
- }
- if (connection != null) {
- number = connection.getAddress();
- if (number != null) {
- type = PhoneNumberUtils.toaFromString(number);
- }
- }
- if (number == null) {
- number = "";
- }
- return new CallNumber(number, type);
- }
-
- private class CallNumber
- {
- private String mNumber = null;
- private int mType = 0;
-
- private CallNumber(String number, int type) {
- mNumber = number;
- mType = type;
- }
-
- private boolean equalTo(CallNumber callNumber)
- {
- if (mType != callNumber.mType) return false;
-
- if (mNumber != null && mNumber.compareTo(callNumber.mNumber) == 0) {
- return true;
- }
- return false;
- }
- }
-
- private BluetoothProfile.ServiceListener mProfileListener =
- new BluetoothProfile.ServiceListener() {
- public void onServiceConnected(int profile, BluetoothProfile proxy) {
- mBluetoothHeadset = (BluetoothHeadset) proxy;
- }
- public void onServiceDisconnected(int profile) {
- mBluetoothHeadset = null;
- }
- };
-
- private void listCurrentCallsGsm() {
- // Collect all known connections
- // clccConnections isindexed by CLCC index
- Connection[] clccConnections = new Connection[GSM_MAX_CONNECTIONS];
- LinkedList<Connection> newConnections = new LinkedList<Connection>();
- LinkedList<Connection> connections = new LinkedList<Connection>();
-
- Call foregroundCall = mCM.getActiveFgCall();
- Call backgroundCall = mCM.getFirstActiveBgCall();
- Call ringingCall = mCM.getFirstActiveRingingCall();
-
- if (ringingCall.getState().isAlive()) {
- connections.addAll(ringingCall.getConnections());
- }
- if (foregroundCall.getState().isAlive()) {
- connections.addAll(foregroundCall.getConnections());
- }
- if (backgroundCall.getState().isAlive()) {
- connections.addAll(backgroundCall.getConnections());
- }
-
- // Mark connections that we already known about
- boolean clccUsed[] = new boolean[GSM_MAX_CONNECTIONS];
- for (int i = 0; i < GSM_MAX_CONNECTIONS; i++) {
- clccUsed[i] = mClccUsed[i];
- mClccUsed[i] = false;
- }
- for (Connection c : connections) {
- boolean found = false;
- long timestamp = c.getCreateTime();
- for (int i = 0; i < GSM_MAX_CONNECTIONS; i++) {
- if (clccUsed[i] && timestamp == mClccTimestamps[i]) {
- mClccUsed[i] = true;
- found = true;
- clccConnections[i] = c;
- break;
- }
- }
- if (!found) {
- newConnections.add(c);
- }
- }
-
- // Find a CLCC index for new connections
- while (!newConnections.isEmpty()) {
- // Find lowest empty index
- int i = 0;
- while (mClccUsed[i]) i++;
- // Find earliest connection
- long earliestTimestamp = newConnections.get(0).getCreateTime();
- Connection earliestConnection = newConnections.get(0);
- for (int j = 0; j < newConnections.size(); j++) {
- long timestamp = newConnections.get(j).getCreateTime();
- if (timestamp < earliestTimestamp) {
- earliestTimestamp = timestamp;
- earliestConnection = newConnections.get(j);
- }
- }
-
- // update
- mClccUsed[i] = true;
- mClccTimestamps[i] = earliestTimestamp;
- clccConnections[i] = earliestConnection;
- newConnections.remove(earliestConnection);
- }
-
- // Send CLCC response to Bluetooth headset service
- for (int i = 0; i < clccConnections.length; i++) {
- if (mClccUsed[i]) {
- sendClccResponseGsm(i, clccConnections[i]);
- }
- }
- }
-
- /** Convert a Connection object into a single +CLCC result */
- private void sendClccResponseGsm(int index, Connection connection) {
- int state = convertCallState(connection.getState());
- boolean mpty = false;
- Call call = connection.getCall();
- if (call != null) {
- mpty = call.isMultiparty();
- }
-
- boolean isIncoming = connection.isIncoming();
-
- // For GV outgoing calls send the contact phone #, not the gateway #.
- String number = connection.getAddress();
- if (!isIncoming) {
- RawGatewayInfo rawInfo = mCallGatewayManager.getGatewayInfo(connection);
- if (!rawInfo.isEmpty()) {
- number = rawInfo.trueNumber;
- }
- }
- int type = -1;
- if (number != null) {
- type = PhoneNumberUtils.toaFromString(number);
- } else {
- number = "";
- }
-
- if (mBluetoothHeadset != null) {
- mBluetoothHeadset.clccResponse(index + 1, isIncoming ? 1 : 0,
- state, 0, mpty, number, type);
- }
- }
-
- /** Build the +CLCC result for CDMA
- * The complexity arises from the fact that we need to maintain the same
- * CLCC index even as a call moves between states. */
- private synchronized void listCurrentCallsCdma() {
- // In CDMA at one time a user can have only two live/active connections
- Connection[] clccConnections = new Connection[CDMA_MAX_CONNECTIONS];// indexed by CLCC index
- Call foregroundCall = mCM.getActiveFgCall();
- Call ringingCall = mCM.getFirstActiveRingingCall();
-
- Call.State ringingCallState = ringingCall.getState();
- // If the Ringing Call state is INCOMING, that means this is the very first call
- // hence there should not be any Foreground Call
- if (ringingCallState == Call.State.INCOMING) {
- if (VDBG) log("Filling clccConnections[0] for INCOMING state");
- clccConnections[0] = ringingCall.getLatestConnection();
- } else if (foregroundCall.getState().isAlive()) {
- // Getting Foreground Call connection based on Call state
- if (ringingCall.isRinging()) {
- if (VDBG) log("Filling clccConnections[0] & [1] for CALL WAITING state");
- clccConnections[0] = foregroundCall.getEarliestConnection();
- clccConnections[1] = ringingCall.getLatestConnection();
- } else {
- if (foregroundCall.getConnections().size() <= 1) {
- // Single call scenario
- if (VDBG) {
- log("Filling clccConnections[0] with ForgroundCall latest connection");
- }
- clccConnections[0] = foregroundCall.getLatestConnection();
- } else {
- // Multiple Call scenario. This would be true for both
- // CONF_CALL and THRWAY_ACTIVE state
- if (VDBG) {
- log("Filling clccConnections[0] & [1] with ForgroundCall connections");
- }
- clccConnections[0] = foregroundCall.getEarliestConnection();
- clccConnections[1] = foregroundCall.getLatestConnection();
- }
- }
- }
-
- // Update the mCdmaIsSecondCallActive flag based on the Phone call state
- if (PhoneGlobals.getInstance().cdmaPhoneCallState.getCurrentCallState()
- == CdmaPhoneCallState.PhoneCallState.SINGLE_ACTIVE) {
- Message msg = mHandler.obtainMessage(CDMA_SET_SECOND_CALL_STATE, false);
- mHandler.sendMessage(msg);
- } else if (PhoneGlobals.getInstance().cdmaPhoneCallState.getCurrentCallState()
- == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
- Message msg = mHandler.obtainMessage(CDMA_SET_SECOND_CALL_STATE, true);
- mHandler.sendMessage(msg);
- }
-
- // send CLCC result
- for (int i = 0; (i < clccConnections.length) && (clccConnections[i] != null); i++) {
- sendClccResponseCdma(i, clccConnections[i]);
- }
- }
-
- /** Send ClCC results for a Connection object for CDMA phone */
- private void sendClccResponseCdma(int index, Connection connection) {
- int state;
- PhoneGlobals app = PhoneGlobals.getInstance();
- CdmaPhoneCallState.PhoneCallState currCdmaCallState =
- app.cdmaPhoneCallState.getCurrentCallState();
- CdmaPhoneCallState.PhoneCallState prevCdmaCallState =
- app.cdmaPhoneCallState.getPreviousCallState();
-
- if ((prevCdmaCallState == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE)
- && (currCdmaCallState == CdmaPhoneCallState.PhoneCallState.CONF_CALL)) {
- // If the current state is reached after merging two calls
- // we set the state of all the connections as ACTIVE
- state = CALL_STATE_ACTIVE;
- } else {
- Call.State callState = connection.getState();
- switch (callState) {
- case ACTIVE:
- // For CDMA since both the connections are set as active by FW after accepting
- // a Call waiting or making a 3 way call, we need to set the state specifically
- // to ACTIVE/HOLDING based on the mCdmaIsSecondCallActive flag. This way the
- // CLCC result will allow BT devices to enable the swap or merge options
- if (index == 0) { // For the 1st active connection
- state = mCdmaIsSecondCallActive ? CALL_STATE_HELD : CALL_STATE_ACTIVE;
- } else { // for the 2nd active connection
- state = mCdmaIsSecondCallActive ? CALL_STATE_ACTIVE : CALL_STATE_HELD;
- }
- break;
- case HOLDING:
- state = CALL_STATE_HELD;
- break;
- case DIALING:
- state = CALL_STATE_DIALING;
- break;
- case ALERTING:
- state = CALL_STATE_ALERTING;
- break;
- case INCOMING:
- state = CALL_STATE_INCOMING;
- break;
- case WAITING:
- state = CALL_STATE_WAITING;
- break;
- default:
- Log.e(TAG, "bad call state: " + callState);
- return;
- }
- }
-
- boolean mpty = false;
- if (currCdmaCallState == CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
- if (prevCdmaCallState == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
- // If the current state is reached after merging two calls
- // we set the multiparty call true.
- mpty = true;
- } // else
- // CALL_CONF state is not from merging two calls, but from
- // accepting the second call. In this case first will be on
- // hold in most cases but in some cases its already merged.
- // However, we will follow the common case and the test case
- // as per Bluetooth SIG PTS
- }
-
- boolean isIncoming = connection.isIncoming();
-
- // For GV outgoing calls send the contact phone #, not the gateway #.
- String number = connection.getAddress();
- if (!isIncoming) {
- RawGatewayInfo rawInfo = mCallGatewayManager.getGatewayInfo(connection);
- if (!rawInfo.isEmpty()) {
- number = rawInfo.trueNumber;
- }
- }
- int type = -1;
- if (number != null) {
- type = PhoneNumberUtils.toaFromString(number);
- } else {
- number = "";
- }
-
- if (mBluetoothHeadset != null) {
- mBluetoothHeadset.clccResponse(index + 1, isIncoming ? 1 : 0,
- state, 0, mpty, number, type);
- }
- }
-
- private void handleCdmaSwapSecondCallState() {
- if (VDBG) log("cdmaSwapSecondCallState: Toggling mCdmaIsSecondCallActive");
- mCdmaIsSecondCallActive = !mCdmaIsSecondCallActive;
- mCdmaCallsSwapped = true;
- }
-
- private void handleCdmaSetSecondCallState(boolean state) {
- if (VDBG) log("cdmaSetSecondCallState: Setting mCdmaIsSecondCallActive to " + state);
- mCdmaIsSecondCallActive = state;
-
- if (!mCdmaIsSecondCallActive) {
- mCdmaCallsSwapped = false;
- }
- }
-
- private final IBluetoothHeadsetPhone.Stub mBinder = new IBluetoothHeadsetPhone.Stub() {
- public boolean answerCall() {
- enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
- return PhoneUtils.answerCall(mCM.getFirstActiveRingingCall());
- }
-
- public boolean hangupCall() {
- enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
- if (mCM.hasActiveFgCall()) {
- return PhoneUtils.hangupActiveCall(mCM.getActiveFgCall());
- } else if (mCM.hasActiveRingingCall()) {
- return PhoneUtils.hangupRingingCall(mCM.getFirstActiveRingingCall());
- } else if (mCM.hasActiveBgCall()) {
- return PhoneUtils.hangupHoldingCall(mCM.getFirstActiveBgCall());
- }
- // TODO(BT) handle virtual voice call
- return false;
- }
-
- public boolean sendDtmf(int dtmf) {
- enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
- return mCM.sendDtmf((char) dtmf);
- }
-
- public boolean processChld(int chld) {
- enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
- Phone phone = mCM.getDefaultPhone();
- int phoneType = phone.getPhoneType();
- Call ringingCall = mCM.getFirstActiveRingingCall();
- Call backgroundCall = mCM.getFirstActiveBgCall();
-
- if (chld == CHLD_TYPE_RELEASEHELD) {
- if (ringingCall.isRinging()) {
- return PhoneUtils.hangupRingingCall(ringingCall);
- } else {
- return PhoneUtils.hangupHoldingCall(backgroundCall);
- }
- } else if (chld == CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD) {
- if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
- if (ringingCall.isRinging()) {
- // Hangup the active call and then answer call waiting call.
- if (VDBG) log("CHLD:1 Callwaiting Answer call");
- PhoneUtils.hangupRingingAndActive(phone);
- } else {
- // If there is no Call waiting then just hangup
- // the active call. In CDMA this mean that the complete
- // call session would be ended
- if (VDBG) log("CHLD:1 Hangup Call");
- PhoneUtils.hangup(PhoneGlobals.getInstance().mCM);
- }
- return true;
- } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
- if (ringingCall.isRinging() && (mNumHeld > 0 && mNumActive == 0)) {
- if (VDBG) log("CHLD:1 Answer the Call");
- return PhoneUtils.answerCall(ringingCall);
- }
- // Hangup active call, answer held call
- return PhoneUtils.answerAndEndActive(PhoneGlobals.getInstance().mCM, ringingCall);
- } else {
- Log.e(TAG, "bad phone type: " + phoneType);
- return false;
- }
- } else if (chld == CHLD_TYPE_HOLDACTIVE_ACCEPTHELD) {
- if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
- // For CDMA, the way we switch to a new incoming call is by
- // calling PhoneUtils.answerCall(). switchAndHoldActive() won't
- // properly update the call state within telephony.
- // If the Phone state is already in CONF_CALL then we simply send
- // a flash cmd by calling switchHoldingAndActive()
- if (ringingCall.isRinging()) {
- if (VDBG) log("CHLD:2 Callwaiting Answer call");
- PhoneUtils.answerCall(ringingCall);
- // Setting the second callers state flag to TRUE (i.e. active)
- cdmaSetSecondCallState(true);
- return true;
- } else if (PhoneGlobals.getInstance().cdmaPhoneCallState
- .getCurrentCallState()
- == CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
- if (VDBG) log("CHLD:2 Swap Calls");
- PhoneUtils.switchHoldingAndActive(backgroundCall);
- // Toggle the second callers active state flag
- cdmaSwapSecondCallState();
- return true;
- }
- Log.e(TAG, "CDMA fail to do hold active and accept held");
- return false;
- } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
- if (ringingCall.isRinging() && (mNumHeld > 0 && mNumActive == 0)) {
- PhoneUtils.answerCall(ringingCall);
- } else {
- PhoneUtils.switchHoldingAndActive(backgroundCall);
- }
- return true;
- } else {
- Log.e(TAG, "Unexpected phone type: " + phoneType);
- return false;
- }
- } else if (chld == CHLD_TYPE_ADDHELDTOCONF) {
- if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
- CdmaPhoneCallState.PhoneCallState state =
- PhoneGlobals.getInstance().cdmaPhoneCallState.getCurrentCallState();
- // For CDMA, we need to check if the call is in THRWAY_ACTIVE state
- if (state == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
- if (VDBG) log("CHLD:3 Merge Calls");
- PhoneUtils.mergeCalls();
- return true;
- } else if (state == CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
- // State is CONF_CALL already and we are getting a merge call
- // This can happen when CONF_CALL was entered from a Call Waiting
- // TODO(BT)
- return false;
- }
- Log.e(TAG, "GSG no call to add conference");
- return false;
- } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
- if (mCM.hasActiveFgCall() && mCM.hasActiveBgCall()) {
- PhoneUtils.mergeCalls();
- return true;
- } else {
- Log.e(TAG, "GSG no call to merge");
- return false;
- }
- } else {
- Log.e(TAG, "Unexpected phone type: " + phoneType);
- return false;
- }
- } else {
- Log.e(TAG, "bad CHLD value: " + chld);
- return false;
- }
- }
-
- public String getNetworkOperator() {
- enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
- return mCM.getDefaultPhone().getServiceState().getOperatorAlphaLong();
- }
-
- public String getSubscriberNumber() {
- enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
- return mCM.getDefaultPhone().getLine1Number();
- }
-
- public boolean listCurrentCalls() {
- enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
- Message msg = Message.obtain(mHandler, LIST_CURRENT_CALLS);
- mHandler.sendMessage(msg);
- return true;
- }
-
- public boolean queryPhoneState() {
- enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
- Message msg = Message.obtain(mHandler, QUERY_PHONE_STATE);
- mHandler.sendMessage(msg);
- return true;
- }
-
- public void updateBtHandsfreeAfterRadioTechnologyChange() {
- enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
- if (VDBG) Log.d(TAG, "updateBtHandsfreeAfterRadioTechnologyChange...");
- updateBtPhoneStateAfterRadioTechnologyChange();
- }
-
- public void cdmaSwapSecondCallState() {
- enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
- Message msg = Message.obtain(mHandler, CDMA_SWAP_SECOND_CALL_STATE);
- mHandler.sendMessage(msg);
- }
-
- public void cdmaSetSecondCallState(boolean state) {
- enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
- Message msg = mHandler.obtainMessage(CDMA_SET_SECOND_CALL_STATE, state);
- mHandler.sendMessage(msg);
- }
- };
-
- // match up with bthf_call_state_t of bt_hf.h
- final static int CALL_STATE_ACTIVE = 0;
- final static int CALL_STATE_HELD = 1;
- final static int CALL_STATE_DIALING = 2;
- final static int CALL_STATE_ALERTING = 3;
- final static int CALL_STATE_INCOMING = 4;
- final static int CALL_STATE_WAITING = 5;
- final static int CALL_STATE_IDLE = 6;
-
- // match up with bthf_chld_type_t of bt_hf.h
- final static int CHLD_TYPE_RELEASEHELD = 0;
- final static int CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD = 1;
- final static int CHLD_TYPE_HOLDACTIVE_ACCEPTHELD = 2;
- final static int CHLD_TYPE_ADDHELDTOCONF = 3;
-
- /* Convert telephony phone call state into hf hal call state */
- static int convertCallState(Call.State ringingState, Call.State foregroundState) {
- int retval = CALL_STATE_IDLE;
-
- if ((ringingState == Call.State.INCOMING) ||
- (ringingState == Call.State.WAITING) )
- retval = CALL_STATE_INCOMING;
- else if (foregroundState == Call.State.DIALING)
- retval = CALL_STATE_DIALING;
- else if (foregroundState == Call.State.ALERTING)
- retval = CALL_STATE_ALERTING;
- else
- retval = CALL_STATE_IDLE;
-
- if (VDBG) {
- Log.v(TAG, "Call state Converted2: " + ringingState + "/" + foregroundState + " -> " +
- retval);
- }
- return retval;
- }
-
- static int convertCallState(Call.State callState) {
- int retval = CALL_STATE_IDLE;
-
- switch (callState) {
- case IDLE:
- case DISCONNECTED:
- case DISCONNECTING:
- retval = CALL_STATE_IDLE;
- break;
- case ACTIVE:
- retval = CALL_STATE_ACTIVE;
- break;
- case HOLDING:
- retval = CALL_STATE_HELD;
- break;
- case DIALING:
- retval = CALL_STATE_DIALING;
- break;
- case ALERTING:
- retval = CALL_STATE_ALERTING;
- break;
- case INCOMING:
- retval = CALL_STATE_INCOMING;
- break;
- case WAITING:
- retval = CALL_STATE_WAITING;
- break;
- default:
- Log.e(TAG, "bad call state: " + callState);
- retval = CALL_STATE_IDLE;
- break;
- }
-
- if (VDBG) {
- Log.v(TAG, "Call state Converted2: " + callState + " -> " + retval);
- }
-
- return retval;
- }
-
- private static void log(String msg) {
- Log.d(TAG, msg);
- }
-}
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index b2e1332..4dd8ee2 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -143,7 +143,6 @@
private BluetoothManager bluetoothManager;
private CallGatewayManager callGatewayManager;
private CallStateMonitor callStateMonitor;
- private IBluetoothHeadsetPhone mBluetoothPhone;
static int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
static boolean sVoiceCapable = true;
@@ -350,17 +349,6 @@
cdmaPhoneCallState.CdmaPhoneCallStateInit();
}
- if (BluetoothAdapter.getDefaultAdapter() != null) {
- // Start BluetoothPhoneService even if device is not voice capable.
- // The device can still support VOIP.
- startService(new Intent(this, BluetoothPhoneService.class));
- bindService(new Intent(this, BluetoothPhoneService.class),
- mBluetoothPhoneConnection, 0);
- } else {
- // Device is not bluetooth capable
- mBluetoothPhone = null;
- }
-
// before registering for phone state changes
mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
mWakeLock = mPowerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, LOG_TAG);
@@ -499,10 +487,6 @@
return getInstance().phone;
}
- IBluetoothHeadsetPhone getBluetoothPhoneService() {
- return mBluetoothPhone;
- }
-
/* package */ BluetoothManager getBluetoothManager() {
return bluetoothManager;
}
@@ -797,14 +781,6 @@
notifier.updateCallNotifierRegistrationsAfterRadioTechnologyChange();
callStateMonitor.updateAfterRadioTechnologyChange();
- if (mBluetoothPhone != null) {
- try {
- mBluetoothPhone.updateBtHandsfreeAfterRadioTechnologyChange();
- } catch (RemoteException e) {
- Log.e(LOG_TAG, Log.getStackTraceString(new Throwable()));
- }
- }
-
// Update registration for ICC status after radio technology change
IccCard sim = phone.getIccCard();
if (sim != null) {
@@ -967,21 +943,4 @@
* Used to determine if the preserved call origin is fresh enough.
*/
private static final long CALL_ORIGIN_EXPIRATION_MILLIS = 30 * 1000;
-
- /** Service connection */
- private final ServiceConnection mBluetoothPhoneConnection = new ServiceConnection() {
-
- /** Handle the task of binding the local object to the service */
- public void onServiceConnected(ComponentName className, IBinder service) {
- Log.i(LOG_TAG, "Headset phone created, binding local service.");
- mBluetoothPhone = IBluetoothHeadsetPhone.Stub.asInterface(service);
- }
-
- /** Handle the task of cleaning up the local binding */
- public void onServiceDisconnected(ComponentName className) {
- Log.i(LOG_TAG, "Headset phone disconnected, cleaning local binding.");
- mBluetoothPhone = null;
- }
- };
-
}
diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java
index fa3d18b..56d26c9 100644
--- a/src/com/android/phone/PhoneUtils.java
+++ b/src/com/android/phone/PhoneUtils.java
@@ -227,19 +227,7 @@
// should be allowed to add another call in case one of the parties
// drops off
app.cdmaPhoneCallState.setAddCallMenuStateAfterCallWaiting(true);
-
- // If a BluetoothPhoneService is valid we need to set the second call state
- // so that the Bluetooth client can update the Call state correctly when
- // a call waiting is answered from the Phone.
- btPhone = app.getBluetoothPhoneService();
- if (btPhone != null) {
- try {
- btPhone.cdmaSetSecondCallState(true);
- } catch (RemoteException e) {
- Log.e(LOG_TAG, Log.getStackTraceString(new Throwable()));
- }
- }
- }
+ }
}
final boolean isRealIncomingCall = isRealIncomingCall(ringingCall.getState());
@@ -737,20 +725,6 @@
// In the future we may provide some way for user to choose among
// multiple background calls, for now, always act on the first background call.
PhoneUtils.switchHoldingAndActive(mApp.mCM.getFirstActiveBgCall());
-
- // If we have a valid BluetoothPhoneService then since CDMA network or
- // Telephony FW does not send us information on which caller got swapped
- // we need to update the second call active state in BluetoothPhoneService internally
- if (mApp.mCM.getBgPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
- final IBluetoothHeadsetPhone btPhone = mApp.getBluetoothPhoneService();
- if (btPhone != null) {
- try {
- btPhone.cdmaSwapSecondCallState();
- } catch (RemoteException e) {
- Log.e(LOG_TAG, Log.getStackTraceString(new Throwable()));
- }
- }
- }
}
/**