diff options
| author | 2020-08-27 04:23:02 +0000 | |
|---|---|---|
| committer | 2020-08-27 04:23:02 +0000 | |
| commit | 2d0adaf884e2ba8835daa1bd31f792fc35b6c60c (patch) | |
| tree | 46f62d74c68547f692a86218610b137164727d34 | |
| parent | d52541efe9d40b7d0a158aff1eccb4924f2a7de8 (diff) | |
| parent | 02664711e924d13d7053ff8b02be935e1116c6e1 (diff) | |
Merge "Revert "Snap for 6792834 from edbf3411d2c91f38a1a5d93b9e5b338052...""
14 files changed, 153 insertions, 50 deletions
diff --git a/api/test-current.txt b/api/test-current.txt index 529dcf71ef6e..5741fe7e90a4 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -5579,7 +5579,7 @@ package android.window { method @BinderThread public void onTaskInfoChanged(@NonNull android.app.ActivityManager.RunningTaskInfo); method @BinderThread public void onTaskVanished(@NonNull android.app.ActivityManager.RunningTaskInfo); method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public final void registerOrganizer(); - method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void setInterceptBackPressedOnTaskRoot(boolean); + method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void setInterceptBackPressedOnTaskRoot(@NonNull android.window.WindowContainerToken, boolean); method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public static void setLaunchRoot(int, @NonNull android.window.WindowContainerToken); method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public final void unregisterOrganizer(); } diff --git a/core/java/android/inputmethodservice/TEST_MAPPING b/core/java/android/inputmethodservice/TEST_MAPPING new file mode 100644 index 000000000000..0ccd75dcbdce --- /dev/null +++ b/core/java/android/inputmethodservice/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "imports": [ + { + "path": "frameworks/base/core/java/android/view/inputmethod" + } + ] +} diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java index b80718018652..cbc304b3293a 100644 --- a/core/java/android/telephony/PhoneStateListener.java +++ b/core/java/android/telephony/PhoneStateListener.java @@ -950,10 +950,6 @@ public class PhoneStateListener { * This method will be called when an emergency call is placed on any subscription (including * the no-SIM case), regardless of which subscription this listener was registered on. * - * This method is deprecated. Both this method and the new - * {@link #onOutgoingEmergencyCall(EmergencyNumber, int)} will be called when an outgoing - * emergency call is placed. - * * @param placedEmergencyNumber The {@link EmergencyNumber} the emergency call was placed to. * * @deprecated Use {@link #onOutgoingEmergencyCall(EmergencyNumber, int)}. @@ -972,22 +968,24 @@ public class PhoneStateListener { * This method will be called when an emergency call is placed on any subscription (including * the no-SIM case), regardless of which subscription this listener was registered on. * - * Both this method and the deprecated {@link #onOutgoingEmergencyCall(EmergencyNumber)} will be - * called when an outgoing emergency call is placed. You should only implement one of these - * methods. + * The default implementation of this method calls + * {@link #onOutgoingEmergencyCall(EmergencyNumber)} for backwards compatibility purposes. Do + * not call {@code super(...)} from within your implementation unless you want + * {@link #onOutgoingEmergencyCall(EmergencyNumber)} to be called as well. * * @param placedEmergencyNumber The {@link EmergencyNumber} the emergency call was placed to. * @param subscriptionId The subscription ID used to place the emergency call. If the * emergency call was placed without a valid subscription (e.g. when there * are no SIM cards in the device), this will be equal to * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}. - * * @hide */ @SystemApi @TestApi public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber, int subscriptionId) { + // Default implementation for backwards compatibility + onOutgoingEmergencyCall(placedEmergencyNumber); } /** @@ -1375,10 +1373,6 @@ public class PhoneStateListener { Binder.withCleanCallingIdentity( () -> mExecutor.execute( - () -> psl.onOutgoingEmergencyCall(placedEmergencyNumber))); - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute( () -> psl.onOutgoingEmergencyCall(placedEmergencyNumber, subscriptionId))); } diff --git a/core/java/android/view/inputmethod/TEST_MAPPING b/core/java/android/view/inputmethod/TEST_MAPPING new file mode 100644 index 000000000000..4b2ea1a096c8 --- /dev/null +++ b/core/java/android/view/inputmethod/TEST_MAPPING @@ -0,0 +1,18 @@ +{ + "presubmit": [ + { + "name": "CtsAutoFillServiceTestCases", + "options": [ + { + "include-filter": "android.autofillservice.cts.inline" + }, + { + "exclude-annotation": "androidx.test.filters.FlakyTest" + }, + { + "exclude-annotation": "android.platform.test.annotations.AppModeFull" + } + ] + } + ] +} diff --git a/core/java/android/window/ITaskOrganizerController.aidl b/core/java/android/window/ITaskOrganizerController.aidl index 92fa80e40caf..12b16ff6645c 100644 --- a/core/java/android/window/ITaskOrganizerController.aidl +++ b/core/java/android/window/ITaskOrganizerController.aidl @@ -60,5 +60,6 @@ interface ITaskOrganizerController { * Requests that the given task organizer is notified when back is pressed on the root activity * of one of its controlled tasks. */ - void setInterceptBackPressedOnTaskRoot(ITaskOrganizer organizer, boolean interceptBackPressed); + void setInterceptBackPressedOnTaskRoot(in WindowContainerToken task, + boolean interceptBackPressed); } diff --git a/core/java/android/window/TaskOrganizer.java b/core/java/android/window/TaskOrganizer.java index 7ec4f99ce959..38fb023a0822 100644 --- a/core/java/android/window/TaskOrganizer.java +++ b/core/java/android/window/TaskOrganizer.java @@ -149,9 +149,10 @@ public class TaskOrganizer extends WindowOrganizer { * of one of its controlled tasks. */ @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) - public void setInterceptBackPressedOnTaskRoot(boolean interceptBackPressed) { + public void setInterceptBackPressedOnTaskRoot(@NonNull WindowContainerToken task, + boolean interceptBackPressed) { try { - getController().setInterceptBackPressedOnTaskRoot(mInterface, interceptBackPressed); + getController().setInterceptBackPressedOnTaskRoot(task, interceptBackPressed); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/window/TaskOrganizerTaskEmbedder.java b/core/java/android/window/TaskOrganizerTaskEmbedder.java index 46c72f88e14b..eb9dfed7f644 100644 --- a/core/java/android/window/TaskOrganizerTaskEmbedder.java +++ b/core/java/android/window/TaskOrganizerTaskEmbedder.java @@ -74,7 +74,7 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder { // windowing mode tasks. Plan is to migrate this to a wm-shell front-end when that // infrastructure is ready. // mTaskOrganizer.registerOrganizer(); - mTaskOrganizer.setInterceptBackPressedOnTaskRoot(true); + // mTaskOrganizer.setInterceptBackPressedOnTaskRoot(true); return super.onInitialize(); } diff --git a/media/packages/BluetoothMidiService/AndroidManifest.xml b/media/packages/BluetoothMidiService/AndroidManifest.xml index b88bf2a0b2b7..fc96fd926e2d 100644 --- a/media/packages/BluetoothMidiService/AndroidManifest.xml +++ b/media/packages/BluetoothMidiService/AndroidManifest.xml @@ -19,8 +19,6 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.android.bluetoothmidiservice" - android:versionCode="1" - android:versionName="R-initial" > <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29" /> diff --git a/media/packages/BluetoothMidiService/AndroidManifestBase.xml b/media/packages/BluetoothMidiService/AndroidManifestBase.xml index ebe62b039434..bfb05469adb9 100644 --- a/media/packages/BluetoothMidiService/AndroidManifestBase.xml +++ b/media/packages/BluetoothMidiService/AndroidManifestBase.xml @@ -18,8 +18,6 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.bluetoothmidiservice" - android:versionCode="1" - android:versionName="R-initial" > <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29" /> <application diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java index 51ad30ebcac6..78f83d3c09b4 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java @@ -49,6 +49,7 @@ import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Color; import android.graphics.PixelFormat; +import android.graphics.Region; import android.graphics.drawable.ColorDrawable; import android.media.AudioManager; import android.media.AudioSystem; @@ -71,6 +72,7 @@ import android.view.View.AccessibilityDelegate; import android.view.ViewGroup; import android.view.ViewPropertyAnimator; import android.view.ViewStub; +import android.view.ViewTreeObserver; import android.view.Window; import android.view.WindowManager; import android.view.accessibility.AccessibilityEvent; @@ -109,7 +111,8 @@ import java.util.List; * Methods ending in "H" must be called on the (ui) handler. */ public class VolumeDialogImpl implements VolumeDialog, - ConfigurationController.ConfigurationListener { + ConfigurationController.ConfigurationListener, + ViewTreeObserver.OnComputeInternalInsetsListener { private static final String TAG = Util.logTag(VolumeDialogImpl.class); private static final long USER_ATTEMPT_GRACE_PERIOD = 1000; @@ -126,6 +129,7 @@ public class VolumeDialogImpl implements VolumeDialog, private final H mHandler = new H(); private final VolumeDialogController mController; private final DeviceProvisionedController mDeviceProvisionedController; + private final Region mTouchableRegion = new Region(); private Window mWindow; private CustomDialog mDialog; @@ -204,6 +208,33 @@ public class VolumeDialogImpl implements VolumeDialog, Dependency.get(ConfigurationController.class).removeCallback(this); } + @Override + public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo internalInsetsInfo) { + // Set touchable region insets on the root dialog view. This tells WindowManager that + // touches outside of this region should not be delivered to the volume window, and instead + // go to the window below. This is the only way to do this - returning false in + // onDispatchTouchEvent results in the event being ignored entirely, rather than passed to + // the next window. + internalInsetsInfo.setTouchableInsets( + ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION); + + mTouchableRegion.setEmpty(); + + // Set the touchable region to the union of all child view bounds. We don't use touches on + // the volume dialog container itself, so this is fine. + for (int i = 0; i < mDialogView.getChildCount(); i++) { + final View view = mDialogView.getChildAt(i); + mTouchableRegion.op( + view.getLeft(), + view.getTop(), + view.getRight(), + view.getBottom(), + Region.Op.UNION); + } + + internalInsetsInfo.touchableRegion.set(mTouchableRegion); + } + private void initDialog() { mDialog = new CustomDialog(mContext); @@ -235,6 +266,7 @@ public class VolumeDialogImpl implements VolumeDialog, mDialogView.setAlpha(0); mDialog.setCanceledOnTouchOutside(true); mDialog.setOnShowListener(dialog -> { + mDialogView.getViewTreeObserver().addOnComputeInternalInsetsListener(this); if (!isLandscape()) mDialogView.setTranslationX(mDialogView.getWidth() / 2.0f); mDialogView.setAlpha(0); mDialogView.animate() @@ -253,6 +285,11 @@ public class VolumeDialogImpl implements VolumeDialog, .start(); }); + mDialog.setOnDismissListener(dialogInterface -> + mDialogView + .getViewTreeObserver() + .removeOnComputeInternalInsetsListener(VolumeDialogImpl.this)); + mDialogView.setOnHoverListener((v, event) -> { int action = event.getActionMasked(); mHovering = (action == MotionEvent.ACTION_HOVER_ENTER) @@ -1369,6 +1406,11 @@ public class VolumeDialogImpl implements VolumeDialog, super(context, R.style.volume_dialog_theme); } + /** + * NOTE: This will only be called for touches within the touchable region of the volume + * dialog, as returned by {@link #onComputeInternalInsets}. Other touches, even if they are + * within the bounds of the volume dialog, will fall through to the window below. + */ @Override public boolean dispatchTouchEvent(MotionEvent ev) { rescheduleTimeoutH(); @@ -1387,6 +1429,12 @@ public class VolumeDialogImpl implements VolumeDialog, mHandler.sendEmptyMessage(H.RECHECK_ALL); } + /** + * NOTE: This will be called with ACTION_OUTSIDE MotionEvents for touches that occur outside + * of the touchable region of the volume dialog (as returned by + * {@link #onComputeInternalInsets}) even if those touches occurred within the bounds of the + * volume dialog. + */ @Override public boolean onTouchEvent(MotionEvent event) { if (mShowing) { diff --git a/services/core/java/com/android/server/inputmethod/TEST_MAPPING b/services/core/java/com/android/server/inputmethod/TEST_MAPPING new file mode 100644 index 000000000000..0ccd75dcbdce --- /dev/null +++ b/services/core/java/com/android/server/inputmethod/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "imports": [ + { + "path": "frameworks/base/core/java/android/view/inputmethod" + } + ] +} diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java index 1b779c6a0cc9..63a595e3bc17 100644 --- a/services/core/java/com/android/server/wm/TaskOrganizerController.java +++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java @@ -38,6 +38,7 @@ import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; import android.util.Slog; +import android.util.SparseBooleanArray; import android.view.SurfaceControl; import android.window.ITaskOrganizer; import android.window.ITaskOrganizerController; @@ -50,6 +51,7 @@ import com.android.internal.util.ArrayUtils; import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; @@ -206,7 +208,6 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { private final DeathRecipient mDeathRecipient; private final ArrayList<Task> mOrganizedTasks = new ArrayList<>(); private final int mUid; - private boolean mInterceptBackPressedOnTaskRoot; TaskOrganizerState(ITaskOrganizer organizer, int uid) { final Consumer<Runnable> deferTaskOrgCallbacksConsumer = @@ -224,10 +225,6 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { mUid = uid; } - void setInterceptBackPressedOnTaskRoot(boolean interceptBackPressed) { - mInterceptBackPressedOnTaskRoot = interceptBackPressed; - } - void addTask(Task t) { if (t.mTaskAppearedSent) return; @@ -247,6 +244,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { mOrganizer.onTaskVanished(t); } mOrganizedTasks.remove(t); + mInterceptBackPressedOnRootTasks.remove(t.mTaskId); } void dispose() { @@ -278,6 +276,8 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { private final HashMap<IBinder, TaskOrganizerState> mTaskOrganizerStates = new HashMap<>(); private final WeakHashMap<Task, RunningTaskInfo> mLastSentTaskInfos = new WeakHashMap<>(); private final ArrayList<Task> mPendingTaskInfoChanges = new ArrayList<>(); + // Set of organized tasks (by taskId) that dispatch back pressed to their organizers + private final HashSet<Integer> mInterceptBackPressedOnRootTasks = new HashSet(); private final ActivityTaskManagerService mService; @@ -623,7 +623,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { } @Override - public void setInterceptBackPressedOnTaskRoot(ITaskOrganizer organizer, + public void setInterceptBackPressedOnTaskRoot(WindowContainerToken token, boolean interceptBackPressed) { enforceStackPermission("setInterceptBackPressedOnTaskRoot()"); final long origId = Binder.clearCallingIdentity(); @@ -631,9 +631,15 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { synchronized (mGlobalLock) { ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Set intercept back pressed on root=%b", interceptBackPressed); - final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder()); - if (state != null) { - state.setInterceptBackPressedOnTaskRoot(interceptBackPressed); + final Task task = WindowContainer.fromBinder(token.asBinder()).asTask(); + if (task == null) { + Slog.w(TAG, "Could not resolve task from token"); + return; + } + if (interceptBackPressed) { + mInterceptBackPressedOnRootTasks.add(task.mTaskId); + } else { + mInterceptBackPressedOnRootTasks.remove(task.mTaskId); } } } finally { @@ -642,15 +648,12 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { } public boolean handleInterceptBackPressedOnTaskRoot(Task task) { - if (task == null || !task.isOrganized()) { + if (task == null || !task.isOrganized() + || !mInterceptBackPressedOnRootTasks.contains(task.mTaskId)) { return false; } final TaskOrganizerState state = mTaskOrganizerStates.get(task.mTaskOrganizer.asBinder()); - if (!state.mInterceptBackPressedOnTaskRoot) { - return false; - } - state.mOrganizer.onBackPressedOnTaskRoot(task); return true; } diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java index 289d54e967f5..46a6a82faba5 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java @@ -930,23 +930,36 @@ public class WindowOrganizerTests extends WindowTestsBase { final Task stack = createStack(); final Task task = createTask(stack); final ActivityRecord activity = createActivityRecordInTask(stack.mDisplayContent, task); + final Task stack2 = createStack(); + final Task task2 = createTask(stack2); + final ActivityRecord activity2 = createActivityRecordInTask(stack.mDisplayContent, task2); final ITaskOrganizer organizer = registerMockOrganizer(); // Setup the task to be controlled by the MW mode organizer stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW); + stack2.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW); assertTrue(stack.isOrganized()); + assertTrue(stack2.isOrganized()); // Verify a back pressed does not call the organizer mWm.mAtmService.onBackPressedOnTaskRoot(activity.token); verify(organizer, never()).onBackPressedOnTaskRoot(any()); // Enable intercepting back - mWm.mAtmService.mTaskOrganizerController.setInterceptBackPressedOnTaskRoot(organizer, - true); + mWm.mAtmService.mTaskOrganizerController.setInterceptBackPressedOnTaskRoot( + stack.mRemoteToken.toWindowContainerToken(), true); // Verify now that the back press does call the organizer mWm.mAtmService.onBackPressedOnTaskRoot(activity.token); verify(organizer, times(1)).onBackPressedOnTaskRoot(any()); + + // Disable intercepting back + mWm.mAtmService.mTaskOrganizerController.setInterceptBackPressedOnTaskRoot( + stack.mRemoteToken.toWindowContainerToken(), false); + + // Verify now that the back press no longer calls the organizer + mWm.mAtmService.onBackPressedOnTaskRoot(activity.token); + verify(organizer, times(1)).onBackPressedOnTaskRoot(any()); } @Test diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java index 81aad972898e..f151d9ca2420 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UsageStatsService.java @@ -183,6 +183,7 @@ public class UsageStatsService extends SystemService implements private static class ActivityData { private final String mTaskRootPackage; private final String mTaskRootClass; + public int lastEvent = Event.NONE; private ActivityData(String taskRootPackage, String taskRootClass) { mTaskRootPackage = taskRootPackage; mTaskRootClass = taskRootClass; @@ -785,6 +786,7 @@ public class UsageStatsService extends SystemService implements switch (event.mEventType) { case Event.ACTIVITY_RESUMED: case Event.ACTIVITY_PAUSED: + case Event.ACTIVITY_STOPPED: uid = mPackageManagerInternal.getPackageUid(event.mPackage, 0, userId); break; default: @@ -817,8 +819,10 @@ public class UsageStatsService extends SystemService implements .APP_USAGE_EVENT_OCCURRED__EVENT_TYPE__MOVE_TO_FOREGROUND); // check if this activity has already been resumed if (mVisibleActivities.get(event.mInstanceId) != null) break; - mVisibleActivities.put(event.mInstanceId, - new ActivityData(event.mTaskRootPackage, event.mTaskRootClass)); + final ActivityData resumedData = new ActivityData(event.mTaskRootPackage, + event.mTaskRootClass); + resumedData.lastEvent = Event.ACTIVITY_RESUMED; + mVisibleActivities.put(event.mInstanceId, resumedData); try { switch(mUsageSource) { case USAGE_SOURCE_CURRENT_ACTIVITY: @@ -834,16 +838,17 @@ public class UsageStatsService extends SystemService implements } break; case Event.ACTIVITY_PAUSED: - if (event.mTaskRootPackage == null) { - // Task Root info is missing. Repair the event based on previous data - final ActivityData prevData = mVisibleActivities.get(event.mInstanceId); - if (prevData == null) { - Slog.w(TAG, "Unexpected activity event reported! (" + event.mPackage - + "/" + event.mClass + " event : " + event.mEventType - + " instanceId : " + event.mInstanceId + ")"); - } else { - event.mTaskRootPackage = prevData.mTaskRootPackage; - event.mTaskRootClass = prevData.mTaskRootClass; + final ActivityData pausedData = mVisibleActivities.get(event.mInstanceId); + if (pausedData == null) { + Slog.w(TAG, "Unexpected activity event reported! (" + event.mPackage + + "/" + event.mClass + " event : " + event.mEventType + + " instanceId : " + event.mInstanceId + ")"); + } else { + pausedData.lastEvent = Event.ACTIVITY_PAUSED; + if (event.mTaskRootPackage == null) { + // Task Root info is missing. Repair the event based on previous data + event.mTaskRootPackage = pausedData.mTaskRootPackage; + event.mTaskRootClass = pausedData.mTaskRootClass; } } FrameworkStatsLog.write( @@ -866,6 +871,16 @@ public class UsageStatsService extends SystemService implements return; } + if (prevData.lastEvent != Event.ACTIVITY_PAUSED) { + FrameworkStatsLog.write( + FrameworkStatsLog.APP_USAGE_EVENT_OCCURRED, + uid, + event.mPackage, + event.mClass, + FrameworkStatsLog + .APP_USAGE_EVENT_OCCURRED__EVENT_TYPE__MOVE_TO_BACKGROUND); + } + ArraySet<String> tokens; synchronized (mUsageReporters) { tokens = mUsageReporters.removeReturnOld(event.mInstanceId); |