From 69b1b27310fe99e9bf6525418d0e8a8e20af7227 Mon Sep 17 00:00:00 2001 From: Patrick Wardle Date: Mon, 23 Sep 2024 21:13:34 +0200 Subject: [PATCH] Localizations (Spanish), Friends++, UI improvements --- .../Application.xcodeproj/project.pbxproj | 19 + Application/Application/AVMonitor.m | 57 ++- .../Application/Base.lproj/MainMenu.xib | 7 +- .../Application/Base.lproj/Preferences.xib | 80 ++-- .../Base.lproj/StatusBarPopover.xib | 14 +- Application/Application/Event.h | 3 + Application/Application/Event.m | 8 + .../Application/PrefsWindowController.m | 21 +- Application/Application/StatusBarItem.m | 12 +- .../Application/es.lproj/InfoPlist.strings | 6 + .../mul.lproj/AboutWindow.xcstrings | 24 ++ .../Application/mul.lproj/MainMenu.xcstrings | 92 ++++- .../mul.lproj/Preferences.xcstrings | 144 ++++++++ .../Application/mul.lproj/Rules.xcstrings | 36 ++ .../mul.lproj/StatusBarPopover.xcstrings | 22 +- Application/Localizable.xcstrings | 343 ++++++++++++++++++ Installer/Installer.xcodeproj/project.pbxproj | 18 + Installer/Localizable.xcstrings | 193 ++++++++++ .../Friends1Password.imageset/Contents.json | 35 ++ .../Friends1Password.imageset/darkMode.png | Bin 0 -> 4080 bytes .../Friends1Password.imageset/lightMode.png | Bin 0 -> 4441 bytes .../FriendsHuntress.imageset/Contents.json | 35 ++ .../FriendsHuntress.imageset/darkMode.png | Bin 0 -> 17901 bytes .../FriendsHuntress.imageset/lightMode.png | Bin 0 -> 17901 bytes .../FriendsMacPaw.imageset/darkMode.png | Bin 103918 -> 2387 bytes .../FriendsMacPaw.imageset/lightMode.png | Bin 104358 -> 2387 bytes .../Contents.json | 15 + .../malwarebytes.png | Bin 0 -> 72323 bytes .../FriendsiVerify.imageset/Contents.json | 15 + .../FriendsiVerify.imageset/iVerify.png | Bin 0 -> 6277 bytes Installer/Source/Base.lproj/AboutWindow.xib | 14 +- .../Base.lproj/ConfigureWindowController.xib | 102 ++++-- Installer/Source/Base.lproj/MainMenu.xib | 4 +- Installer/Source/ConfigureWindowController.m | 8 +- Installer/Source/es.lproj/InfoPlist.strings | 3 + .../Source/mul.lproj/AboutWindow.xcstrings | 24 ++ .../ConfigureWindowController.xcstrings | 72 ++++ Installer/Source/mul.lproj/MainMenu.xcstrings | 24 ++ Shared/Consts.h | 9 - 39 files changed, 1317 insertions(+), 142 deletions(-) create mode 100644 Application/Application/es.lproj/InfoPlist.strings create mode 100644 Application/Localizable.xcstrings create mode 100644 Installer/Localizable.xcstrings create mode 100644 Installer/Source/Assets.xcassets/Friends1Password.imageset/Contents.json create mode 100644 Installer/Source/Assets.xcassets/Friends1Password.imageset/darkMode.png create mode 100644 Installer/Source/Assets.xcassets/Friends1Password.imageset/lightMode.png create mode 100644 Installer/Source/Assets.xcassets/FriendsHuntress.imageset/Contents.json create mode 100644 Installer/Source/Assets.xcassets/FriendsHuntress.imageset/darkMode.png create mode 100644 Installer/Source/Assets.xcassets/FriendsHuntress.imageset/lightMode.png create mode 100644 Installer/Source/Assets.xcassets/FriendsMalwarebytes.imageset/Contents.json create mode 100644 Installer/Source/Assets.xcassets/FriendsMalwarebytes.imageset/malwarebytes.png create mode 100644 Installer/Source/Assets.xcassets/FriendsiVerify.imageset/Contents.json create mode 100644 Installer/Source/Assets.xcassets/FriendsiVerify.imageset/iVerify.png create mode 100644 Installer/Source/es.lproj/InfoPlist.strings diff --git a/Application/Application.xcodeproj/project.pbxproj b/Application/Application.xcodeproj/project.pbxproj index 21fdc14..3cfa571 100644 --- a/Application/Application.xcodeproj/project.pbxproj +++ b/Application/Application.xcodeproj/project.pbxproj @@ -25,6 +25,8 @@ CD8641512CA161D500803551 /* Rules.xib in Resources */ = {isa = PBXBuildFile; fileRef = CD8641502CA161D500803551 /* Rules.xib */; }; CD8641552CA161DA00803551 /* StatusBarPopover.xib in Resources */ = {isa = PBXBuildFile; fileRef = CD8641542CA161DA00803551 /* StatusBarPopover.xib */; }; CD8641592CA161DF00803551 /* UpdateWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CD8641582CA161DF00803551 /* UpdateWindow.xib */; }; + CD8641702CA1B5F300803551 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = CD86416E2CA1B5F300803551 /* InfoPlist.strings */; }; + CD8641802CA1F03E00803551 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = CD86417F2CA1F03E00803551 /* Localizable.xcstrings */; }; CD8FD5D623BAE2D200EFE0FB /* PrefsWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = CD8FD5D423BAE2D200EFE0FB /* PrefsWindowController.m */; }; CD8FD5F623C05AD900EFE0FB /* RuleRow.m in Sources */ = {isa = PBXBuildFile; fileRef = CD8FD5F023C05AD800EFE0FB /* RuleRow.m */; }; CD8FD5F723C05AD900EFE0FB /* RuleRowCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CD8FD5F223C05AD800EFE0FB /* RuleRowCell.m */; }; @@ -85,6 +87,8 @@ CD8641562CA161DA00803551 /* mul */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; name = mul; path = mul.lproj/StatusBarPopover.xcstrings; sourceTree = ""; }; CD8641572CA161DF00803551 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UpdateWindow.xib; sourceTree = ""; }; CD86415A2CA161DF00803551 /* mul */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; name = mul; path = mul.lproj/UpdateWindow.xcstrings; sourceTree = ""; }; + CD86416F2CA1B5F300803551 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; + CD86417F2CA1F03E00803551 /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = ""; }; CD8FD5D223BAE2D100EFE0FB /* PrefsWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrefsWindowController.h; sourceTree = ""; }; CD8FD5D423BAE2D200EFE0FB /* PrefsWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PrefsWindowController.m; sourceTree = ""; }; CD8FD5ED23C05AD800EFE0FB /* RuleRowCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RuleRowCell.h; sourceTree = ""; }; @@ -137,6 +141,7 @@ 7D7755DA1F02E05B00D0017D = { isa = PBXGroup; children = ( + CD86417F2CA1F03E00803551 /* Localizable.xcstrings */, CDE09AF12919829000561CFF /* Uninstaller */, 7D3B75201F13356900568828 /* Shared */, 7D7755E51F02E05B00D0017D /* Source */, @@ -170,6 +175,7 @@ CDCBF0DC26499DFF001D9F9A /* Event.h */, CDCBF0DD26499DFF001D9F9A /* Event.m */, 7D7755F11F02E05B00D0017D /* Info.plist */, + CD86416E2CA1B5F300803551 /* InfoPlist.strings */, CDC6098C263CB7EB006D1332 /* LogMonitor.h */, CDC6098D263CB7EB006D1332 /* LogMonitor.m */, CD86414C2CA161CF00803551 /* MainMenu.xib */, @@ -281,6 +287,7 @@ English, en, Base, + es, ); mainGroup = 7D7755DA1F02E05B00D0017D; productRefGroup = 7D7755E41F02E05B00D0017D /* Products */; @@ -302,10 +309,12 @@ CD6836682391DB6F00CF19C1 /* security.plist in Resources */, CD86413C2CA1617A00803551 /* AboutWindow.xib in Resources */, CD8641592CA161DF00803551 /* UpdateWindow.xib in Resources */, + CD8641802CA1F03E00803551 /* Localizable.xcstrings in Resources */, CD8641552CA161DA00803551 /* StatusBarPopover.xib in Resources */, CD2F801724468A8C009C3D77 /* patrons.txt in Resources */, CD8641512CA161D500803551 /* Rules.xib in Resources */, CD86414D2CA161CF00803551 /* MainMenu.xib in Resources */, + CD8641702CA1B5F300803551 /* InfoPlist.strings in Resources */, 7DD25FF01F23B73C00277EC4 /* Assets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -402,6 +411,14 @@ name = UpdateWindow.xib; sourceTree = ""; }; + CD86416E2CA1B5F300803551 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + CD86416F2CA1B5F300803551 /* es */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ @@ -458,6 +475,7 @@ MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = NO; SDKROOT = macosx; + SWIFT_EMIT_LOC_STRINGS = YES; }; name = Debug; }; @@ -507,6 +525,7 @@ MACOSX_DEPLOYMENT_TARGET = 10.12; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; + SWIFT_EMIT_LOC_STRINGS = YES; }; name = Release; }; diff --git a/Application/Application/AVMonitor.m b/Application/Application/AVMonitor.m index e926049..27718f4 100644 --- a/Application/Application/AVMonitor.m +++ b/Application/Application/AVMonitor.m @@ -752,6 +752,9 @@ extern os_log_t logHandle; return; } +//TODO: refactor alerts +// delay showing them! + //register for audio changes -(BOOL)watchAudioDevice:(AVCaptureDevice*)device { @@ -813,12 +816,18 @@ extern os_log_t logHandle; //dbg msg os_log_debug(logHandle, "audio event: off"); - //init event - // process (client) and device are nil - event = [[Event alloc] init:nil device:device deviceType:Device_Microphone state:NSControlStateValueOff]; - - //handle event - [self handleEvent:event]; + //still wait + // cuz the on event is waiting... + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5 * NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + + //init event + // process (client) and device are nil + event = [[Event alloc] init:nil device:device deviceType:Device_Microphone state:NSControlStateValueOff]; + + //handle event + [self handleEvent:event]; + + }); } //audio on? @@ -987,12 +996,18 @@ bail: //dbg msg os_log_debug(logHandle, "camera event: off"); - //init event - // process (client) and device are nil - event = [[Event alloc] init:nil device:device deviceType:Device_Camera state:NSControlStateValueOff]; - - //handle event - [self handleEvent:event]; + //still wait + // cuz the on event is waiting... + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5 * NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + + //init event + // process (client) and device are nil + event = [[Event alloc] init:nil device:device deviceType:Device_Camera state:NSControlStateValueOff]; + + //handle event + [self handleEvent:event]; + + }); } } //macOS 13.3 @@ -1435,7 +1450,7 @@ bail: result = NOTIFICATION_SPURIOUS; //dbg msg - os_log_debug(logHandle, "ignoring event, as it happened <1.0s ago"); + os_log_debug(logHandle, "ignoring event, as last event happened <1.0s ago"); //bail goto bail; @@ -1498,6 +1513,9 @@ bail: //result NSInteger result = NOTIFICATION_ERROR; + //dbg msg + os_log_debug(logHandle, "handling event: %{public}@", event); + //should show? @synchronized (self) { @@ -1586,6 +1604,19 @@ bail: //init request request = [UNNotificationRequest requestWithIdentifier:NSUUID.UUID.UUIDString content:content trigger:NULL]; + //log: on + if(NSControlStateValueOn == event.state) + { + //log + os_log(logHandle, "[Alert] On Event: %@ / Device: %@ / %@", content.title, content.subtitle, content.body); + } + //log: off + else + { + //log + os_log(logHandle, "[Alert] Off Event: %@ / Device: %@", content.title, content.subtitle); + } + //send notification [UNUserNotificationCenter.currentNotificationCenter addNotificationRequest:request withCompletionHandler:^(NSError *_Nullable error) { diff --git a/Application/Application/Base.lproj/MainMenu.xib b/Application/Application/Base.lproj/MainMenu.xib index d724ddf..a778e60 100644 --- a/Application/Application/Base.lproj/MainMenu.xib +++ b/Application/Application/Base.lproj/MainMenu.xib @@ -31,8 +31,7 @@ - - + @@ -69,9 +68,7 @@ - - - + diff --git a/Application/Application/Base.lproj/Preferences.xib b/Application/Application/Base.lproj/Preferences.xib index 43991f6..e8337cb 100644 --- a/Application/Application/Base.lproj/Preferences.xib +++ b/Application/Application/Base.lproj/Preferences.xib @@ -94,7 +94,7 @@ - + @@ -103,11 +103,11 @@ - + - - + + @@ -123,7 +123,7 @@ - + @@ -143,7 +143,7 @@ - + @@ -152,11 +152,11 @@ - + - - + + @@ -172,7 +172,7 @@ - + @@ -181,16 +181,25 @@ - + - - + + + + + + + + + + + - - - - - - - - - @@ -228,7 +228,7 @@ - + @@ -248,7 +248,7 @@ - + @@ -257,7 +257,7 @@ - + @@ -286,8 +286,8 @@ - - + + @@ -295,11 +295,11 @@ - + OverSight will pass in the following arguments:
-device <camera|microphone> -event <on|off> -process <pid> -activeCount <0..n>

Notes: -process is only specified on activation events. -activeCount is the number of devices still active. - + @@ -327,7 +327,7 @@ - + @@ -336,16 +336,16 @@ - + - - + + - - - - @@ -368,8 +364,12 @@ + + + + - + diff --git a/Application/Application/Base.lproj/StatusBarPopover.xib b/Application/Application/Base.lproj/StatusBarPopover.xib index 5912c25..172acb5 100755 --- a/Application/Application/Base.lproj/StatusBarPopover.xib +++ b/Application/Application/Base.lproj/StatusBarPopover.xib @@ -1,8 +1,8 @@ - + - + @@ -22,7 +22,7 @@ - + @@ -31,16 +31,16 @@ - - + + - + - - + + + + @@ -163,18 +170,25 @@ - + + + + @@ -255,17 +269,8 @@ - - - - - - - - - - + @@ -273,48 +278,69 @@ - - + + - + + + + + + + + + + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + + + + + + + + + + + - + + + - - - + + + diff --git a/Installer/Source/Base.lproj/MainMenu.xib b/Installer/Source/Base.lproj/MainMenu.xib index b304a83..7fba047 100644 --- a/Installer/Source/Base.lproj/MainMenu.xib +++ b/Installer/Source/Base.lproj/MainMenu.xib @@ -1,8 +1,8 @@ - + - + diff --git a/Installer/Source/ConfigureWindowController.m b/Installer/Source/ConfigureWindowController.m index bc4f490..f337815 100644 --- a/Installer/Source/ConfigureWindowController.m +++ b/Installer/Source/ConfigureWindowController.m @@ -75,7 +75,7 @@ extern os_log_t logHandle; [self window].title = [NSString stringWithFormat:NSLocalizedString(@"version %@", @"version %@"), getAppVersion()]; //init status msg - [self.statusMsg setStringValue:NSLocalizedString(@"...protects your webcam & microphone!", @"...protects your webcam & microphone!")]; + [self.statusMsg setStringValue:NSLocalizedString(@"Protects your webcam & microphone!", @"Protects your webcam & microphone!")]; //uninstall via app? // just enable uinstall button @@ -106,7 +106,7 @@ extern os_log_t logHandle; self.uninstallButton.enabled = YES; //set to 'upgrade' - self.installButton.title = ACTION_UPGRADE; + self.installButton.title = NSLocalizedString(@"Upgrade", @"Upgrade"); } //otherwise disable @@ -540,7 +540,7 @@ extern os_log_t logHandle; (ACTION_INSTALL_FLAG == event) ) { //next - self.installButton.title = ACTION_NEXT; + self.installButton.title = NSLocalizedString(@"Next »", @"Next »"); //set tag self.installButton.tag = ACTION_SHOW_NOTIFICATION_VIEW; @@ -550,7 +550,7 @@ extern os_log_t logHandle; else { //close - self.installButton.title = ACTION_CLOSE; + self.installButton.title = NSLocalizedString(@"Close", @"Close"); //update it's tag // will allow button handler method process diff --git a/Installer/Source/es.lproj/InfoPlist.strings b/Installer/Source/es.lproj/InfoPlist.strings new file mode 100644 index 0000000..9146e59 --- /dev/null +++ b/Installer/Source/es.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Copyright (human-readable) */ +"NSHumanReadableCopyright" = "Copyright (c) 2020 Objective-See. Todos los derechos reservados. "; + diff --git a/Installer/Source/mul.lproj/AboutWindow.xcstrings b/Installer/Source/mul.lproj/AboutWindow.xcstrings index 813e0e6..6220247 100644 --- a/Installer/Source/mul.lproj/AboutWindow.xcstrings +++ b/Installer/Source/mul.lproj/AboutWindow.xcstrings @@ -10,6 +10,12 @@ "state" : "new", "value" : "Support Us!" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "¡Apóyanos!" + } } } }, @@ -22,6 +28,12 @@ "state" : "new", "value" : "Version:" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Versión:" + } } } }, @@ -34,6 +46,12 @@ "state" : "new", "value" : "Supporters/Patrons:" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Friends/Patrons:" + } } } }, @@ -46,6 +64,12 @@ "state" : "new", "value" : "More Info" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Más Información" + } } } } diff --git a/Installer/Source/mul.lproj/ConfigureWindowController.xcstrings b/Installer/Source/mul.lproj/ConfigureWindowController.xcstrings index d0adc2e..548984a 100644 --- a/Installer/Source/mul.lproj/ConfigureWindowController.xcstrings +++ b/Installer/Source/mul.lproj/ConfigureWindowController.xcstrings @@ -10,6 +10,12 @@ "state" : "new", "value" : "Next »" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Siguiente »" + } } } }, @@ -22,6 +28,12 @@ "state" : "new", "value" : "Install" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Instalar" + } } } }, @@ -34,6 +46,12 @@ "state" : "new", "value" : "If prompted, please allow OverSight to show notifications, setting the style to \"Alerts\"" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Si solicitado, permite que OverSight muestre notificaciones, configurando el estilo en \"Alertas\"" + } } } }, @@ -46,6 +64,12 @@ "state" : "new", "value" : "Next »" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Siguiente »" + } } } }, @@ -58,6 +82,12 @@ "state" : "new", "value" : "Yes!" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "¡Sí!" + } } } }, @@ -70,6 +100,12 @@ "state" : "new", "value" : "Uninstall" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Desinstalar" + } } } }, @@ -82,6 +118,12 @@ "state" : "new", "value" : "Support OverSight?" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "¿Apoyas OverSight?" + } } } }, @@ -94,6 +136,12 @@ "state" : "new", "value" : "Show some love? " } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "¿Nos das tu apoyo?" + } } } }, @@ -106,6 +154,12 @@ "state" : "new", "value" : "No" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "No" + } } } }, @@ -118,6 +172,12 @@ "state" : "new", "value" : "Mahalo to the \"Friends Objective-See\"" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mahalo a los \"Friends de Objective-See\"" + } } } }, @@ -130,6 +190,12 @@ "state" : "new", "value" : "It's free, open-source, and written by a single (mac-loving) coder!" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sin cargo, open-source y desarrollado por un único programador (amante de Mac)! " + } } } }, @@ -142,6 +208,12 @@ "state" : "new", "value" : "If \"Do Not Disturb\" mode is activated, OverSight's alerts won't be shown" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Si el modo \"No Molestar\" está activado, las alertas de OverSight no se mostrarán" + } } } } diff --git a/Installer/Source/mul.lproj/MainMenu.xcstrings b/Installer/Source/mul.lproj/MainMenu.xcstrings index 1fdac7a..5d97a3d 100644 --- a/Installer/Source/mul.lproj/MainMenu.xcstrings +++ b/Installer/Source/mul.lproj/MainMenu.xcstrings @@ -10,6 +10,12 @@ "state" : "new", "value" : "About OverSight" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Acerca de OverSight" + } } } }, @@ -22,6 +28,12 @@ "state" : "new", "value" : "OverSight" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "OverSight" + } } } }, @@ -34,6 +46,12 @@ "state" : "new", "value" : "Main Menu" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Menú Principal" + } } } }, @@ -46,6 +64,12 @@ "state" : "new", "value" : "OverSight" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "OverSight" + } } } } diff --git a/Shared/Consts.h b/Shared/Consts.h index 4ee40c2..7811fa0 100644 --- a/Shared/Consts.h +++ b/Shared/Consts.h @@ -186,15 +186,6 @@ //flag to install #define ACTION_INSTALL_FLAG 1 -//button title: upgrade -#define ACTION_UPGRADE NSLocalizedString(@"Upgrade", @"Upgrade") - -//button title: close -#define ACTION_CLOSE NSLocalizedString(@"Close", @"Close") - -//button title: next -#define ACTION_NEXT NSLocalizedString(@"Next »", @"Next »") - //show info about notifications #define ACTION_SHOW_NOTIFICATION_VIEW 2