• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 
16 #include "display_manager_stub.h"
17 
18 #include "dm_common.h"
19 
20 #include <ipc_skeleton.h>
21 
22 #include "marshalling_helper.h"
23 #include "window_manager_hilog.h"
24 
25 #include "transaction/rs_interfaces.h"
26 
27 namespace OHOS::Rosen {
28 namespace {
29 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "DisplayManagerStub"};
30 const static uint32_t MAX_SCREEN_SIZE = 32;
31 }
32 
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)33 int32_t DisplayManagerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
34     MessageOption &option)
35 {
36     WLOGFD("OnRemoteRequest code is %{public}u", code);
37     if (data.ReadInterfaceToken() != GetDescriptor()) {
38         WLOGFE("InterfaceToken check failed");
39         return -1;
40     }
41     DisplayManagerMessage msgId = static_cast<DisplayManagerMessage>(code);
42     switch (msgId) {
43         case DisplayManagerMessage::TRANS_ID_GET_DEFAULT_DISPLAY_INFO: {
44             auto info = GetDefaultDisplayInfo();
45             reply.WriteParcelable(info);
46             break;
47         }
48         case DisplayManagerMessage::TRANS_ID_GET_DISPLAY_BY_ID: {
49             DisplayId displayId = data.ReadUint64();
50             auto info = GetDisplayInfoById(displayId);
51             reply.WriteParcelable(info);
52             break;
53         }
54         case DisplayManagerMessage::TRANS_ID_GET_VISIBLE_AREA_DISPLAY_INFO_BY_ID: {
55             DisplayId displayId = static_cast<DisplayId>(data.ReadUint64());
56             auto info = GetVisibleAreaDisplayInfoById(displayId);
57             reply.WriteParcelable(info);
58             break;
59         }
60         case DisplayManagerMessage::TRANS_ID_GET_DISPLAY_BY_SCREEN: {
61             ScreenId screenId = data.ReadUint64();
62             auto info = GetDisplayInfoByScreen(screenId);
63             reply.WriteParcelable(info);
64             break;
65         }
66         case DisplayManagerMessage::TRANS_ID_CREATE_VIRTUAL_SCREEN: {
67             std::string name = data.ReadString();
68             uint32_t width = data.ReadUint32();
69             uint32_t height = data.ReadUint32();
70             float density = data.ReadFloat();
71             int32_t flags = data.ReadInt32();
72             bool isForShot = data.ReadBool();
73             std::vector<uint64_t> missionIds;
74             data.ReadUInt64Vector(&missionIds);
75             bool isSurfaceValid = data.ReadBool();
76             sptr<Surface> surface = nullptr;
77             if (isSurfaceValid) {
78                 sptr<IRemoteObject> surfaceObject = data.ReadRemoteObject();
79                 sptr<IBufferProducer> bp = iface_cast<IBufferProducer>(surfaceObject);
80                 surface = Surface::CreateSurfaceAsProducer(bp);
81             }
82             sptr<IRemoteObject> virtualScreenAgent = data.ReadRemoteObject();
83             VirtualScreenOption virScrOption = {
84                 .name_ = name,
85                 .width_ = width,
86                 .height_ = height,
87                 .density_ = density,
88                 .surface_ = surface,
89                 .flags_ = flags,
90                 .isForShot_ = isForShot,
91                 .missionIds_ = missionIds
92             };
93             ScreenId screenId = CreateVirtualScreen(virScrOption, virtualScreenAgent);
94             reply.WriteUint64(static_cast<uint64_t>(screenId));
95             break;
96         }
97         case DisplayManagerMessage::TRANS_ID_DESTROY_VIRTUAL_SCREEN: {
98             ScreenId screenId = static_cast<ScreenId>(data.ReadUint64());
99             DMError result = DestroyVirtualScreen(screenId);
100             reply.WriteInt32(static_cast<int32_t>(result));
101             break;
102         }
103         case DisplayManagerMessage::TRANS_ID_SET_VIRTUAL_SCREEN_SURFACE: {
104             ScreenId screenId = static_cast<ScreenId>(data.ReadUint64());
105             bool isSurfaceValid = data.ReadBool();
106             sptr<IBufferProducer> bp = nullptr;
107             if (isSurfaceValid) {
108                 sptr<IRemoteObject> surfaceObject = data.ReadRemoteObject();
109                 bp = iface_cast<IBufferProducer>(surfaceObject);
110             }
111             DMError result = SetVirtualScreenSurface(screenId, bp);
112             reply.WriteInt32(static_cast<int32_t>(result));
113             break;
114         }
115         case DisplayManagerMessage::TRANS_ID_SET_ORIENTATION: {
116             ScreenId screenId = static_cast<ScreenId>(data.ReadUint64());
117             Orientation orientation = static_cast<Orientation>(data.ReadUint32());
118             DMError ret = SetOrientation(screenId, orientation);
119             reply.WriteInt32(static_cast<int32_t>(ret));
120             break;
121         }
122         case DisplayManagerMessage::TRANS_ID_GET_DISPLAY_SNAPSHOT: {
123             DisplayId displayId = data.ReadUint64();
124             DmErrorCode errorCode = DmErrorCode::DM_OK;
125             std::shared_ptr<Media::PixelMap> displaySnapshot = GetDisplaySnapshot(displayId, &errorCode);
126             reply.WriteParcelable(displaySnapshot == nullptr ? nullptr : displaySnapshot.get());
127             reply.WriteInt32(static_cast<int32_t>(errorCode));
128             break;
129         }
130         case DisplayManagerMessage::TRANS_ID_REGISTER_DISPLAY_MANAGER_AGENT: {
131             auto agent = iface_cast<IDisplayManagerAgent>(data.ReadRemoteObject());
132             if (agent == nullptr) {
133                 WLOGFE("agent is nullptr");
134                 break;
135             }
136             auto type = static_cast<DisplayManagerAgentType>(data.ReadUint32());
137             DMError ret = RegisterDisplayManagerAgent(agent, type);
138             reply.WriteInt32(static_cast<int32_t>(ret));
139             break;
140         }
141         case DisplayManagerMessage::TRANS_ID_UNREGISTER_DISPLAY_MANAGER_AGENT: {
142             auto agent = iface_cast<IDisplayManagerAgent>(data.ReadRemoteObject());
143             if (agent == nullptr) {
144                 WLOGFE("agent is nullptr");
145                 break;
146             }
147             auto type = static_cast<DisplayManagerAgentType>(data.ReadUint32());
148             DMError ret = UnregisterDisplayManagerAgent(agent, type);
149             reply.WriteInt32(static_cast<int32_t>(ret));
150             break;
151         }
152         case DisplayManagerMessage::TRANS_ID_WAKE_UP_BEGIN: {
153             PowerStateChangeReason reason = static_cast<PowerStateChangeReason>(data.ReadUint32());
154             reply.WriteBool(WakeUpBegin(reason));
155             break;
156         }
157         case DisplayManagerMessage::TRANS_ID_WAKE_UP_END: {
158             reply.WriteBool(WakeUpEnd());
159             break;
160         }
161         case DisplayManagerMessage::TRANS_ID_SUSPEND_BEGIN: {
162             PowerStateChangeReason reason = static_cast<PowerStateChangeReason>(data.ReadUint32());
163             reply.WriteBool(SuspendBegin(reason));
164             break;
165         }
166         case DisplayManagerMessage::TRANS_ID_SUSPEND_END: {
167             reply.WriteBool(SuspendEnd());
168             break;
169         }
170         case DisplayManagerMessage::TRANS_ID_SET_SPECIFIED_SCREEN_POWER: {
171             ScreenId screenId = static_cast<ScreenId>(data.ReadUint32());
172             ScreenPowerState state = static_cast<ScreenPowerState>(data.ReadUint32());
173             PowerStateChangeReason reason = static_cast<PowerStateChangeReason>(data.ReadUint32());
174             reply.WriteBool(SetSpecifiedScreenPower(screenId, state, reason));
175             break;
176         }
177         case DisplayManagerMessage::TRANS_ID_SET_SCREEN_POWER_FOR_ALL: {
178             ScreenPowerState state = static_cast<ScreenPowerState>(data.ReadUint32());
179             PowerStateChangeReason reason = static_cast<PowerStateChangeReason>(data.ReadUint32());
180             reply.WriteBool(SetScreenPowerForAll(state, reason));
181             break;
182         }
183         case DisplayManagerMessage::TRANS_ID_GET_SCREEN_POWER: {
184             ScreenId dmsScreenId;
185             if (!data.ReadUint64(dmsScreenId)) {
186                 WLOGFE("fail to read dmsScreenId.");
187                 break;
188             }
189             reply.WriteUint32(static_cast<uint32_t>(GetScreenPower(dmsScreenId)));
190             break;
191         }
192         case DisplayManagerMessage::TRANS_ID_SET_DISPLAY_STATE: {
193             DisplayState state = static_cast<DisplayState>(data.ReadUint32());
194             reply.WriteBool(SetDisplayState(state));
195             break;
196         }
197         case DisplayManagerMessage::TRANS_ID_GET_DISPLAY_STATE: {
198             DisplayState state = GetDisplayState(data.ReadUint64());
199             reply.WriteUint32(static_cast<uint32_t>(state));
200             break;
201         }
202         case DisplayManagerMessage::TRANS_ID_SET_SCREEN_BRIGHTNESS: {
203             uint64_t screenId = data.ReadUint64();
204             uint32_t level = data.ReadUint64();
205             reply.WriteBool(SetScreenBrightness(screenId, level));
206             break;
207         }
208         case DisplayManagerMessage::TRANS_ID_GET_SCREEN_BRIGHTNESS: {
209             uint64_t screenId = data.ReadUint64();
210             reply.WriteUint32(GetScreenBrightness(screenId));
211             break;
212         }
213         case DisplayManagerMessage::TRANS_ID_NOTIFY_DISPLAY_EVENT: {
214             DisplayEvent event = static_cast<DisplayEvent>(data.ReadUint32());
215             NotifyDisplayEvent(event);
216             break;
217         }
218         case DisplayManagerMessage::TRANS_ID_SET_FREEZE_EVENT: {
219             std::vector<DisplayId> ids;
220             data.ReadUInt64Vector(&ids);
221             SetFreeze(ids, data.ReadBool());
222             break;
223         }
224         case DisplayManagerMessage::TRANS_ID_SCREEN_MAKE_MIRROR: {
225             ScreenId mainScreenId = static_cast<ScreenId>(data.ReadUint64());
226             std::vector<ScreenId> mirrorScreenId;
227             if (!data.ReadUInt64Vector(&mirrorScreenId)) {
228                 WLOGE("fail to receive mirror screen in stub. screen:%{public}" PRIu64"", mainScreenId);
229                 break;
230             }
231             ScreenId screenGroupId = INVALID_SCREEN_ID;
232             DMError ret = MakeMirror(mainScreenId, mirrorScreenId, screenGroupId);
233             reply.WriteInt32(static_cast<int32_t>(ret));
234             reply.WriteUint64(static_cast<uint64_t>(screenGroupId));
235             break;
236         }
237         case DisplayManagerMessage::TRANS_ID_GET_SCREEN_INFO_BY_ID: {
238             ScreenId screenId = static_cast<ScreenId>(data.ReadUint64());
239             auto screenInfo = GetScreenInfoById(screenId);
240             reply.WriteStrongParcelable(screenInfo);
241             break;
242         }
243         case DisplayManagerMessage::TRANS_ID_GET_SCREEN_GROUP_INFO_BY_ID: {
244             ScreenId screenId = static_cast<ScreenId>(data.ReadUint64());
245             auto screenGroupInfo = GetScreenGroupInfoById(screenId);
246             reply.WriteStrongParcelable(screenGroupInfo);
247             break;
248         }
249         case DisplayManagerMessage::TRANS_ID_GET_ALL_SCREEN_INFOS: {
250             std::vector<sptr<ScreenInfo>> screenInfos;
251             DMError ret  = GetAllScreenInfos(screenInfos);
252             reply.WriteInt32(static_cast<int32_t>(ret));
253             if (!MarshallingHelper::MarshallingVectorParcelableObj<ScreenInfo>(reply, screenInfos)) {
254                 WLOGE("fail to marshalling screenInfos in stub.");
255             }
256             break;
257         }
258         case DisplayManagerMessage::TRANS_ID_GET_ALL_DISPLAYIDS: {
259             std::vector<DisplayId> allDisplayIds = GetAllDisplayIds();
260             reply.WriteUInt64Vector(allDisplayIds);
261             break;
262         }
263         case DisplayManagerMessage::TRANS_ID_SCREEN_MAKE_EXPAND: {
264             std::vector<ScreenId> screenId;
265             if (!data.ReadUInt64Vector(&screenId)) {
266                 WLOGE("fail to receive expand screen in stub.");
267                 break;
268             }
269             std::vector<Point> startPoint;
270             if (!MarshallingHelper::UnmarshallingVectorObj<Point>(data, startPoint, [](Parcel& parcel, Point& point) {
271                     return parcel.ReadInt32(point.posX_) && parcel.ReadInt32(point.posY_);
272                 })) {
273                 WLOGE("fail to receive startPoint in stub.");
274                 break;
275             }
276             ScreenId screenGroupId = INVALID_SCREEN_ID;
277             DMError ret = MakeExpand(screenId, startPoint, screenGroupId);
278             reply.WriteInt32(static_cast<int32_t>(ret));
279             reply.WriteUint64(static_cast<uint64_t>(screenGroupId));
280             break;
281         }
282         case DisplayManagerMessage::TRANS_ID_REMOVE_VIRTUAL_SCREEN_FROM_SCREEN_GROUP: {
283             std::vector<ScreenId> screenId;
284             if (!data.ReadUInt64Vector(&screenId)) {
285                 WLOGE("fail to receive screens in stub.");
286                 break;
287             }
288             RemoveVirtualScreenFromGroup(screenId);
289             break;
290         }
291         case DisplayManagerMessage::TRANS_ID_SET_SCREEN_ACTIVE_MODE: {
292             ScreenId screenId = static_cast<ScreenId>(data.ReadUint64());
293             uint32_t modeId = data.ReadUint32();
294             DMError ret = SetScreenActiveMode(screenId, modeId);
295             reply.WriteInt32(static_cast<int32_t>(ret));
296             break;
297         }
298         case DisplayManagerMessage::TRANS_ID_SET_VIRTUAL_PIXEL_RATIO: {
299             ScreenId screenId = static_cast<ScreenId>(data.ReadUint64());
300             float virtualPixelRatio = data.ReadFloat();
301             DMError ret = SetVirtualPixelRatio(screenId, virtualPixelRatio);
302             reply.WriteInt32(static_cast<int32_t>(ret));
303             break;
304         }
305         case DisplayManagerMessage::TRANS_ID_SCREEN_GET_SUPPORTED_COLOR_GAMUTS: {
306             ScreenId screenId = static_cast<ScreenId>(data.ReadUint64());
307             std::vector<ScreenColorGamut> colorGamuts;
308             DMError ret = GetScreenSupportedColorGamuts(screenId, colorGamuts);
309             reply.WriteInt32(static_cast<int32_t>(ret));
310             if (ret != DMError::DM_OK) {
311                 break;
312             }
313             MarshallingHelper::MarshallingVectorObj<ScreenColorGamut>(reply, colorGamuts,
314                 [](Parcel& parcel, const ScreenColorGamut& color) {
315                     return parcel.WriteUint32(static_cast<uint32_t>(color));
316                 }
317             );
318             break;
319         }
320         case DisplayManagerMessage::TRANS_ID_SCREEN_GET_COLOR_GAMUT: {
321             ScreenId screenId = static_cast<ScreenId>(data.ReadUint64());
322             ScreenColorGamut colorGamut;
323             DMError ret = GetScreenColorGamut(screenId, colorGamut);
324             reply.WriteInt32(static_cast<int32_t>(ret));
325             if (ret != DMError::DM_OK) {
326                 break;
327             }
328             reply.WriteUint32(static_cast<uint32_t>(colorGamut));
329             break;
330         }
331         case DisplayManagerMessage::TRANS_ID_SCREEN_SET_COLOR_GAMUT: {
332             ScreenId screenId = static_cast<ScreenId>(data.ReadUint64());
333             int32_t colorGamutIdx = data.ReadInt32();
334             DMError ret = SetScreenColorGamut(screenId, colorGamutIdx);
335             reply.WriteInt32(static_cast<int32_t>(ret));
336             break;
337         }
338         case DisplayManagerMessage::TRANS_ID_SCREEN_GET_GAMUT_MAP: {
339             ScreenId screenId = static_cast<ScreenId>(data.ReadUint64());
340             ScreenGamutMap gamutMap;
341             DMError ret = GetScreenGamutMap(screenId, gamutMap);
342             reply.WriteInt32(static_cast<int32_t>(ret));
343             if (ret != DMError::DM_OK) {
344                 break;
345             }
346             reply.WriteInt32(static_cast<uint32_t>(gamutMap));
347             break;
348         }
349         case DisplayManagerMessage::TRANS_ID_SCREEN_SET_GAMUT_MAP: {
350             ScreenId screenId = static_cast<ScreenId>(data.ReadUint64());
351             ScreenGamutMap gamutMap = static_cast<ScreenGamutMap>(data.ReadUint32());
352             DMError ret = SetScreenGamutMap(screenId, gamutMap);
353             reply.WriteInt32(static_cast<int32_t>(ret));
354             break;
355         }
356         case DisplayManagerMessage::TRANS_ID_SCREEN_SET_COLOR_TRANSFORM: {
357             ScreenId screenId = static_cast<ScreenId>(data.ReadUint64());
358             DMError ret = SetScreenColorTransform(screenId);
359             reply.WriteInt32(static_cast<int32_t>(ret));
360             break;
361         }
362         case DisplayManagerMessage::TRANS_ID_IS_SCREEN_ROTATION_LOCKED: {
363             bool isLocked = false;
364             DMError ret = IsScreenRotationLocked(isLocked);
365             reply.WriteInt32(static_cast<int32_t>(ret));
366             reply.WriteBool(isLocked);
367             break;
368         }
369         case DisplayManagerMessage::TRANS_ID_SET_SCREEN_ROTATION_LOCKED: {
370             bool isLocked = static_cast<bool>(data.ReadBool());
371             DMError ret = SetScreenRotationLocked(isLocked);
372             reply.WriteInt32(static_cast<int32_t>(ret));
373             break;
374         }
375         case DisplayManagerMessage::TRANS_ID_SET_SCREEN_ROTATION_LOCKED_FROM_JS: {
376             bool isLocked = static_cast<bool>(data.ReadBool());
377             DMError ret = SetScreenRotationLockedFromJs(isLocked);
378             reply.WriteInt32(static_cast<int32_t>(ret));
379             break;
380         }
381         case DisplayManagerMessage::TRANS_ID_HAS_PRIVATE_WINDOW: {
382             DisplayId id = static_cast<DisplayId>(data.ReadUint64());
383             bool hasPrivateWindow = false;
384             DMError ret = HasPrivateWindow(id, hasPrivateWindow);
385             reply.WriteInt32(static_cast<int32_t>(ret));
386             reply.WriteBool(hasPrivateWindow);
387             break;
388         }
389         case DisplayManagerMessage::TRANS_ID_GET_CUTOUT_INFO: {
390             DisplayId displayId = static_cast<DisplayId>(data.ReadUint64());
391             sptr<CutoutInfo> cutoutInfo = GetCutoutInfo(displayId);
392             reply.WriteParcelable(cutoutInfo);
393             break;
394         }
395         case DisplayManagerMessage::TRANS_ID_ADD_SURFACE_NODE: {
396             DisplayId displayId = static_cast<DisplayId>(data.ReadUint64());
397             std::shared_ptr<RSSurfaceNode> surfaceNode = RSSurfaceNode::Unmarshalling(data);
398             auto ret = AddSurfaceNodeToDisplay(displayId, surfaceNode, true);
399             reply.WriteUint32(static_cast<uint32_t>(ret));
400             break;
401         }
402         case DisplayManagerMessage::TRANS_ID_REMOVE_SURFACE_NODE: {
403             DisplayId displayId = static_cast<DisplayId>(data.ReadUint64());
404             std::shared_ptr<RSSurfaceNode> surfaceNode = RSSurfaceNode::Unmarshalling(data);
405             auto ret = RemoveSurfaceNodeFromDisplay(displayId, surfaceNode);
406             reply.WriteUint32(static_cast<uint32_t>(ret));
407             break;
408         }
409         case DisplayManagerMessage::TRANS_ID_SCREEN_STOP_MIRROR: {
410             std::vector<ScreenId> mirrorScreenIds;
411             if (!data.ReadUInt64Vector(&mirrorScreenIds)) {
412                 WLOGE("fail to receive mirror screens in stub.");
413                 break;
414             }
415             DMError ret = StopMirror(mirrorScreenIds);
416             reply.WriteInt32(static_cast<int32_t>(ret));
417             break;
418         }
419         case DisplayManagerMessage::TRANS_ID_SCREEN_STOP_EXPAND: {
420             std::vector<ScreenId> expandScreenIds;
421             if (!data.ReadUInt64Vector(&expandScreenIds)) {
422                 WLOGE("fail to receive expand screens in stub.");
423                 break;
424             }
425             DMError ret = StopExpand(expandScreenIds);
426             reply.WriteInt32(static_cast<int32_t>(ret));
427             break;
428         }
429         case DisplayManagerMessage::TRANS_ID_RESIZE_VIRTUAL_SCREEN: {
430             ScreenId screenId = static_cast<ScreenId>(data.ReadUint64());
431             uint32_t width = data.ReadUint32();
432             uint32_t height = data.ReadUint32();
433             DMError ret = ResizeVirtualScreen(screenId, width, height);
434             reply.WriteInt32(static_cast<int32_t>(ret));
435             break;
436         }
437         case DisplayManagerMessage::TRANS_ID_SCENE_BOARD_MAKE_UNIQUE_SCREEN: {
438             std::vector<ScreenId> uniqueScreenIds;
439             uint32_t size = data.ReadUint32();
440             if (size > MAX_SCREEN_SIZE) {
441                 WLOGFE("screenIds size is bigger than %{public}u", MAX_SCREEN_SIZE);
442                 break;
443             }
444             if (!data.ReadUInt64Vector(&uniqueScreenIds)) {
445                 WLOGFE("failed to receive unique screens in stub");
446                 break;
447             }
448             std::vector<DisplayId> displayIds;
449             DMError ret = MakeUniqueScreen(uniqueScreenIds, displayIds);
450             reply.WriteUInt64Vector(displayIds);
451             reply.WriteInt32(static_cast<int32_t>(ret));
452             break;
453         }
454         case DisplayManagerMessage::TRANS_ID_GET_ALL_PHYSICAL_DISPLAY_RESOLUTION: {
455             auto physicalInfos = GetAllDisplayPhysicalResolution();
456             size_t infoSize = physicalInfos.size();
457             bool writeRet = reply.WriteInt32(static_cast<int32_t>(infoSize));
458             if (!writeRet) {
459                 WLOGFE("write physical size error");
460                 break;
461             }
462             for (const auto &physicalItem : physicalInfos) {
463                 writeRet = reply.WriteUint32(static_cast<uint32_t>(physicalItem.foldDisplayMode_));
464                 if (!writeRet) {
465                     WLOGFE("write display mode error");
466                     break;
467                 }
468                 writeRet = reply.WriteUint32(physicalItem.physicalWidth_);
469                 if (!writeRet) {
470                     WLOGFE("write physical width error");
471                     break;
472                 }
473                 writeRet = reply.WriteUint32(physicalItem.physicalHeight_);
474                 if (!writeRet) {
475                     WLOGFE("write physical height error");
476                     break;
477                 }
478             }
479             break;
480         }
481         default:
482             WLOGFW("unknown transaction code");
483             return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
484     }
485     return 0;
486 }
487 } // namespace OHOS::Rosen