summaryrefslogtreecommitdiff
path: root/telecomm
diff options
context:
space:
mode:
authorXin Li <delphij@google.com>2020-08-31 21:21:38 -0700
committerXin Li <delphij@google.com>2020-08-31 21:21:38 -0700
commit628590d7ec80e10a3fc24b1c18a1afb55cca10a8 (patch)
tree4b1c3f52d86d7fb53afbe9e9438468588fa489f8 /telecomm
parentb11b8ec3aec8bb42f2c07e1c5ac7942da293baa8 (diff)
parentd2d3a20624d968199353ccf6ddbae6f3ac39c9af (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-xtelecomm/java/android/telecom/Call.java13
-rw-r--r--telecomm/java/android/telecom/CallScreeningService.java14
-rw-r--r--telecomm/java/android/telecom/CallerInfoAsyncQuery.java7
-rwxr-xr-xtelecomm/java/android/telecom/ConnectionService.java58
-rw-r--r--telecomm/java/android/telecom/Log.java44
-rw-r--r--telecomm/java/android/telecom/Logging/Session.java40
-rw-r--r--telecomm/java/android/telecom/Logging/SessionManager.java16
-rw-r--r--telecomm/java/android/telecom/RemoteConnection.java95
-rw-r--r--telecomm/java/android/telecom/TelecomManager.java51
-rw-r--r--telecomm/java/com/android/internal/telecom/ITelecomService.aidl28
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