Merge "Disallow userLeaving when split drag drop" into 24D1-dev
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index af56cb4..c15105a 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -19,6 +19,7 @@
 import static android.content.pm.PackageManager.PERMISSION_DENIED;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.StrictMode.vmIncorrectContextUseEnabled;
+import static android.permission.flags.Flags.shouldRegisterAttributionSource;
 import static android.view.WindowManager.LayoutParams.WindowType;
 
 import android.annotation.CallbackExecutor;
@@ -3094,7 +3095,8 @@
             int deviceId = vdm.getDeviceIdForDisplayId(displayId);
             if (deviceId != mDeviceId) {
                 mDeviceId = deviceId;
-                mAttributionSource = mAttributionSource.withDeviceId(mDeviceId);
+                mAttributionSource =
+                        createAttributionSourceWithDeviceId(mAttributionSource, mDeviceId);
                 notifyOnDeviceChangedListeners(mDeviceId);
             }
         }
@@ -3117,6 +3119,7 @@
 
         if (mDeviceId != updatedDeviceId) {
             mDeviceId = updatedDeviceId;
+            mAttributionSource = createAttributionSourceWithDeviceId(mAttributionSource, mDeviceId);
             notifyOnDeviceChangedListeners(updatedDeviceId);
         }
     }
@@ -3485,8 +3488,22 @@
                 deviceId, nextAttributionSource);
         // If we want to access protected data on behalf of another app we need to
         // tell the OS that we opt in to participate in the attribution chain.
-        if (nextAttributionSource != null || shouldRegister) {
-            attributionSource = getSystemService(PermissionManager.class)
+        return registerAttributionSourceIfNeeded(attributionSource, shouldRegister);
+    }
+
+    private @NonNull AttributionSource createAttributionSourceWithDeviceId(
+            @NonNull AttributionSource oldSource, int deviceId) {
+        boolean shouldRegister = false;
+        if (shouldRegisterAttributionSource()) {
+            shouldRegister = mParams.shouldRegisterAttributionSource();
+        }
+        return registerAttributionSourceIfNeeded(oldSource.withDeviceId(deviceId), shouldRegister);
+    }
+
+    private @NonNull AttributionSource registerAttributionSourceIfNeeded(
+            @NonNull AttributionSource attributionSource, boolean shouldRegister) {
+        if (shouldRegister || attributionSource.getNext() != null) {
+            return getSystemService(PermissionManager.class)
                     .registerAttributionSource(attributionSource);
         }
         return attributionSource;
diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml
index ce1881a..2f99580 100644
--- a/core/res/res/values/config_telephony.xml
+++ b/core/res/res/values/config_telephony.xml
@@ -373,4 +373,23 @@
     <bool name="config_wait_for_device_alignment_in_demo_datagram">false</bool>
     <java-symbol type="bool" name="config_wait_for_device_alignment_in_demo_datagram" />
 
+    <!-- The time duration in millis after which Telephony will abort the last message datagram
+     sending requests. Telephony starts a timer when receiving a last message datagram sending
+     request in either OFF, IDLE, or NOT_CONNECTED state. In NOT_CONNECTED, the duration of the
+     timer is given by this config.
+     In OFF or IDLE state, the duration of the timer is the sum of this config and the
+     config_satellite_modem_image_switching_duration_millis.
+     -->
+    <integer name="config_datagram_wait_for_connected_state_for_last_message_timeout_millis">60000</integer>
+    <java-symbol type="integer" name="config_datagram_wait_for_connected_state_for_last_message_timeout_millis" />
+
+    <!-- The time duration in millis after which Telephony will abort the last message datagram
+     sending requests and send failure response to the client that has requested sending the
+     datagrams. Telephony starts a timer after pushing down the last message datagram sending
+     request to modem. Before expiry, the timer will be stopped when Telephony receives the response
+     for the sending request from modem.
+     -->
+    <integer name="config_wait_for_datagram_sending_response_for_last_message_timeout_millis">60000</integer>
+    <java-symbol type="integer" name="config_wait_for_datagram_sending_response_for_last_message_timeout_millis" />
+
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index 4916f0b..a2723ce 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -222,7 +222,8 @@
     private Bitmap mScreenBitmap;
     private SaveImageInBackgroundTask mSaveInBgTask;
     private boolean mScreenshotTakenInPortrait;
-    private boolean mBlockAttach;
+    private boolean mAttachRequested;
+    private boolean mDetachRequested;
     private Animator mScreenshotAnimation;
     private RequestCallback mCurrentRequestCallback;
     private ScreenshotActionsProvider mActionsProvider;
@@ -660,7 +661,7 @@
                 () -> {
                     final Intent intent = ActionIntentCreator.INSTANCE.createLongScreenshotIntent(
                             owner, mContext);
-                    mActionIntentExecutor.launchIntentAsync(intent, owner, true, null, null);
+                    mContext.startActivity(intent);
                 },
                 mViewProxy::restoreNonScrollingUi,
                 mViewProxy::startLongScreenshotTransition);
@@ -675,7 +676,7 @@
                     new ViewTreeObserver.OnWindowAttachListener() {
                         @Override
                         public void onWindowAttached() {
-                            mBlockAttach = false;
+                            mAttachRequested = false;
                             decorView.getViewTreeObserver().removeOnWindowAttachListener(this);
                             action.run();
                         }
@@ -691,13 +692,13 @@
     @MainThread
     private void attachWindow() {
         View decorView = mWindow.getDecorView();
-        if (decorView.isAttachedToWindow() || mBlockAttach) {
+        if (decorView.isAttachedToWindow() || mAttachRequested) {
             return;
         }
         if (DEBUG_WINDOW) {
             Log.d(TAG, "attachWindow");
         }
-        mBlockAttach = true;
+        mAttachRequested = true;
         mWindowManager.addView(decorView, mWindowLayoutParams);
         decorView.requestApplyInsets();
 
@@ -715,6 +716,11 @@
                 Log.d(TAG, "Removing screenshot window");
             }
             mWindowManager.removeViewImmediate(decorView);
+            mDetachRequested = false;
+        }
+        if (mAttachRequested && !mDetachRequested) {
+            mDetachRequested = true;
+            withWindowAttached(this::removeWindow);
         }
 
         mViewProxy.stopInputListening();