1 /*
2  * Copyright (c) 2021-2024 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 
16 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMMON_CONTAINER_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMMON_CONTAINER_H
18 
19 #include <atomic>
20 #include <functional>
21 #include <mutex>
22 #include <unordered_map>
23 
24 #include "interfaces/inner_api/ace/ace_forward_compatibility.h"
25 #include "interfaces/inner_api/ace/constants.h"
26 #include "interfaces/inner_api/ace/navigation_controller.h"
27 
28 #include "base/memory/ace_type.h"
29 #include "base/view_data/hint_to_type_wrap.h"
30 #include "base/resource/asset_manager.h"
31 #include "base/resource/shared_image_manager.h"
32 #include "base/thread/task_executor.h"
33 #include "base/utils/macros.h"
34 #include "base/utils/noncopyable.h"
35 #include "base/utils/system_properties.h"
36 #include "base/utils/utils.h"
37 #include "core/common/ace_application_info.h"
38 #include "core/common/container_consts.h"
39 #include "core/common/display_info.h"
40 #include "core/common/display_info_utils.h"
41 #include "core/common/frontend.h"
42 #include "core/common/page_url_checker.h"
43 #include "core/common/platform_res_register.h"
44 #include "core/common/resource/resource_configuration.h"
45 #include "core/common/settings.h"
46 #include "core/common/window.h"
47 #include "core/components/common/layout/constants.h"
48 #include "core/components_ng/base/distributed_ui.h"
49 #include "core/components_ng/pattern/app_bar/app_bar_view.h"
50 #include "core/components_ng/pattern/navigation/navigation_route.h"
51 #include "core/components_ng/pattern/navigator/navigator_event_hub.h"
52 #include "core/event/pointer_event.h"
53 #include "core/pipeline/pipeline_base.h"
54 
55 namespace OHOS::Ace {
56 
57 using PageTask = std::function<void()>;
58 using TouchEventCallback = std::function<void(const TouchEvent&, const std::function<void()>&,
59     const RefPtr<NG::FrameNode>&)>;
60 using KeyEventCallback = std::function<bool(const KeyEvent&)>;
61 using MouseEventCallback = std::function<void(const MouseEvent&, const std::function<void()>&,
62     const RefPtr<NG::FrameNode>&)>;
63 using AxisEventCallback = std::function<void(const AxisEvent&, const std::function<void()>&,
64     const RefPtr<NG::FrameNode>&)>;
65 using RotationEventCallBack = std::function<bool(const RotationEvent&)>;
66 using CardViewPositionCallBack = std::function<void(int id, float offsetX, float offsetY)>;
67 using DragEventCallBack = std::function<void(const PointerEvent&, const DragEventAction&,
68     const RefPtr<NG::FrameNode>&)>;
69 using StopDragCallback = std::function<void()>;
70 
71 class ACE_FORCE_EXPORT Container : public virtual AceType {
72     DECLARE_ACE_TYPE(Container, AceType);
73 
74 public:
75     Container() = default;
76     ~Container() override = default;
77 
78     virtual void Initialize() = 0;
79 
80     virtual void Destroy() = 0;
81 
IsKeyboard()82     virtual bool IsKeyboard()
83     {
84         return false;
85     }
86 
DestroyView()87     virtual void DestroyView() {}
88     virtual bool UpdatePopupUIExtension(const RefPtr<NG::FrameNode>& node,
89         uint32_t autoFillSessionId, bool isNative = true)
90     {
91         return false;
92     }
93 
ClosePopupUIExtension(uint32_t autoFillSessionId)94     virtual bool ClosePopupUIExtension(uint32_t autoFillSessionId)
95     {
96         return false;
97     }
98 
PlaceHolderToType(const std::string & onePlaceHolder)99     virtual HintToTypeWrap PlaceHolderToType(const std::string& onePlaceHolder)
100     {
101         HintToTypeWrap hintToTypeWrap;
102         return hintToTypeWrap;
103     }
104 
105     // Get the instance id of this container
106     virtual int32_t GetInstanceId() const = 0;
107 
108     // Get the ability name of this container
109     virtual std::string GetHostClassName() const = 0;
110 
111     // Get the frontend of container
112     virtual RefPtr<Frontend> GetFrontend() const = 0;
113 
114     // Get task executor.
115     virtual RefPtr<TaskExecutor> GetTaskExecutor() const = 0;
116 
117     // Get assert manager.
118     virtual RefPtr<AssetManager> GetAssetManager() const = 0;
119 
120     // Get platform resource register.
121     virtual RefPtr<PlatformResRegister> GetPlatformResRegister() const = 0;
122 
123     // Get the pipelineContext of container.
124     virtual RefPtr<PipelineBase> GetPipelineContext() const = 0;
125 
126     // Dump container.
127     virtual bool Dump(const std::vector<std::string>& params, std::vector<std::string>& info);
128 
129     // Get the width/height of the view
130     virtual int32_t GetViewWidth() const = 0;
131     virtual int32_t GetViewHeight() const = 0;
132     virtual int32_t GetViewPosX() const = 0;
133     virtual int32_t GetViewPosY() const = 0;
134 
135     virtual uint32_t GetWindowId() const = 0;
SetWindowId(uint32_t windowId)136     virtual void SetWindowId(uint32_t windowId) {}
WindowIsShow()137     virtual bool WindowIsShow() const
138     {
139         return false;
140     }
141 
142     virtual RefPtr<AceView> GetAceView() const = 0;
143 
144     virtual void* GetView() const = 0;
145 
146     // Trigger garbage collection
TriggerGarbageCollection()147     virtual void TriggerGarbageCollection() {}
148 
DumpHeapSnapshot(bool isPrivate)149     virtual void DumpHeapSnapshot(bool isPrivate) {}
150 
DestroyHeapProfiler()151     virtual void DestroyHeapProfiler() {}
152 
ForceFullGC()153     virtual void ForceFullGC() {}
154 
NotifyFontNodes()155     virtual void NotifyFontNodes() {}
156 
NotifyAppStorage(const std::string & key,const std::string & value)157     virtual void NotifyAppStorage(const std::string& key, const std::string& value) {}
158 
SetCardFrontend(WeakPtr<Frontend> frontend,int64_t cardId)159     virtual void SetCardFrontend(WeakPtr<Frontend> frontend, int64_t cardId) {}
160 
GetCardFrontend(int64_t cardId)161     virtual WeakPtr<Frontend> GetCardFrontend(int64_t cardId) const
162     {
163         return nullptr;
164     }
165 
SetCardPipeline(WeakPtr<PipelineBase>,int64_t cardId)166     virtual void SetCardPipeline(WeakPtr<PipelineBase>, int64_t cardId) {}
167 
GetCardPipeline(int64_t cardId)168     virtual WeakPtr<PipelineBase> GetCardPipeline(int64_t cardId) const
169     {
170         return nullptr;
171     }
172 
173     // Get MultiModal ptr.
GetMutilModalPtr()174     virtual uintptr_t GetMutilModalPtr() const
175     {
176         return 0;
177     }
178 
ProcessScreenOnEvents()179     virtual void ProcessScreenOnEvents() {}
180 
ProcessScreenOffEvents()181     virtual void ProcessScreenOffEvents() {}
182 
SetOrientation(Orientation orientation)183     virtual void SetOrientation(Orientation orientation) {}
184 
GetOrientation()185     virtual Orientation GetOrientation()
186     {
187         return Orientation::UNSPECIFIED;
188     }
189 
190     virtual RefPtr<DisplayInfo> GetDisplayInfo();
191 
192     virtual void InitIsFoldable();
193 
194     virtual bool IsFoldable();
195 
196     virtual FoldStatus GetCurrentFoldStatus();
197 
GetKeyboardSafeArea()198     virtual NG::SafeAreaInsets GetKeyboardSafeArea()
199     {
200         return {};
201     }
202 
GetHapPath()203     virtual std::string GetHapPath() const
204     {
205         return {};
206     }
207 
GetWebHapPath()208     virtual std::string GetWebHapPath() const
209     {
210         return {};
211     }
212 
SetCreateTime(std::chrono::time_point<std::chrono::high_resolution_clock> time)213     void SetCreateTime(std::chrono::time_point<std::chrono::high_resolution_clock> time)
214     {
215         createTime_ = time;
216     }
217 
IsFirstUpdate()218     bool IsFirstUpdate() const
219     {
220         return firstUpdateData_;
221     }
222 
AlreadyFirstUpdate()223     void AlreadyFirstUpdate()
224     {
225         firstUpdateData_ = false;
226     }
227 
SetBundleName(const std::string & bundleName)228     void SetBundleName(const std::string& bundleName)
229     {
230         bundleName_ = bundleName;
231     }
232 
GetBundleName()233     const std::string& GetBundleName() const
234     {
235         return bundleName_;
236     }
237 
SetModuleName(const std::string & moduleName)238     void SetModuleName(const std::string& moduleName)
239     {
240         moduleName_ = moduleName;
241     }
242 
GetModuleName()243     std::string GetModuleName() const
244     {
245         return moduleName_;
246     }
247 
IsMainWindow()248     virtual bool IsMainWindow() const { return false; }
IsSubWindow()249     virtual bool IsSubWindow() const { return false; }
IsDialogWindow()250     virtual bool IsDialogWindow() const { return false; }
IsSystemWindow()251     virtual bool IsSystemWindow() const { return false; }
IsHostMainWindow()252     virtual bool IsHostMainWindow() const { return false; }
IsHostSubWindow()253     virtual bool IsHostSubWindow() const { return false; }
IsHostDialogWindow()254     virtual bool IsHostDialogWindow() const { return false; }
IsHostSystemWindow()255     virtual bool IsHostSystemWindow() const { return false; }
IsHostScenceBoardWindow()256     virtual bool IsHostScenceBoardWindow() const { return false; }
IsSubContainer()257     virtual bool IsSubContainer() const { return false; }
IsFormRender()258     virtual bool IsFormRender() const { return false; }
GetParentMainWindowId(uint32_t currentWindowId)259     virtual uint32_t GetParentMainWindowId(uint32_t currentWindowId) const
260     {
261         return 0;
262     }
263 
SetIsFormRender(bool isFormRender)264     virtual void SetIsFormRender(bool isFormRender) {};
265 
GetCardHapPath()266     const std::string& GetCardHapPath() const
267     {
268         return cardHapPath_;
269     }
270 
271     bool UpdateState(const Frontend::State& state);
272 
GetSettings()273     Settings& GetSettings()
274     {
275         return settings_;
276     }
277 
SetBundlePath(const std::string & path)278     void SetBundlePath(const std::string& path)
279     {
280         bundlePath_ = path;
281     }
282 
GetBundlePath()283     const std::string& GetBundlePath() const
284     {
285         return bundlePath_;
286     }
287 
SetFilesDataPath(const std::string & path)288     void SetFilesDataPath(const std::string& path)
289     {
290         filesDataPath_ = path;
291     }
292 
GetFilesDataPath()293     const std::string& GetFilesDataPath() const
294     {
295         return filesDataPath_;
296     }
297 
SetTempDir(const std::string & path)298     void SetTempDir(const std::string& path)
299     {
300         tempDir_ = path;
301     }
302 
GetTempDir()303     const std::string& GetTempDir() const
304     {
305         return tempDir_;
306     }
307 
SetViewFirstUpdating(std::chrono::time_point<std::chrono::high_resolution_clock> time)308     virtual void SetViewFirstUpdating(std::chrono::time_point<std::chrono::high_resolution_clock> time) {}
309 
UpdateResourceConfiguration(const std::string & jsonStr)310     virtual void UpdateResourceConfiguration(const std::string& jsonStr) {}
311 
312     static int32_t SafelyId();
313     static int32_t CurrentId();
314     static int32_t CurrentIdSafely();
315     static int32_t CurrentIdSafelyWithCheck();
316     static RefPtr<Container> Current();
317     static RefPtr<Container> CurrentSafely();
318     static RefPtr<Container> CurrentSafelyWithCheck();
319     static RefPtr<Container> GetContainer(int32_t containerId);
320     static RefPtr<Container> GetActive();
321     static RefPtr<Container> GetDefault();
322     static RefPtr<Container> GetFoucsed();
323     static RefPtr<TaskExecutor> CurrentTaskExecutor();
324     static RefPtr<TaskExecutor> CurrentTaskExecutorSafely();
325     static RefPtr<TaskExecutor> CurrentTaskExecutorSafelyWithCheck();
326     static void UpdateCurrent(int32_t id);
327 
SetUseNewPipeline()328     void SetUseNewPipeline()
329     {
330         useNewPipeline_ = true;
331     }
332 
SetUsePartialUpdate()333     void SetUsePartialUpdate()
334     {
335         usePartialUpdate_ = true;
336     }
337 
IsUseNewPipeline()338     bool IsUseNewPipeline() const
339     {
340         return useNewPipeline_;
341     }
342 
IsCurrentUseNewPipeline()343     static bool IsCurrentUseNewPipeline()
344     {
345         auto container = Current();
346         return container ? container->useNewPipeline_ : AceForwardCompatibility::IsUseNG();
347     }
348 
349     // SetCurrentUsePartialUpdate is called when initial render on a page
350     // starts, see zyz_view_register loadDocument() implementation
IsCurrentUsePartialUpdate()351     static bool IsCurrentUsePartialUpdate()
352     {
353         auto container = Current();
354         return container ? container->usePartialUpdate_ : false;
355     }
356 
357     static void SetCurrentUsePartialUpdate(bool useIt = false)
358     {
359         auto container = Current();
360         if (container) {
361             container->usePartialUpdate_ = useIt;
362         }
363     }
364 
IsInFormContainer()365     static bool IsInFormContainer() {
366         auto container = Current();
367         return container ? container->isFRSCardContainer_ : false;
368     }
369 
IsInSubContainer()370     static bool IsInSubContainer()
371     {
372         auto container = Current();
373         return container ? container->IsSubContainer() : false;
374     }
375 
GetWindow()376     Window* GetWindow() const
377     {
378         auto context = GetPipelineContext();
379         return context ? context->GetWindow() : nullptr;
380     }
381 
IsUseStageModel()382     virtual bool IsUseStageModel() const
383     {
384         return false;
385     }
386 
GetCardFrontendMap(std::unordered_map<int64_t,WeakPtr<Frontend>> & cardFrontendMap)387     virtual void GetCardFrontendMap(std::unordered_map<int64_t, WeakPtr<Frontend>>& cardFrontendMap) const {}
388 
SetSharedRuntime(void * runtime)389     virtual void SetSharedRuntime(void* runtime) {}
GetSharedRuntime()390     virtual void* GetSharedRuntime()
391     {
392         return nullptr;
393     }
394 
IsFRSCardContainer()395     bool IsFRSCardContainer() const
396     {
397         return isFRSCardContainer_;
398     }
399 
SetIsFRSCardContainer(bool isFRSCardContainer)400     void SetIsFRSCardContainer(bool isFRSCardContainer)
401     {
402         isFRSCardContainer_ = isFRSCardContainer;
403     }
404 
IsDynamicRender()405     bool IsDynamicRender() const
406     {
407         return isDynamicRender_;
408     }
409 
SetIsDynamicRender(bool isDynamicRender)410     void SetIsDynamicRender(bool isDynamicRender)
411     {
412         isDynamicRender_ = isDynamicRender;
413     }
414 
GetRegisterComponents()415     virtual std::vector<std::string> GetRegisterComponents() { return {}; };
416 
SetPageUrlChecker(const RefPtr<PageUrlChecker> & pageUrlChecker)417     void SetPageUrlChecker(const RefPtr<PageUrlChecker>& pageUrlChecker)
418     {
419         pageUrlChecker_ = pageUrlChecker;
420     }
421 
GetPageUrlChecker()422     const RefPtr<PageUrlChecker>& GetPageUrlChecker()
423     {
424         return pageUrlChecker_;
425     }
426 
SetNavigationRoute(const RefPtr<NG::NavigationRoute> & navigationRoute)427     void SetNavigationRoute(const RefPtr<NG::NavigationRoute>& navigationRoute)
428     {
429         navigationRoute_ = navigationRoute;
430     }
431 
GetNavigationRoute()432     RefPtr<NG::NavigationRoute> GetNavigationRoute() const
433     {
434         return navigationRoute_;
435     }
436 
IsDialogContainer()437     virtual bool IsDialogContainer() const
438     {
439         return false;
440     }
441 
SetWindowScale(float windowScale)442     virtual void SetWindowScale(float windowScale) {}
443 
GetWindowScale()444     virtual float GetWindowScale() const
445     {
446         return 1.0f;
447     }
448 
449     virtual void NotifyConfigurationChange(bool, const ConfigurationChange& configurationChange = { false, false }) {}
450 
HotReload()451     virtual void HotReload() {}
452 
SetIsModule(bool isModule)453     void SetIsModule(bool isModule)
454     {
455         isModule_ = isModule;
456     }
457 
IsModule()458     bool IsModule() const
459     {
460         return isModule_;
461     }
462 
SetDistributedUI(std::shared_ptr<NG::DistributedUI> & distributedUI)463     void SetDistributedUI(std::shared_ptr<NG::DistributedUI>& distributedUI)
464     {
465         distributedUI_ = distributedUI;
466     }
467 
GetDistributedUI()468     std::shared_ptr<NG::DistributedUI>& GetDistributedUI()
469     {
470         return distributedUI_;
471     }
472 
IsLauncherContainer()473     virtual bool IsLauncherContainer()
474     {
475         return false;
476     }
477 
IsScenceBoardWindow()478     virtual bool IsScenceBoardWindow()
479     {
480         return false;
481     }
482 
IsUIExtensionWindow()483     virtual bool IsUIExtensionWindow()
484     {
485         return false;
486     }
487 
IsSceneBoardEnabled()488     virtual bool IsSceneBoardEnabled()
489     {
490         return false;
491     }
492 
GetCurPointerEventInfo(int32_t & pointerId,int32_t & globalX,int32_t & globalY,int32_t & sourceType,int32_t & sourceTool,StopDragCallback && stopDragCallback)493     virtual bool GetCurPointerEventInfo(
494         int32_t& pointerId, int32_t& globalX, int32_t& globalY, int32_t& sourceType,
495         int32_t& sourceTool, StopDragCallback&& stopDragCallback)
496     {
497         return false;
498     }
499 
GetCurPointerEventSourceType(int32_t & sourceType)500     virtual bool GetCurPointerEventSourceType(int32_t& sourceType)
501     {
502         return false;
503     }
504 
505     virtual bool RequestAutoFill(const RefPtr<NG::FrameNode>& node, AceAutoFillType autoFillType,
506         bool isNewPassWord, bool& isPopup, uint32_t& autoFillSessionId, bool isNative = true)
507     {
508         return false;
509     }
510 
IsNeedToCreatePopupWindow(const AceAutoFillType & autoFillType)511     virtual bool IsNeedToCreatePopupWindow(const AceAutoFillType& autoFillType)
512     {
513         return false;
514     }
515 
516     virtual bool RequestAutoSave(const RefPtr<NG::FrameNode>& node, const std::function<void()>& onFinish = nullptr,
517         const std::function<void()>& onUIExtNodeBindingCompleted = nullptr, bool isNative = true,
518         int32_t instanceId = -1)
519     {
520         return false;
521     }
522 
523 
GetNavigationController(const std::string & navigationId)524     virtual std::shared_ptr<NavigationController> GetNavigationController(const std::string& navigationId)
525     {
526         return nullptr;
527     }
528 
LessThanAPIVersion(PlatformVersion version)529     static bool LessThanAPIVersion(PlatformVersion version)
530     {
531         return PipelineBase::GetCurrentContext() &&
532                PipelineBase::GetCurrentContext()->GetMinPlatformVersion() < static_cast<int32_t>(version);
533     }
534 
GreatOrEqualAPIVersion(PlatformVersion version)535     static bool GreatOrEqualAPIVersion(PlatformVersion version)
536     {
537         return PipelineBase::GetCurrentContext() &&
538                PipelineBase::GetCurrentContext()->GetMinPlatformVersion() >= static_cast<int32_t>(version);
539     }
540 
LessThanAPITargetVersion(PlatformVersion version)541     static bool LessThanAPITargetVersion(PlatformVersion version)
542     {
543         auto container = Current();
544         CHECK_NULL_RETURN(container, false);
545         auto apiTargetVersion = container->GetApiTargetVersion();
546         return apiTargetVersion < static_cast<int32_t>(version);
547     }
548 
GreatOrEqualAPITargetVersion(PlatformVersion version)549     static bool GreatOrEqualAPITargetVersion(PlatformVersion version)
550     {
551         auto container = Current();
552         if (!container) {
553             auto apiTargetVersion = AceApplicationInfo::GetInstance().GetApiTargetVersion() % 1000;
554             return apiTargetVersion >= static_cast<int32_t>(version);
555         }
556         auto apiTargetVersion = container->GetApiTargetVersion();
557         return apiTargetVersion >= static_cast<int32_t>(version);
558     }
559 
SetAppBar(const RefPtr<NG::AppBarView> & appBar)560     void SetAppBar(const RefPtr<NG::AppBarView>& appBar)
561     {
562         appBar_ = appBar;
563     }
564 
GetAppBar()565     RefPtr<NG::AppBarView> GetAppBar() const
566     {
567         return appBar_;
568     }
569 
TerminateUIExtension()570     virtual void TerminateUIExtension() {}
571 
572     template<ContainerType type>
573     static int32_t GenerateId();
574     static void SetFontScale(int32_t instanceId, float fontScale);
575     static void SetFontWeightScale(int32_t instanceId, float fontScale);
576 
GetApiTargetVersion()577     int32_t GetApiTargetVersion() const
578     {
579         return apiTargetVersion_;
580     }
581 
SetApiTargetVersion(int32_t apiTargetVersion)582     void SetApiTargetVersion(int32_t apiTargetVersion)
583     {
584         apiTargetVersion_ = apiTargetVersion % 1000;
585     }
586 
GetUIContentType()587     UIContentType GetUIContentType() const
588     {
589         return uIContentType_;
590     }
591 
SetUIContentType(UIContentType uIContentType)592     void SetUIContentType(UIContentType uIContentType)
593     {
594         uIContentType_ = uIContentType;
595     }
596 
IsFreeMultiWindow()597     virtual bool IsFreeMultiWindow() const
598     {
599         return false;
600     }
601 
602     virtual ResourceConfiguration GetResourceConfiguration() const = 0;
603 
604 private:
605     static bool IsIdAvailable(int32_t id);
606 
607 protected:
608     std::chrono::time_point<std::chrono::high_resolution_clock> createTime_;
609     bool firstUpdateData_ = true;
610     std::string cardHapPath_;
611     bool useNewPipeline_ = false;
612     std::mutex stateMutex_;
613     Frontend::State state_ = Frontend::State::UNDEFINE;
614     bool isFRSCardContainer_ = false;
615     bool isDynamicRender_ = false;
616 
617 private:
618     std::string bundleName_;
619     std::string moduleName_;
620     std::string bundlePath_;
621     std::string filesDataPath_;
622     std::string tempDir_;
623     bool usePartialUpdate_ = false;
624     Settings settings_;
625     RefPtr<PageUrlChecker> pageUrlChecker_;
626     RefPtr<NG::NavigationRoute> navigationRoute_;
627     bool isModule_ = false;
628     std::shared_ptr<NG::DistributedUI> distributedUI_;
629     RefPtr<NG::AppBarView> appBar_;
630     int32_t apiTargetVersion_ = 0;
631     // Define the type of UI Content, for example, Security UIExtension.
632     UIContentType uIContentType_ = UIContentType::UNDEFINED;
633     ACE_DISALLOW_COPY_AND_MOVE(Container);
634 };
635 
636 template<ContainerType type>
GenerateId()637 int32_t Container::GenerateId()
638 {
639     static std::atomic<int32_t> gInstanceId;
640     int32_t id;
641     do {
642         id = type * CONTAINER_ID_DIVIDE_SIZE + gInstanceId.fetch_add(1) % CONTAINER_ID_DIVIDE_SIZE;
643     } while (!IsIdAvailable(id));
644     return id;
645 }
646 
647 template<>
648 int32_t Container::GenerateId<PLUGIN_SUBCONTAINER>();
649 
650 } // namespace OHOS::Ace
651 
652 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMMON_CONTAINER_H
653