• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/**
2 * Copyright (c) 2022-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import windowAnimationManager from '@ohos.animation.windowAnimationManager';
17import curves from '@ohos.curves';
18import { Log } from '../utils/Log';
19import { Trace } from '../utils/Trace';
20import { StyleConstants } from '../constants/StyleConstants';
21import { CommonConstants } from '../constants/CommonConstants';
22import OverlayAppIcon from './OverlayAppIcon';
23import RemoteConstants from '../constants/RemoteConstants';
24import { localEventManager } from '../manager/LocalEventManager';
25import { EventConstants } from '../constants/EventConstants';
26import { CloseAppManager } from '../manager/CloseAppManager';
27import WindowAnimationControllerImpl from '../animation/remoteanimation/WindowAnimationControllerImpl';
28import { AppItemInfo } from '../bean/AppItemInfo';
29import { LauncherDragItemInfo } from '../bean/LauncherDragItemInfo';
30
31const TAG = 'RemoteWindowWrapper';
32
33class StartAppCalculate {
34  startAppCalculateScaleX: number = 0;
35  startAppCalculateScaleY: number = 0;
36  startAppCalculateTranslateX: number = 0;
37  startAppCalculateTranslateY: number = 0;
38}
39
40class CloseAppCalculate {
41  closeAppCalculateScaleX: number = 0;
42  closeAppCalculateScaleY: number = 0;
43  closeAppCalculateTranslateX: number = 0;
44  closeAppCalculateTranslateY: number = 0;
45}
46
47@Observed
48class RemoteVo {
49  public remoteAnimationType: number;
50  public finishCallback: windowAnimationManager.WindowAnimationFinishedCallback;
51  public target: windowAnimationManager.WindowAnimationTarget;
52  public fromWindowTarget: windowAnimationManager.WindowAnimationTarget;
53  public remoteWindowKey: string;
54  public iconInfo: StartAppIconInfo;
55  public appItemInfo: StartAppItemInfo;
56  public count: number = 0;
57
58  mScreenWidth: number;
59  mScreenHeight: number;
60
61  startAppTypeFromPageDesktop: number;
62
63  remoteWindowScaleX: number = 0;
64  remoteWindowScaleY: number = 0;
65  remoteWindowTranslateX: number = 0;
66  remoteWindowTranslateY: number = 0;
67  remoteWindowWindowAlpha: number = 0;
68  remoteWindowRadius: number = 0;
69
70  fromRemoteWindowScaleX: number = 1.0;
71  fromRemoteWindowScaleY: number = 1.0;
72  fromRemoteWindowTranslateX: number = 0;
73  fromRemoteWindowTranslateY: number = 0;
74  fromRemoteWindowWindowAlpha: number = 1.0;
75
76  startAppIconScaleX: number = 0;
77  startAppIconScaleY: number = 0;
78  startAppIconTranslateX: number = 0;
79  startAppIconTranslateY: number = 0;
80  startAppIconWindowAlpha: number = 0;
81
82  constructor(
83    remoteAnimationType: number,
84    startAppTypeFromPageDesktop: number,
85    target: windowAnimationManager.WindowAnimationTarget,
86    iconInfo: StartAppIconInfo = {} as StartAppIconInfo,
87    appItemInfo: StartAppItemInfo = {} as StartAppItemInfo,
88    fromWindowTarget: windowAnimationManager.WindowAnimationTarget | undefined = undefined,
89    finishCallback: windowAnimationManager.WindowAnimationFinishedCallback
90  ) {
91    this.remoteAnimationType = remoteAnimationType;
92    this.target = target;
93    this.fromWindowTarget = fromWindowTarget as WindowAnimationTarget;
94    this.mScreenWidth = px2vp(this.target.windowBounds.width);
95    this.mScreenHeight = px2vp(this.target.windowBounds.height);
96    this.iconInfo = iconInfo;
97    this.appItemInfo = appItemInfo;
98    this.startAppTypeFromPageDesktop = startAppTypeFromPageDesktop;
99    this.finishCallback = finishCallback;
100    this.remoteWindowKey = this.target.bundleName + this.target.abilityName + this.target.missionId;
101    this.initRemoteWindowProperty();
102  }
103
104  initRemoteWindowProperty() {
105    if (this.remoteAnimationType == RemoteConstants.TYPE_START_APP_FROM_LAUNCHER) {
106      const res = this.calculateStartAppProperty();
107      Log.showInfo(TAG, `initRemoteWindowProperty res: ${JSON.stringify(res)}, mScreenWidth: ${this.mScreenWidth}, mScreenHeight: ${this.mScreenHeight}, startAppTypeFromPageDesktop: ${this.startAppTypeFromPageDesktop}`);
108      this.remoteWindowScaleX = res.startAppCalculateScaleX;
109      this.remoteWindowScaleY = res.startAppCalculateScaleY;
110      this.remoteWindowTranslateX = res.startAppCalculateTranslateX;
111      this.remoteWindowTranslateY = res.startAppCalculateTranslateY;
112      this.remoteWindowWindowAlpha = 0.0;
113      this.remoteWindowRadius = 96;
114
115      this.startAppIconWindowAlpha = 1.0;
116      this.startAppIconScaleX = 1.0;
117      this.startAppIconScaleY = 1.0;
118      this.startAppIconTranslateX = 0.0;
119      this.startAppIconTranslateY = 0.0;
120      this.count = 1;
121    } else if (this.remoteAnimationType == RemoteConstants.TYPE_START_APP_FROM_RECENT) {
122    } else if (this.remoteAnimationType == RemoteConstants.TYPE_START_APP_FROM_OTHER) {
123    } else if (this.remoteAnimationType == RemoteConstants.TYPE_APP_TRANSITION) {
124      this.remoteWindowScaleX = 1.0;
125      this.remoteWindowScaleY = 1.0;
126      this.remoteWindowTranslateX = px2vp(this.target?.windowBounds.width - this.target?.windowBounds.left);
127      this.remoteWindowTranslateY = 0.0;
128      this.remoteWindowWindowAlpha = 1.0;
129      this.remoteWindowRadius = 12;
130
131      this.startAppIconScaleX = 1.0;
132      this.startAppIconScaleY = 1.0;
133      this.startAppIconTranslateX = 0.0;
134      this.startAppIconTranslateY = 0.0;
135      this.startAppIconWindowAlpha = 1.0;
136    } else if (this.remoteAnimationType == RemoteConstants.TYPE_MINIMIZE_WINDOW) {
137      this.remoteWindowScaleX = 1.0;
138      this.remoteWindowScaleY = 1.0;
139      this.remoteWindowTranslateX = 0.0;
140      this.remoteWindowTranslateY = 0.0;
141      this.remoteWindowWindowAlpha = 1.0;
142      this.remoteWindowRadius = 12;
143
144      const res = this.calculateCloseAppProperty();
145      this.startAppIconScaleX = res.closeAppCalculateScaleX;
146      this.startAppIconScaleY = res.closeAppCalculateScaleY;
147      this.startAppIconTranslateX = -res.closeAppCalculateTranslateX;
148      this.startAppIconTranslateY = -res.closeAppCalculateTranslateY;
149      this.startAppIconWindowAlpha = 0.0;
150    } else if (this.remoteAnimationType == RemoteConstants.TYPE_CLOSE_WINDOW) {
151      this.remoteWindowScaleX = 1.0;
152      this.remoteWindowScaleY = 1.0;
153      this.remoteWindowTranslateX = 0.0;
154      this.remoteWindowTranslateY = 0.0;
155      this.remoteWindowRadius = 12;
156      this.remoteWindowWindowAlpha = 1.0;
157
158      this.startAppIconScaleX = 1.0;
159      this.startAppIconScaleY = 1.0;
160      this.startAppIconTranslateX = 0.0;
161      this.startAppIconTranslateY = 0.0;
162      this.startAppIconWindowAlpha = 0.0;
163    }
164  }
165
166  calculateStartAppProperty() {
167    let startAppCalculate = new StartAppCalculate();
168    Log.showInfo(TAG, `calculateStartAppProperty appIconSize: ${this.iconInfo?.appIconSize}, windowBounds: ${JSON.stringify(this.target?.windowBounds)},
169    appIconPosition: [${this.iconInfo?.appIconPositionX}, ${this.iconInfo?.appIconPositionY}], appIconPositionY: ${this.startAppTypeFromPageDesktop}`);
170    startAppCalculate.startAppCalculateScaleX = this.iconInfo?.appIconSize / px2vp(this.target?.windowBounds.width);
171    startAppCalculate.startAppCalculateTranslateX = this.iconInfo?.appIconPositionX + this.iconInfo?.appIconSize / 2
172    - (px2vp(this.target?.windowBounds.left) + px2vp(this.target?.windowBounds.width) / 2);
173
174    if (this.startAppTypeFromPageDesktop === CommonConstants.OVERLAY_TYPE_CARD) {
175      startAppCalculate.startAppCalculateScaleY = this.iconInfo?.appIconHeight / px2vp(this.target?.windowBounds.height);
176      startAppCalculate.startAppCalculateTranslateY = this.iconInfo?.appIconPositionY + this.iconInfo?.appIconHeight / 2
177      - (px2vp(this.target?.windowBounds.top) + px2vp(this.target?.windowBounds.height) / 2);
178    } else {
179      startAppCalculate.startAppCalculateScaleY = this.iconInfo?.appIconSize / px2vp(this.target?.windowBounds.height);
180      startAppCalculate.startAppCalculateTranslateY = this.iconInfo?.appIconPositionY + this.iconInfo?.appIconSize / 2
181      - (px2vp(this.target?.windowBounds.top) + px2vp(this.target?.windowBounds.height) / 2);
182    }
183    return startAppCalculate;
184  }
185
186  calculateCloseAppProperty() {
187    let closeAppCalculate = new CloseAppCalculate();
188    closeAppCalculate.closeAppCalculateScaleX = px2vp(this.target?.windowBounds.width) / this.iconInfo?.appIconSize;
189    closeAppCalculate.closeAppCalculateTranslateX = this.iconInfo?.appIconPositionX + this.iconInfo?.appIconSize / 2
190    - (px2vp(this.target?.windowBounds.left) + px2vp(this.target?.windowBounds.width) / 2);
191    if (this.startAppTypeFromPageDesktop === CommonConstants.OVERLAY_TYPE_CARD) {
192      closeAppCalculate.closeAppCalculateScaleY = px2vp(this.target?.windowBounds.height) / this.iconInfo?.appIconHeight;
193      closeAppCalculate.closeAppCalculateTranslateY = this.iconInfo?.appIconPositionY + this.iconInfo?.appIconHeight / 2
194      - (px2vp(this.target?.windowBounds.top) + px2vp(this.target?.windowBounds.height) / 2);
195    } else {
196      closeAppCalculate.closeAppCalculateScaleY = px2vp(this.target?.windowBounds.height) / this.iconInfo?.appIconSize;
197      closeAppCalculate.closeAppCalculateTranslateY = this.iconInfo?.appIconPositionY + this.iconInfo?.appIconSize / 2
198      - (px2vp(this.target?.windowBounds.top) + px2vp(this.target?.windowBounds.height) / 2);
199    }
200    return closeAppCalculate;
201  }
202}
203
204class SelfWindowAnimationController extends WindowAnimationControllerImpl {
205  mCloseAppManager: CloseAppManager;
206  mLastRemoteVo: RemoteVo;
207  calculateAppProperty: (remoteVo: RemoteVo, finishCallback: windowAnimationManager.WindowAnimationFinishedCallback) => void
208  getRemoteWindowVo: (remoteWindowKey: string) => RemoteVo | null;
209  pushRemoteVoIntoList: (remoteVo: RemoteVo) => void;
210
211  constructor(mCloseAppManager: CloseAppManager, mLastRemoteVo: RemoteVo,
212              getRemoteWindowVo: (remoteWindowKey: string) => RemoteVo | null,
213              pushRemoteVoIntoList: (remoteVo: RemoteVo) => void,
214              calculateAppProperty: (remoteVo: RemoteVo,
215                                     finishCallback: windowAnimationManager.WindowAnimationFinishedCallback) => void) {
216    super();
217    this.mCloseAppManager = mCloseAppManager;
218    this.mLastRemoteVo = mLastRemoteVo;
219    this.calculateAppProperty = calculateAppProperty;
220    this.getRemoteWindowVo = getRemoteWindowVo;
221    this.pushRemoteVoIntoList = pushRemoteVoIntoList;
222  }
223  onStartAppFromLauncher(startingWindowTarget: windowAnimationManager.WindowAnimationTarget,
224                         finishCallback: windowAnimationManager.WindowAnimationFinishedCallback) {
225    Log.showInfo(TAG, `remote window animaion onStartAppFromLauncher`);
226    const remoteWindowKey = startingWindowTarget.bundleName + startingWindowTarget.abilityName + startingWindowTarget.missionId;
227    const startAppTypeFromPageDesktop: number = AppStorage.get('startAppTypeFromPageDesktop') as number;
228    const appItemInfo: StartAppItemInfo = AppStorage.get('startAppItemInfo') as StartAppItemInfo;
229    const startAppIconInfo: StartAppIconInfo = AppStorage.get('startAppIconInfo') as StartAppIconInfo;
230    let remoteVo: RemoteVo | null = this.getRemoteWindowVo(remoteWindowKey);
231    if (remoteVo) {
232      remoteVo.remoteAnimationType = RemoteConstants.TYPE_START_APP_FROM_LAUNCHER;
233      remoteVo.target = startingWindowTarget;
234      remoteVo.startAppTypeFromPageDesktop = startAppTypeFromPageDesktop;
235      remoteVo.iconInfo = startAppIconInfo;
236      remoteVo.appItemInfo = appItemInfo;
237      remoteVo.count = remoteVo.count + 1;
238    } else {
239      remoteVo = new RemoteVo(
240        RemoteConstants.TYPE_START_APP_FROM_LAUNCHER,
241        startAppTypeFromPageDesktop,
242        startingWindowTarget,
243        startAppIconInfo,
244        appItemInfo,
245        undefined,
246        finishCallback
247      );
248      this.mLastRemoteVo = remoteVo;
249    }
250    this.pushRemoteVoIntoList(remoteVo);
251    AppStorage.setOrCreate(remoteWindowKey, remoteVo.count);
252    this.calculateAppProperty(remoteVo, finishCallback);
253    super.onStartAppFromLauncher(startingWindowTarget, finishCallback);
254  }
255
256  onStartAppFromRecent(startingWindowTarget: windowAnimationManager.WindowAnimationTarget,
257                       finishCallback: windowAnimationManager.WindowAnimationFinishedCallback) {
258    Log.showInfo(TAG, `remote window animaion onStartAppFromRecent`);
259    const remoteWindowKey = startingWindowTarget.bundleName + startingWindowTarget.abilityName + startingWindowTarget.missionId;
260    const startAppTypeFromPageDesktop: number = AppStorage.get('startAppTypeFromPageDesktop') as number;
261    const appItemInfo: StartAppItemInfo = AppStorage.get('startAppItemInfo') as StartAppItemInfo;
262    const startAppIconInfo: StartAppIconInfo = AppStorage.get('startAppIconInfo') as StartAppIconInfo;
263    let remoteVo: RemoteVo | null = this.getRemoteWindowVo(remoteWindowKey);
264    if (remoteVo) {
265      remoteVo.remoteAnimationType = RemoteConstants.TYPE_START_APP_FROM_LAUNCHER;
266      remoteVo.target = startingWindowTarget;
267      remoteVo.startAppTypeFromPageDesktop = startAppTypeFromPageDesktop;
268      remoteVo.iconInfo = startAppIconInfo;
269      remoteVo.appItemInfo = appItemInfo;
270      remoteVo.count = remoteVo.count + 1;
271    } else {
272      remoteVo = new RemoteVo(
273        RemoteConstants.TYPE_START_APP_FROM_LAUNCHER,
274        startAppTypeFromPageDesktop,
275        startingWindowTarget,
276        startAppIconInfo,
277        appItemInfo,
278        undefined,
279        finishCallback
280      );
281      this.mLastRemoteVo = remoteVo;
282    }
283    this.pushRemoteVoIntoList(remoteVo);
284    AppStorage.setOrCreate(remoteWindowKey, remoteVo.count);
285    this.calculateAppProperty(remoteVo, finishCallback);
286    super.onStartAppFromRecent(startingWindowTarget, finishCallback);
287  }
288
289  onStartAppFromOther(startingWindowTarget: windowAnimationManager.WindowAnimationTarget,
290                      finishCallback: windowAnimationManager.WindowAnimationFinishedCallback) {
291    Log.showInfo(TAG, `remote window animaion onStartAppFromOther`);
292    const remoteWindowKey = startingWindowTarget.bundleName + startingWindowTarget.abilityName + startingWindowTarget.missionId;
293    const startAppTypeFromPageDesktop: number = AppStorage.get('startAppTypeFromPageDesktop') as number;
294    AppStorage.setOrCreate('startAppItemInfo', {} as StartAppItemInfo);
295    AppStorage.setOrCreate('startAppIconInfo', {} as StartAppIconInfo);
296    const appItemInfo: StartAppItemInfo = AppStorage.get('startAppItemInfo') as StartAppItemInfo;
297    const startAppIconInfo: StartAppIconInfo = AppStorage.get('startAppIconInfo') as StartAppIconInfo;
298    let remoteVo: RemoteVo | null = this.getRemoteWindowVo(remoteWindowKey);
299    if (remoteVo) {
300      remoteVo.remoteAnimationType = RemoteConstants.TYPE_START_APP_FROM_LAUNCHER;
301      remoteVo.target = startingWindowTarget;
302      remoteVo.startAppTypeFromPageDesktop = startAppTypeFromPageDesktop;
303      remoteVo.iconInfo = startAppIconInfo;
304      remoteVo.appItemInfo = appItemInfo;
305      remoteVo.count = remoteVo.count + 1;
306    } else {
307      remoteVo = new RemoteVo(
308        RemoteConstants.TYPE_START_APP_FROM_LAUNCHER,
309        startAppTypeFromPageDesktop,
310        startingWindowTarget,
311        startAppIconInfo,
312        appItemInfo,
313        undefined,
314        finishCallback
315      );
316      this.mLastRemoteVo = remoteVo;
317    }
318    this.pushRemoteVoIntoList(remoteVo);
319    AppStorage.setOrCreate(remoteWindowKey, remoteVo.count);
320    this.calculateAppProperty(remoteVo, finishCallback);
321    super.onStartAppFromOther(startingWindowTarget, finishCallback);
322  }
323
324  onAppTransition(fromWindowTarget: windowAnimationManager.WindowAnimationTarget,
325                  toWindowTarget: windowAnimationManager.WindowAnimationTarget,
326                  finishCallback: windowAnimationManager.WindowAnimationFinishedCallback) {
327    Log.showInfo(TAG, `remote window animaion onAppTransition`);
328    const remoteWindowKey = toWindowTarget.bundleName + toWindowTarget.abilityName + toWindowTarget.missionId;
329    const startAppTypeFromPageDesktop: number = AppStorage.get('startAppTypeFromPageDesktop') as number;
330    const remoteVo = new RemoteVo(
331      RemoteConstants.TYPE_APP_TRANSITION,
332      startAppTypeFromPageDesktop,
333      toWindowTarget,
334      {} as StartAppIconInfo,
335      {} as StartAppItemInfo,
336      fromWindowTarget,
337      finishCallback
338    );
339    this.mLastRemoteVo = remoteVo;
340    this.pushRemoteVoIntoList(remoteVo);
341    this.calculateAppProperty(remoteVo, finishCallback);
342    super.onAppTransition(fromWindowTarget, toWindowTarget, finishCallback);
343  }
344
345  onMinimizeWindow(minimizingWindowTarget: windowAnimationManager.WindowAnimationTarget,
346                   finishCallback: windowAnimationManager.WindowAnimationFinishedCallback) {
347    Log.showInfo(TAG, `remote window animaion onMinimizeWindow`);
348    const startAppTypeFromPageDesktop: number = AppStorage.get('startAppTypeFromPageDesktop') as number;
349    const appInfo: StartAppInfo = this.mCloseAppManager.getAppInfo(minimizingWindowTarget);
350    const remoteWindowKey = minimizingWindowTarget.bundleName + minimizingWindowTarget.abilityName + minimizingWindowTarget.missionId;
351    let remoteVo: RemoteVo | null = this.getRemoteWindowVo(remoteWindowKey);
352    if (appInfo.appItemInfo?.page) {
353      AppStorage.setOrCreate('pageIndex', appInfo.appItemInfo?.page);
354    }
355    if (remoteVo) {
356      remoteVo.remoteAnimationType = RemoteConstants.TYPE_MINIMIZE_WINDOW;
357      remoteVo.target = minimizingWindowTarget;
358      remoteVo.startAppTypeFromPageDesktop = startAppTypeFromPageDesktop;
359      remoteVo.iconInfo = appInfo.iconInfo;
360      remoteVo.appItemInfo = appInfo.appItemInfo;
361      remoteVo.count = remoteVo.count + 1;
362    } else {
363      remoteVo = new RemoteVo(
364        RemoteConstants.TYPE_MINIMIZE_WINDOW,
365        startAppTypeFromPageDesktop,
366        minimizingWindowTarget,
367        appInfo.iconInfo,
368        appInfo.appItemInfo,
369        undefined,
370        finishCallback
371      );
372      this.mLastRemoteVo = remoteVo;
373    }
374    this.pushRemoteVoIntoList(remoteVo);
375    AppStorage.setOrCreate(remoteWindowKey, remoteVo.count);
376    this.calculateAppProperty(remoteVo, finishCallback);
377    super.onMinimizeWindow(minimizingWindowTarget, finishCallback);
378  }
379
380  onCloseWindow(closingWindowTarget: windowAnimationManager.WindowAnimationTarget,
381                finishCallback: windowAnimationManager.WindowAnimationFinishedCallback) {
382    Log.showInfo(TAG, `remote window animaion onCloseWindow`);
383    const startAppTypeFromPageDesktop: number = AppStorage.get('startAppTypeFromPageDesktop') as number;
384    const appInfo: StartAppInfo = this.mCloseAppManager.getAppInfo(closingWindowTarget);
385    const remoteWindowKey = closingWindowTarget.bundleName + closingWindowTarget.abilityName + closingWindowTarget.missionId;
386    let remoteVo: RemoteVo | null = this.getRemoteWindowVo(remoteWindowKey);
387    if (remoteVo) {
388      remoteVo.remoteAnimationType = RemoteConstants.TYPE_MINIMIZE_WINDOW;
389      remoteVo.target = closingWindowTarget;
390      remoteVo.startAppTypeFromPageDesktop = startAppTypeFromPageDesktop;
391      remoteVo.iconInfo = appInfo.iconInfo;
392      remoteVo.appItemInfo = appInfo.appItemInfo;
393    } else {
394      remoteVo = new RemoteVo(
395        RemoteConstants.TYPE_MINIMIZE_WINDOW,
396        startAppTypeFromPageDesktop,
397        closingWindowTarget,
398        appInfo.iconInfo,
399        appInfo.appItemInfo,
400        undefined,
401        finishCallback
402      );
403      this.mLastRemoteVo = remoteVo;
404    }
405    this.pushRemoteVoIntoList(remoteVo);
406    AppStorage.setOrCreate(remoteWindowKey, remoteVo.count);
407    this.calculateAppProperty(remoteVo, finishCallback);
408    super.onCloseWindow(closingWindowTarget, finishCallback);
409  }
410}
411
412@Component
413export struct RemoteWindowWrapper {
414  private mCloseAppManager?: CloseAppManager;
415  private mLastRemoteVo?: RemoteVo;
416  @StorageLink('remoteWindowList') remoteWindowList: RemoteVo[] = [];
417
418  getRemoteWindowVo(remoteWindowKey: string): RemoteVo | null {
419    const remoteVoIndex = this.remoteWindowList.findIndex(item => {
420      return (item.remoteWindowKey) == remoteWindowKey;
421    })
422    if (remoteVoIndex != -1) {
423      return this.remoteWindowList[remoteVoIndex];
424    } else if (this.mLastRemoteVo && this.mLastRemoteVo.remoteWindowKey === remoteWindowKey) {
425      return this.mLastRemoteVo;
426    } else {
427      return null;
428    }
429  }
430
431  private pushRemoteVoIntoList(remoteVo: RemoteVo): void {
432    const remoteVoIndex = this.remoteWindowList.findIndex(item => {
433      return (item.remoteWindowKey) == remoteVo.remoteWindowKey;
434    })
435    if (remoteVoIndex == -1) {
436      this.remoteWindowList.push(remoteVo);
437    }
438  }
439
440  aboutToAppear(): void {
441    this.mCloseAppManager = CloseAppManager.getInstance();
442    let control = new SelfWindowAnimationController(this.mCloseAppManager, this.mLastRemoteVo as RemoteVo,
443      this.getRemoteWindowVo, this.pushRemoteVoIntoList, this.calculateAppProperty);
444
445    windowAnimationManager.setController(control);
446  }
447
448  removeRemoteWindowFromList(remoteWindowKey: string): void {
449    const remoteWindowIndex = this.remoteWindowList.findIndex(item => {
450      return item.remoteWindowKey === remoteWindowKey;
451    });
452    if (remoteWindowIndex != CommonConstants.INVALID_VALUE) {
453      this.remoteWindowList.splice(remoteWindowIndex, 1);
454      Log.showDebug(TAG, `removeRemoteWindowFromList remoteWindowList length: ${this.remoteWindowList.length}`);
455    }
456  }
457
458  calculateAppProperty(remoteVo: RemoteVo, finishCallback: windowAnimationManager.WindowAnimationFinishedCallback) {
459    Log.showDebug(TAG, `calculateAppProperty ${remoteVo.remoteAnimationType}`);
460    if (remoteVo.remoteAnimationType == RemoteConstants.TYPE_START_APP_FROM_LAUNCHER) {
461      Trace.start(Trace.CORE_METHOD_START_APP_ANIMATION);
462      const callback = finishCallback;
463      const count = remoteVo.count;
464      localEventManager.sendLocalEventSticky(EventConstants.EVENT_ANIMATION_START_APPLICATION, null);
465      animateTo({
466        duration: 50,
467        delay: 50,
468        curve: Curve.Friction,
469        onFinish: () => {
470        }
471      }, () => {
472        remoteVo.startAppIconWindowAlpha = 0.0;
473        remoteVo.remoteWindowWindowAlpha = 1.0;
474      })
475
476      animateTo({
477        duration: 370,
478        curve: curves.springMotion(0.25, 0.99, 0),
479        onFinish: () => {
480          callback.onAnimationFinish();
481          Trace.end(Trace.CORE_METHOD_START_APP_ANIMATION);
482          const startCount: number = AppStorage.get(remoteVo.remoteWindowKey);
483          Log.showDebug(TAG, `calculateAppProperty ${remoteVo.remoteAnimationType}, count: ${count}, startCount: ${startCount}`);
484          if (startCount === count) {
485            this.removeRemoteWindowFromList(remoteVo.remoteWindowKey);
486            AppStorage.setOrCreate(remoteVo.remoteWindowKey, 0);
487          }
488        }
489      }, () => {
490        remoteVo.remoteWindowScaleX = 1.0;
491        remoteVo.remoteWindowScaleY = 1.0;
492        remoteVo.remoteWindowTranslateX = 0.0;
493        remoteVo.remoteWindowTranslateY = 0.0;
494        remoteVo.startAppIconScaleX = remoteVo.mScreenWidth / remoteVo.iconInfo?.appIconSize;
495        remoteVo.startAppIconTranslateX = remoteVo.mScreenWidth / 2 - remoteVo.iconInfo?.appIconPositionX - remoteVo.iconInfo?.appIconSize / 2;
496        remoteVo.remoteWindowRadius = 0;
497        if (remoteVo.startAppTypeFromPageDesktop === CommonConstants.OVERLAY_TYPE_CARD) {
498          remoteVo.startAppIconScaleY = remoteVo.mScreenHeight / remoteVo.iconInfo?.appIconHeight;
499          remoteVo.startAppIconTranslateY = remoteVo.mScreenHeight / 2 + px2vp(remoteVo.target.windowBounds.top) - remoteVo.iconInfo?.appIconPositionY - remoteVo.iconInfo?.appIconHeight / 2;
500        } else {
501          remoteVo.startAppIconScaleY = remoteVo.mScreenHeight / remoteVo.iconInfo?.appIconSize;
502          remoteVo.startAppIconTranslateY = remoteVo.mScreenHeight / 2 + px2vp(remoteVo.target.windowBounds.top) - remoteVo.iconInfo?.appIconPositionY - remoteVo.iconInfo?.appIconSize / 2;
503        }
504      })
505    } else if (remoteVo.remoteAnimationType  == RemoteConstants.TYPE_MINIMIZE_WINDOW) {
506      Trace.start(Trace.CORE_METHOD_CLOSE_APP_ANIMATION);
507      const res = remoteVo.calculateCloseAppProperty();
508      const callback = finishCallback;
509      const count = remoteVo.count;
510      localEventManager.sendLocalEventSticky(EventConstants.EVENT_ANIMATION_CLOSE_APPLICATION, null);
511      animateTo({
512        duration: 370,
513        curve: curves.springMotion(0.25, 0.99, 0),
514        onFinish: () => {
515          callback.onAnimationFinish();
516          Trace.end(Trace.CORE_METHOD_CLOSE_APP_ANIMATION);
517          const startCount: number = AppStorage.get(remoteVo.remoteWindowKey);
518          Log.showDebug(TAG, `calculateAppProperty ${remoteVo.remoteAnimationType}, count: ${count}, startCount: ${startCount}`);
519          if (startCount === count) {
520            this.removeRemoteWindowFromList(remoteVo.remoteWindowKey);
521            AppStorage.setOrCreate(remoteVo.remoteWindowKey, 0);
522          }
523        }
524      }, () => {
525        remoteVo.remoteWindowScaleX = 1 / res.closeAppCalculateScaleX;
526        remoteVo.remoteWindowScaleY = 1 / res.closeAppCalculateScaleY;
527        remoteVo.remoteWindowTranslateX = res.closeAppCalculateTranslateX;
528        remoteVo.remoteWindowTranslateY = res.closeAppCalculateTranslateY;
529
530        remoteVo.startAppIconScaleX = 1.0;
531        remoteVo.startAppIconScaleY = 1.0;
532        remoteVo.startAppIconTranslateX = 0.0;
533        remoteVo.startAppIconTranslateY = 0.0;
534        remoteVo.remoteWindowRadius = 96;
535      })
536
537      animateTo({
538        duration: 50,
539        delay: 50,
540        curve: Curve.Friction,
541        onFinish: () => {
542        }
543      }, () => {
544        remoteVo.startAppIconWindowAlpha = 1.0;
545        remoteVo.remoteWindowWindowAlpha = 0;
546      })
547    } else if (remoteVo.remoteAnimationType  == RemoteConstants.TYPE_CLOSE_WINDOW) {
548    } else if (remoteVo.remoteAnimationType  == RemoteConstants.TYPE_APP_TRANSITION) {
549      const callback = finishCallback;
550      animateTo({
551        duration: 300,
552        curve: Curve.Friction,
553        onFinish: () => {
554          this.removeRemoteWindowFromList(remoteVo.remoteWindowKey);
555        }
556      }, () => {
557        remoteVo.remoteWindowRadius = 0;
558        remoteVo.remoteWindowTranslateX = 0;
559        remoteVo.fromRemoteWindowTranslateX = px2vp(remoteVo.fromWindowTarget?.windowBounds.left - remoteVo.fromWindowTarget?.windowBounds.width);
560      })
561
562      animateTo({
563        duration: 150,
564        curve: Curve.Friction,
565        onFinish: () => {
566          this.removeRemoteWindowFromList(remoteVo.remoteWindowKey);
567        }
568      }, () => {
569        remoteVo.remoteWindowScaleX = 0.9
570        remoteVo.remoteWindowScaleY = 0.9
571        remoteVo.fromRemoteWindowScaleX = 0.9
572        remoteVo.fromRemoteWindowScaleY = 0.9
573      })
574
575      animateTo({
576        duration: 350,
577        delay: 150,
578        curve: Curve.Friction,
579        onFinish: () => {
580          callback.onAnimationFinish();
581          this.removeRemoteWindowFromList(remoteVo.remoteWindowKey);
582        }
583      }, () => {
584        remoteVo.remoteWindowScaleX = 1.0
585        remoteVo.remoteWindowScaleY = 1.0
586        remoteVo.fromRemoteWindowScaleX = 1.0
587        remoteVo.fromRemoteWindowScaleY = 1.0
588      })
589    }
590  }
591
592  build() {
593    Stack() {
594      ForEach(this.remoteWindowList, (item: RemoteVo) => {
595        if (item.remoteAnimationType == RemoteConstants.TYPE_APP_TRANSITION) {
596          StartAppTransitionRemoteWindow({
597            targetInfo: item
598          })
599        } else {
600          StartAppFromLauncherRemoteWindow({
601            targetInfo: item
602          })
603        }
604      }, (item: RemoteVo) => item.remoteWindowKey)
605    }
606    .width(StyleConstants.PERCENTAGE_100)
607    .height(StyleConstants.PERCENTAGE_100)
608    .focusable(false)
609    .enabled(false)
610  }
611}
612
613@Component
614export struct StartAppFromLauncherRemoteWindow {
615  @ObjectLink targetInfo: RemoteVo;
616
617  aboutToAppear(): void {
618  }
619
620  aboutToDisappear(): void {
621  }
622
623  build() {
624    Stack() {
625      Column() {
626        if (this.targetInfo.startAppTypeFromPageDesktop === CommonConstants.OVERLAY_TYPE_CARD) {
627          FormComponent({
628            id: this.targetInfo.appItemInfo?.cardId as number,
629            name: this.targetInfo.appItemInfo?.cardName as string,
630            bundle: this.targetInfo.appItemInfo?.bundleName as string,
631            ability: this.targetInfo.appItemInfo?.abilityName as string,
632            module: this.targetInfo.appItemInfo?.moduleName as string,
633            dimension: this.targetInfo.appItemInfo?.cardDimension
634          })
635            .clip(new Rect({
636              width: this.targetInfo.iconInfo?.appIconSize as number,
637              height: this.targetInfo.iconInfo?.appIconHeight as number,
638              radius: 24
639            }))
640            .size({
641              width: this.targetInfo.iconInfo?.appIconSize as number,
642              height: this.targetInfo.iconInfo?.appIconHeight as number
643            })
644        } else {
645          OverlayAppIcon({
646            iconSize: this.targetInfo.iconInfo?.appIconSize as number,
647            icon: this.targetInfo.appItemInfo?.icon as ResourceStr
648          })
649        }
650      }
651      .translate({ x: this.targetInfo.startAppIconTranslateX as number,
652        y: this.targetInfo.startAppIconTranslateY as number })
653      .scale({ x: this.targetInfo.startAppIconScaleX as number,
654        y: this.targetInfo.startAppIconScaleY as number })
655      .opacity(this.targetInfo.startAppIconWindowAlpha as number)
656      .position({
657        x: this.targetInfo.iconInfo?.appIconPositionX as number,
658        y: this.targetInfo.iconInfo?.appIconPositionY as number,
659      })
660
661      RemoteWindow(this.targetInfo.target)
662        .translate({ x: this.targetInfo.remoteWindowTranslateX, y: this.targetInfo.remoteWindowTranslateY })
663        .scale({ x: this.targetInfo.remoteWindowScaleX, y: this.targetInfo.remoteWindowScaleY })
664        .opacity(this.targetInfo.remoteWindowWindowAlpha)
665        .position({ x: px2vp(this.targetInfo.target?.windowBounds.left), y: px2vp(this.targetInfo.target?.windowBounds.top) })
666        .width(px2vp(this.targetInfo.target?.windowBounds.width))
667        .height(px2vp(this.targetInfo.target?.windowBounds.height))
668        .borderRadius(this.targetInfo.remoteWindowRadius)
669    }
670    .width(StyleConstants.PERCENTAGE_100)
671    .height(StyleConstants.PERCENTAGE_100)
672    .focusable(false)
673    .enabled(false)
674  }
675}
676
677class StartAppItemInfo extends LauncherDragItemInfo {
678  icon?: ResourceStr;
679}
680
681interface StartAppIconInfo {
682  appIconSize: number;
683  appIconHeight: number;
684  appIconPositionX: number;
685  appIconPositionY: number;
686}
687
688interface StartAppInfo {
689  iconInfo: StartAppIconInfo;
690  appItemInfo: StartAppItemInfo;
691}
692
693@Component
694export struct StartAppTransitionRemoteWindow {
695  @ObjectLink targetInfo: RemoteVo;
696  private target?: windowAnimationManager.WindowAnimationTarget;
697  private mFromWindowTarget?: windowAnimationManager.WindowAnimationTarget = undefined;
698  private remoteAnimationType: number = 0;
699  private startAppTypeFromPageDesktop: number = 1;
700  private mScreenWidth: number = 0;
701  private mScreenHeight: number = 0;
702  private startAppIconInfo: StartAppIconInfo =
703    { appIconSize: 0,
704      appIconHeight: 0,
705      appIconPositionX: 0,
706      appIconPositionY: 0 };
707  private mStartAppItemInfo: StartAppItemInfo = new StartAppItemInfo();
708  private mFinishCallback?: windowAnimationManager.WindowAnimationFinishedCallback;
709  private remoteWindowKey?: string;
710
711  aboutToAppear(): void  {
712    this.target = this.targetInfo.target;
713    this.mFromWindowTarget = this.targetInfo.fromWindowTarget;
714    this.mFinishCallback = this.targetInfo.finishCallback;
715    this.remoteWindowKey = this.targetInfo.remoteWindowKey;
716    this.mStartAppItemInfo = this.targetInfo.appItemInfo;
717    this.mScreenWidth = px2vp(this.target.windowBounds.width);
718    this.mScreenHeight = px2vp(this.target.windowBounds.height);
719  }
720
721  aboutToDisappear() {
722  }
723
724  build() {
725    Stack() {
726      Column() {
727        RemoteWindow(this.targetInfo.target)
728          .position({ x: px2vp(this.target?.windowBounds.left as number),
729            y: px2vp(this.target?.windowBounds.top as number) })
730          .width(px2vp(this.target?.windowBounds.width as number))
731          .height(px2vp(this.target?.windowBounds.height as number))
732          .translate({ x: this.targetInfo.remoteWindowTranslateX, y: this.targetInfo.remoteWindowTranslateY })
733          .scale({ x: this.targetInfo.remoteWindowScaleX, y: this.targetInfo.remoteWindowScaleY })
734          .opacity(this.targetInfo.remoteWindowWindowAlpha)
735          .borderRadius(this.targetInfo.remoteWindowRadius)
736
737        RemoteWindow(this.mFromWindowTarget)
738          .translate({ x: this.targetInfo.fromRemoteWindowTranslateX, y: this.targetInfo.fromRemoteWindowTranslateY })
739          .scale({ x: this.targetInfo.fromRemoteWindowScaleX, y: this.targetInfo.fromRemoteWindowScaleY })
740          .opacity(this.targetInfo.fromRemoteWindowWindowAlpha)
741          .position({
742            x: px2vp(this.mFromWindowTarget?.windowBounds.left as number),
743            y: px2vp(this.mFromWindowTarget?.windowBounds.top as number)
744          })
745          .width(px2vp(this.mFromWindowTarget?.windowBounds.width as number))
746          .height(px2vp(this.mFromWindowTarget?.windowBounds.height as number))
747          .borderRadius(this.targetInfo.remoteWindowRadius)
748      }
749      .width(StyleConstants.PERCENTAGE_100)
750      .height(StyleConstants.PERCENTAGE_100)
751      .focusable(false)
752      .enabled(false)
753    }
754  }
755}