diff options
author | Xin Li <delphij@google.com> | 2020-08-31 21:21:38 -0700 |
---|---|---|
committer | Xin Li <delphij@google.com> | 2020-08-31 21:21:38 -0700 |
commit | 628590d7ec80e10a3fc24b1c18a1afb55cca10a8 (patch) | |
tree | 4b1c3f52d86d7fb53afbe9e9438468588fa489f8 /telecomm | |
parent | b11b8ec3aec8bb42f2c07e1c5ac7942da293baa8 (diff) | |
parent | d2d3a20624d968199353ccf6ddbae6f3ac39c9af (diff) |
Merge Android R (rvc-dev-plus-aosp-without-vendor@6692709)
Bug: 166295507
Merged-In: I3d92a6de21a938f6b352ec26dc23420c0fe02b27
Change-Id: Ifdb80563ef042738778ebb8a7581a97c4e3d96e2
Diffstat (limited to 'telecomm')
-rwxr-xr-x | telecomm/java/android/telecom/Call.java | 13 | ||||
-rw-r--r-- | telecomm/java/android/telecom/CallScreeningService.java | 14 | ||||
-rw-r--r-- | telecomm/java/android/telecom/CallerInfoAsyncQuery.java | 7 | ||||
-rwxr-xr-x | telecomm/java/android/telecom/ConnectionService.java | 58 | ||||
-rw-r--r-- | telecomm/java/android/telecom/Log.java | 44 | ||||
-rw-r--r-- | telecomm/java/android/telecom/Logging/Session.java | 40 | ||||
-rw-r--r-- | telecomm/java/android/telecom/Logging/SessionManager.java | 16 | ||||
-rw-r--r-- | telecomm/java/android/telecom/RemoteConnection.java | 95 | ||||
-rw-r--r-- | telecomm/java/android/telecom/TelecomManager.java | 51 | ||||
-rw-r--r-- | telecomm/java/com/android/internal/telecom/ITelecomService.aidl | 28 |
10 files changed, 291 insertions, 75 deletions
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java index 4b9a9abac88f..0469fa56e648 100755 --- a/telecomm/java/android/telecom/Call.java +++ b/telecomm/java/android/telecom/Call.java @@ -22,6 +22,7 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; +import android.content.pm.ServiceInfo; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -1638,13 +1639,21 @@ public final class Call { /** * Instructs Telecom to put the call into the background audio processing state. - * + * <p> * This method can be called either when the call is in {@link #STATE_RINGING} or * {@link #STATE_ACTIVE}. After Telecom acknowledges the request by setting the call's state to * {@link #STATE_AUDIO_PROCESSING}, your app may setup the audio paths with the audio stack in * order to capture and play audio on the call stream. - * + * <p> * This method can only be called by the default dialer app. + * <p> + * Apps built with SDK version {@link android.os.Build.VERSION_CODES#R} or later which are using + * the microphone as part of audio processing should specify the foreground service type using + * the attribute {@link android.R.attr#foregroundServiceType} in the {@link InCallService} + * service element of the app's manifest file. + * The {@link ServiceInfo#FOREGROUND_SERVICE_TYPE_MICROPHONE} attribute should be specified. + * @see <a href="https://developer.android.com/preview/privacy/foreground-service-types"> + * the Android Developer Site</a> for more information. * @hide */ @SystemApi diff --git a/telecomm/java/android/telecom/CallScreeningService.java b/telecomm/java/android/telecom/CallScreeningService.java index 6bb49057458b..4d9311c282f7 100644 --- a/telecomm/java/android/telecom/CallScreeningService.java +++ b/telecomm/java/android/telecom/CallScreeningService.java @@ -25,6 +25,7 @@ import android.annotation.TestApi; import android.app.Service; import android.content.ComponentName; import android.content.Intent; +import android.content.pm.ServiceInfo; import android.net.Uri; import android.os.Handler; import android.os.IBinder; @@ -283,9 +284,20 @@ public abstract class CallScreeningService extends Service { * Sets whether to request background audio processing so that the in-call service can * screen the call further. If set to {@code true}, {@link #setDisallowCall} should be * called with {@code false}, and all other parameters in this builder will be ignored. - * + * <p> * This request will only be honored if the {@link CallScreeningService} shares the same * uid as the default dialer app. Otherwise, the call will go through as usual. + * <p> + * Apps built with SDK version {@link android.os.Build.VERSION_CODES#R} or later which + * are using the microphone as part of audio processing should specify the + * foreground service type using the attribute + * {@link android.R.attr#foregroundServiceType} in the {@link CallScreeningService} + * service element of the app's manifest file. + * The {@link ServiceInfo#FOREGROUND_SERVICE_TYPE_MICROPHONE} attribute should be + * specified. + * @see + * <a href="https://developer.android.com/preview/privacy/foreground-service-types"> + * the Android Developer Site</a> for more information. * * @param shouldScreenCallViaAudioProcessing Whether to request further call screening. * @hide diff --git a/telecomm/java/android/telecom/CallerInfoAsyncQuery.java b/telecomm/java/android/telecom/CallerInfoAsyncQuery.java index f38b34e85d89..4a81a8eea5cf 100644 --- a/telecomm/java/android/telecom/CallerInfoAsyncQuery.java +++ b/telecomm/java/android/telecom/CallerInfoAsyncQuery.java @@ -17,6 +17,7 @@ package android.telecom; import android.app.ActivityManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.AsyncQueryHandler; import android.content.ContentResolver; import android.content.Context; @@ -34,6 +35,7 @@ import android.provider.ContactsContract.PhoneLookup; import android.telephony.PhoneNumberUtils; import android.telephony.SubscriptionManager; import android.text.TextUtils; + import java.util.ArrayList; import java.util.List; @@ -78,6 +80,10 @@ public class CallerInfoAsyncQuery { * classes. */ private static final class CookieWrapper { + @UnsupportedAppUsage + private CookieWrapper() { + } + public OnQueryCompleteListener listener; public Object cookie; public int event; @@ -525,6 +531,7 @@ public class CallerInfoAsyncQuery { /** * Releases the relevant data. */ + @UnsupportedAppUsage private void release() { mHandler.mContext = null; mHandler.mQueryUri = null; diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java index 67bdba68b778..6288bc1698e9 100755 --- a/telecomm/java/android/telecom/ConnectionService.java +++ b/telecomm/java/android/telecom/ConnectionService.java @@ -2103,12 +2103,12 @@ public abstract class ConnectionService extends Service { private void abort(String callId) { - Log.d(this, "abort %s", callId); + Log.i(this, "abort %s", callId); findConnectionForAction(callId, "abort").onAbort(); } private void answerVideo(String callId, int videoState) { - Log.d(this, "answerVideo %s", callId); + Log.i(this, "answerVideo %s", callId); if (mConnectionById.containsKey(callId)) { findConnectionForAction(callId, "answer").onAnswer(videoState); } else { @@ -2117,7 +2117,7 @@ public abstract class ConnectionService extends Service { } private void answer(String callId) { - Log.d(this, "answer %s", callId); + Log.i(this, "answer %s", callId); if (mConnectionById.containsKey(callId)) { findConnectionForAction(callId, "answer").onAnswer(); } else { @@ -2126,12 +2126,12 @@ public abstract class ConnectionService extends Service { } private void deflect(String callId, Uri address) { - Log.d(this, "deflect %s", callId); + Log.i(this, "deflect %s", callId); findConnectionForAction(callId, "deflect").onDeflect(address); } private void reject(String callId) { - Log.d(this, "reject %s", callId); + Log.i(this, "reject %s", callId); if (mConnectionById.containsKey(callId)) { findConnectionForAction(callId, "reject").onReject(); } else { @@ -2140,34 +2140,34 @@ public abstract class ConnectionService extends Service { } private void reject(String callId, String rejectWithMessage) { - Log.d(this, "reject %s with message", callId); + Log.i(this, "reject %s with message", callId); findConnectionForAction(callId, "reject").onReject(rejectWithMessage); } private void reject(String callId, @android.telecom.Call.RejectReason int rejectReason) { - Log.d(this, "reject %s with reason %d", callId, rejectReason); + Log.i(this, "reject %s with reason %d", callId, rejectReason); findConnectionForAction(callId, "reject").onReject(rejectReason); } private void transfer(String callId, Uri number, boolean isConfirmationRequired) { - Log.d(this, "transfer %s", callId); + Log.i(this, "transfer %s", callId); findConnectionForAction(callId, "transfer").onTransfer(number, isConfirmationRequired); } private void consultativeTransfer(String callId, String otherCallId) { - Log.d(this, "consultativeTransfer %s", callId); + Log.i(this, "consultativeTransfer %s", callId); Connection connection1 = findConnectionForAction(callId, "consultativeTransfer"); Connection connection2 = findConnectionForAction(otherCallId, " consultativeTransfer"); connection1.onTransfer(connection2); } private void silence(String callId) { - Log.d(this, "silence %s", callId); + Log.i(this, "silence %s", callId); findConnectionForAction(callId, "silence").onSilence(); } private void disconnect(String callId) { - Log.d(this, "disconnect %s", callId); + Log.i(this, "disconnect %s", callId); if (mConnectionById.containsKey(callId)) { findConnectionForAction(callId, "disconnect").onDisconnect(); } else { @@ -2176,7 +2176,7 @@ public abstract class ConnectionService extends Service { } private void hold(String callId) { - Log.d(this, "hold %s", callId); + Log.i(this, "hold %s", callId); if (mConnectionById.containsKey(callId)) { findConnectionForAction(callId, "hold").onHold(); } else { @@ -2185,7 +2185,7 @@ public abstract class ConnectionService extends Service { } private void unhold(String callId) { - Log.d(this, "unhold %s", callId); + Log.i(this, "unhold %s", callId); if (mConnectionById.containsKey(callId)) { findConnectionForAction(callId, "unhold").onUnhold(); } else { @@ -2194,7 +2194,7 @@ public abstract class ConnectionService extends Service { } private void onCallAudioStateChanged(String callId, CallAudioState callAudioState) { - Log.d(this, "onAudioStateChanged %s %s", callId, callAudioState); + Log.i(this, "onAudioStateChanged %s %s", callId, callAudioState); if (mConnectionById.containsKey(callId)) { findConnectionForAction(callId, "onCallAudioStateChanged").setCallAudioState( callAudioState); @@ -2205,7 +2205,7 @@ public abstract class ConnectionService extends Service { } private void playDtmfTone(String callId, char digit) { - Log.d(this, "playDtmfTone %s %c", callId, digit); + Log.i(this, "playDtmfTone %s %c", callId, digit); if (mConnectionById.containsKey(callId)) { findConnectionForAction(callId, "playDtmfTone").onPlayDtmfTone(digit); } else { @@ -2214,7 +2214,7 @@ public abstract class ConnectionService extends Service { } private void stopDtmfTone(String callId) { - Log.d(this, "stopDtmfTone %s", callId); + Log.i(this, "stopDtmfTone %s", callId); if (mConnectionById.containsKey(callId)) { findConnectionForAction(callId, "stopDtmfTone").onStopDtmfTone(); } else { @@ -2223,7 +2223,7 @@ public abstract class ConnectionService extends Service { } private void conference(String callId1, String callId2) { - Log.d(this, "conference %s, %s", callId1, callId2); + Log.i(this, "conference %s, %s", callId1, callId2); // Attempt to get second connection or conference. Connection connection2 = findConnectionForAction(callId2, "conference"); @@ -2270,7 +2270,7 @@ public abstract class ConnectionService extends Service { } private void splitFromConference(String callId) { - Log.d(this, "splitFromConference(%s)", callId); + Log.i(this, "splitFromConference(%s)", callId); Connection connection = findConnectionForAction(callId, "splitFromConference"); if (connection == getNullConnection()) { @@ -2285,7 +2285,7 @@ public abstract class ConnectionService extends Service { } private void mergeConference(String callId) { - Log.d(this, "mergeConference(%s)", callId); + Log.i(this, "mergeConference(%s)", callId); Conference conference = findConferenceForAction(callId, "mergeConference"); if (conference != null) { conference.onMerge(); @@ -2293,7 +2293,7 @@ public abstract class ConnectionService extends Service { } private void swapConference(String callId) { - Log.d(this, "swapConference(%s)", callId); + Log.i(this, "swapConference(%s)", callId); Conference conference = findConferenceForAction(callId, "swapConference"); if (conference != null) { conference.onSwap(); @@ -2301,7 +2301,7 @@ public abstract class ConnectionService extends Service { } private void addConferenceParticipants(String callId, List<Uri> participants) { - Log.d(this, "addConferenceParticipants(%s)", callId); + Log.i(this, "addConferenceParticipants(%s)", callId); if (mConnectionById.containsKey(callId)) { findConnectionForAction(callId, "addConferenceParticipants") .onAddConferenceParticipants(participants); @@ -2319,7 +2319,7 @@ public abstract class ConnectionService extends Service { * @param callId The ID of the call to pull. */ private void pullExternalCall(String callId) { - Log.d(this, "pullExternalCall(%s)", callId); + Log.i(this, "pullExternalCall(%s)", callId); Connection connection = findConnectionForAction(callId, "pullExternalCall"); if (connection != null) { connection.onPullExternalCall(); @@ -2336,7 +2336,7 @@ public abstract class ConnectionService extends Service { * @param extras Extras associated with the event. */ private void sendCallEvent(String callId, String event, Bundle extras) { - Log.d(this, "sendCallEvent(%s, %s)", callId, event); + Log.i(this, "sendCallEvent(%s, %s)", callId, event); Connection connection = findConnectionForAction(callId, "sendCallEvent"); if (connection != null) { connection.onCallEvent(event, extras); @@ -2349,7 +2349,7 @@ public abstract class ConnectionService extends Service { * @param callId The ID of the call which completed handover. */ private void notifyHandoverComplete(String callId) { - Log.d(this, "notifyHandoverComplete(%s)", callId); + Log.i(this, "notifyHandoverComplete(%s)", callId); Connection connection = findConnectionForAction(callId, "notifyHandoverComplete"); if (connection != null) { connection.onHandoverComplete(); @@ -2369,7 +2369,7 @@ public abstract class ConnectionService extends Service { * @param extras The new extras bundle. */ private void handleExtrasChanged(String callId, Bundle extras) { - Log.d(this, "handleExtrasChanged(%s, %s)", callId, extras); + Log.i(this, "handleExtrasChanged(%s, %s)", callId, extras); if (mConnectionById.containsKey(callId)) { findConnectionForAction(callId, "handleExtrasChanged").handleExtrasChanged(extras); } else if (mConferenceById.containsKey(callId)) { @@ -2378,7 +2378,7 @@ public abstract class ConnectionService extends Service { } private void startRtt(String callId, Connection.RttTextStream rttTextStream) { - Log.d(this, "startRtt(%s)", callId); + Log.i(this, "startRtt(%s)", callId); if (mConnectionById.containsKey(callId)) { findConnectionForAction(callId, "startRtt").onStartRtt(rttTextStream); } else if (mConferenceById.containsKey(callId)) { @@ -2387,7 +2387,7 @@ public abstract class ConnectionService extends Service { } private void stopRtt(String callId) { - Log.d(this, "stopRtt(%s)", callId); + Log.i(this, "stopRtt(%s)", callId); if (mConnectionById.containsKey(callId)) { findConnectionForAction(callId, "stopRtt").onStopRtt(); } else if (mConferenceById.containsKey(callId)) { @@ -2396,7 +2396,7 @@ public abstract class ConnectionService extends Service { } private void handleRttUpgradeResponse(String callId, Connection.RttTextStream rttTextStream) { - Log.d(this, "handleRttUpgradeResponse(%s, %s)", callId, rttTextStream == null); + Log.i(this, "handleRttUpgradeResponse(%s, %s)", callId, rttTextStream == null); if (mConnectionById.containsKey(callId)) { findConnectionForAction(callId, "handleRttUpgradeResponse") .handleRttUpgradeResponse(rttTextStream); @@ -2406,7 +2406,7 @@ public abstract class ConnectionService extends Service { } private void onPostDialContinue(String callId, boolean proceed) { - Log.d(this, "onPostDialContinue(%s)", callId); + Log.i(this, "onPostDialContinue(%s)", callId); findConnectionForAction(callId, "stopDtmfTone").onPostDialContinue(proceed); } diff --git a/telecomm/java/android/telecom/Log.java b/telecomm/java/android/telecom/Log.java index 4f6a9d6450f8..a90d0532b721 100644 --- a/telecomm/java/android/telecom/Log.java +++ b/telecomm/java/android/telecom/Log.java @@ -16,7 +16,9 @@ package android.telecom; +import android.annotation.NonNull; import android.compat.annotation.UnsupportedAppUsage; +import android.content.ComponentName; import android.content.Context; import android.net.Uri; import android.os.Build; @@ -29,8 +31,10 @@ import android.text.TextUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.IndentingPrintWriter; +import java.util.Arrays; import java.util.IllegalFormatException; import java.util.Locale; +import java.util.stream.Collectors; /** * Manages logging for the entire module. @@ -212,6 +216,16 @@ public class Log { return getSessionManager().getExternalSession(); } + /** + * Retrieves external session information, providing a context for the recipient of the session + * info where the external session came from. + * @param ownerInfo The external owner info. + * @return New {@link Session.Info} instance with owner info set. + */ + public static Session.Info getExternalSession(@NonNull String ownerInfo) { + return getSessionManager().getExternalSession(ownerInfo); + } + public static void cancelSubsession(Session subsession) { getSessionManager().cancelSubsession(subsession); } @@ -481,4 +495,34 @@ public class Log { } return String.format(Locale.US, "%s: %s%s", prefix, msg, sessionPostfix); } + + /** + * Generates an abbreviated version of the package name from a component. + * E.g. com.android.phone becomes cap + * @param componentName The component name to abbreviate. + * @return Abbreviation of empty string if component is null. + * @hide + */ + public static String getPackageAbbreviation(ComponentName componentName) { + if (componentName == null) { + return ""; + } + return getPackageAbbreviation(componentName.getPackageName()); + } + + /** + * Generates an abbreviated version of the package name. + * E.g. com.android.phone becomes cap + * @param packageName The packageName name to abbreviate. + * @return Abbreviation of empty string if package is null. + * @hide + */ + public static String getPackageAbbreviation(String packageName) { + if (packageName == null) { + return ""; + } + return Arrays.stream(packageName.split("\\.")) + .map(s -> s.substring(0,1)) + .collect(Collectors.joining("")); + } } diff --git a/telecomm/java/android/telecom/Logging/Session.java b/telecomm/java/android/telecom/Logging/Session.java index 8d3f4e1df8bc..4aa3614fa004 100644 --- a/telecomm/java/android/telecom/Logging/Session.java +++ b/telecomm/java/android/telecom/Logging/Session.java @@ -17,6 +17,7 @@ package android.telecom.Logging; import android.annotation.NonNull; +import android.annotation.Nullable; import android.os.Parcel; import android.os.Parcelable; import android.telecom.Log; @@ -59,10 +60,12 @@ public class Session { public static class Info implements Parcelable { public final String sessionId; public final String methodPath; + public final String ownerInfo; - private Info(String id, String path) { + private Info(String id, String path, String owner) { sessionId = id; methodPath = path; + ownerInfo = owner; } public static Info getInfo (Session s) { @@ -70,7 +73,28 @@ public class Session { // not get multiple stacking external sessions (unless we have DEBUG level logging or // lower). return new Info(s.getFullSessionId(), s.getFullMethodPath( - !Log.DEBUG && s.isSessionExternal())); + !Log.DEBUG && s.isSessionExternal()), s.getOwnerInfo()); + } + + public static Info getExternalInfo(Session s, @Nullable String ownerInfo) { + // When creating session information for an existing session, the caller may pass in a + // context to be passed along to the recipient of the external session info. + // So, for example, if telecom has an active session with owner 'cad', and Telecom is + // calling into Telephony and providing external session info, it would pass in 'cast' + // as the owner info. This would result in Telephony seeing owner info 'cad/cast', + // which would make it very clear in the Telephony logs the chain of package calls which + // ultimately resulted in the logs. + String newInfo = ownerInfo != null && s.getOwnerInfo() != null + // If we've got both, concatenate them. + ? s.getOwnerInfo() + "/" + ownerInfo + // Otherwise use whichever is present. + : ownerInfo != null ? ownerInfo : s.getOwnerInfo(); + + // Create Info based on the truncated method path if the session is external, so we do + // not get multiple stacking external sessions (unless we have DEBUG level logging or + // lower). + return new Info(s.getFullSessionId(), s.getFullMethodPath( + !Log.DEBUG && s.isSessionExternal()), newInfo); } /** Responsible for creating Info objects for deserialized Parcels. */ @@ -80,7 +104,8 @@ public class Session { public Info createFromParcel(Parcel source) { String id = source.readString(); String methodName = source.readString(); - return new Info(id, methodName); + String ownerInfo = source.readString(); + return new Info(id, methodName, ownerInfo); } @Override @@ -100,6 +125,7 @@ public class Session { public void writeToParcel(Parcel destination, int flags) { destination.writeString(sessionId); destination.writeString(methodPath); + destination.writeString(ownerInfo); } } @@ -206,6 +232,14 @@ public class Session { return Info.getInfo(this); } + public Info getExternalInfo(@Nullable String ownerInfo) { + return Info.getExternalInfo(this, ownerInfo); + } + + public String getOwnerInfo() { + return mOwnerInfo; + } + @VisibleForTesting public String getSessionId() { return mSessionId; diff --git a/telecomm/java/android/telecom/Logging/SessionManager.java b/telecomm/java/android/telecom/Logging/SessionManager.java index ac300587cef8..67e5eabf54eb 100644 --- a/telecomm/java/android/telecom/Logging/SessionManager.java +++ b/telecomm/java/android/telecom/Logging/SessionManager.java @@ -16,6 +16,7 @@ package android.telecom.Logging; +import android.annotation.Nullable; import android.content.Context; import android.os.Handler; import android.os.Looper; @@ -180,7 +181,7 @@ public class SessionManager { Log.d(LOGGING_TAG, Session.START_EXTERNAL_SESSION); Session externalSession = new Session(Session.EXTERNAL_INDICATOR + sessionInfo.sessionId, sessionInfo.methodPath, System.currentTimeMillis(), - false /*isStartedFromActiveSession*/, null); + false /*isStartedFromActiveSession*/, sessionInfo.ownerInfo); externalSession.setIsExternal(true); // Mark the external session as already completed, since we have no way of knowing when // the external session actually has completed. @@ -224,7 +225,7 @@ public class SessionManager { // Start execution time of the session will be overwritten in continueSession(...). Session newSubsession = new Session(threadSession.getNextChildId(), threadSession.getShortMethodName(), System.currentTimeMillis(), - isStartedFromActiveSession, null); + isStartedFromActiveSession, threadSession.getOwnerInfo()); threadSession.addChild(newSubsession); newSubsession.setParentSession(threadSession); @@ -238,12 +239,18 @@ public class SessionManager { return newSubsession; } + public synchronized Session.Info getExternalSession() { + return getExternalSession(null /* ownerInfo */); + } + /** * Retrieve the information of the currently active Session. This information is parcelable and * is used to create an external Session ({@link #startExternalSession(Session.Info, String)}). * If there is no Session active, this method will return null. + * @param ownerInfo Owner information for the session. + * @return The session information */ - public synchronized Session.Info getExternalSession() { + public synchronized Session.Info getExternalSession(@Nullable String ownerInfo) { int threadId = getCallingThreadId(); Session threadSession = mSessionMapper.get(threadId); if (threadSession == null) { @@ -251,8 +258,7 @@ public class SessionManager { "active."); return null; } - - return threadSession.getInfo(); + return threadSession.getExternalInfo(ownerInfo); } /** diff --git a/telecomm/java/android/telecom/RemoteConnection.java b/telecomm/java/android/telecom/RemoteConnection.java index 78b4f3bfb90b..52210a55c8d0 100644 --- a/telecomm/java/android/telecom/RemoteConnection.java +++ b/telecomm/java/android/telecom/RemoteConnection.java @@ -26,6 +26,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; +import android.telecom.Logging.Session; import android.view.Surface; import com.android.internal.telecom.IConnectionService; @@ -33,10 +34,12 @@ import com.android.internal.telecom.IVideoCallback; import com.android.internal.telecom.IVideoProvider; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; /** * A connection provided to a {@link ConnectionService} by another {@code ConnectionService} @@ -655,6 +658,7 @@ public final class RemoteConnection { private int mCallerDisplayNamePresentation; private RemoteConference mConference; private Bundle mExtras; + private String mCallingPackageAbbreviation; /** * @hide @@ -667,6 +671,13 @@ public final class RemoteConnection { mConnectionService = connectionService; mConnected = true; mState = Connection.STATE_INITIALIZING; + if (request != null && request.getExtras() != null + && request.getExtras().containsKey( + Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME)) { + String callingPackage = request.getExtras().getString( + Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME); + mCallingPackageAbbreviation = Log.getPackageAbbreviation(callingPackage); + } } /** @@ -705,6 +716,7 @@ public final class RemoteConnection { Bundle newExtras = new Bundle(); newExtras.putString(Connection.EXTRA_ORIGINAL_CONNECTION_ID, callId); putExtras(newExtras); + mCallingPackageAbbreviation = Log.getPackageAbbreviation(callingPackage); } /** @@ -899,11 +911,15 @@ public final class RemoteConnection { * Instructs this {@code RemoteConnection} to abort. */ public void abort() { + Log.startSession("RC.a", getActiveOwnerInfo()); try { if (mConnected) { - mConnectionService.abort(mConnectionId, null /*Session.Info*/); + mConnectionService.abort(mConnectionId, Log.getExternalSession( + mCallingPackageAbbreviation)); } } catch (RemoteException ignored) { + } finally { + Log.endSession(); } } @@ -911,11 +927,15 @@ public final class RemoteConnection { * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to answer. */ public void answer() { + Log.startSession("RC.an", getActiveOwnerInfo()); try { if (mConnected) { - mConnectionService.answer(mConnectionId, null /*Session.Info*/); + mConnectionService.answer(mConnectionId, Log.getExternalSession( + mCallingPackageAbbreviation)); } } catch (RemoteException ignored) { + } finally { + Log.endSession(); } } @@ -925,11 +945,15 @@ public final class RemoteConnection { * @hide */ public void answer(int videoState) { + Log.startSession("RC.an2", getActiveOwnerInfo()); try { if (mConnected) { - mConnectionService.answerVideo(mConnectionId, videoState, null /*Session.Info*/); + mConnectionService.answerVideo(mConnectionId, videoState, + Log.getExternalSession(mCallingPackageAbbreviation)); } } catch (RemoteException ignored) { + } finally { + Log.endSession(); } } @@ -937,11 +961,15 @@ public final class RemoteConnection { * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to reject. */ public void reject() { + Log.startSession("RC.r", getActiveOwnerInfo()); try { if (mConnected) { - mConnectionService.reject(mConnectionId, null /*Session.Info*/); + mConnectionService.reject(mConnectionId, Log.getExternalSession( + mCallingPackageAbbreviation)); } } catch (RemoteException ignored) { + } finally { + Log.endSession(); } } @@ -949,11 +977,15 @@ public final class RemoteConnection { * Instructs this {@code RemoteConnection} to go on hold. */ public void hold() { + Log.startSession("RC.h", getActiveOwnerInfo()); try { if (mConnected) { - mConnectionService.hold(mConnectionId, null /*Session.Info*/); + mConnectionService.hold(mConnectionId, Log.getExternalSession( + mCallingPackageAbbreviation)); } } catch (RemoteException ignored) { + } finally { + Log.endSession(); } } @@ -961,11 +993,15 @@ public final class RemoteConnection { * Instructs this {@link Connection#STATE_HOLDING} call to release from hold. */ public void unhold() { + Log.startSession("RC.u", getActiveOwnerInfo()); try { if (mConnected) { - mConnectionService.unhold(mConnectionId, null /*Session.Info*/); + mConnectionService.unhold(mConnectionId, Log.getExternalSession( + mCallingPackageAbbreviation)); } } catch (RemoteException ignored) { + } finally { + Log.endSession(); } } @@ -973,11 +1009,15 @@ public final class RemoteConnection { * Instructs this {@code RemoteConnection} to disconnect. */ public void disconnect() { + Log.startSession("RC.d", getActiveOwnerInfo()); try { if (mConnected) { - mConnectionService.disconnect(mConnectionId, null /*Session.Info*/); + mConnectionService.disconnect(mConnectionId, Log.getExternalSession( + mCallingPackageAbbreviation)); } } catch (RemoteException ignored) { + } finally { + Log.endSession(); } } @@ -991,11 +1031,14 @@ public final class RemoteConnection { * value must be one of {@code '0'} through {@code '9'}, {@code '*'} or {@code '#'}. */ public void playDtmfTone(char digit) { + Log.startSession("RC.pDT", getActiveOwnerInfo()); try { if (mConnected) { mConnectionService.playDtmfTone(mConnectionId, digit, null /*Session.Info*/); } } catch (RemoteException ignored) { + } finally { + Log.endSession(); } } @@ -1007,11 +1050,14 @@ public final class RemoteConnection { * currently playing, this method will do nothing. */ public void stopDtmfTone() { + Log.startSession("RC.sDT", getActiveOwnerInfo()); try { if (mConnected) { mConnectionService.stopDtmfTone(mConnectionId, null /*Session.Info*/); } } catch (RemoteException ignored) { + } finally { + Log.endSession(); } } @@ -1037,12 +1083,16 @@ public final class RemoteConnection { * @param proceed Whether or not to continue with the post-dial sequence. */ public void postDialContinue(boolean proceed) { + Log.startSession("RC.pDC", getActiveOwnerInfo()); try { if (mConnected) { mConnectionService.onPostDialContinue(mConnectionId, proceed, null /*Session.Info*/); } } catch (RemoteException ignored) { + // bliss + } finally { + Log.endSession(); } } @@ -1052,11 +1102,14 @@ public final class RemoteConnection { * See {@link Call#pullExternalCall()} for more information. */ public void pullExternalCall() { + Log.startSession("RC.pEC", getActiveOwnerInfo()); try { if (mConnected) { mConnectionService.pullExternalCall(mConnectionId, null /*Session.Info*/); } } catch (RemoteException ignored) { + } finally { + Log.endSession(); } } @@ -1096,12 +1149,15 @@ public final class RemoteConnection { * @param state The audio state of this {@code RemoteConnection}. */ public void setCallAudioState(CallAudioState state) { + Log.startSession("RC.sCAS", getActiveOwnerInfo()); try { if (mConnected) { mConnectionService.onCallAudioStateChanged(mConnectionId, state, null /*Session.Info*/); } } catch (RemoteException ignored) { + } finally { + Log.endSession(); } } @@ -1112,12 +1168,15 @@ public final class RemoteConnection { * @hide */ public void startRtt(@NonNull Connection.RttTextStream rttTextStream) { + Log.startSession("RC.sR", getActiveOwnerInfo()); try { if (mConnected) { mConnectionService.startRtt(mConnectionId, rttTextStream.getFdFromInCall(), rttTextStream.getFdToInCall(), null /*Session.Info*/); } } catch (RemoteException ignored) { + } finally { + Log.endSession(); } } @@ -1127,11 +1186,14 @@ public final class RemoteConnection { * @hide */ public void stopRtt() { + Log.startSession("RC.stR", getActiveOwnerInfo()); try { if (mConnected) { mConnectionService.stopRtt(mConnectionId, null /*Session.Info*/); } } catch (RemoteException ignored) { + } finally { + Log.endSession(); } } @@ -1145,6 +1207,7 @@ public final class RemoteConnection { * the in-call app. */ public void sendRttUpgradeResponse(@Nullable Connection.RttTextStream rttTextStream) { + Log.startSession("RC.sRUR", getActiveOwnerInfo()); try { if (mConnected) { if (rttTextStream == null) { @@ -1157,6 +1220,8 @@ public final class RemoteConnection { } } } catch (RemoteException ignored) { + } finally { + Log.endSession(); } } @@ -1181,6 +1246,22 @@ public final class RemoteConnection { return mConference; } + /** + * Get the owner info for the currently active session. We want to make sure that any owner + * info from the original call into the connection manager gets retained so that the full + * context of the calls can be traced down to Telephony. + * Example: Telecom will provide owner info in it's external session info that indicates + * 'cast' as the calling owner. + * @return The active owner + */ + private String getActiveOwnerInfo() { + Session.Info info = Log.getExternalSession(); + if (info == null) { + return null; + } + return info.ownerInfo; + } + /** {@hide} */ String getId() { return mConnectionId; diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index 08f31a9ea9eb..bcb1736f416e 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -49,6 +49,7 @@ import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.concurrent.Executor; /** @@ -937,7 +938,8 @@ public class TelecomManager { */ public TelecomManager(Context context, ITelecomService telecomServiceImpl) { Context appContext = context.getApplicationContext(); - if (appContext != null) { + if (appContext != null && Objects.equals(context.getAttributionTag(), + appContext.getAttributionTag())) { mContext = appContext; } else { mContext = context; @@ -971,7 +973,7 @@ public class TelecomManager { try { if (isServiceConnected()) { return getTelecomService().getDefaultOutgoingPhoneAccount(uriScheme, - mContext.getOpPackageName()); + mContext.getOpPackageName(), mContext.getAttributionTag()); } } catch (RemoteException e) { Log.e(TAG, "Error calling ITelecomService#getDefaultOutgoingPhoneAccount", e); @@ -1168,7 +1170,8 @@ public class TelecomManager { public List<PhoneAccountHandle> getSelfManagedPhoneAccounts() { try { if (isServiceConnected()) { - return getTelecomService().getSelfManagedPhoneAccounts(mContext.getOpPackageName()); + return getTelecomService().getSelfManagedPhoneAccounts(mContext.getOpPackageName(), + mContext.getAttributionTag()); } } catch (RemoteException e) { Log.e(TAG, "Error calling ITelecomService#getSelfManagedPhoneAccounts()", e); @@ -1193,8 +1196,8 @@ public class TelecomManager { boolean includeDisabledAccounts) { try { if (isServiceConnected()) { - return getTelecomService().getCallCapablePhoneAccounts( - includeDisabledAccounts, mContext.getOpPackageName()); + return getTelecomService().getCallCapablePhoneAccounts(includeDisabledAccounts, + mContext.getOpPackageName(), mContext.getAttributionTag()); } } catch (RemoteException e) { Log.e(TAG, "Error calling ITelecomService#getCallCapablePhoneAccounts(" + @@ -1498,7 +1501,7 @@ public class TelecomManager { try { if (isServiceConnected()) { return getTelecomService().isVoiceMailNumber(accountHandle, number, - mContext.getOpPackageName()); + mContext.getOpPackageName(), mContext.getAttributionTag()); } } catch (RemoteException e) { Log.e(TAG, "RemoteException calling ITelecomService#isVoiceMailNumber.", e); @@ -1520,7 +1523,7 @@ public class TelecomManager { try { if (isServiceConnected()) { return getTelecomService().getVoiceMailNumber(accountHandle, - mContext.getOpPackageName()); + mContext.getOpPackageName(), mContext.getAttributionTag()); } } catch (RemoteException e) { Log.e(TAG, "RemoteException calling ITelecomService#hasVoiceMailNumber.", e); @@ -1531,17 +1534,27 @@ public class TelecomManager { /** * Return the line 1 phone number for given phone account. * - * Requires permission: {@link android.Manifest.permission#READ_PHONE_STATE} + * <p>Requires Permission: + * {@link android.Manifest.permission#READ_SMS READ_SMS}, + * {@link android.Manifest.permission#READ_PHONE_NUMBERS READ_PHONE_NUMBERS}, + * or that the caller is the default SMS app for any API level. + * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} + * for apps targeting SDK API level 29 and below. * * @param accountHandle The handle for the account retrieve a number for. * @return A string representation of the line 1 phone number. */ - @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges or default SMS app + @RequiresPermission(anyOf = { + android.Manifest.permission.READ_PHONE_STATE, + android.Manifest.permission.READ_SMS, + android.Manifest.permission.READ_PHONE_NUMBERS + }, conditional = true) public String getLine1Number(PhoneAccountHandle accountHandle) { try { if (isServiceConnected()) { return getTelecomService().getLine1Number(accountHandle, - mContext.getOpPackageName()); + mContext.getOpPackageName(), mContext.getAttributionTag()); } } catch (RemoteException e) { Log.e(TAG, "RemoteException calling ITelecomService#getLine1Number.", e); @@ -1562,7 +1575,8 @@ public class TelecomManager { public boolean isInCall() { try { if (isServiceConnected()) { - return getTelecomService().isInCall(mContext.getOpPackageName()); + return getTelecomService().isInCall(mContext.getOpPackageName(), + mContext.getAttributionTag()); } } catch (RemoteException e) { Log.e(TAG, "RemoteException calling isInCall().", e); @@ -1587,7 +1601,8 @@ public class TelecomManager { public boolean isInManagedCall() { try { if (isServiceConnected()) { - return getTelecomService().isInManagedCall(mContext.getOpPackageName()); + return getTelecomService().isInManagedCall(mContext.getOpPackageName(), + mContext.getAttributionTag()); } } catch (RemoteException e) { Log.e(TAG, "RemoteException calling isInManagedCall().", e); @@ -1768,7 +1783,8 @@ public class TelecomManager { public boolean isTtySupported() { try { if (isServiceConnected()) { - return getTelecomService().isTtySupported(mContext.getOpPackageName()); + return getTelecomService().isTtySupported(mContext.getOpPackageName(), + mContext.getAttributionTag()); } } catch (RemoteException e) { Log.e(TAG, "RemoteException attempting to get TTY supported state.", e); @@ -1792,7 +1808,8 @@ public class TelecomManager { public @TtyMode int getCurrentTtyMode() { try { if (isServiceConnected()) { - return getTelecomService().getCurrentTtyMode(mContext.getOpPackageName()); + return getTelecomService().getCurrentTtyMode(mContext.getOpPackageName(), + mContext.getAttributionTag()); } } catch (RemoteException e) { Log.e(TAG, "RemoteException attempting to get the current TTY mode.", e); @@ -2023,7 +2040,8 @@ public class TelecomManager { ITelecomService service = getTelecomService(); if (service != null) { try { - service.showInCallScreen(showDialpad, mContext.getOpPackageName()); + service.showInCallScreen(showDialpad, mContext.getOpPackageName(), + mContext.getAttributionTag()); } catch (RemoteException e) { Log.e(TAG, "Error calling ITelecomService#showCallScreen", e); } @@ -2086,7 +2104,7 @@ public class TelecomManager { } try { service.placeCall(address, extras == null ? new Bundle() : extras, - mContext.getOpPackageName()); + mContext.getOpPackageName(), mContext.getAttributionTag()); } catch (RemoteException e) { Log.e(TAG, "Error calling ITelecomService#placeCall", e); } @@ -2199,6 +2217,7 @@ public class TelecomManager { * @hide */ @SystemApi + @TestApi @NonNull public Intent createLaunchEmergencyDialerIntent(@Nullable String number) { ITelecomService service = getTelecomService(); diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl index 19cb7f453fe2..7c6f1df972f3 100644 --- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl +++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl @@ -35,12 +35,13 @@ interface ITelecomService { * * @param showDialpad if true, make the dialpad visible initially. */ - void showInCallScreen(boolean showDialpad, String callingPackage); + void showInCallScreen(boolean showDialpad, String callingPackage, String callingFeatureId); /** * @see TelecomServiceImpl#getDefaultOutgoingPhoneAccount */ - PhoneAccountHandle getDefaultOutgoingPhoneAccount(in String uriScheme, String callingPackage); + PhoneAccountHandle getDefaultOutgoingPhoneAccount(in String uriScheme, String callingPackage, + String callingFeatureId); /** * @see TelecomServiceImpl#getUserSelectedOutgoingPhoneAccount @@ -56,12 +57,13 @@ interface ITelecomService { * @see TelecomServiceImpl#getCallCapablePhoneAccounts */ List<PhoneAccountHandle> getCallCapablePhoneAccounts( - boolean includeDisabledAccounts, String callingPackage); + boolean includeDisabledAccounts, String callingPackage, String callingFeatureId); /** * @see TelecomServiceImpl#getSelfManagedPhoneAccounts */ - List<PhoneAccountHandle> getSelfManagedPhoneAccounts(String callingPackage); + List<PhoneAccountHandle> getSelfManagedPhoneAccounts(String callingPackage, + String callingFeatureId); /** * @see TelecomManager#getPhoneAccountsSupportingScheme @@ -123,17 +125,19 @@ interface ITelecomService { * @see TelecomServiceImpl#isVoiceMailNumber */ boolean isVoiceMailNumber(in PhoneAccountHandle accountHandle, String number, - String callingPackage); + String callingPackage, String callingFeatureId); /** * @see TelecomServiceImpl#getVoiceMailNumber */ - String getVoiceMailNumber(in PhoneAccountHandle accountHandle, String callingPackage); + String getVoiceMailNumber(in PhoneAccountHandle accountHandle, String callingPackage, + String callingFeatureId); /** * @see TelecomServiceImpl#getLine1Number */ - String getLine1Number(in PhoneAccountHandle accountHandle, String callingPackage); + String getLine1Number(in PhoneAccountHandle accountHandle, String callingPackage, + String callingFeatureId); /** * @see TelecomServiceImpl#getDefaultPhoneApp @@ -172,12 +176,12 @@ interface ITelecomService { /** * @see TelecomServiceImpl#isInCall */ - boolean isInCall(String callingPackage); + boolean isInCall(String callingPackage, String callingFeatureId); /** * @see TelecomServiceImpl#isInManagedCall */ - boolean isInManagedCall(String callingPackage); + boolean isInManagedCall(String callingPackage, String callingFeatureId); /** * @see TelecomServiceImpl#isRinging @@ -229,12 +233,12 @@ interface ITelecomService { /** * @see TelecomServiceImpl#isTtySupported */ - boolean isTtySupported(String callingPackage); + boolean isTtySupported(String callingPackage, String callingFeatureId); /** * @see TelecomServiceImpl#getCurrentTtyMode */ - int getCurrentTtyMode(String callingPackage); + int getCurrentTtyMode(String callingPackage, String callingFeatureId); /** * @see TelecomServiceImpl#addNewIncomingCall @@ -260,7 +264,7 @@ interface ITelecomService { /** * @see TelecomServiceImpl#placeCall */ - void placeCall(in Uri handle, in Bundle extras, String callingPackage); + void placeCall(in Uri handle, in Bundle extras, String callingPackage, String callingFeatureId); /** * @see TelecomServiceImpl#enablePhoneAccount |