diff options
author | Andrew Lee <anwlee@google.com> | 2015-04-23 15:47:06 -0700 |
---|---|---|
committer | Andrew Lee <anwlee@google.com> | 2015-04-30 15:24:50 -0700 |
commit | 011728fc3a4368b601844d225d1f37bf48ea5735 (patch) | |
tree | d5cc5259d91e3d1ef5647a60c0ed2e7655e29857 /telecomm/java | |
parent | 24863faa05dc8934f790e13f8cf153c0edb4a32a (diff) | |
download | frameworks_base-011728fc3a4368b601844d225d1f37bf48ea5735.zip frameworks_base-011728fc3a4368b601844d225d1f37bf48ea5735.tar.gz frameworks_base-011728fc3a4368b601844d225d1f37bf48ea5735.tar.bz2 |
Add handler parameter for callbacks.
Bug: 20160491
Change-Id: I94639b06b8c97b6585e169d667a67ce328e716af
Diffstat (limited to 'telecomm/java')
-rw-r--r-- | telecomm/java/android/telecom/Call.java | 139 | ||||
-rw-r--r-- | telecomm/java/android/telecom/CallbackRecord.java | 44 | ||||
-rw-r--r-- | telecomm/java/android/telecom/InCallService.java | 13 | ||||
-rw-r--r-- | telecomm/java/android/telecom/Phone.java | 4 | ||||
-rw-r--r-- | telecomm/java/android/telecom/RemoteConference.java | 112 | ||||
-rw-r--r-- | telecomm/java/android/telecom/RemoteConnection.java | 244 | ||||
-rw-r--r-- | telecomm/java/android/telecom/VideoCallImpl.java | 62 |
7 files changed, 497 insertions, 121 deletions
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java index d92c0c7..9273939 100644 --- a/telecomm/java/android/telecom/Call.java +++ b/telecomm/java/android/telecom/Call.java @@ -19,10 +19,12 @@ package android.telecom; import android.annotation.SystemApi; import android.net.Uri; import android.os.Bundle; +import android.os.Handler; import java.lang.String; import java.util.ArrayList; import java.util.Collections; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Objects; @@ -608,7 +610,7 @@ public final class Call { private final List<String> mChildrenIds = new ArrayList<>(); private final List<Call> mChildren = new ArrayList<>(); private final List<Call> mUnmodifiableChildren = Collections.unmodifiableList(mChildren); - private final List<Callback> mCallbacks = new CopyOnWriteArrayList<>(); + private final List<CallbackRecord<Callback>> mCallbackRecords = new CopyOnWriteArrayList<>(); private final List<Call> mConferenceableCalls = new ArrayList<>(); private final List<Call> mUnmodifiableConferenceableCalls = Collections.unmodifiableList(mConferenceableCalls); @@ -850,7 +852,20 @@ public final class Call { * @param callback A {@code Callback}. */ public void registerCallback(Callback callback) { - mCallbacks.add(callback); + registerCallback(callback, new Handler()); + } + + /** + * Registers a callback to this {@code Call}. + * + * @param callback A {@code Callback}. + * @param handler A handler which command and status changes will be delivered to. + */ + public void registerCallback(Callback callback, Handler handler) { + unregisterCallback(callback); + if (callback != null && handler != null) { + mCallbackRecords.add(new CallbackRecord<Callback>(callback, handler)); + } } /** @@ -860,7 +875,12 @@ public final class Call { */ public void unregisterCallback(Callback callback) { if (callback != null) { - mCallbacks.remove(callback); + for (CallbackRecord<Callback> record : mCallbackRecords) { + if (record.getCallback() == callback) { + mCallbackRecords.remove(record); + break; + } + } } } @@ -1021,57 +1041,120 @@ public final class Call { } } - private void fireStateChanged(int newState) { - for (Callback callback : mCallbacks) { - callback.onStateChanged(this, newState); + private void fireStateChanged(final int newState) { + for (CallbackRecord<Callback> record : mCallbackRecords) { + final Call call = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onStateChanged(call, newState); + } + }); } } - private void fireParentChanged(Call newParent) { - for (Callback callback : mCallbacks) { - callback.onParentChanged(this, newParent); + private void fireParentChanged(final Call newParent) { + for (CallbackRecord<Callback> record : mCallbackRecords) { + final Call call = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onParentChanged(call, newParent); + } + }); } } - private void fireChildrenChanged(List<Call> children) { - for (Callback callback : mCallbacks) { - callback.onChildrenChanged(this, children); + private void fireChildrenChanged(final List<Call> children) { + for (CallbackRecord<Callback> record : mCallbackRecords) { + final Call call = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onChildrenChanged(call, children); + } + }); } } - private void fireDetailsChanged(Details details) { - for (Callback callback : mCallbacks) { - callback.onDetailsChanged(this, details); + private void fireDetailsChanged(final Details details) { + for (CallbackRecord<Callback> record : mCallbackRecords) { + final Call call = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onDetailsChanged(call, details); + } + }); } } - private void fireCannedTextResponsesLoaded(List<String> cannedTextResponses) { - for (Callback callback : mCallbacks) { - callback.onCannedTextResponsesLoaded(this, cannedTextResponses); + private void fireCannedTextResponsesLoaded(final List<String> cannedTextResponses) { + for (CallbackRecord<Callback> record : mCallbackRecords) { + final Call call = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onCannedTextResponsesLoaded(call, cannedTextResponses); + } + }); } } - private void fireVideoCallChanged(InCallService.VideoCall videoCall) { - for (Callback callback : mCallbacks) { - callback.onVideoCallChanged(this, videoCall); + private void fireVideoCallChanged(final InCallService.VideoCall videoCall) { + for (CallbackRecord<Callback> record : mCallbackRecords) { + final Call call = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onVideoCallChanged(call, videoCall); + } + }); } } - private void firePostDialWait(String remainingPostDialSequence) { - for (Callback callback : mCallbacks) { - callback.onPostDialWait(this, remainingPostDialSequence); + private void firePostDialWait(final String remainingPostDialSequence) { + for (CallbackRecord<Callback> record : mCallbackRecords) { + final Call call = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onPostDialWait(call, remainingPostDialSequence); + } + }); } } private void fireCallDestroyed() { - for (Callback callback : mCallbacks) { - callback.onCallDestroyed(this); + for (CallbackRecord<Callback> record: mCallbackRecords) { + final Call call = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onCallDestroyed(call); + } + }); } } private void fireConferenceableCallsChanged() { - for (Callback callback : mCallbacks) { - callback.onConferenceableCallsChanged(this, mUnmodifiableConferenceableCalls); + for (CallbackRecord<Callback> record : mCallbackRecords) { + final Call call = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onConferenceableCallsChanged(call, mUnmodifiableConferenceableCalls); + } + }); } } } diff --git a/telecomm/java/android/telecom/CallbackRecord.java b/telecomm/java/android/telecom/CallbackRecord.java new file mode 100644 index 0000000..1a81925 --- /dev/null +++ b/telecomm/java/android/telecom/CallbackRecord.java @@ -0,0 +1,44 @@ +/* + * 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 android.telecom; + +import android.os.Handler; + + +/** + * This class is used to associate a generic callback of type T with a handler to which commands and + * status updates will be delivered to. + * + * @hide + */ +class CallbackRecord<T> { + private final T mCallback; + private final Handler mHandler; + + public CallbackRecord(T callback, Handler handler) { + mCallback = callback; + mHandler = handler; + } + + public T getCallback() { + return mCallback; + } + + public Handler getHandler() { + return mHandler; + } +} diff --git a/telecomm/java/android/telecom/InCallService.java b/telecomm/java/android/telecom/InCallService.java index 2c8415a..3cb4e87 100644 --- a/telecomm/java/android/telecom/InCallService.java +++ b/telecomm/java/android/telecom/InCallService.java @@ -362,6 +362,9 @@ public abstract class InCallService extends Service { */ public static abstract class VideoCall { + /** @hide */ + public abstract void destroy(); + /** * Registers a callback to receive commands and state changes for video calls. * @@ -370,9 +373,17 @@ public abstract class InCallService extends Service { public abstract void registerCallback(VideoCall.Callback callback); /** + * Registers a callback to receive commands and state changes for video calls. + * + * @param callback The video call callback. + * @param handler A handler which commands and status changes will be delivered to. + */ + public abstract void registerCallback(VideoCall.Callback callback, Handler handler); + + /** * Clears the video call listener set via {@link #registerCallback}. */ - public abstract void unregisterCallback(); + public abstract void unregisterCallback(VideoCall.Callback callback); /** * Sets the camera to be used for video recording in a video call. diff --git a/telecomm/java/android/telecom/Phone.java b/telecomm/java/android/telecom/Phone.java index 3d9acda..4cdfd2e 100644 --- a/telecomm/java/android/telecom/Phone.java +++ b/telecomm/java/android/telecom/Phone.java @@ -125,7 +125,7 @@ public final class Phone { InCallService.VideoCall videoCall = call.getVideoCall(); if (videoCall != null) { - videoCall.unregisterCallback(); + videoCall.destroy(); } fireCallRemoved(call); } @@ -174,7 +174,7 @@ public final class Phone { for (Call call : mCalls) { InCallService.VideoCall videoCall = call.getVideoCall(); if (videoCall != null) { - videoCall.unregisterCallback(); + videoCall.destroy(); } if (call.getState() != Call.STATE_DISCONNECTED) { call.internalSetDisconnected(); diff --git a/telecomm/java/android/telecom/RemoteConference.java b/telecomm/java/android/telecom/RemoteConference.java index fba3ee3..a76bf59 100644 --- a/telecomm/java/android/telecom/RemoteConference.java +++ b/telecomm/java/android/telecom/RemoteConference.java @@ -18,6 +18,7 @@ package android.telecom; import com.android.internal.telecom.IConnectionService; +import android.os.Handler; import android.os.RemoteException; import java.util.ArrayList; @@ -49,7 +50,7 @@ public final class RemoteConference { private final String mId; private final IConnectionService mConnectionService; - private final Set<Callback> mCallbacks = new CopyOnWriteArraySet<>(); + private final Set<CallbackRecord<Callback>> mCallbackRecords = new CopyOnWriteArraySet<>(); private final List<RemoteConnection> mChildConnections = new CopyOnWriteArrayList<>(); private final List<RemoteConnection> mUnmodifiableChildConnections = Collections.unmodifiableList(mChildConnections); @@ -77,13 +78,20 @@ public final class RemoteConference { for (RemoteConnection connection : mChildConnections) { connection.setConference(null); } - for (Callback c : mCallbacks) { - c.onDestroyed(this); + for (CallbackRecord<Callback> record : mCallbackRecords) { + final RemoteConference conference = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onDestroyed(conference); + } + }); } } /** {@hide} */ - void setState(int newState) { + void setState(final int newState) { if (newState != Connection.STATE_ACTIVE && newState != Connection.STATE_HOLDING && newState != Connection.STATE_DISCONNECTED) { @@ -93,42 +101,71 @@ public final class RemoteConference { } if (mState != newState) { - int oldState = mState; + final int oldState = mState; mState = newState; - for (Callback c : mCallbacks) { - c.onStateChanged(this, oldState, newState); + for (CallbackRecord<Callback> record : mCallbackRecords) { + final RemoteConference conference = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onStateChanged(conference, oldState, newState); + } + }); } } } /** {@hide} */ - void addConnection(RemoteConnection connection) { + void addConnection(final RemoteConnection connection) { if (!mChildConnections.contains(connection)) { mChildConnections.add(connection); connection.setConference(this); - for (Callback c : mCallbacks) { - c.onConnectionAdded(this, connection); + for (CallbackRecord<Callback> record : mCallbackRecords) { + final RemoteConference conference = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onConnectionAdded(conference, connection); + } + }); } } } /** {@hide} */ - void removeConnection(RemoteConnection connection) { + void removeConnection(final RemoteConnection connection) { if (mChildConnections.contains(connection)) { mChildConnections.remove(connection); connection.setConference(null); - for (Callback c : mCallbacks) { - c.onConnectionRemoved(this, connection); + for (CallbackRecord<Callback> record : mCallbackRecords) { + final RemoteConference conference = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onConnectionRemoved(conference, connection); + } + }); } } } /** {@hide} */ - void setConnectionCapabilities(int connectionCapabilities) { + void setConnectionCapabilities(final int connectionCapabilities) { if (mConnectionCapabilities != connectionCapabilities) { mConnectionCapabilities = connectionCapabilities; - for (Callback c : mCallbacks) { - c.onConnectionCapabilitiesChanged(this, mConnectionCapabilities); + for (CallbackRecord<Callback> record : mCallbackRecords) { + final RemoteConference conference = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onConnectionCapabilitiesChanged( + conference, mConnectionCapabilities); + } + }); } } } @@ -137,18 +174,33 @@ public final class RemoteConference { void setConferenceableConnections(List<RemoteConnection> conferenceableConnections) { mConferenceableConnections.clear(); mConferenceableConnections.addAll(conferenceableConnections); - for (Callback c : mCallbacks) { - c.onConferenceableConnectionsChanged(this, mUnmodifiableConferenceableConnections); + for (CallbackRecord<Callback> record : mCallbackRecords) { + final RemoteConference conference = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onConferenceableConnectionsChanged( + conference, mUnmodifiableConferenceableConnections); + } + }); } } /** {@hide} */ - void setDisconnected(DisconnectCause disconnectCause) { + void setDisconnected(final DisconnectCause disconnectCause) { if (mState != Connection.STATE_DISCONNECTED) { mDisconnectCause = disconnectCause; setState(Connection.STATE_DISCONNECTED); - for (Callback c : mCallbacks) { - c.onDisconnected(this, disconnectCause); + for (CallbackRecord<Callback> record : mCallbackRecords) { + final RemoteConference conference = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onDisconnected(conference, disconnectCause); + } + }); } } } @@ -239,10 +291,24 @@ public final class RemoteConference { } public final void registerCallback(Callback callback) { - mCallbacks.add(callback); + registerCallback(callback, new Handler()); + } + + public final void registerCallback(Callback callback, Handler handler) { + unregisterCallback(callback); + if (callback != null && handler != null) { + mCallbackRecords.add(new CallbackRecord(callback, handler)); + } } public final void unregisterCallback(Callback callback) { - mCallbacks.remove(callback); + if (callback != null) { + for (CallbackRecord<Callback> record : mCallbackRecords) { + if (record.getCallback() == callback) { + mCallbackRecords.remove(record); + break; + } + } + } } } diff --git a/telecomm/java/android/telecom/RemoteConnection.java b/telecomm/java/android/telecom/RemoteConnection.java index 4ecfd50..1493b20 100644 --- a/telecomm/java/android/telecom/RemoteConnection.java +++ b/telecomm/java/android/telecom/RemoteConnection.java @@ -21,6 +21,7 @@ import com.android.internal.telecom.IVideoCallback; import com.android.internal.telecom.IVideoProvider; import android.net.Uri; +import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.view.Surface; @@ -392,8 +393,8 @@ public final class RemoteConnection { * load factor before resizing, 1 means we only expect a single thread to * access the map so make only a single shard */ - private final Set<Callback> mCallbacks = Collections.newSetFromMap( - new ConcurrentHashMap<Callback, Boolean>(8, 0.9f, 1)); + private final Set<CallbackRecord> mCallbackRecords = Collections.newSetFromMap( + new ConcurrentHashMap<CallbackRecord, Boolean>(8, 0.9f, 1)); private final List<RemoteConnection> mConferenceableConnections = new ArrayList<>(); private final List<RemoteConnection> mUnmodifiableconferenceableConnections = Collections.unmodifiableList(mConferenceableConnections); @@ -470,7 +471,20 @@ public final class RemoteConnection { * @param callback A {@code Callback}. */ public void registerCallback(Callback callback) { - mCallbacks.add(callback); + registerCallback(callback, new Handler()); + } + + /** + * Adds a callback to this {@code RemoteConnection}. + * + * @param callback A {@code Callback}. + * @param handler A {@code Handler} which command and status changes will be delivered to. + */ + public void registerCallback(Callback callback, Handler handler) { + unregisterCallback(callback); + if (callback != null && handler != null) { + mCallbackRecords.add(new CallbackRecord(callback, handler)); + } } /** @@ -480,7 +494,12 @@ public final class RemoteConnection { */ public void unregisterCallback(Callback callback) { if (callback != null) { - mCallbacks.remove(callback); + for (CallbackRecord record : mCallbackRecords) { + if (record.getCallback() == callback) { + mCallbackRecords.remove(record); + break; + } + } } } @@ -800,11 +819,18 @@ public final class RemoteConnection { /** * @hide */ - void setState(int state) { + void setState(final int state) { if (mState != state) { mState = state; - for (Callback c: mCallbacks) { - c.onStateChanged(this, state); + for (CallbackRecord record: mCallbackRecords) { + final RemoteConnection connection = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onStateChanged(connection, state); + } + }); } } } @@ -812,13 +838,20 @@ public final class RemoteConnection { /** * @hide */ - void setDisconnected(DisconnectCause disconnectCause) { + void setDisconnected(final DisconnectCause disconnectCause) { if (mState != Connection.STATE_DISCONNECTED) { mState = Connection.STATE_DISCONNECTED; mDisconnectCause = disconnectCause; - for (Callback c : mCallbacks) { - c.onDisconnected(this, mDisconnectCause); + for (CallbackRecord record : mCallbackRecords) { + final RemoteConnection connection = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onDisconnected(connection, disconnectCause); + } + }); } } } @@ -826,11 +859,18 @@ public final class RemoteConnection { /** * @hide */ - void setRingbackRequested(boolean ringback) { + void setRingbackRequested(final boolean ringback) { if (mRingbackRequested != ringback) { mRingbackRequested = ringback; - for (Callback c : mCallbacks) { - c.onRingbackRequested(this, ringback); + for (CallbackRecord record : mCallbackRecords) { + final RemoteConnection connection = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onRingbackRequested(connection, ringback); + } + }); } } } @@ -838,10 +878,17 @@ public final class RemoteConnection { /** * @hide */ - void setConnectionCapabilities(int connectionCapabilities) { + void setConnectionCapabilities(final int connectionCapabilities) { mConnectionCapabilities = connectionCapabilities; - for (Callback c : mCallbacks) { - c.onConnectionCapabilitiesChanged(this, connectionCapabilities); + for (CallbackRecord record : mCallbackRecords) { + final RemoteConnection connection = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onConnectionCapabilitiesChanged(connection, connectionCapabilities); + } + }); } } @@ -849,17 +896,24 @@ public final class RemoteConnection { * @hide */ void setDestroyed() { - if (!mCallbacks.isEmpty()) { + if (!mCallbackRecords.isEmpty()) { // Make sure that the callbacks are notified that the call is destroyed first. if (mState != Connection.STATE_DISCONNECTED) { setDisconnected( new DisconnectCause(DisconnectCause.ERROR, "Connection destroyed.")); } - for (Callback c : mCallbacks) { - c.onDestroyed(this); + for (CallbackRecord record : mCallbackRecords) { + final RemoteConnection connection = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onDestroyed(connection); + } + }); } - mCallbacks.clear(); + mCallbackRecords.clear(); mConnected = false; } @@ -868,90 +922,162 @@ public final class RemoteConnection { /** * @hide */ - void setPostDialWait(String remainingDigits) { - for (Callback c : mCallbacks) { - c.onPostDialWait(this, remainingDigits); + void setPostDialWait(final String remainingDigits) { + for (CallbackRecord record : mCallbackRecords) { + final RemoteConnection connection = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onPostDialWait(connection, remainingDigits); + } + }); } } /** * @hide */ - void onPostDialChar(char nextChar) { - for (Callback c : mCallbacks) { - c.onPostDialChar(this, nextChar); + void onPostDialChar(final char nextChar) { + for (CallbackRecord record : mCallbackRecords) { + final RemoteConnection connection = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onPostDialWait(connection, String.valueOf(nextChar)); + } + }); } } /** * @hide */ - void setVideoState(int videoState) { + void setVideoState(final int videoState) { mVideoState = videoState; - for (Callback c : mCallbacks) { - c.onVideoStateChanged(this, videoState); + for (CallbackRecord record : mCallbackRecords) { + final RemoteConnection connection = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onVideoStateChanged(connection, videoState); + } + }); } } /** * @hide */ - void setVideoProvider(VideoProvider videoProvider) { + void setVideoProvider(final VideoProvider videoProvider) { mVideoProvider = videoProvider; - for (Callback c : mCallbacks) { - c.onVideoProviderChanged(this, videoProvider); + for (CallbackRecord record : mCallbackRecords) { + final RemoteConnection connection = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onVideoProviderChanged(connection, videoProvider); + } + }); } } /** @hide */ - void setIsVoipAudioMode(boolean isVoip) { + void setIsVoipAudioMode(final boolean isVoip) { mIsVoipAudioMode = isVoip; - for (Callback c : mCallbacks) { - c.onVoipAudioChanged(this, isVoip); + for (CallbackRecord record : mCallbackRecords) { + final RemoteConnection connection = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onVoipAudioChanged(connection, isVoip); + } + }); } } /** @hide */ - void setStatusHints(StatusHints statusHints) { + void setStatusHints(final StatusHints statusHints) { mStatusHints = statusHints; - for (Callback c : mCallbacks) { - c.onStatusHintsChanged(this, statusHints); + for (CallbackRecord record : mCallbackRecords) { + final RemoteConnection connection = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onStatusHintsChanged(connection, statusHints); + } + }); } } /** @hide */ - void setAddress(Uri address, int presentation) { + void setAddress(final Uri address, final int presentation) { mAddress = address; mAddressPresentation = presentation; - for (Callback c : mCallbacks) { - c.onAddressChanged(this, address, presentation); + for (CallbackRecord record : mCallbackRecords) { + final RemoteConnection connection = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onAddressChanged(connection, address, presentation); + } + }); } } /** @hide */ - void setCallerDisplayName(String callerDisplayName, int presentation) { + void setCallerDisplayName(final String callerDisplayName, final int presentation) { mCallerDisplayName = callerDisplayName; mCallerDisplayNamePresentation = presentation; - for (Callback c : mCallbacks) { - c.onCallerDisplayNameChanged(this, callerDisplayName, presentation); + for (CallbackRecord record : mCallbackRecords) { + final RemoteConnection connection = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onCallerDisplayNameChanged( + connection, callerDisplayName, presentation); + } + }); } } /** @hide */ - void setConferenceableConnections(List<RemoteConnection> conferenceableConnections) { + void setConferenceableConnections(final List<RemoteConnection> conferenceableConnections) { mConferenceableConnections.clear(); mConferenceableConnections.addAll(conferenceableConnections); - for (Callback c : mCallbacks) { - c.onConferenceableConnectionsChanged(this, mUnmodifiableconferenceableConnections); + for (CallbackRecord record : mCallbackRecords) { + final RemoteConnection connection = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onConferenceableConnectionsChanged( + connection, mUnmodifiableconferenceableConnections); + } + }); } } /** @hide */ - void setConference(RemoteConference conference) { + void setConference(final RemoteConference conference) { if (mConference != conference) { mConference = conference; - for (Callback c : mCallbacks) { - c.onConferenceChanged(this, conference); + for (CallbackRecord record : mCallbackRecords) { + final RemoteConnection connection = this; + final Callback callback = record.getCallback(); + record.getHandler().post(new Runnable() { + @Override + public void run() { + callback.onConferenceChanged(connection, conference); + } + }); } } } @@ -968,4 +1094,22 @@ public final class RemoteConnection { public static RemoteConnection failure(DisconnectCause disconnectCause) { return new RemoteConnection(disconnectCause); } + + private static final class CallbackRecord extends Callback { + private final Callback mCallback; + private final Handler mHandler; + + public CallbackRecord(Callback callback, Handler handler) { + mCallback = callback; + mHandler = handler; + } + + public Callback getCallback() { + return mCallback; + } + + public Handler getHandler() { + return mHandler; + } + } } diff --git a/telecomm/java/android/telecom/VideoCallImpl.java b/telecomm/java/android/telecom/VideoCallImpl.java index 3779d1a..7a82c1b 100644 --- a/telecomm/java/android/telecom/VideoCallImpl.java +++ b/telecomm/java/android/telecom/VideoCallImpl.java @@ -36,13 +36,6 @@ import com.android.internal.telecom.IVideoProvider; * {@hide} */ public class VideoCallImpl extends VideoCall { - private static final int MSG_RECEIVE_SESSION_MODIFY_REQUEST = 1; - private static final int MSG_RECEIVE_SESSION_MODIFY_RESPONSE = 2; - private static final int MSG_HANDLE_CALL_SESSION_EVENT = 3; - private static final int MSG_CHANGE_PEER_DIMENSIONS = 4; - private static final int MSG_CHANGE_CALL_DATA_USAGE = 5; - private static final int MSG_CHANGE_CAMERA_CAPABILITIES = 6; - private static final int MSG_CHANGE_VIDEO_QUALITY = 7; private final IVideoProvider mVideoProvider; private final VideoCallListenerBinder mBinder; @@ -61,7 +54,7 @@ public class VideoCallImpl extends VideoCall { private final class VideoCallListenerBinder extends IVideoCallback.Stub { @Override public void receiveSessionModifyRequest(VideoProfile videoProfile) { - mHandler.obtainMessage(MSG_RECEIVE_SESSION_MODIFY_REQUEST, + mHandler.obtainMessage(MessageHandler.MSG_RECEIVE_SESSION_MODIFY_REQUEST, videoProfile).sendToTarget(); } @@ -72,12 +65,14 @@ public class VideoCallImpl extends VideoCall { args.arg1 = status; args.arg2 = requestProfile; args.arg3 = responseProfile; - mHandler.obtainMessage(MSG_RECEIVE_SESSION_MODIFY_RESPONSE, args).sendToTarget(); + mHandler.obtainMessage(MessageHandler.MSG_RECEIVE_SESSION_MODIFY_RESPONSE, args) + .sendToTarget(); } @Override public void handleCallSessionEvent(int event) { - mHandler.obtainMessage(MSG_HANDLE_CALL_SESSION_EVENT, event).sendToTarget(); + mHandler.obtainMessage(MessageHandler.MSG_HANDLE_CALL_SESSION_EVENT, event) + .sendToTarget(); } @Override @@ -85,28 +80,42 @@ public class VideoCallImpl extends VideoCall { SomeArgs args = SomeArgs.obtain(); args.arg1 = width; args.arg2 = height; - mHandler.obtainMessage(MSG_CHANGE_PEER_DIMENSIONS, args).sendToTarget(); + mHandler.obtainMessage(MessageHandler.MSG_CHANGE_PEER_DIMENSIONS, args).sendToTarget(); } @Override public void changeVideoQuality(int videoQuality) { - mHandler.obtainMessage(MSG_CHANGE_VIDEO_QUALITY, videoQuality, 0).sendToTarget(); + mHandler.obtainMessage(MessageHandler.MSG_CHANGE_VIDEO_QUALITY, videoQuality, 0) + .sendToTarget(); } @Override public void changeCallDataUsage(long dataUsage) { - mHandler.obtainMessage(MSG_CHANGE_CALL_DATA_USAGE, dataUsage).sendToTarget(); + mHandler.obtainMessage(MessageHandler.MSG_CHANGE_CALL_DATA_USAGE, dataUsage) + .sendToTarget(); } @Override public void changeCameraCapabilities(CameraCapabilities cameraCapabilities) { - mHandler.obtainMessage(MSG_CHANGE_CAMERA_CAPABILITIES, + mHandler.obtainMessage(MessageHandler.MSG_CHANGE_CAMERA_CAPABILITIES, cameraCapabilities).sendToTarget(); } } /** Default handler used to consolidate binder method calls onto a single thread. */ - private final Handler mHandler = new Handler(Looper.getMainLooper()) { + private final class MessageHandler extends Handler { + private static final int MSG_RECEIVE_SESSION_MODIFY_REQUEST = 1; + private static final int MSG_RECEIVE_SESSION_MODIFY_RESPONSE = 2; + private static final int MSG_HANDLE_CALL_SESSION_EVENT = 3; + private static final int MSG_CHANGE_PEER_DIMENSIONS = 4; + private static final int MSG_CHANGE_CALL_DATA_USAGE = 5; + private static final int MSG_CHANGE_CAMERA_CAPABILITIES = 6; + private static final int MSG_CHANGE_VIDEO_QUALITY = 7; + + public MessageHandler(Looper looper) { + super(looper); + } + @Override public void handleMessage(Message msg) { if (mCallback == null) { @@ -160,7 +169,8 @@ public class VideoCallImpl extends VideoCall { } }; - /** {@hide} */ + private Handler mHandler; + VideoCallImpl(IVideoProvider videoProvider) throws RemoteException { mVideoProvider = videoProvider; mVideoProvider.asBinder().linkToDeath(mDeathRecipient, 0); @@ -169,13 +179,31 @@ public class VideoCallImpl extends VideoCall { mVideoProvider.addVideoCallback(mBinder); } + public void destroy() { + unregisterCallback(mCallback); + } + /** {@inheritDoc} */ public void registerCallback(VideoCall.Callback callback) { + registerCallback(callback, null); + } + + /** {@inheritDoc} */ + public void registerCallback(VideoCall.Callback callback, Handler handler) { mCallback = callback; + if (handler == null) { + mHandler = new MessageHandler(Looper.getMainLooper()); + } else { + mHandler = new MessageHandler(handler.getLooper()); + } } /** {@inheritDoc} */ - public void unregisterCallback() { + public void unregisterCallback(VideoCall.Callback callback) { + if (callback != mCallback) { + return; + } + mCallback = null; try { mVideoProvider.removeVideoCallback(mBinder); |