blob: 20ec05b1f0f9c0b60f4f92a977d6f22881941315 [file] [log] [blame]
Winson73bc1592016-10-18 18:47:43 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.systemui.pip.phone;
18
Arthur Hungd52d1192019-08-30 16:06:59 +080019import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
20import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
21
Sudheer Shankadc589ac2016-11-10 15:30:17 -080022import android.app.ActivityManager;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070023import android.app.ActivityTaskManager;
Winson73bc1592016-10-18 18:47:43 -070024import android.app.IActivityManager;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070025import android.app.IActivityTaskManager;
Winson Chung3535df22017-01-17 18:43:39 -080026import android.content.ComponentName;
Winson73bc1592016-10-18 18:47:43 -070027import android.content.Context;
Winson Chunga29eb982016-12-14 12:01:27 -080028import android.content.pm.ParceledListSlice;
Winson Chung0c5a5922017-05-22 17:41:06 -070029import android.content.res.Configuration;
Winson Chung2a82fe52017-02-02 14:43:34 -080030import android.graphics.Rect;
Winson Chunga29eb982016-12-14 12:01:27 -080031import android.os.Handler;
32import android.os.RemoteException;
33import android.util.Log;
Winson Chung85d3c8a2017-09-15 15:41:00 -070034import android.util.Pair;
Hongwei Wang43a752b2019-09-17 20:20:30 +000035import android.view.DisplayInfo;
Winson Chunga29eb982016-12-14 12:01:27 -080036import android.view.IPinnedStackController;
Hongwei Wangebf18082019-09-26 14:25:11 -070037import android.view.WindowContainerTransaction;
Gus Prevasab336792018-11-14 13:52:20 -050038
Winson Chung67f5c8b2018-09-24 12:09:19 -070039import com.android.systemui.Dependency;
40import com.android.systemui.UiOffloadThread;
Fabian Kozynski5ca7a512019-10-16 19:56:11 +000041import com.android.systemui.broadcast.BroadcastDispatcher;
Winson Chung29a78652017-02-09 18:35:26 -080042import com.android.systemui.pip.BasePipManager;
Hongwei Wang43a752b2019-09-17 20:20:30 +000043import com.android.systemui.pip.PipBoundsHandler;
jorgegil@google.com5bdec5f2020-02-28 13:14:39 -080044import com.android.systemui.pip.PipSnapAlgorithm;
Hongwei Wang85cf41f2020-01-15 15:14:47 -080045import com.android.systemui.pip.PipTaskOrganizer;
46import com.android.systemui.shared.recents.IPinnedStackAnimationListener;
Winson Chungaa357452017-10-31 11:35:30 -070047import com.android.systemui.shared.system.ActivityManagerWrapper;
Winson Chungcbb15a92018-01-25 17:46:16 +000048import com.android.systemui.shared.system.InputConsumerController;
Hongwei Wang43a752b2019-09-17 20:20:30 +000049import com.android.systemui.shared.system.PinnedStackListenerForwarder.PinnedStackListener;
Winson Chung67f5c8b2018-09-24 12:09:19 -070050import com.android.systemui.shared.system.TaskStackChangeListener;
51import com.android.systemui.shared.system.WindowManagerWrapper;
Beverly660d0a72020-02-26 12:32:42 -050052import com.android.systemui.util.DeviceConfigProxy;
Joshua Tsujic81ff3d2020-02-13 14:48:40 -050053import com.android.systemui.util.FloatingContentCoordinator;
Winson Chung95c9fca2020-01-22 09:48:40 -080054import com.android.systemui.wm.DisplayChangeController;
55import com.android.systemui.wm.DisplayController;
Gus Prevasab336792018-11-14 13:52:20 -050056
Winson Chung29a78652017-02-09 18:35:26 -080057import java.io.PrintWriter;
58
Dave Mankofff5019142019-12-20 16:22:57 -050059import javax.inject.Inject;
60import javax.inject.Singleton;
61
Winson73bc1592016-10-18 18:47:43 -070062/**
63 * Manages the picture-in-picture (PIP) UI and states for Phones.
64 */
Dave Mankofff5019142019-12-20 16:22:57 -050065@Singleton
Hongwei Wang85cf41f2020-01-15 15:14:47 -080066public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitionCallback {
Winson73bc1592016-10-18 18:47:43 -070067 private static final String TAG = "PipManager";
68
Winson73bc1592016-10-18 18:47:43 -070069 private Context mContext;
70 private IActivityManager mActivityManager;
Winson Chunga29eb982016-12-14 12:01:27 -080071 private Handler mHandler = new Handler();
72
Hongwei Wang43a752b2019-09-17 20:20:30 +000073 private final DisplayInfo mTmpDisplayInfo = new DisplayInfo();
74 private final Rect mTmpInsetBounds = new Rect();
75 private final Rect mTmpNormalBounds = new Rect();
jorgegil@google.com62f735e2019-10-30 14:37:19 -070076 private final Rect mReentryBounds = new Rect();
Winson73bc1592016-10-18 18:47:43 -070077
Hongwei Wang43a752b2019-09-17 20:20:30 +000078 private PipBoundsHandler mPipBoundsHandler;
Winson Chungd2d90972017-02-28 11:40:41 -080079 private InputConsumerController mInputConsumerController;
Winson Chung15504af2016-11-02 18:11:36 -070080 private PipMenuActivityController mMenuController;
Winson Chung97a60d92017-01-18 16:01:53 -080081 private PipMediaController mMediaController;
Winson73bc1592016-10-18 18:47:43 -070082 private PipTouchHandler mTouchHandler;
Hongwei Wang85cf41f2020-01-15 15:14:47 -080083 private PipTaskOrganizer mPipTaskOrganizer;
Winson Chung95bccdc2018-01-03 11:45:47 -080084 private PipAppOpsListener mAppOpsListener;
Hongwei Wang85cf41f2020-01-15 15:14:47 -080085 private IPinnedStackAnimationListener mPinnedStackAnimationRecentsListener;
Winson73bc1592016-10-18 18:47:43 -070086
Winson Chunga29eb982016-12-14 12:01:27 -080087 /**
Hongwei Wangebf18082019-09-26 14:25:11 -070088 * Handler for display rotation changes.
89 */
Winson Chung95c9fca2020-01-22 09:48:40 -080090 private final DisplayChangeController.OnDisplayChangingListener mRotationController = (
Hongwei Wangebf18082019-09-26 14:25:11 -070091 int displayId, int fromRotation, int toRotation, WindowContainerTransaction t) -> {
92 final boolean changed = mPipBoundsHandler.onDisplayRotationChanged(mTmpNormalBounds,
93 displayId, fromRotation, toRotation, t);
94 if (changed) {
95 updateMovementBounds(mTmpNormalBounds, false /* fromImeAdjustment */,
96 false /* fromShelfAdjustment */);
97 }
98 };
99
100 /**
Winson Chung929d4f72017-01-13 10:21:33 -0800101 * Handler for system task stack changes.
102 */
Hongwei Wangebf18082019-09-26 14:25:11 -0700103 private final TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
Winson Chung929d4f72017-01-13 10:21:33 -0800104 @Override
Wale Ogunwale89be5762017-10-04 13:27:49 -0700105 public void onActivityPinned(String packageName, int userId, int taskId, int stackId) {
Winson Chung929d4f72017-01-13 10:21:33 -0800106 mTouchHandler.onActivityPinned();
Winson Chung97a60d92017-01-18 16:01:53 -0800107 mMediaController.onActivityPinned();
Winson Chungd2d90972017-02-28 11:40:41 -0800108 mMenuController.onActivityPinned();
Winson Chung95bccdc2018-01-03 11:45:47 -0800109 mAppOpsListener.onActivityPinned(packageName);
Winson Chungac52f282017-03-30 14:44:52 -0700110
Dave Mankoffc7cf9fc2019-12-19 15:43:20 -0500111 Dependency.get(UiOffloadThread.class).execute(() -> {
Winson Chung67f5c8b2018-09-24 12:09:19 -0700112 WindowManagerWrapper.getInstance().setPipVisibility(true);
113 });
Winson Chungc81c0ce2017-03-17 12:27:30 -0700114 }
115
116 @Override
117 public void onActivityUnpinned() {
Winson Chung85d3c8a2017-09-15 15:41:00 -0700118 final Pair<ComponentName, Integer> topPipActivityInfo = PipUtils.getTopPinnedActivity(
119 mContext, mActivityManager);
120 final ComponentName topActivity = topPipActivityInfo.first;
Winson Chung85d3c8a2017-09-15 15:41:00 -0700121 mMenuController.onActivityUnpinned();
122 mTouchHandler.onActivityUnpinned(topActivity);
Winson Chung95bccdc2018-01-03 11:45:47 -0800123 mAppOpsListener.onActivityUnpinned();
Winson Chungac52f282017-03-30 14:44:52 -0700124
Dave Mankoffc7cf9fc2019-12-19 15:43:20 -0500125 Dependency.get(UiOffloadThread.class).execute(() -> {
Winson Chung67f5c8b2018-09-24 12:09:19 -0700126 WindowManagerWrapper.getInstance().setPipVisibility(topActivity != null);
127 });
Winson Chung929d4f72017-01-13 10:21:33 -0800128 }
129
130 @Override
Winson Chunge6385a22017-05-02 18:15:16 -0700131 public void onPinnedActivityRestartAttempt(boolean clearedTask) {
Winson Chunge6385a22017-05-02 18:15:16 -0700132 mTouchHandler.getMotionHelper().expandPip(clearedTask /* skipAnimation */);
Winson Chung929d4f72017-01-13 10:21:33 -0800133 }
134 };
135
136 /**
Winson Chunga29eb982016-12-14 12:01:27 -0800137 * Handler for messages from the PIP controller.
138 */
Hongwei Wang43a752b2019-09-17 20:20:30 +0000139 private class PipManagerPinnedStackListener extends PinnedStackListener {
Winson Chunga29eb982016-12-14 12:01:27 -0800140 @Override
141 public void onListenerRegistered(IPinnedStackController controller) {
Hongwei Wang85cf41f2020-01-15 15:14:47 -0800142 mHandler.post(() -> mTouchHandler.setPinnedStackController(controller));
Winson Chunga29eb982016-12-14 12:01:27 -0800143 }
144
145 @Override
Winson Chung2a82fe52017-02-02 14:43:34 -0800146 public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
Winson Chunga29eb982016-12-14 12:01:27 -0800147 mHandler.post(() -> {
Hongwei Wang43a752b2019-09-17 20:20:30 +0000148 mPipBoundsHandler.onImeVisibilityChanged(imeVisible, imeHeight);
Winson Chung2a82fe52017-02-02 14:43:34 -0800149 mTouchHandler.onImeVisibilityChanged(imeVisible, imeHeight);
Winson Chunga29eb982016-12-14 12:01:27 -0800150 });
151 }
152
153 @Override
Hongwei Wang85cf41f2020-01-15 15:14:47 -0800154 public void onMovementBoundsChanged(Rect animatingBounds, boolean fromImeAdjustment) {
Hongwei Wang9b751802019-09-11 12:13:21 -0700155 mHandler.post(() -> updateMovementBounds(animatingBounds, fromImeAdjustment,
Hongwei Wang85cf41f2020-01-15 15:14:47 -0800156 false /* fromShelfAdjustment */));
Winson Chung2a82fe52017-02-02 14:43:34 -0800157 }
158
159 @Override
160 public void onActionsChanged(ParceledListSlice actions) {
Hongwei Wang43a752b2019-09-17 20:20:30 +0000161 mHandler.post(() -> mMenuController.setAppActions(actions));
162 }
163
164 @Override
jorgegil@google.com62f735e2019-10-30 14:37:19 -0700165 public void onSaveReentryBounds(ComponentName componentName, Rect bounds) {
166 mHandler.post(() -> {
167 // On phones, the expansion animation that happens on pip tap before restoring
168 // to fullscreen makes it so that the bounds received here are the expanded
169 // bounds. We want to restore to the unexpanded bounds when re-entering pip,
170 // so we save the bounds before expansion (normal) instead of the current
171 // bounds.
172 mReentryBounds.set(mTouchHandler.getNormalBounds());
173 // Apply the snap fraction of the current bounds to the normal bounds.
174 float snapFraction = mPipBoundsHandler.getSnapFraction(bounds);
175 mPipBoundsHandler.applySnapFraction(mReentryBounds, snapFraction);
176 // Save reentry bounds (normal non-expand bounds with current position applied).
177 mPipBoundsHandler.onSaveReentryBounds(componentName, mReentryBounds);
178 });
Hongwei Wang43a752b2019-09-17 20:20:30 +0000179 }
180
181 @Override
jorgegil@google.com62f735e2019-10-30 14:37:19 -0700182 public void onResetReentryBounds(ComponentName componentName) {
183 mHandler.post(() -> mPipBoundsHandler.onResetReentryBounds(componentName));
Hongwei Wang43a752b2019-09-17 20:20:30 +0000184 }
185
186 @Override
187 public void onDisplayInfoChanged(DisplayInfo displayInfo) {
Hongwei Wang89f18ff2020-03-10 10:24:35 -0700188 mHandler.post(() -> mPipBoundsHandler.onDisplayInfoChanged(displayInfo));
Hongwei Wang43a752b2019-09-17 20:20:30 +0000189 }
190
191 @Override
192 public void onConfigurationChanged() {
193 mHandler.post(() -> mPipBoundsHandler.onConfigurationChanged());
194 }
195
196 @Override
197 public void onAspectRatioChanged(float aspectRatio) {
198 mHandler.post(() -> mPipBoundsHandler.onAspectRatioChanged(aspectRatio));
199 }
Winson Chunga29eb982016-12-14 12:01:27 -0800200 }
201
Dave Mankofff5019142019-12-20 16:22:57 -0500202 @Inject
203 public PipManager(Context context, BroadcastDispatcher broadcastDispatcher,
Joshua Tsujic81ff3d2020-02-13 14:48:40 -0500204 DisplayController displayController,
Beverly660d0a72020-02-26 12:32:42 -0500205 FloatingContentCoordinator floatingContentCoordinator,
jorgegil@google.com5bdec5f2020-02-28 13:14:39 -0800206 DeviceConfigProxy deviceConfig,
207 PipBoundsHandler pipBoundsHandler,
208 PipSnapAlgorithm pipSnapAlgorithm) {
Winson73bc1592016-10-18 18:47:43 -0700209 mContext = context;
Sudheer Shankadc589ac2016-11-10 15:30:17 -0800210 mActivityManager = ActivityManager.getService();
Winson73bc1592016-10-18 18:47:43 -0700211
Winson Chunga29eb982016-12-14 12:01:27 -0800212 try {
Hongwei Wangea2ae852020-02-27 13:47:52 -0800213 WindowManagerWrapper.getInstance().addPinnedStackListener(
214 new PipManagerPinnedStackListener());
Winson Chunga29eb982016-12-14 12:01:27 -0800215 } catch (RemoteException e) {
216 Log.e(TAG, "Failed to register pinned stack listener", e);
217 }
Winson Chung2cf6ad82017-11-09 17:36:59 -0800218 ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
Winson Chunga29eb982016-12-14 12:01:27 -0800219
Hongwei Wang85cf41f2020-01-15 15:14:47 -0800220 final IActivityTaskManager activityTaskManager = ActivityTaskManager.getService();
jorgegil@google.com5bdec5f2020-02-28 13:14:39 -0800221 mPipBoundsHandler = pipBoundsHandler;
Hongwei Wang85cf41f2020-01-15 15:14:47 -0800222 mPipTaskOrganizer = new PipTaskOrganizer(mContext, mPipBoundsHandler);
223 mPipTaskOrganizer.registerPipTransitionCallback(this);
Winson Chungcbb15a92018-01-25 17:46:16 +0000224 mInputConsumerController = InputConsumerController.getPipInputConsumer();
Fabian Kozynski5ca7a512019-10-16 19:56:11 +0000225 mMediaController = new PipMediaController(context, mActivityManager, broadcastDispatcher);
Hongwei Wang85cf41f2020-01-15 15:14:47 -0800226 mMenuController = new PipMenuActivityController(context, mMediaController,
Winson Chungd2d90972017-02-28 11:40:41 -0800227 mInputConsumerController);
Hongwei Wang85cf41f2020-01-15 15:14:47 -0800228 mTouchHandler = new PipTouchHandler(context, mActivityManager, activityTaskManager,
229 mMenuController, mInputConsumerController, mPipBoundsHandler, mPipTaskOrganizer,
jorgegil@google.com5bdec5f2020-02-28 13:14:39 -0800230 floatingContentCoordinator, deviceConfig, pipSnapAlgorithm);
Winson Chung95bccdc2018-01-03 11:45:47 -0800231 mAppOpsListener = new PipAppOpsListener(context, mActivityManager,
232 mTouchHandler.getMotionHelper());
Winson Chung95c9fca2020-01-22 09:48:40 -0800233 displayController.addDisplayChangingController(mRotationController);
Arthur Hungd52d1192019-08-30 16:06:59 +0800234
Winson Chung77338ab2020-03-09 16:32:34 -0700235 // Ensure that we have the display info in case we get calls to update the bounds before the
236 // listener calls back
237 final DisplayInfo displayInfo = new DisplayInfo();
238 context.getDisplay().getDisplayInfo(displayInfo);
239 mPipBoundsHandler.onDisplayInfoChanged(displayInfo);
240
Arthur Hungd52d1192019-08-30 16:06:59 +0800241 try {
Hongwei Wang85cf41f2020-01-15 15:14:47 -0800242 ActivityTaskManager.getTaskOrganizerController().registerTaskOrganizer(
243 mPipTaskOrganizer, WINDOWING_MODE_PINNED);
244 ActivityManager.StackInfo stackInfo = activityTaskManager.getStackInfo(
Arthur Hungd52d1192019-08-30 16:06:59 +0800245 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
246 if (stackInfo != null) {
Hongwei Wang85cf41f2020-01-15 15:14:47 -0800247 // If SystemUI restart, and it already existed a pinned stack,
248 // register the pip input consumer to ensure touch can send to it.
Arthur Hungd52d1192019-08-30 16:06:59 +0800249 mInputConsumerController.registerInputConsumer();
250 }
251 } catch (RemoteException e) {
252 e.printStackTrace();
253 }
Winson73bc1592016-10-18 18:47:43 -0700254 }
255
256 /**
257 * Updates the PIP per configuration changed.
258 */
Winson Chung0c5a5922017-05-22 17:41:06 -0700259 public void onConfigurationChanged(Configuration newConfig) {
Winson Chung303c6b72016-10-24 17:12:49 -0700260 mTouchHandler.onConfigurationChanged();
261 }
Winson73bc1592016-10-18 18:47:43 -0700262
263 /**
Winson Chungb5026902017-05-03 12:45:13 -0700264 * Expands the PIP.
265 */
Winson Chung2dbcf092018-10-24 13:00:41 -0700266 @Override
267 public void expandPip() {
Winson Chungb5026902017-05-03 12:45:13 -0700268 mTouchHandler.getMotionHelper().expandPip(false /* skipAnimation */);
269 }
270
271 /**
Winson Chung2dbcf092018-10-24 13:00:41 -0700272 * Hides the PIP menu.
273 */
274 @Override
275 public void hidePipMenu(Runnable onStartCallback, Runnable onEndCallback) {
276 mMenuController.hideMenu(onStartCallback, onEndCallback);
277 }
278
279 /**
Winson Chungac52f282017-03-30 14:44:52 -0700280 * Sent from KEYCODE_WINDOW handler in PhoneWindowManager, to request the menu to be shown.
281 */
282 public void showPictureInPictureMenu() {
283 mTouchHandler.showPictureInPictureMenu();
284 }
285
286 /**
Ben Lin1a80f122020-01-27 14:09:52 -0800287 * Sets a customized touch gesture that replaces the default one.
288 */
289 public void setTouchGesture(PipTouchGesture gesture) {
290 mTouchHandler.setTouchGesture(gesture);
291 }
292
293 /**
Hongwei Wang9b751802019-09-11 12:13:21 -0700294 * Sets both shelf visibility and its height.
295 */
296 @Override
297 public void setShelfHeight(boolean visible, int height) {
298 mHandler.post(() -> {
299 final boolean changed = mPipBoundsHandler.setShelfHeight(visible, height);
300 if (changed) {
301 mTouchHandler.onShelfVisibilityChanged(visible, height);
302 updateMovementBounds(mPipBoundsHandler.getLastDestinationBounds(),
303 false /* fromImeAdjustment */, true /* fromShelfAdjustment */);
304 }
305 });
306 }
307
Hongwei Wang85cf41f2020-01-15 15:14:47 -0800308 @Override
309 public void setPinnedStackAnimationType(int animationType) {
310 mHandler.post(() -> mPipTaskOrganizer.setOneShotAnimationType(animationType));
311 }
312
313 @Override
314 public void setPinnedStackAnimationListener(IPinnedStackAnimationListener listener) {
315 mHandler.post(() -> mPinnedStackAnimationRecentsListener = listener);
316 }
317
318 @Override
319 public void onPipTransitionStarted() {
320 // Disable touches while the animation is running
321 mTouchHandler.setTouchEnabled(false);
322 if (mPinnedStackAnimationRecentsListener != null) {
323 try {
324 mPinnedStackAnimationRecentsListener.onPinnedStackAnimationStarted();
325 } catch (RemoteException e) {
326 Log.e(TAG, "Failed to callback recents", e);
327 }
328 }
329 }
330
331 @Override
332 public void onPipTransitionFinished() {
333 onPipTransitionFinishedOrCanceled();
334 }
335
336 @Override
337 public void onPipTransitionCanceled() {
338 onPipTransitionFinishedOrCanceled();
339 }
340
341 private void onPipTransitionFinishedOrCanceled() {
342 // Re-enable touches after the animation completes
343 mTouchHandler.setTouchEnabled(true);
344 mTouchHandler.onPinnedStackAnimationEnded();
345 mMenuController.onPinnedStackAnimationEnded();
346 }
347
Hongwei Wang9b751802019-09-11 12:13:21 -0700348 private void updateMovementBounds(Rect animatingBounds, boolean fromImeAdjustment,
349 boolean fromShelfAdjustment) {
Hongwei Wangbede2c12020-02-26 12:11:53 -0800350 // Populate inset / normal bounds and DisplayInfo from mPipBoundsHandler before
351 // passing to mTouchHandler, mTouchHandler would rely on the bounds calculated by
352 // mPipBoundsHandler with up-to-dated information
Hongwei Wang9b751802019-09-11 12:13:21 -0700353 mPipBoundsHandler.onMovementBoundsChanged(mTmpInsetBounds, mTmpNormalBounds,
354 animatingBounds, mTmpDisplayInfo);
355 mTouchHandler.onMovementBoundsChanged(mTmpInsetBounds, mTmpNormalBounds,
356 animatingBounds, fromImeAdjustment, fromShelfAdjustment,
357 mTmpDisplayInfo.rotation);
358 }
359
Winson Chung29a78652017-02-09 18:35:26 -0800360 public void dump(PrintWriter pw) {
361 final String innerPrefix = " ";
362 pw.println(TAG);
Winson Chungd2d90972017-02-28 11:40:41 -0800363 mInputConsumerController.dump(pw, innerPrefix);
Winson Chung29a78652017-02-09 18:35:26 -0800364 mMenuController.dump(pw, innerPrefix);
365 mTouchHandler.dump(pw, innerPrefix);
Hongwei Wang43a752b2019-09-17 20:20:30 +0000366 mPipBoundsHandler.dump(pw, innerPrefix);
Winson Chung29a78652017-02-09 18:35:26 -0800367 }
Winson73bc1592016-10-18 18:47:43 -0700368}