diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-08-30 02:12:20 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-08-30 02:12:20 +0000 |
commit | e9d071e8333db88a8f81b0fcd21f5f18a3ae8222 (patch) | |
tree | b65e30f0bb6a9aa3a7a3164907d97c5e81a4b70b | |
parent | 115b8514743671277ff9ac6b3d21c8e220d34aa9 (diff) | |
parent | b1c856d5fc454ac0edbf62200fd8903b9315a26b (diff) | |
download | base-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
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() { |