diff options
author | Srinivas Visvanathan <sriniv@google.com> | 2017-04-17 16:57:51 -0700 |
---|---|---|
committer | Srinivas Visvanathan <sriniv@google.com> | 2017-04-18 10:45:22 -0700 |
commit | de4cf995d62280d139c05a9639832a9bf781b480 (patch) | |
tree | 13f19b47451e5c54ef86a67b7dcadc013f74ea98 | |
parent | 42fd6617649dc6bdd9df6f36fc00cdef716a5002 (diff) | |
download | Dialer-de4cf995d62280d139c05a9639832a9bf781b480.tar.gz |
Killing CallList + crash fix
- Replacing UiCallList and subclass with simple HashMap in
TelecomUiCallManager. TelecomUiCallManager.getOrCreateCallContainer
now does simple map search. Removed synchronization since callbacks
from InCallServiceImpl are on main thread AFAICT; double-checked with
logging.
- OngoingCallFragment crash fix: Don't unset uiBluetoothMonitor since
the fragment object can be re-used by TelecomActivity for next call.
TelecomActivity only passes uiBluetoothMonitor the first time after
construction.
- Fixing UiCall.disconnectClause -> UiCall.disconnectCause.
Bug: 37251324
Test: Made test calls, incoming, outgoing, conference.
Change-Id: I63f24cc9793b4b2c4547146a836205413f106c83
5 files changed, 74 insertions, 194 deletions
diff --git a/src/com/android/car/dialer/OngoingCallFragment.java b/src/com/android/car/dialer/OngoingCallFragment.java index 9c322412..2eb659e2 100644 --- a/src/com/android/car/dialer/OngoingCallFragment.java +++ b/src/com/android/car/dialer/OngoingCallFragment.java @@ -125,7 +125,6 @@ public class OngoingCallFragment extends Fragment { mHandler = null; mUiCallManager = null; mLoadedNumber = null; - mUiBluetoothMonitor = null; } @Override @@ -297,7 +296,7 @@ public class OngoingCallFragment extends Fragment { // Toggle the visibility between the active call controls, ringing call controls, // and no controls. CharSequence disconnectCauseLabel = mLastRemovedCall == null ? - null : mLastRemovedCall.getDisconnectClause(); + null : mLastRemovedCall.getDisconnectCause(); if (mPrimaryCall == null && !TextUtils.isEmpty(disconnectCauseLabel)) { closeDialpad(); setStateText(disconnectCauseLabel); diff --git a/src/com/android/car/dialer/telecom/UiCall.java b/src/com/android/car/dialer/telecom/UiCall.java index 523d893d..7b98c649 100644 --- a/src/com/android/car/dialer/telecom/UiCall.java +++ b/src/com/android/car/dialer/telecom/UiCall.java @@ -26,7 +26,7 @@ public class UiCall { private int mState; private boolean mHasParent; private String mNumber; - private CharSequence mDisconnectClause; + private CharSequence mDisconnectCause; private boolean mHasChildren; private Uri mGatewayInfoOriginalAddress; private long connectTimeMillis; @@ -71,12 +71,12 @@ public class UiCall { mNumber = number; } - public CharSequence getDisconnectClause() { - return mDisconnectClause; + public CharSequence getDisconnectCause() { + return mDisconnectCause; } - public void setDisconnectClause(CharSequence disconnectClause) { - mDisconnectClause = disconnectClause; + public void setDisconnectCause(CharSequence disconnectCause) { + mDisconnectCause = disconnectCause; } public Uri getGatewayInfoOriginalAddress() { diff --git a/src/com/android/car/dialer/telecom/UiCallList.java b/src/com/android/car/dialer/telecom/UiCallList.java deleted file mode 100644 index cb730f19..00000000 --- a/src/com/android/car/dialer/telecom/UiCallList.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2015 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.car.dialer.telecom; - -import android.support.v4.util.Pair; -import android.util.SparseArray; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Holds a list of {@link UiCall} and implements convenient mapping from underlying - * {@code Call} class to {@link UiCall}. - */ -public abstract class UiCallList<C> { - private Map<C, UiCall> mCallToCallInfoMap = new HashMap<>(); - private SparseArray<Pair<UiCall, C>> mIdToCallMap = new SparseArray<>(); - - /** - * Creates or gets existing {@code CallInfo} instance for a given key - */ - public UiCall getOrCreate(C call) { - if (call == null) { - return null; - } - UiCall uiCall = mCallToCallInfoMap.get(call); - if (uiCall == null) { - uiCall = createUiCall(call); - mCallToCallInfoMap.put(call, uiCall); - mIdToCallMap.append(uiCall.getId(), new Pair<>(uiCall, call)); - } - return uiCall; - } - - /** - * Returns a list of existing {@code CallInfo}. - */ - public List<UiCall> getCalls() { - return new ArrayList<>(mCallToCallInfoMap.values()); - } - - /** - * Clears a list. - */ - public void clearCalls() { - mCallToCallInfoMap.clear(); - mIdToCallMap.clear(); - } - - /** - * Removes {@code CallInfo} by given key. - */ - public void remove(UiCall uiCall) { - int callId = uiCall.getId(); - C call = getCall(callId); - if (mCallToCallInfoMap.containsKey(call)) { - mCallToCallInfoMap.remove(call); - } - mIdToCallMap.remove(callId); - } - - protected C getCall(int callId) { - return mIdToCallMap.get(callId).second; - } - - public UiCall getUiCall(int callId) { - return mIdToCallMap.get(callId).first; - } - - abstract protected UiCall createUiCall(C call); -} diff --git a/src/com/android/car/dialer/telecom/embedded/TelecomUiCallList.java b/src/com/android/car/dialer/telecom/embedded/TelecomUiCallList.java deleted file mode 100644 index 17e1df87..00000000 --- a/src/com/android/car/dialer/telecom/embedded/TelecomUiCallList.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2015 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.car.dialer.telecom.embedded; - -import com.android.car.dialer.telecom.UiCall; -import com.android.car.dialer.telecom.UiCallList; - -import android.telecom.Call; -import android.telecom.DisconnectCause; -import android.telecom.GatewayInfo; -import android.util.Log; - -/** - * Represents a list of {@link UiCall} for underlying {@link android.telecom.Call}. - */ -public class TelecomUiCallList extends UiCallList<Call> { - private final static String TAG = "Em.UiCallList"; - - private volatile static int nextCarPhoneCallId = 0; - - private int getNewCarPhoneCallId() { - return nextCarPhoneCallId++; - } - - @Override - protected UiCall createUiCall(Call telecomCall) { - int id = getNewCarPhoneCallId(); - - UiCall uiCall = new UiCall(id); - updateCallContainerFromTelecom(uiCall, telecomCall); - return uiCall; - } - - static void updateCallContainerFromTelecom(UiCall uiCall, Call telecomCall) { - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log.d(TAG, "updateCallContainerFromTelecom: call: " + uiCall + ", telecomCall: " - + telecomCall); - } - - uiCall.setState(telecomCall.getState()); - uiCall.setHasChildren(!telecomCall.getChildren().isEmpty()); - uiCall.setHasParent(telecomCall.getParent() != null); - - Call.Details details = telecomCall.getDetails(); - if (details != null) { - uiCall.setConnectTimeMillis(details.getConnectTimeMillis()); - - DisconnectCause cause = details.getDisconnectCause(); - CharSequence causeLabel = cause == null ? null : cause.getLabel(); - uiCall.setDisconnectClause(causeLabel == null ? null : causeLabel.toString()); - - GatewayInfo gatewayInfo = details.getGatewayInfo(); - uiCall.setGatewayInfoOriginalAddress( - gatewayInfo == null ? null : gatewayInfo.getOriginalAddress()); - - String number = ""; - if (gatewayInfo != null) { - number = gatewayInfo.getOriginalAddress().getSchemeSpecificPart(); - } else if (details.getHandle() != null) { - number = details.getHandle().getSchemeSpecificPart(); - } - uiCall.setNumber(number); - } - } - - public Call getTelecomCall(UiCall uiCall) { - return uiCall != null ? getCall(uiCall.getId()) : null; - } -} diff --git a/src/com/android/car/dialer/telecom/embedded/TelecomUiCallManager.java b/src/com/android/car/dialer/telecom/embedded/TelecomUiCallManager.java index f81dec32..357512f7 100644 --- a/src/com/android/car/dialer/telecom/embedded/TelecomUiCallManager.java +++ b/src/com/android/car/dialer/telecom/embedded/TelecomUiCallManager.java @@ -27,12 +27,17 @@ import android.os.IBinder; import android.telecom.Call; import android.telecom.Call.Details; import android.telecom.CallAudioState; +import android.telecom.DisconnectCause; +import android.telecom.GatewayInfo; import android.telecom.InCallService.VideoCall; import android.telecom.TelecomManager; import android.util.Log; import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; /** @@ -40,11 +45,14 @@ import java.util.concurrent.CopyOnWriteArrayList; */ public class TelecomUiCallManager extends UiCallManager { - private static final String TAG = "Em.TelecomMgrImpl"; + private static final String TAG = "Em.TelecomUiCallMgr"; + + // Used to assign id's to UiCall objects as they're created. + private static int nextCarPhoneCallId = 0; private TelecomManager mTelecomManager; private InCallServiceImpl mInCallService; - private TelecomUiCallList mCallList = new TelecomUiCallList(); + private Map<UiCall, Call> mCallMapping = new HashMap<>(); private List<CallListener> mCallListeners = new CopyOnWriteArrayList<>(); @@ -62,7 +70,7 @@ public class TelecomUiCallManager extends UiCallManager { mContext.unbindService(mInCallServiceConnection); mInCallService = null; } - mCallList.clearCalls(); + mCallMapping.clear(); } @Override @@ -97,7 +105,7 @@ public class TelecomUiCallManager extends UiCallManager { Log.d(TAG, "answerCall: " + uiCall); } - Call telecomCall = mCallList.getTelecomCall(uiCall); + Call telecomCall = mCallMapping.get(uiCall); if (telecomCall != null) { telecomCall.answer(0); } @@ -110,7 +118,7 @@ public class TelecomUiCallManager extends UiCallManager { + "textMessage: " + textMessage); } - Call telecomCall = mCallList.getTelecomCall(uiCall); + Call telecomCall = mCallMapping.get(uiCall); if (telecomCall != null) { telecomCall.reject(rejectWithMessage, textMessage); } @@ -122,7 +130,7 @@ public class TelecomUiCallManager extends UiCallManager { Log.d(TAG, "disconnectCall: " + uiCall); } - Call telecomCall = mCallList.getTelecomCall(uiCall); + Call telecomCall = mCallMapping.get(uiCall); if (telecomCall != null) { telecomCall.disconnect(); } @@ -130,7 +138,7 @@ public class TelecomUiCallManager extends UiCallManager { @Override public List<UiCall> getCalls() { - return mCallList.getCalls(); + return new ArrayList<>(mCallMapping.keySet()); } @Override @@ -189,7 +197,7 @@ public class TelecomUiCallManager extends UiCallManager { Log.d(TAG, "holdCall: " + uiCall); } - Call telecomCall = mCallList.getTelecomCall(uiCall); + Call telecomCall = mCallMapping.get(uiCall); if (telecomCall != null) { telecomCall.hold(); } @@ -201,7 +209,7 @@ public class TelecomUiCallManager extends UiCallManager { Log.d(TAG, "unholdCall: " + uiCall); } - Call telecomCall = mCallList.getTelecomCall(uiCall); + Call telecomCall = mCallMapping.get(uiCall); if (telecomCall != null) { telecomCall.unhold(); } @@ -213,7 +221,7 @@ public class TelecomUiCallManager extends UiCallManager { Log.d(TAG, "playDtmfTone: call: " + uiCall + ", digit: " + digit); } - Call telecomCall = mCallList.getTelecomCall(uiCall); + Call telecomCall = mCallMapping.get(uiCall); if (telecomCall != null) { telecomCall.playDtmfTone(digit); } @@ -225,7 +233,7 @@ public class TelecomUiCallManager extends UiCallManager { Log.d(TAG, "stopDtmfTone: call: " + uiCall); } - Call telecomCall = mCallList.getTelecomCall(uiCall); + Call telecomCall = mCallMapping.get(uiCall); if (telecomCall != null) { telecomCall.stopDtmfTone(); } @@ -237,7 +245,7 @@ public class TelecomUiCallManager extends UiCallManager { Log.d(TAG, "postDialContinue: call: " + uiCall + ", proceed: " + proceed); } - Call telecomCall = mCallList.getTelecomCall(uiCall); + Call telecomCall = mCallMapping.get(uiCall); if (telecomCall != null) { telecomCall.postDialContinue(proceed); } @@ -249,8 +257,8 @@ public class TelecomUiCallManager extends UiCallManager { Log.d(TAG, "conference: call: " + uiCall + ", otherCall: " + otherUiCall); } - Call telecomCall = mCallList.getTelecomCall(uiCall); - Call otherTelecomCall = mCallList.getTelecomCall(otherUiCall); + Call telecomCall = mCallMapping.get(uiCall); + Call otherTelecomCall = mCallMapping.get(otherUiCall); if (telecomCall != null) { telecomCall.conference(otherTelecomCall); } @@ -262,7 +270,7 @@ public class TelecomUiCallManager extends UiCallManager { Log.d(TAG, "splitFromConference: call: " + uiCall); } - Call telecomCall = mCallList.getTelecomCall(uiCall); + Call telecomCall = mCallMapping.get(uiCall); if (telecomCall != null) { telecomCall.splitFromConference(); } @@ -292,7 +300,7 @@ public class TelecomUiCallManager extends UiCallManager { private void doTelecomCallRemoved(Call telecomCall) { UiCall uiCall = getOrCreateCallContainer(telecomCall); - mCallList.remove(uiCall); + mCallMapping.remove(uiCall); for (CallListener listener : mCallListeners) { listener.onCallRemoved(uiCall); @@ -377,7 +385,7 @@ public class TelecomUiCallManager extends UiCallManager { TelecomUiCallManager manager = mCarTelecomMangerRef.get(); UiCall uiCall = mCallContainerRef.get(); if (manager != null && uiCall != null) { - TelecomUiCallList.updateCallContainerFromTelecom(uiCall, telecomCall); + updateCallContainerFromTelecom(uiCall, telecomCall); manager.onCallUpdated(uiCall); } } @@ -430,9 +438,50 @@ public class TelecomUiCallManager extends UiCallManager { }; private UiCall getOrCreateCallContainer(Call telecomCall) { - synchronized (mCallList) { - return mCallList.getOrCreate(telecomCall); + for (Map.Entry<UiCall, Call> entry : mCallMapping.entrySet()) { + if (entry.getValue() == telecomCall) { + return entry.getKey(); + } + } + + UiCall uiCall = new UiCall(nextCarPhoneCallId++); + updateCallContainerFromTelecom(uiCall, telecomCall); + mCallMapping.put(uiCall, telecomCall); + return uiCall; + } + + private static void updateCallContainerFromTelecom(UiCall uiCall, Call telecomCall) { + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "updateCallContainerFromTelecom: call: " + uiCall + ", telecomCall: " + + telecomCall); + } + + uiCall.setState(telecomCall.getState()); + uiCall.setHasChildren(!telecomCall.getChildren().isEmpty()); + uiCall.setHasParent(telecomCall.getParent() != null); + + Call.Details details = telecomCall.getDetails(); + if (details == null) { + return; } + + uiCall.setConnectTimeMillis(details.getConnectTimeMillis()); + + DisconnectCause cause = details.getDisconnectCause(); + uiCall.setDisconnectCause(cause == null ? null : cause.getLabel()); + + GatewayInfo gatewayInfo = details.getGatewayInfo(); + uiCall.setGatewayInfoOriginalAddress( + gatewayInfo == null ? null : gatewayInfo.getOriginalAddress()); + + String number = ""; + if (gatewayInfo != null) { + number = gatewayInfo.getOriginalAddress().getSchemeSpecificPart(); + } else if (details.getHandle() != null) { + number = details.getHandle().getSchemeSpecificPart(); + } + uiCall.setNumber(number); + } private CallAudioState getCallAudioStateOrNull() { |