summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-08-30 02:12:20 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-08-30 02:12:20 +0000
commite9d071e8333db88a8f81b0fcd21f5f18a3ae8222 (patch)
treeb65e30f0bb6a9aa3a7a3164907d97c5e81a4b70b
parent115b8514743671277ff9ac6b3d21c8e220d34aa9 (diff)
parentb1c856d5fc454ac0edbf62200fd8903b9315a26b (diff)
downloadbase-android12-d1-s1-release.tar.gz
Merge cherrypicks of [15712549, 15712550, 15712551, 15712641, 15712642, 15712643, 15710166, 15711786, 15711787, 15711788, 15711789, 15712646, 15712631, 15712552, 15712632, 15712633, 15712634, 15712559, 15712560, 15712561] into sc-d1-releaseandroid-12.0.0_r4android12-d1-s1-release
Change-Id: I2850a9e1a3d8bd3c15a5b3cb1809017aa9f1f0da
-rw-r--r--core/java/android/app/ActivityThread.java3
-rw-r--r--packages/SystemUI/res/layout/status_bar_expanded.xml1
-rw-r--r--services/core/java/com/android/server/policy/AppOpsPolicy.java5
-rw-r--r--services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java34
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java14
-rw-r--r--telecomm/java/android/telecom/Connection.java15
-rw-r--r--telecomm/java/android/telecom/RemoteConnectionService.java26
7 files changed, 69 insertions, 29 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 0c64c86daf3e..12b1df44b6f5 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4911,7 +4911,8 @@ public final class ActivityThread extends ClientTransactionHandler
Slog.w(TAG, "Activity top position already set to onTop=" + onTop);
return;
}
- throw new IllegalStateException("Activity top position already set to onTop=" + onTop);
+ // TODO(b/197484331): Remove this short-term workaround while fixing the binder failure.
+ Slog.e(TAG, "Activity top position already set to onTop=" + onTop);
}
r.isTopResumedActivity = onTop;
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index e71ed59d2e04..d8346aba4a8f 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -113,6 +113,7 @@
android:layout_width="@dimen/notification_panel_width"
android:layout_height="match_parent"
android:layout_marginBottom="@dimen/close_handle_underlap"
+ android:importantForAccessibility="no"
systemui:layout_constraintStart_toStartOf="parent"
systemui:layout_constraintEnd_toEndOf="parent"
/>
diff --git a/services/core/java/com/android/server/policy/AppOpsPolicy.java b/services/core/java/com/android/server/policy/AppOpsPolicy.java
index 18c45e494c9b..8b4690629ec5 100644
--- a/services/core/java/com/android/server/policy/AppOpsPolicy.java
+++ b/services/core/java/com/android/server/policy/AppOpsPolicy.java
@@ -196,9 +196,8 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat
}
private static boolean isHotwordDetectionServiceRequired(PackageManager pm) {
- // The HotwordDetectionService APIs aren't ready yet for Auto or TV.
- return !(pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
- || pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK));
+ // Usage of the HotwordDetectionService won't be enforced until a later release.
+ return false;
}
@Override
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java
index 9999aff3aa91..2b03fe88a1ec 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java
@@ -125,16 +125,25 @@ public class SoundTriggerMiddlewarePermission implements ISoundTriggerMiddleware
* originator temporarily doesn't have the right permissions to use this service.
*/
private void enforcePermissionsForPreflight(@NonNull Identity identity) {
- enforcePermissionForPreflight(mContext, identity, RECORD_AUDIO);
- enforcePermissionForPreflight(mContext, identity, CAPTURE_AUDIO_HOTWORD);
+ enforcePermissionForPreflight(mContext, identity, RECORD_AUDIO,
+ /* allowSoftDenial= */ true);
+ enforcePermissionForPreflight(mContext, identity, CAPTURE_AUDIO_HOTWORD,
+ /* allowSoftDenial= */ true);
}
/**
* Throws a {@link SecurityException} iff the originator has permission to receive data.
*/
void enforcePermissionsForDataDelivery(@NonNull Identity identity, @NonNull String reason) {
- enforcePermissionForDataDelivery(mContext, identity, RECORD_AUDIO,
- reason);
+ // SoundTrigger data is treated the same as Hotword-source audio. This should incur the
+ // HOTWORD op instead of the RECORD_AUDIO op. The RECORD_AUDIO permission is still required,
+ // and since this is a data delivery check, soft denials aren't accepted.
+ enforcePermissionForPreflight(mContext, identity, RECORD_AUDIO,
+ /* allowSoftDenial= */ false);
+ int hotwordOp = AppOpsManager.strOpToOp(AppOpsManager.OPSTR_RECORD_AUDIO_HOTWORD);
+ mContext.getSystemService(AppOpsManager.class).noteOpNoThrow(hotwordOp, identity.uid,
+ identity.packageName, identity.attributionTag, reason);
+
enforcePermissionForDataDelivery(mContext, identity, CAPTURE_AUDIO_HOTWORD,
reason);
}
@@ -163,20 +172,25 @@ public class SoundTriggerMiddlewarePermission implements ISoundTriggerMiddleware
/**
* Throws a {@link SecurityException} if originator permanently doesn't have the given
* permission.
- * Soft (temporary) denials are considered OK for preflight purposes.
*
- * @param context A {@link Context}, used for permission checks.
- * @param identity The identity to check.
- * @param permission The identifier of the permission we want to check.
+ * @param context A {@link Context}, used for permission checks.
+ * @param identity The identity to check.
+ * @param permission The identifier of the permission we want to check.
+ * @param allowSoftDenial If true, the operation succeeds even for soft (temporary) denials.
*/
+ // TODO: Consider splitting up this method instead of using `allowSoftDenial`, to make it
+ // clearer when soft denials are not allowed.
private static void enforcePermissionForPreflight(@NonNull Context context,
- @NonNull Identity identity, @NonNull String permission) {
+ @NonNull Identity identity, @NonNull String permission, boolean allowSoftDenial) {
final int status = PermissionUtil.checkPermissionForPreflight(context, identity,
permission);
switch (status) {
case PermissionChecker.PERMISSION_GRANTED:
- case PermissionChecker.PERMISSION_SOFT_DENIED:
return;
+ case PermissionChecker.PERMISSION_SOFT_DENIED:
+ if (allowSoftDenial) {
+ return;
+ } // else fall through
case PermissionChecker.PERMISSION_HARD_DENIED:
throw new SecurityException(
String.format("Failed to obtain permission %s for identity %s", permission,
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index 734172fc1549..a9aeb985d115 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -23,11 +23,8 @@ import static android.service.voice.HotwordDetectionService.AUDIO_SOURCE_MICROPH
import static android.service.voice.HotwordDetectionService.INITIALIZATION_STATUS_UNKNOWN;
import static android.service.voice.HotwordDetectionService.KEY_INITIALIZATION_STATUS;
-import static com.android.server.voiceinteraction.SoundTriggerSessionPermissionsDecorator.enforcePermissionForPreflight;
-
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.app.AppOpsManager;
import android.content.ComponentName;
import android.content.ContentCaptureOptions;
import android.content.Context;
@@ -935,11 +932,12 @@ final class HotwordDetectionConnection {
// TODO: Share this code with SoundTriggerMiddlewarePermission.
private void enforcePermissionsForDataDelivery() {
Binder.withCleanCallingIdentity(() -> {
- enforcePermissionForPreflight(mContext, mVoiceInteractorIdentity, RECORD_AUDIO);
- int hotwordOp = AppOpsManager.strOpToOp(AppOpsManager.OPSTR_RECORD_AUDIO_HOTWORD);
- mContext.getSystemService(AppOpsManager.class).noteOpNoThrow(hotwordOp,
- mVoiceInteractorIdentity.uid, mVoiceInteractorIdentity.packageName,
- mVoiceInteractorIdentity.attributionTag, OP_MESSAGE);
+ // Hack to make sure we show the mic privacy-indicator since the Trusted Hotword
+ // requirement isn't being enforced for now. Normally, we would note the HOTWORD op here
+ // instead.
+ enforcePermissionForDataDelivery(mContext, mVoiceInteractorIdentity,
+ RECORD_AUDIO, OP_MESSAGE);
+
enforcePermissionForDataDelivery(mContext, mVoiceInteractorIdentity,
CAPTURE_AUDIO_HOTWORD, OP_MESSAGE);
});
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 759afd72d539..f2f1645b335d 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -775,6 +775,21 @@ public abstract class Connection extends Conferenceable {
"android.telecom.extra.REMOTE_PHONE_ACCOUNT_HANDLE";
/**
+ * The Telecom call ID of the conference an existing connection should be added to. This is
+ * required when {@link com.android.services.telephony.TelephonyConnectionService} adds a
+ * {@link Conference} to Telecom using the
+ * {@link ConnectionService#addExistingConnection(PhoneAccountHandle, Connection, Conference)}
+ * API. That API specifies a parent conference associated with the new existing connection
+ * being added, and there is no equivalent as part of the {@link RemoteConnectionService} API.
+ * This extra key is used to stack the ID of the conference to which the existing connection
+ * will be added so that Telecom can link it up correctly when the {@link RemoteConference}
+ * is added to Telecom by the connection manager.
+ * @hide
+ */
+ public static final String EXTRA_ADD_TO_CONFERENCE_ID =
+ "android.telecom.extra.ADD_TO_CONFERENCE_ID";
+
+ /**
* Extra key set from a {@link ConnectionService} when using the remote connection APIs
* (e.g. {@link RemoteConnectionService#createRemoteConnection(PhoneAccountHandle,
* ConnectionRequest, boolean)}) to create a remote connection. Provides the receiving
diff --git a/telecomm/java/android/telecom/RemoteConnectionService.java b/telecomm/java/android/telecom/RemoteConnectionService.java
index bf6a6ef793ff..efe35d21c003 100644
--- a/telecomm/java/android/telecom/RemoteConnectionService.java
+++ b/telecomm/java/android/telecom/RemoteConnectionService.java
@@ -239,13 +239,9 @@ final class RemoteConnectionService {
conference.addConnection(c);
}
}
- if (conference.getConnections().size() == 0) {
- // A conference was created, but none of its connections are ones that have been
- // created by, and therefore being tracked by, this remote connection service. It
- // is of no interest to us.
- Log.d(this, "addConferenceCall - skipping");
- return;
- }
+ // We used to skip adding empty conferences; however in the world of IMS conference
+ // calls we need to add them to the remote connection service because they will always
+ // start with no participants.
conference.setState(parcel.getState());
conference.setConnectionCapabilities(parcel.getConnectionCapabilities());
@@ -379,6 +375,8 @@ final class RemoteConnectionService {
@Override
public void addExistingConnection(String callId, ParcelableConnection connection,
Session.Info sessionInfo) {
+ Log.i(RemoteConnectionService.this, "addExistingConnection: callId=%s, conn=%s", callId,
+ connection);
String callingPackage = mOurConnectionServiceImpl.getApplicationContext().
getOpPackageName();
int callingTargetSdkVersion = mOurConnectionServiceImpl.getApplicationInfo()
@@ -390,6 +388,20 @@ final class RemoteConnectionService {
Bundle newExtras = new Bundle();
newExtras.putParcelable(Connection.EXTRA_REMOTE_PHONE_ACCOUNT_HANDLE,
connection.getPhoneAccount());
+ if (connection.getParentCallId() != null) {
+ RemoteConference parentConf = mConferenceById.get(connection.getParentCallId());
+ // If there is a parent being set, we need to stash the conference ID here.
+ // Telephony can add an existing connection while specifying a parent conference.
+ // There is no equivalent version of that operation as part of the remote connection
+ // API, so we will stash the pre-defined parent's ID in the extras. When the
+ // connectionmanager copies over the extras from the remote connection to the
+ // actual one, it'll get passed to Telecom so that it can make the association.
+ if (parentConf != null) {
+ newExtras.putString(Connection.EXTRA_ADD_TO_CONFERENCE_ID, parentConf.getId());
+ Log.i(this, "addExistingConnection: stash parent of %s as %s",
+ connection.getParentCallId(), parentConf.getId());
+ }
+ }
remoteConnection.putExtras(newExtras);
mConnectionById.put(callId, remoteConnection);
remoteConnection.registerCallback(new RemoteConnection.Callback() {