summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWonYoung Choi <wy80.choi@samsung.com>2017-07-21 10:52:25 +0900
committerWonYoung Choi <wy80.choi@samsung.com>2017-07-21 10:52:25 +0900
commit9551e95f9270c4f076ce9b10a57f4b7db7bf04bd (patch)
tree233b134d53b7bbadd250014fb27d7a512883152d
parent0b8fdbbe5a40fdd31d1c73a7a5f920332bb7ab24 (diff)
downloadmeta-package-tizenfx.tar.gz
meta-package-tizenfx.tar.bz2
meta-package-tizenfx.zip
Initial unified Tizen .NET modulestizenfx
Change-Id: I56353c0f86e2eeb665eec3eb92f695da69fa9afe
-rw-r--r--.editorconfig8
-rwxr-xr-x.gitattributes14
-rw-r--r--.gitignore210
-rw-r--r--LICENSE202
-rw-r--r--README.md2
-rw-r--r--build/Open.snkbin0 -> 596 bytes
-rw-r--r--build/common.props18
-rw-r--r--build/common.targets3
-rw-r--r--build/dependencies.props7
-rw-r--r--build/version.props8
-rw-r--r--pkg/Tizen.NET/Tizen.NET.csproj42
-rw-r--r--pkg/descriptions.json262
-rw-r--r--src/ElmSharp/ElmSharp.csproj9
-rwxr-xr-xsrc/ElmSharp/ElmSharp/AccessRole.cs438
-rwxr-xr-xsrc/ElmSharp/ElmSharp/AccessibleObject.cs248
-rwxr-xr-xsrc/ElmSharp/ElmSharp/AccessibleRelation.cs371
-rwxr-xr-xsrc/ElmSharp/ElmSharp/AccessibleUtil.cs90
-rw-r--r--src/ElmSharp/ElmSharp/Background.cs158
-rw-r--r--src/ElmSharp/ElmSharp/Box.cs239
-rw-r--r--src/ElmSharp/ElmSharp/Button.cs177
-rwxr-xr-xsrc/ElmSharp/ElmSharp/Calendar.cs479
-rwxr-xr-xsrc/ElmSharp/ElmSharp/Check.cs79
-rwxr-xr-xsrc/ElmSharp/ElmSharp/CheckStateChangedEventArgs.cs49
-rw-r--r--src/ElmSharp/ElmSharp/Color.cs339
-rwxr-xr-xsrc/ElmSharp/ElmSharp/ColorChangedEventArgs.cs49
-rwxr-xr-xsrc/ElmSharp/ElmSharp/ColorSelector.cs190
-rwxr-xr-xsrc/ElmSharp/ElmSharp/ColorSelectorItem.cs50
-rwxr-xr-xsrc/ElmSharp/ElmSharp/Conformant.cs45
-rwxr-xr-xsrc/ElmSharp/ElmSharp/Container.cs81
-rwxr-xr-xsrc/ElmSharp/ElmSharp/ContextPopup.cs250
-rwxr-xr-xsrc/ElmSharp/ElmSharp/ContextPopupItem.cs53
-rwxr-xr-xsrc/ElmSharp/ElmSharp/DateChangedEventArgs.cs53
-rwxr-xr-xsrc/ElmSharp/ElmSharp/DateTimeSelector.cs184
-rwxr-xr-xsrc/ElmSharp/ElmSharp/DisplayedMonthChangedEventArgs.cs53
-rwxr-xr-xsrc/ElmSharp/ElmSharp/EcoreAnimator.cs88
-rwxr-xr-xsrc/ElmSharp/ElmSharp/EcoreEvent.cs210
-rwxr-xr-xsrc/ElmSharp/ElmSharp/EcoreKeyEventArgs.cs68
-rwxr-xr-xsrc/ElmSharp/ElmSharp/EcoreMainloop.cs144
-rwxr-xr-xsrc/ElmSharp/ElmSharp/EcoreSynchronizationContext.cs77
-rw-r--r--src/ElmSharp/ElmSharp/EdjeObject.cs328
-rwxr-xr-xsrc/ElmSharp/ElmSharp/EffectBase.cs38
-rw-r--r--src/ElmSharp/ElmSharp/Elementary.cs330
-rw-r--r--src/ElmSharp/ElmSharp/ElmScrollConfig.cs43
-rwxr-xr-xsrc/ElmSharp/ElmSharp/Entry.cs1045
-rw-r--r--src/ElmSharp/ElmSharp/EvasCanvas.cs173
-rwxr-xr-xsrc/ElmSharp/ElmSharp/EvasKeyEventArgs.cs107
-rwxr-xr-xsrc/ElmSharp/ElmSharp/EvasMap.cs146
-rw-r--r--src/ElmSharp/ElmSharp/EvasObject.cs964
-rwxr-xr-xsrc/ElmSharp/ElmSharp/EvasObjectEvent.cs419
-rwxr-xr-xsrc/ElmSharp/ElmSharp/FlipSelector.cs193
-rwxr-xr-xsrc/ElmSharp/ElmSharp/FlipSelectorItem.cs50
-rwxr-xr-xsrc/ElmSharp/ElmSharp/FloatingButton.cs160
-rw-r--r--src/ElmSharp/ElmSharp/GenGrid.cs606
-rw-r--r--src/ElmSharp/ElmSharp/GenGridItem.cs195
-rw-r--r--src/ElmSharp/ElmSharp/GenItem.cs129
-rw-r--r--src/ElmSharp/ElmSharp/GenItemClass.cs255
-rw-r--r--src/ElmSharp/ElmSharp/GenList.cs762
-rw-r--r--src/ElmSharp/ElmSharp/GenListItem.cs320
-rwxr-xr-xsrc/ElmSharp/ElmSharp/GestureLayer.cs807
-rw-r--r--src/ElmSharp/ElmSharp/Hoversel.cs207
-rwxr-xr-xsrc/ElmSharp/ElmSharp/HoverselItem.cs45
-rwxr-xr-xsrc/ElmSharp/ElmSharp/IAccessibleObject.cs37
-rwxr-xr-xsrc/ElmSharp/ElmSharp/Icon.cs115
-rw-r--r--src/ElmSharp/ElmSharp/Image.cs688
-rwxr-xr-xsrc/ElmSharp/ElmSharp/Index.cs260
-rwxr-xr-xsrc/ElmSharp/ElmSharp/IndexItem.cs59
-rw-r--r--src/ElmSharp/ElmSharp/ItemObject.cs366
-rwxr-xr-xsrc/ElmSharp/ElmSharp/ItemObjectExtension.cs44
-rwxr-xr-xsrc/ElmSharp/ElmSharp/Label.cs215
-rw-r--r--src/ElmSharp/ElmSharp/Layout.cs352
-rwxr-xr-xsrc/ElmSharp/ElmSharp/List.cs253
-rw-r--r--src/ElmSharp/ElmSharp/ListItem.cs50
-rwxr-xr-xsrc/ElmSharp/ElmSharp/MultiButtonEntry.cs407
-rwxr-xr-xsrc/ElmSharp/ElmSharp/MultiButtonEntryItem.cs86
-rwxr-xr-xsrc/ElmSharp/ElmSharp/NaviItem.cs126
-rwxr-xr-xsrc/ElmSharp/ElmSharp/Naviframe.cs259
-rwxr-xr-xsrc/ElmSharp/ElmSharp/Panel.cs137
-rwxr-xr-xsrc/ElmSharp/ElmSharp/Panes.cs193
-rwxr-xr-xsrc/ElmSharp/ElmSharp/Point.cs84
-rwxr-xr-xsrc/ElmSharp/ElmSharp/Point3D.cs92
-rwxr-xr-xsrc/ElmSharp/ElmSharp/Polygon.cs67
-rwxr-xr-xsrc/ElmSharp/ElmSharp/Popup.cs291
-rwxr-xr-xsrc/ElmSharp/ElmSharp/PopupItem.cs42
-rwxr-xr-xsrc/ElmSharp/ElmSharp/ProgressBar.cs224
-rwxr-xr-xsrc/ElmSharp/ElmSharp/Radio.cs97
-rwxr-xr-xsrc/ElmSharp/ElmSharp/ReadingInfoType.cs48
-rw-r--r--src/ElmSharp/ElmSharp/Rect.cs144
-rwxr-xr-xsrc/ElmSharp/ElmSharp/Rectangle.cs41
-rwxr-xr-xsrc/ElmSharp/ElmSharp/Scroller.cs794
-rwxr-xr-xsrc/ElmSharp/ElmSharp/Size.cs99
-rwxr-xr-xsrc/ElmSharp/ElmSharp/Slider.cs328
-rwxr-xr-xsrc/ElmSharp/ElmSharp/SmartEvent.cs242
-rwxr-xr-xsrc/ElmSharp/ElmSharp/Spinner.cs254
-rwxr-xr-xsrc/ElmSharp/ElmSharp/Table.cs160
-rw-r--r--src/ElmSharp/ElmSharp/Toolbar.cs468
-rwxr-xr-xsrc/ElmSharp/ElmSharp/ToolbarItem.cs141
-rwxr-xr-xsrc/ElmSharp/ElmSharp/Transit.cs386
-rwxr-xr-xsrc/ElmSharp/ElmSharp/TransitEffect.cs461
-rw-r--r--src/ElmSharp/ElmSharp/Utility.cs160
-rwxr-xr-xsrc/ElmSharp/ElmSharp/Widget.cs442
-rw-r--r--src/ElmSharp/ElmSharp/Window.cs1058
-rwxr-xr-xsrc/ElmSharp/ElmSharp/WrapType.cs44
-rw-r--r--src/ElmSharp/Interop/Interop.Ecore.cs76
-rw-r--r--src/ElmSharp/Interop/Interop.Eext.Event.cs38
-rwxr-xr-xsrc/ElmSharp/Interop/Interop.Eext.FloatingButton.cs48
-rw-r--r--src/ElmSharp/Interop/Interop.Eina.cs28
-rw-r--r--src/ElmSharp/Interop/Interop.Elementary.Accessibility.cs249
-rw-r--r--src/ElmSharp/Interop/Interop.Elementary.Bg.cs60
-rw-r--r--src/ElmSharp/Interop/Interop.Elementary.Box.cs94
-rw-r--r--src/ElmSharp/Interop/Interop.Elementary.Button.cs78
-rw-r--r--src/ElmSharp/Interop/Interop.Elementary.CalendarView.cs108
-rwxr-xr-xsrc/ElmSharp/Interop/Interop.Elementary.ColorPicker.cs82
-rw-r--r--src/ElmSharp/Interop/Interop.Elementary.CtxPopup.cs66
-rw-r--r--src/ElmSharp/Interop/Interop.Elementary.DateTimePicker.cs80
-rw-r--r--src/ElmSharp/Interop/Interop.Elementary.Entry.cs391
-rw-r--r--src/ElmSharp/Interop/Interop.Elementary.FlipSelector.cs54
-rw-r--r--src/ElmSharp/Interop/Interop.Elementary.GenGridView.cs192
-rw-r--r--src/ElmSharp/Interop/Interop.Elementary.GenListView.cs247
-rw-r--r--src/ElmSharp/Interop/Interop.Elementary.GestureLayer.cs138
-rwxr-xr-xsrc/ElmSharp/Interop/Interop.Elementary.Hoversel.cs67
-rw-r--r--src/ElmSharp/Interop/Interop.Elementary.Image.cs142
-rw-r--r--src/ElmSharp/Interop/Interop.Elementary.Index.cs103
-rw-r--r--src/ElmSharp/Interop/Interop.Elementary.Item.cs116
-rwxr-xr-xsrc/ElmSharp/Interop/Interop.Elementary.Label.cs80
-rw-r--r--src/ElmSharp/Interop/Interop.Elementary.List.cs60
-rw-r--r--src/ElmSharp/Interop/Interop.Elementary.MultiButtonEntry.cs94
-rw-r--r--src/ElmSharp/Interop/Interop.Elementary.Naviframe.cs87
-rw-r--r--src/ElmSharp/Interop/Interop.Elementary.Panel.cs48
-rw-r--r--src/ElmSharp/Interop/Interop.Elementary.Panes.cs75
-rw-r--r--src/ElmSharp/Interop/Interop.Elementary.Popup.cs101
-rw-r--r--src/ElmSharp/Interop/Interop.Elementary.ProgressBar.cs78
-rw-r--r--src/ElmSharp/Interop/Interop.Elementary.ScrollView.cs147
-rwxr-xr-xsrc/ElmSharp/Interop/Interop.Elementary.Slider.cs119
-rw-r--r--src/ElmSharp/Interop/Interop.Elementary.Spinner.cs103
-rw-r--r--src/ElmSharp/Interop/Interop.Elementary.Table.cs55
-rw-r--r--src/ElmSharp/Interop/Interop.Elementary.Toolbar.cs134
-rwxr-xr-xsrc/ElmSharp/Interop/Interop.Elementary.Win.cs429
-rw-r--r--src/ElmSharp/Interop/Interop.Elementary.cs763
-rw-r--r--src/ElmSharp/Interop/Interop.Eo.cs38
-rw-r--r--src/ElmSharp/Interop/Interop.Evas.Image.cs54
-rwxr-xr-xsrc/ElmSharp/Interop/Interop.Evas.cs808
-rw-r--r--src/ElmSharp/Interop/Interop.Libc.cs67
-rw-r--r--src/ElmSharp/Interop/Interop.Libdl.cs60
-rw-r--r--src/ElmSharp/Interop/Interop.Libraries.cs31
-rw-r--r--src/Tizen.Account.AccountManager/Interop/Interop.Account.cs153
-rw-r--r--src/Tizen.Account.AccountManager/Interop/Interop.AccountProvider.cs92
-rw-r--r--src/Tizen.Account.AccountManager/Interop/Interop.AccountService.cs118
-rw-r--r--src/Tizen.Account.AccountManager/Interop/Interop.Libraries.cs33
-rw-r--r--src/Tizen.Account.AccountManager/Tizen.Account.AccountManager.csproj14
-rw-r--r--src/Tizen.Account.AccountManager/Tizen.Account.AccountManager/Account.cs619
-rw-r--r--src/Tizen.Account.AccountManager/Tizen.Account.AccountManager/AccountEnums.cs166
-rw-r--r--src/Tizen.Account.AccountManager/Tizen.Account.AccountManager/AccountErrorFactory.cs204
-rw-r--r--src/Tizen.Account.AccountManager/Tizen.Account.AccountManager/AccountProvider.cs366
-rw-r--r--src/Tizen.Account.AccountManager/Tizen.Account.AccountManager/AccountService.cs606
-rw-r--r--src/Tizen.Account.AccountManager/Tizen.Account.AccountManager/AccountSubscriberEventArgs.cs73
-rwxr-xr-xsrc/Tizen.Account.FidoClient/Interop/Interop.Libc.cs27
-rwxr-xr-xsrc/Tizen.Account.FidoClient/Interop/Interop.Libraries.cs28
-rwxr-xr-xsrc/Tizen.Account.FidoClient/Interop/Interop.Uaf.Authenticator.cs68
-rwxr-xr-xsrc/Tizen.Account.FidoClient/Interop/Interop.Uaf.Client.cs35
-rw-r--r--src/Tizen.Account.FidoClient/Tizen.Account.FidoClient.csproj14
-rwxr-xr-xsrc/Tizen.Account.FidoClient/Tizen.Account.FidoClient/AuthenticatorInformation.cs126
-rwxr-xr-xsrc/Tizen.Account.FidoClient/Tizen.Account.FidoClient/ErrorFactory.cs91
-rwxr-xr-xsrc/Tizen.Account.FidoClient/Tizen.Account.FidoClient/UafAuthenticatorFinder.cs208
-rwxr-xr-xsrc/Tizen.Account.FidoClient/Tizen.Account.FidoClient/UafClient.cs242
-rwxr-xr-xsrc/Tizen.Account.FidoClient/Tizen.Account.FidoClient/UafEnumerations.cs312
-rwxr-xr-xsrc/Tizen.Account.FidoClient/Tizen.Account.FidoClient/UafMessage.cs39
-rwxr-xr-xsrc/Tizen.Account.FidoClient/Tizen.Account.FidoClient/UafResponse.cs39
-rw-r--r--src/Tizen.Account.OAuth2/Interop/Interop.Common.cs55
-rw-r--r--src/Tizen.Account.OAuth2/Interop/Interop.Error.cs44
-rw-r--r--src/Tizen.Account.OAuth2/Interop/Interop.Libraries.cs28
-rwxr-xr-xsrc/Tizen.Account.OAuth2/Interop/Interop.Manager.cs70
-rw-r--r--src/Tizen.Account.OAuth2/Interop/Interop.Request.cs129
-rw-r--r--src/Tizen.Account.OAuth2/Interop/Interop.Response.cs62
-rw-r--r--src/Tizen.Account.OAuth2/Interop/Interop.Types.cs38
-rw-r--r--src/Tizen.Account.OAuth2/Tizen.Account.OAuth2.csproj14
-rwxr-xr-xsrc/Tizen.Account.OAuth2/Tizen.Account.OAuth2/AccessToken.cs55
-rwxr-xr-xsrc/Tizen.Account.OAuth2/Tizen.Account.OAuth2/AuthenticationScheme.cs45
-rwxr-xr-xsrc/Tizen.Account.OAuth2/Tizen.Account.OAuth2/AuthorizationRequest.cs76
-rwxr-xr-xsrc/Tizen.Account.OAuth2/Tizen.Account.OAuth2/AuthorizationResponse.cs108
-rwxr-xr-xsrc/Tizen.Account.OAuth2/Tizen.Account.OAuth2/Authorizer.cs490
-rwxr-xr-xsrc/Tizen.Account.OAuth2/Tizen.Account.OAuth2/ClientCredentials.cs49
-rwxr-xr-xsrc/Tizen.Account.OAuth2/Tizen.Account.OAuth2/ClientCredentialsAuthorizer.cs168
-rwxr-xr-xsrc/Tizen.Account.OAuth2/Tizen.Account.OAuth2/ClientCredentialsTokenRequest.cs42
-rwxr-xr-xsrc/Tizen.Account.OAuth2/Tizen.Account.OAuth2/CodeGrantAuthorizationRequest.cs40
-rwxr-xr-xsrc/Tizen.Account.OAuth2/Tizen.Account.OAuth2/CodeGrantAuthorizer.cs343
-rwxr-xr-xsrc/Tizen.Account.OAuth2/Tizen.Account.OAuth2/CodeGrantTokenRequest.cs48
-rwxr-xr-xsrc/Tizen.Account.OAuth2/Tizen.Account.OAuth2/ImplicitGrantAuthorizationRequest.cs39
-rwxr-xr-xsrc/Tizen.Account.OAuth2/Tizen.Account.OAuth2/ImplicitGrantAuthorizer.cs246
-rwxr-xr-xsrc/Tizen.Account.OAuth2/Tizen.Account.OAuth2/OAuth2ErrorFactory.cs127
-rwxr-xr-xsrc/Tizen.Account.OAuth2/Tizen.Account.OAuth2/OAuth2ErrorResponse.cs72
-rwxr-xr-xsrc/Tizen.Account.OAuth2/Tizen.Account.OAuth2/RefreshToken.cs36
-rwxr-xr-xsrc/Tizen.Account.OAuth2/Tizen.Account.OAuth2/RefreshTokenRequest.cs46
-rwxr-xr-xsrc/Tizen.Account.OAuth2/Tizen.Account.OAuth2/ResourceOwnerPwdCredentialsAuthorizer.cs182
-rwxr-xr-xsrc/Tizen.Account.OAuth2/Tizen.Account.OAuth2/ResourceOwnerPwdCredentialsTokenRequest.cs51
-rwxr-xr-xsrc/Tizen.Account.OAuth2/Tizen.Account.OAuth2/TokenRequest.cs76
-rwxr-xr-xsrc/Tizen.Account.OAuth2/Tizen.Account.OAuth2/TokenResponse.cs116
-rwxr-xr-xsrc/Tizen.Applications.Alarm/Interop/Interop.Alarm.cs102
-rwxr-xr-xsrc/Tizen.Applications.Alarm/Interop/Interop.Libraries.cs23
-rwxr-xr-xsrc/Tizen.Applications.Alarm/Tizen.Applications.Alarm.csproj14
-rwxr-xr-xsrc/Tizen.Applications.Alarm/Tizen.Applications/Alarm.cs181
-rwxr-xr-xsrc/Tizen.Applications.Alarm/Tizen.Applications/AlarmErrorFactory.cs58
-rwxr-xr-xsrc/Tizen.Applications.Alarm/Tizen.Applications/AlarmManager.cs412
-rwxr-xr-xsrc/Tizen.Applications.Badge/Interop/Interop.Badge.cs65
-rwxr-xr-xsrc/Tizen.Applications.Badge/Interop/Interop.Libraries.cs23
-rwxr-xr-xsrc/Tizen.Applications.Badge/Tizen.Applications.Badge.csproj14
-rwxr-xr-xsrc/Tizen.Applications.Badge/Tizen.Applications/Badge.cs71
-rwxr-xr-xsrc/Tizen.Applications.Badge/Tizen.Applications/BadgeControl.cs286
-rwxr-xr-xsrc/Tizen.Applications.Badge/Tizen.Applications/BadgeErrorFactory.cs61
-rwxr-xr-xsrc/Tizen.Applications.Badge/Tizen.Applications/BadgeEventArgs.cs64
-rwxr-xr-xsrc/Tizen.Applications.Common/Interop/Interop.AppCommon.cs96
-rwxr-xr-xsrc/Tizen.Applications.Common/Interop/Interop.AppControl.cs138
-rwxr-xr-xsrc/Tizen.Applications.Common/Interop/Interop.ApplicationManager.cs347
-rwxr-xr-xsrc/Tizen.Applications.Common/Interop/Interop.Bundle.cs82
-rwxr-xr-xsrc/Tizen.Applications.Common/Interop/Interop.Glib.cs30
-rwxr-xr-xsrc/Tizen.Applications.Common/Interop/Interop.Libc.cs27
-rwxr-xr-xsrc/Tizen.Applications.Common/Interop/Interop.Libraries.cs31
-rw-r--r--src/Tizen.Applications.Common/Tizen.Applications.Common.csproj14
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications.CoreBackend/DefaultCoreBackend.cs155
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications.CoreBackend/EventType.cs123
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications.CoreBackend/ICoreBackend.cs52
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/AppControl.cs1038
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/AppControlData.cs149
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/AppControlLaunchMode.cs34
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/AppControlOperations.cs159
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/AppControlReceivedEventArgs.cs40
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/AppControlReplyCallback.cs26
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/AppControlReplyResult.cs44
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/Application.cs140
-rw-r--r--src/Tizen.Applications.Common/Tizen.Applications/ApplicationDisabledEventArgs.cs46
-rw-r--r--src/Tizen.Applications.Common/Tizen.Applications/ApplicationEnabledEventArgs.cs46
-rw-r--r--src/Tizen.Applications.Common/Tizen.Applications/ApplicationEventState.cs40
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/ApplicationInfo.cs406
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/ApplicationInfoFilter.cs70
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/ApplicationInfoMetadataFilter.cs28
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/ApplicationLaunchedEventArgs.cs31
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/ApplicationManager.cs608
-rw-r--r--src/Tizen.Applications.Common/Tizen.Applications/ApplicationRunningContext.cs213
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/ApplicationTerminatedEventArgs.cs31
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/ApplicationType.cs37
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/Bundle.cs714
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/CoreApplication.cs217
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/DeviceOrientation.cs44
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/DeviceOrientationEventArgs.cs40
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/DirectoryInfo.cs173
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/LocaleChangedEventArgs.cs42
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/LowBatteryEventArgs.cs40
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/LowBatteryStatus.cs39
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/LowMemoryEventArgs.cs40
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/LowMemoryStatus.cs44
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/ReceivedAppControl.cs146
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/RecentApplicationControl.cs65
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/RecentApplicationInfo.cs72
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/RegionFormatChangedEventArgs.cs41
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/ResourceManager.cs125
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/SafeAppControlHandle.cs63
-rwxr-xr-xsrc/Tizen.Applications.Common/Tizen.Applications/SafeBundleHandle.cs63
-rw-r--r--src/Tizen.Applications.Common/Tizen.Applications/TizenSynchronizationContext.cs128
-rwxr-xr-xsrc/Tizen.Applications.DataControl/Interop/Interop.DataControl.cs466
-rwxr-xr-xsrc/Tizen.Applications.DataControl/Interop/Interop.Libraries.cs23
-rwxr-xr-xsrc/Tizen.Applications.DataControl/Tizen.Applications.DataControl.Core/CloneCursorCore.cs259
-rw-r--r--src/Tizen.Applications.DataControl/Tizen.Applications.DataControl.csproj18
-rwxr-xr-xsrc/Tizen.Applications.DataControl/Tizen.Applications.DataControl/BulkData.cs361
-rwxr-xr-xsrc/Tizen.Applications.DataControl/Tizen.Applications.DataControl/Consumer.cs973
-rwxr-xr-xsrc/Tizen.Applications.DataControl/Tizen.Applications.DataControl/ErrorFactory.cs60
-rwxr-xr-xsrc/Tizen.Applications.DataControl/Tizen.Applications.DataControl/ICursor.cs81
-rwxr-xr-xsrc/Tizen.Applications.DataControl/Tizen.Applications.DataControl/MatrixCursor.cs629
-rwxr-xr-xsrc/Tizen.Applications.DataControl/Tizen.Applications.DataControl/Provider.cs1091
-rwxr-xr-xsrc/Tizen.Applications.DataControl/Tizen.Applications.DataControl/Results.cs385
-rwxr-xr-xsrc/Tizen.Applications.DataControl/Tizen.Applications.DataControl/Types.cs106
-rwxr-xr-xsrc/Tizen.Applications.MessagePort/Interop/Interop.Libraries.cs23
-rwxr-xr-xsrc/Tizen.Applications.MessagePort/Interop/Interop.MessagePort.cs47
-rwxr-xr-xsrc/Tizen.Applications.MessagePort/Tizen.Applications.MessagePort.csproj13
-rwxr-xr-xsrc/Tizen.Applications.MessagePort/Tizen.Applications.Messages/MessagePort.cs306
-rwxr-xr-xsrc/Tizen.Applications.MessagePort/Tizen.Applications.Messages/MessagePortErrorFactory.cs57
-rwxr-xr-xsrc/Tizen.Applications.MessagePort/Tizen.Applications.Messages/MessageReceivedEventArgs.cs35
-rwxr-xr-xsrc/Tizen.Applications.MessagePort/Tizen.Applications.Messages/RemoteValues.cs39
-rwxr-xr-xsrc/Tizen.Applications.Notification/Interop/Interop.Libraries.cs23
-rwxr-xr-xsrc/Tizen.Applications.Notification/Interop/Interop.Notification.cs311
-rwxr-xr-xsrc/Tizen.Applications.Notification/Tizen.Applications.Notification.csproj13
-rwxr-xr-xsrc/Tizen.Applications.Notification/Tizen.Applications.Notifications/Notification.cs505
-rwxr-xr-xsrc/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationAccessorySet.cs95
-rwxr-xr-xsrc/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationAccessorySetBinder.cs144
-rwxr-xr-xsrc/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationActiveStyle.cs264
-rwxr-xr-xsrc/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationBinder.cs233
-rwxr-xr-xsrc/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationButtonAction.cs86
-rwxr-xr-xsrc/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationEnumerations.cs215
-rwxr-xr-xsrc/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationErrorFactory.cs56
-rwxr-xr-xsrc/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationIndicatorStyle.cs62
-rwxr-xr-xsrc/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationLockStyle.cs61
-rwxr-xr-xsrc/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationMakerBase.cs40
-rwxr-xr-xsrc/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationManager.cs480
-rwxr-xr-xsrc/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationProgress.cs124
-rwxr-xr-xsrc/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationProgressBinder.cs75
-rwxr-xr-xsrc/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationReplyAction.cs111
-rwxr-xr-xsrc/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationSafeHandle.cs53
-rwxr-xr-xsrc/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationStyle.cs38
-rwxr-xr-xsrc/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationStyleBinder.cs286
-rwxr-xr-xsrc/Tizen.Applications.NotificationEventListener/Interop/Interop.Libraries.cs23
-rwxr-xr-xsrc/Tizen.Applications.NotificationEventListener/Interop/Interop.NotificationEventListener.cs298
-rwxr-xr-xsrc/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener.csproj13
-rwxr-xr-xsrc/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationAccessoryArgsBinder.cs65
-rwxr-xr-xsrc/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationButtonActionArgsBinder.cs58
-rwxr-xr-xsrc/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationDeleteEventArgs.cs30
-rwxr-xr-xsrc/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationDeleteEventArgsBinder.cs30
-rwxr-xr-xsrc/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgs.cs185
-rwxr-xr-xsrc/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsAccessory.cs75
-rwxr-xr-xsrc/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsActiveStyle.cs89
-rwxr-xr-xsrc/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsBinder.cs210
-rwxr-xr-xsrc/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsButtonAction.cs50
-rwxr-xr-xsrc/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsEnumerations.cs488
-rwxr-xr-xsrc/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsIndicatorStyle.cs48
-rwxr-xr-xsrc/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsLockStyle.cs48
-rwxr-xr-xsrc/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsProgress.cs45
-rwxr-xr-xsrc/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsReplyAction.cs52
-rwxr-xr-xsrc/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsStyle.cs29
-rwxr-xr-xsrc/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventListenerErrorFactory.cs48
-rwxr-xr-xsrc/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationListenerManager.cs417
-rwxr-xr-xsrc/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationProgressArgsBinder.cs50
-rwxr-xr-xsrc/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationReplyActionArgsBinder.cs101
-rwxr-xr-xsrc/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationStyleArgsBinder.cs94
-rwxr-xr-xsrc/Tizen.Applications.PackageManager/Interop/Interop.Libraries.cs23
-rw-r--r--src/Tizen.Applications.PackageManager/Interop/Interop.Package.cs115
-rw-r--r--src/Tizen.Applications.PackageManager/Interop/Interop.PackageManager.cs225
-rwxr-xr-xsrc/Tizen.Applications.PackageManager/Tizen.Applications.PackageManager.csproj13
-rw-r--r--src/Tizen.Applications.PackageManager/Tizen.Applications/CertCompareResultType.cs47
-rwxr-xr-xsrc/Tizen.Applications.PackageManager/Tizen.Applications/CertificateType.cs37
-rw-r--r--src/Tizen.Applications.PackageManager/Tizen.Applications/Package.cs346
-rwxr-xr-xsrc/Tizen.Applications.PackageManager/Tizen.Applications/PackageCertificate.cs98
-rw-r--r--src/Tizen.Applications.PackageManager/Tizen.Applications/PackageDrm.cs77
-rwxr-xr-xsrc/Tizen.Applications.PackageManager/Tizen.Applications/PackageEventState.cs41
-rwxr-xr-xsrc/Tizen.Applications.PackageManager/Tizen.Applications/PackageEventType.cs45
-rwxr-xr-xsrc/Tizen.Applications.PackageManager/Tizen.Applications/PackageFilter.cs82
-rw-r--r--src/Tizen.Applications.PackageManager/Tizen.Applications/PackageManager.cs1103
-rwxr-xr-xsrc/Tizen.Applications.PackageManager/Tizen.Applications/PackageManagerEventArgs.cs59
-rwxr-xr-xsrc/Tizen.Applications.PackageManager/Tizen.Applications/PackageSizeInformation.cs78
-rwxr-xr-xsrc/Tizen.Applications.PackageManager/Tizen.Applications/PackageType.cs70
-rw-r--r--src/Tizen.Applications.PackageManager/Tizen.Applications/PermissionType.cs39
-rwxr-xr-xsrc/Tizen.Applications.PackageManager/Tizen.Applications/SafePackageManagerHandle.cs50
-rwxr-xr-xsrc/Tizen.Applications.PackageManager/Tizen.Applications/SafePackageManagerRequestHandle.cs50
-rwxr-xr-xsrc/Tizen.Applications.PackageManager/Tizen.Applications/StorageType.cs33
-rwxr-xr-xsrc/Tizen.Applications.Preference/Interop/Interop.Libraries.cs23
-rwxr-xr-xsrc/Tizen.Applications.Preference/Interop/Interop.Preference.cs77
-rwxr-xr-xsrc/Tizen.Applications.Preference/Tizen.Applications.Preference.csproj13
-rwxr-xr-xsrc/Tizen.Applications.Preference/Tizen.Applications/Preference.cs463
-rwxr-xr-xsrc/Tizen.Applications.Preference/Tizen.Applications/PreferenceChangedEventArgs.cs31
-rwxr-xr-xsrc/Tizen.Applications.RemoteView/Interop/Interop.Libraries.cs23
-rwxr-xr-xsrc/Tizen.Applications.RemoteView/Interop/Interop.WidgetViewerEvas.cs95
-rw-r--r--src/Tizen.Applications.RemoteView/Tizen.Applications.RemoteView.csproj15
-rwxr-xr-xsrc/Tizen.Applications.RemoteView/Tizen.Applications/RemoteView.cs231
-rwxr-xr-xsrc/Tizen.Applications.RemoteView/Tizen.Applications/RemoteViewFactory.cs101
-rwxr-xr-xsrc/Tizen.Applications.RemoteView/Tizen.Applications/RemoteWindow.cs53
-rwxr-xr-xsrc/Tizen.Applications.Service/Interop/Interop.Libraries.cs23
-rwxr-xr-xsrc/Tizen.Applications.Service/Interop/Interop.Service.cs54
-rwxr-xr-xsrc/Tizen.Applications.Service/Tizen.Applications.CoreBackend/ServiceCoreBackend.cs190
-rwxr-xr-xsrc/Tizen.Applications.Service/Tizen.Applications.Service.csproj13
-rwxr-xr-xsrc/Tizen.Applications.Service/Tizen.Applications/ServiceApplication.cs42
-rwxr-xr-xsrc/Tizen.Applications.ToastMessage/Interop/Interop.Libraries.cs23
-rwxr-xr-xsrc/Tizen.Applications.ToastMessage/Interop/Interop.ToastMessage.cs28
-rwxr-xr-xsrc/Tizen.Applications.ToastMessage/Tizen.Applications.ToastMessage.csproj13
-rwxr-xr-xsrc/Tizen.Applications.ToastMessage/Tizen.Applications/ToastMessage.cs59
-rwxr-xr-xsrc/Tizen.Applications.ToastMessage/Tizen.Applications/ToastMessageErrorFactory.cs45
-rwxr-xr-xsrc/Tizen.Applications.UI/Interop/Interop.Application.cs61
-rwxr-xr-xsrc/Tizen.Applications.UI/Interop/Interop.Libraries.cs23
-rwxr-xr-xsrc/Tizen.Applications.UI/Tizen.Applications.CoreBackend/UICoreBackend.cs214
-rwxr-xr-xsrc/Tizen.Applications.UI/Tizen.Applications.UI.csproj13
-rwxr-xr-xsrc/Tizen.Applications.UI/Tizen.Applications/CoreUIApplication.cs96
-rwxr-xr-xsrc/Tizen.Applications.WidgetApplication/Interop/Interop.Libraries.cs27
-rwxr-xr-xsrc/Tizen.Applications.WidgetApplication/Interop/Interop.Widget.cs152
-rwxr-xr-xsrc/Tizen.Applications.WidgetApplication/Tizen.Applications.CoreBackend/WidgetCoreBackend.cs238
-rw-r--r--src/Tizen.Applications.WidgetApplication/Tizen.Applications.WidgetApplication.csproj14
-rwxr-xr-xsrc/Tizen.Applications.WidgetApplication/Tizen.Applications/WidgetApplication.cs82
-rwxr-xr-xsrc/Tizen.Applications.WidgetApplication/Tizen.Applications/WidgetBase.cs213
-rwxr-xr-xsrc/Tizen.Applications.WidgetApplication/Tizen.Applications/WidgetType.cs143
-rwxr-xr-xsrc/Tizen.Applications.WidgetApplication/Tizen.Applications/WidgetWindow.cs61
-rwxr-xr-xsrc/Tizen.Applications.WidgetControl/Interop/Interop.Libraries.cs23
-rwxr-xr-xsrc/Tizen.Applications.WidgetControl/Interop/Interop.WidgetService.cs106
-rw-r--r--src/Tizen.Applications.WidgetControl/Tizen.Applications.WidgetControl.csproj13
-rwxr-xr-xsrc/Tizen.Applications.WidgetControl/Tizen.Applications/WidgetControl.cs708
-rwxr-xr-xsrc/Tizen.Applications.WidgetControl/Tizen.Applications/WidgetLifecycleEventArgs.cs71
-rwxr-xr-xsrc/Tizen.Content.Download/Interop/Interop.Download.cs110
-rwxr-xr-xsrc/Tizen.Content.Download/Interop/Interop.Libraries.cs24
-rw-r--r--src/Tizen.Content.Download/Tizen.Content.Download.csproj13
-rwxr-xr-xsrc/Tizen.Content.Download/Tizen.Content.Download/DownloadEnumerator.cs129
-rwxr-xr-xsrc/Tizen.Content.Download/Tizen.Content.Download/DownloadErrorFactory.cs94
-rwxr-xr-xsrc/Tizen.Content.Download/Tizen.Content.Download/Notification.cs237
-rwxr-xr-xsrc/Tizen.Content.Download/Tizen.Content.Download/ProgressChangedEventArgs.cs46
-rwxr-xr-xsrc/Tizen.Content.Download/Tizen.Content.Download/Request.cs858
-rwxr-xr-xsrc/Tizen.Content.Download/Tizen.Content.Download/StateChangedEventArgs.cs46
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Interop/Interop.AudioInformation.cs118
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Interop/Interop.Glib.cs31
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Interop/Interop.ImageInformation.cs91
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Interop/Interop.Libc.cs28
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Interop/Interop.Libraries.cs26
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Interop/Interop.MediaBookmark.cs50
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Interop/Interop.MediaContent.cs54
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Interop/Interop.MediaFace.cs68
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Interop/Interop.MediaFilter.cs56
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Interop/Interop.MediaFolder.cs87
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Interop/Interop.MediaGroup.cs81
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Interop/Interop.MediaInformation.cs287
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Interop/Interop.MediaPlaylist.cs96
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Interop/Interop.MediaStorage.cs66
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Interop/Interop.MediaTag.cs78
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Interop/Interop.VideoInformation.cs115
-rw-r--r--src/Tizen.Content.MediaContent/Tizen.Content.MediaContent.csproj14
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Album.cs224
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Tizen.Content.MediaContent/AudioInformation.cs455
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentCollection.cs50
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentColumns.cs1130
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentDatabase.cs714
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentEventArgs.cs113
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentFilter.cs365
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentManager.cs268
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Tizen.Content.MediaContent/FaceRect.cs59
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Group.cs137
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ImageInformation.cs347
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaBookmark.cs129
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaContentEnums.cs411
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaContentError.cs79
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaFace.cs226
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaFolder.cs330
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaInformation.cs897
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Tizen.Content.MediaContent/PlayList.cs341
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Storage.cs219
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Tag.cs217
-rwxr-xr-xsrc/Tizen.Content.MediaContent/Tizen.Content.MediaContent/VideoInformation.cs431
-rwxr-xr-xsrc/Tizen.Content.MimeType/Interop/Interop.Glib.cs30
-rwxr-xr-xsrc/Tizen.Content.MimeType/Interop/Interop.Libc.cs27
-rwxr-xr-xsrc/Tizen.Content.MimeType/Interop/Interop.Libraries.cs25
-rwxr-xr-xsrc/Tizen.Content.MimeType/Interop/Interop.Mime.cs36
-rw-r--r--src/Tizen.Content.MimeType/Tizen.Content.MimeType.csproj14
-rwxr-xr-xsrc/Tizen.Content.MimeType/Tizen.Content.MimeType/MimeExceptionFactory.cs55
-rwxr-xr-xsrc/Tizen.Content.MimeType/Tizen.Content.MimeType/MimeUtil.cs96
-rwxr-xr-xsrc/Tizen.Location.Geofence/Interop/Interop.Libraries.cs24
-rwxr-xr-xsrc/Tizen.Location.Geofence/Interop/Interop.Location.cs157
-rw-r--r--src/Tizen.Location.Geofence/Tizen.Location.Geofence.csproj14
-rwxr-xr-xsrc/Tizen.Location.Geofence/Tizen.Location.Geofence/Fence.cs302
-rwxr-xr-xsrc/Tizen.Location.Geofence/Tizen.Location.Geofence/FenceData.cs129
-rw-r--r--src/Tizen.Location.Geofence/Tizen.Location.Geofence/FenceStatus.cs126
-rwxr-xr-xsrc/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceEnum.cs197
-rwxr-xr-xsrc/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceErrorFactory.cs174
-rwxr-xr-xsrc/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceEventArgs.cs164
-rwxr-xr-xsrc/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceManager.cs298
-rwxr-xr-xsrc/Tizen.Location.Geofence/Tizen.Location.Geofence/NamespaceDoc.cs33
-rwxr-xr-xsrc/Tizen.Location.Geofence/Tizen.Location.Geofence/VirtualPerimeter.cs269
-rwxr-xr-xsrc/Tizen.Location/Interop/Interop.Libraries.cs24
-rwxr-xr-xsrc/Tizen.Location/Interop/Interop.Location.cs191
-rw-r--r--src/Tizen.Location/Tizen.Location.csproj14
-rwxr-xr-xsrc/Tizen.Location/Tizen.Location/GpsSatellite.cs360
-rwxr-xr-xsrc/Tizen.Location/Tizen.Location/Location.cs246
-rwxr-xr-xsrc/Tizen.Location/Tizen.Location/LocationBoundary.cs364
-rwxr-xr-xsrc/Tizen.Location/Tizen.Location/LocationChangedEventArgs.cs44
-rwxr-xr-xsrc/Tizen.Location/Tizen.Location/LocationError.cs111
-rwxr-xr-xsrc/Tizen.Location/Tizen.Location/Locator.cs839
-rwxr-xr-xsrc/Tizen.Location/Tizen.Location/LocatorEnumerations.cs64
-rwxr-xr-xsrc/Tizen.Location/Tizen.Location/LocatorHelper.cs58
-rwxr-xr-xsrc/Tizen.Location/Tizen.Location/NamespaceDoc.cs21
-rwxr-xr-xsrc/Tizen.Location/Tizen.Location/SatelliteStatusChangedEventArgs.cs55
-rwxr-xr-xsrc/Tizen.Location/Tizen.Location/ServiceStateChangedEventArgs.cs42
-rwxr-xr-xsrc/Tizen.Location/Tizen.Location/SettingChangedEventArgs.cs47
-rwxr-xr-xsrc/Tizen.Location/Tizen.Location/ZoneChangedEventArgs.cs71
-rw-r--r--src/Tizen.Log/Interop/Interop.Dlog.cs67
-rw-r--r--src/Tizen.Log/Tizen.Log.csproj9
-rw-r--r--src/Tizen.Log/Tizen/Log.cs224
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.Address.cs174
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.AddressList.cs66
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.Area.cs65
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.Coordinates.cs75
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.CoordinatesList.cs72
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.ErrorCode.cs107
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.Libraries.cs23
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.Place.Attribute.cs55
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.Place.Category.cs80
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.Place.Contact.cs55
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.Place.Editorial.cs55
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.Place.Filter.cs111
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.Place.Image.cs79
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.Place.Link.Object.cs68
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.Place.Media.cs60
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.Place.Rating.cs53
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.Place.Review.cs84
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.Place.cs239
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.PlaceList.cs46
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.Preference.cs227
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.Route.Maneuver.cs137
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.Route.Segment.cs124
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.Route.cs154
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.SafeMapsHandle.cs103
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.Service.cs195
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.View.Event.Data.cs179
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.View.Marker.cs102
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.View.Object.cs73
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.View.Overlay.cs72
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.View.Polygon.cs79
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.View.Polyline.cs91
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.View.Snapshot.cs32
-rwxr-xr-xsrc/Tizen.Maps/Interop/Interop.View.cs258
-rw-r--r--src/Tizen.Maps/Tizen.Maps.csproj16
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/Area.cs85
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/Direction.cs62
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/DistanceUnit.cs42
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/GeocodeRequest.cs102
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/Geocoordinates.cs104
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/GeocoordinatesList.cs74
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/GestureType.cs58
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/IGeocodePreference.cs41
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/IPlaceSearchPreference.cs60
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/IRouteSearchPreference.cs62
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/Log.cs56
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/MapGestureEventArgs.cs77
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/MapObject.cs40
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/MapService.cs373
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/MapServiceRequest.cs118
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/MapTypes.cs42
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/MapView.cs780
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/Marker.cs266
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/MultiReverseGeocodeRequest.cs67
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/NamespaceDoc.cs132
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/Overlay.cs191
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/Place.cs264
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/PlaceAddress.cs237
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/PlaceAddressList.cs84
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/PlaceAttribute.cs71
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/PlaceCategory.cs108
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/PlaceContact.cs71
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/PlaceEditorial.cs70
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/PlaceFilter.cs135
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/PlaceImage.cs80
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/PlaceLink.cs65
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/PlaceList.cs74
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/PlaceMedia.cs56
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/PlaceRating.cs58
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/PlaceReview.cs93
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/PlaceSearchRequest.cs102
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/Polygon.cs154
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/Polyline.cs171
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/ReverseGeocodeRequest.cs67
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/Route.cs182
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/RouteFeature.cs70
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/RouteFeatureWeight.cs46
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/RouteManeuver.cs96
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/RouteOptimization.cs53
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/RouteSearchRequest.cs123
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/RouteSegment.cs88
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/SearchPreference.cs254
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/ServiceData.cs96
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/ServiceRequestType.cs85
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/SnapshotType.cs34
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/TransportMode.cs46
-rwxr-xr-xsrc/Tizen.Maps/Tizen.Maps/TurnInstruction.cs86
-rwxr-xr-xsrc/Tizen.Maps/res/maps_marker_pin_48.pngbin0 -> 1185 bytes
-rwxr-xr-xsrc/Tizen.Maps/res/maps_marker_pin_72.pngbin0 -> 1725 bytes
-rwxr-xr-xsrc/Tizen.Maps/res/maps_marker_sticker_48.pngbin0 -> 961 bytes
-rwxr-xr-xsrc/Tizen.Maps/res/maps_marker_sticker_72.pngbin0 -> 1379 bytes
-rw-r--r--src/Tizen.Messaging.Push/Interop/Interop.Glib.cs30
-rw-r--r--src/Tizen.Messaging.Push/Interop/Interop.Libc.cs27
-rw-r--r--src/Tizen.Messaging.Push/Interop/Interop.Libraries.cs25
-rw-r--r--src/Tizen.Messaging.Push/Interop/Interop.PushClient.cs113
-rw-r--r--src/Tizen.Messaging.Push/Tizen.Messaging.Push.csproj15
-rw-r--r--src/Tizen.Messaging.Push/Tizen.Messaging.Push/PushClient.cs189
-rw-r--r--src/Tizen.Messaging.Push/Tizen.Messaging.Push/PushConnectionStateEventArgs.cs85
-rw-r--r--src/Tizen.Messaging.Push/Tizen.Messaging.Push/PushExceptionFactory.cs83
-rw-r--r--src/Tizen.Messaging.Push/Tizen.Messaging.Push/PushImpl.cs243
-rw-r--r--src/Tizen.Messaging.Push/Tizen.Messaging.Push/PushMessageEventArgs.cs121
-rw-r--r--src/Tizen.Messaging.Push/Tizen.Messaging.Push/ServerResponse.cs73
-rwxr-xr-xsrc/Tizen.Messaging/Interop/Interop.Email.cs70
-rw-r--r--src/Tizen.Messaging/Interop/Interop.Libraries.cs24
-rwxr-xr-xsrc/Tizen.Messaging/Interop/Interop.Messages.cs124
-rw-r--r--src/Tizen.Messaging/Tizen.Messaging.Email/EmailAttachment.cs36
-rwxr-xr-xsrc/Tizen.Messaging/Tizen.Messaging.Email/EmailEnumerations.cs34
-rwxr-xr-xsrc/Tizen.Messaging/Tizen.Messaging.Email/EmailErrorFactory.cs96
-rw-r--r--src/Tizen.Messaging/Tizen.Messaging.Email/EmailMessage.cs229
-rw-r--r--src/Tizen.Messaging/Tizen.Messaging.Email/EmailRecipient.cs36
-rw-r--r--src/Tizen.Messaging/Tizen.Messaging.Email/EmailSender.cs72
-rwxr-xr-xsrc/Tizen.Messaging/Tizen.Messaging.Email/NamespaceDoc.cs26
-rwxr-xr-xsrc/Tizen.Messaging/Tizen.Messaging.Messages/CBMessage.cs30
-rwxr-xr-xsrc/Tizen.Messaging/Tizen.Messaging.Messages/Message.cs335
-rwxr-xr-xsrc/Tizen.Messaging/Tizen.Messaging.Messages/MessageReceivedEventArgs.cs44
-rwxr-xr-xsrc/Tizen.Messaging/Tizen.Messaging.Messages/MessagesAddress.cs45
-rwxr-xr-xsrc/Tizen.Messaging/Tizen.Messaging.Messages/MessagesAttachment.cs45
-rwxr-xr-xsrc/Tizen.Messaging/Tizen.Messaging.Messages/MessagesEnumerations.cs152
-rwxr-xr-xsrc/Tizen.Messaging/Tizen.Messaging.Messages/MessagesErrorFactory.cs74
-rwxr-xr-xsrc/Tizen.Messaging/Tizen.Messaging.Messages/MessagesEvent.cs125
-rwxr-xr-xsrc/Tizen.Messaging/Tizen.Messaging.Messages/MessagesManager.cs77
-rwxr-xr-xsrc/Tizen.Messaging/Tizen.Messaging.Messages/MessagesManagerImpl.cs233
-rwxr-xr-xsrc/Tizen.Messaging/Tizen.Messaging.Messages/MessagesSearchFilter.cs48
-rwxr-xr-xsrc/Tizen.Messaging/Tizen.Messaging.Messages/MmsMessage.cs162
-rwxr-xr-xsrc/Tizen.Messaging/Tizen.Messaging.Messages/NamespaceDoc.cs25
-rwxr-xr-xsrc/Tizen.Messaging/Tizen.Messaging.Messages/PushMessage.cs30
-rwxr-xr-xsrc/Tizen.Messaging/Tizen.Messaging.Messages/SmsMessage.cs49
-rw-r--r--src/Tizen.Messaging/Tizen.Messaging.csproj15
-rw-r--r--src/Tizen.Multimedia.AudioIO/AudioIO/AudioCapture.cs397
-rw-r--r--src/Tizen.Multimedia.AudioIO/AudioIO/AudioDataAvailableEventArgs.cs36
-rw-r--r--src/Tizen.Multimedia.AudioIO/AudioIO/AudioIOEnums.cs80
-rw-r--r--src/Tizen.Multimedia.AudioIO/AudioIO/AudioIOStateChangedEventArgs.cs48
-rw-r--r--src/Tizen.Multimedia.AudioIO/AudioIO/AudioIOUtil.cs95
-rw-r--r--src/Tizen.Multimedia.AudioIO/AudioIO/AudioPlayback.cs386
-rw-r--r--src/Tizen.Multimedia.AudioIO/AudioIO/AudioPlaybackBufferAvailableEventArgs.cs30
-rw-r--r--src/Tizen.Multimedia.AudioIO/Interop/Interop.AudioIO.cs137
-rw-r--r--src/Tizen.Multimedia.AudioIO/Interop/Interop.Libraries.cs25
-rw-r--r--src/Tizen.Multimedia.AudioIO/Interop/Interop.TonePlayer.cs32
-rw-r--r--src/Tizen.Multimedia.AudioIO/Interop/Interop.WavPlayer.cs34
-rw-r--r--src/Tizen.Multimedia.AudioIO/MultimediaDebug.cs31
-rw-r--r--src/Tizen.Multimedia.AudioIO/Tizen.Multimedia.AudioIO.csproj13
-rw-r--r--src/Tizen.Multimedia.AudioIO/TonePlayer/TonePlayer.cs101
-rw-r--r--src/Tizen.Multimedia.AudioIO/TonePlayer/TonePlayerEnums.cs472
-rw-r--r--src/Tizen.Multimedia.AudioIO/TonePlayer/TonePlayerErrorFactory.cs70
-rw-r--r--src/Tizen.Multimedia.AudioIO/ValdiationUtil.cs31
-rw-r--r--src/Tizen.Multimedia.AudioIO/WavPlayer/WavPlayer.cs93
-rw-r--r--src/Tizen.Multimedia.AudioIO/WavPlayer/WavPlayerErrorFactory.cs94
-rwxr-xr-xsrc/Tizen.Multimedia.Camera/Camera/Camera.cs954
-rwxr-xr-xsrc/Tizen.Multimedia.Camera/Camera/CameraCapturingEventArgs.cs52
-rwxr-xr-xsrc/Tizen.Multimedia.Camera/Camera/CameraDeviceStateChangedEventArgs.cs46
-rwxr-xr-xsrc/Tizen.Multimedia.Camera/Camera/CameraDisplaySettings.cs157
-rwxr-xr-xsrc/Tizen.Multimedia.Camera/Camera/CameraEnums.cs908
-rw-r--r--src/Tizen.Multimedia.Camera/Camera/CameraErrorFactory.cs89
-rwxr-xr-xsrc/Tizen.Multimedia.Camera/Camera/CameraErrorOccurredEventArgs.cs46
-rw-r--r--src/Tizen.Multimedia.Camera/Camera/CameraException.cs53
-rwxr-xr-xsrc/Tizen.Multimedia.Camera/Camera/CameraFeatures.cs816
-rwxr-xr-xsrc/Tizen.Multimedia.Camera/Camera/CameraFocusStateChangedEventArgs.cs39
-rwxr-xr-xsrc/Tizen.Multimedia.Camera/Camera/CameraInterruptedEventArgs.cs53
-rwxr-xr-xsrc/Tizen.Multimedia.Camera/Camera/CameraSettings.cs1159
-rwxr-xr-xsrc/Tizen.Multimedia.Camera/Camera/CameraStateChangedEventArgs.cs54
-rwxr-xr-xsrc/Tizen.Multimedia.Camera/Camera/DoublePlane.cs47
-rwxr-xr-xsrc/Tizen.Multimedia.Camera/Camera/EncodedPlane.cs39
-rwxr-xr-xsrc/Tizen.Multimedia.Camera/Camera/FaceDetectedEventArgs.cs40
-rwxr-xr-xsrc/Tizen.Multimedia.Camera/Camera/FaceDetectionData.cs77
-rwxr-xr-xsrc/Tizen.Multimedia.Camera/Camera/HdrCaptureProgressEventArgs.cs38
-rwxr-xr-xsrc/Tizen.Multimedia.Camera/Camera/IPreviewPlane.cs22
-rwxr-xr-xsrc/Tizen.Multimedia.Camera/Camera/ImageData.cs86
-rwxr-xr-xsrc/Tizen.Multimedia.Camera/Camera/Location.cs56
-rwxr-xr-xsrc/Tizen.Multimedia.Camera/Camera/MediaPacketPreviewEventArgs.cs38
-rwxr-xr-xsrc/Tizen.Multimedia.Camera/Camera/PreviewData.cs124
-rwxr-xr-xsrc/Tizen.Multimedia.Camera/Camera/PreviewEventArgs.cs38
-rwxr-xr-xsrc/Tizen.Multimedia.Camera/Camera/SinglePlane.cs39
-rwxr-xr-xsrc/Tizen.Multimedia.Camera/Camera/TriplePlane.cs55
-rwxr-xr-xsrc/Tizen.Multimedia.Camera/Interop/Interop.Camera.cs273
-rw-r--r--src/Tizen.Multimedia.Camera/Interop/Interop.CameraDisplay.cs58
-rw-r--r--src/Tizen.Multimedia.Camera/Interop/Interop.CameraFeatures.cs160
-rwxr-xr-xsrc/Tizen.Multimedia.Camera/Interop/Interop.CameraSettings.cs235
-rw-r--r--src/Tizen.Multimedia.Camera/Interop/Interop.Libraries.cs23
-rw-r--r--src/Tizen.Multimedia.Camera/Tizen.Multimedia.Camera.csproj13
-rw-r--r--src/Tizen.Multimedia.MediaCodec/Interop/Interop.Libraries.cs27
-rw-r--r--src/Tizen.Multimedia.MediaCodec/Interop/Interop.MediaCodec.cs124
-rw-r--r--src/Tizen.Multimedia.MediaCodec/Interop/Interop.MediaTool.cs14
-rw-r--r--src/Tizen.Multimedia.MediaCodec/MediaCodec/BufferStatusChangedEventArgs.cs41
-rw-r--r--src/Tizen.Multimedia.MediaCodec/MediaCodec/InputProcessedEventArgs.cs43
-rw-r--r--src/Tizen.Multimedia.MediaCodec/MediaCodec/MediaCodec.cs691
-rw-r--r--src/Tizen.Multimedia.MediaCodec/MediaCodec/MediaCodecError.cs54
-rw-r--r--src/Tizen.Multimedia.MediaCodec/MediaCodec/MediaCodecErrorOccurredEventArgs.cs40
-rw-r--r--src/Tizen.Multimedia.MediaCodec/MediaCodec/MediaCodecStatus.cs34
-rw-r--r--src/Tizen.Multimedia.MediaCodec/MediaCodec/MediaCodecType.cs47
-rw-r--r--src/Tizen.Multimedia.MediaCodec/MediaCodec/OutputAvailableEventArgs.cs37
-rw-r--r--src/Tizen.Multimedia.MediaCodec/MediaCodec/SupportedCodecType.cs52
-rw-r--r--src/Tizen.Multimedia.MediaCodec/Tizen.Multimedia.MediaCodec.csproj13
-rw-r--r--src/Tizen.Multimedia.MediaPlayer/Interop/Interop.AudioEffect.cs53
-rw-r--r--src/Tizen.Multimedia.MediaPlayer/Interop/Interop.Display.cs47
-rw-r--r--src/Tizen.Multimedia.MediaPlayer/Interop/Interop.Libraries.cs24
-rw-r--r--src/Tizen.Multimedia.MediaPlayer/Interop/Interop.Player.cs287
-rw-r--r--src/Tizen.Multimedia.MediaPlayer/Player/AudioEffect.cs123
-rw-r--r--src/Tizen.Multimedia.MediaPlayer/Player/BufferingProgressChangedEventArgs.cs41
-rw-r--r--src/Tizen.Multimedia.MediaPlayer/Player/CapturedFrame.cs48
-rw-r--r--src/Tizen.Multimedia.MediaPlayer/Player/DownloadProgress.cs61
-rw-r--r--src/Tizen.Multimedia.MediaPlayer/Player/EqualizerBand.cs106
-rw-r--r--src/Tizen.Multimedia.MediaPlayer/Player/MediaBufferSource.cs140
-rw-r--r--src/Tizen.Multimedia.MediaPlayer/Player/MediaSource.cs46
-rw-r--r--src/Tizen.Multimedia.MediaPlayer/Player/MediaStreamBufferStatusChangedEventArgs.cs45
-rw-r--r--src/Tizen.Multimedia.MediaPlayer/Player/MediaStreamConfiguration.cs172
-rw-r--r--src/Tizen.Multimedia.MediaPlayer/Player/MediaStreamSeekingOccurredEventArgs.cs41
-rw-r--r--src/Tizen.Multimedia.MediaPlayer/Player/MediaStreamSource.cs296
-rw-r--r--src/Tizen.Multimedia.MediaPlayer/Player/MediaUriSource.cs56
-rw-r--r--src/Tizen.Multimedia.MediaPlayer/Player/PlaybackInterruptedEventArgs.cs44
-rw-r--r--src/Tizen.Multimedia.MediaPlayer/Player/Player.cs1317
-rw-r--r--src/Tizen.Multimedia.MediaPlayer/Player/PlayerDisplaySettings.cs181
-rw-r--r--src/Tizen.Multimedia.MediaPlayer/Player/PlayerEnums.cs267
-rw-r--r--src/Tizen.Multimedia.MediaPlayer/Player/PlayerError.cs146
-rw-r--r--src/Tizen.Multimedia.MediaPlayer/Player/PlayerErrorOccurredEventArgs.cs44
-rw-r--r--src/Tizen.Multimedia.MediaPlayer/Player/PlayerTrackInfo.cs150
-rw-r--r--src/Tizen.Multimedia.MediaPlayer/Player/StreamInfo.cs317
-rw-r--r--src/Tizen.Multimedia.MediaPlayer/Player/SubtitleUpdatedEventArgs.cs46
-rw-r--r--src/Tizen.Multimedia.MediaPlayer/Player/VideoFrameDecodedEventArgs.cs39
-rw-r--r--src/Tizen.Multimedia.MediaPlayer/Player/VideoStreamChangedEventArgs.cs59
-rw-r--r--src/Tizen.Multimedia.MediaPlayer/Tizen.Multimedia.MediaPlayer.csproj13
-rw-r--r--src/Tizen.Multimedia.Metadata/Interop/Interop.Libc.cs11
-rw-r--r--src/Tizen.Multimedia.Metadata/Interop/Interop.Libraries.cs25
-rw-r--r--src/Tizen.Multimedia.Metadata/Interop/Interop.MetadataEditor.cs36
-rw-r--r--src/Tizen.Multimedia.Metadata/Interop/Interop.MetadataExtractor.cs55
-rwxr-xr-xsrc/Tizen.Multimedia.Metadata/MetadataEditor/MetadataEditor.cs458
-rw-r--r--src/Tizen.Multimedia.Metadata/MetadataEditor/MetadataEditorAttr.cs35
-rw-r--r--src/Tizen.Multimedia.Metadata/MetadataEditor/MetadataEditorErrorFactory.cs66
-rwxr-xr-xsrc/Tizen.Multimedia.Metadata/MetadataExtractor/Artwork.cs48
-rwxr-xr-xsrc/Tizen.Multimedia.Metadata/MetadataExtractor/Metadata.cs403
-rwxr-xr-xsrc/Tizen.Multimedia.Metadata/MetadataExtractor/MetadataExtractor.cs315
-rw-r--r--src/Tizen.Multimedia.Metadata/MetadataExtractor/MetadataExtractorAttr.cs57
-rw-r--r--src/Tizen.Multimedia.Metadata/MetadataExtractor/MetadataExtractorError.cs62
-rwxr-xr-xsrc/Tizen.Multimedia.Metadata/MetadataExtractor/SyncLyrics.cs48
-rw-r--r--src/Tizen.Multimedia.Metadata/ObjectDescriptionBuilder.cs59
-rw-r--r--src/Tizen.Multimedia.Metadata/Tizen.Multimedia.Metadata.csproj13
-rw-r--r--src/Tizen.Multimedia.Radio/Interop/Interop.Libraries.cs26
-rw-r--r--src/Tizen.Multimedia.Radio/Interop/Interop.Radio.cs136
-rw-r--r--src/Tizen.Multimedia.Radio/Radio/Radio.cs385
-rw-r--r--src/Tizen.Multimedia.Radio/Radio/RadioError.cs69
-rw-r--r--src/Tizen.Multimedia.Radio/Radio/RadioInterruptedEventArgs.cs41
-rw-r--r--src/Tizen.Multimedia.Radio/Radio/RadioInterruptedReason.cs29
-rw-r--r--src/Tizen.Multimedia.Radio/Radio/RadioState.cs37
-rw-r--r--src/Tizen.Multimedia.Radio/Radio/ScanUpdatedEventArgs.cs42
-rw-r--r--src/Tizen.Multimedia.Radio/Tizen.Multimedia.Radio.csproj13
-rw-r--r--src/Tizen.Multimedia.Recorder/Interop/Interop.Libraries.cs23
-rw-r--r--src/Tizen.Multimedia.Recorder/Interop/Interop.Recorder.cs121
-rw-r--r--src/Tizen.Multimedia.Recorder/Interop/Interop.RecorderFeatures.cs49
-rw-r--r--src/Tizen.Multimedia.Recorder/Interop/Interop.RecorderSettings.cs119
-rwxr-xr-xsrc/Tizen.Multimedia.Recorder/Recorder/AudioStreamDeliveredEventArgs.cs67
-rwxr-xr-xsrc/Tizen.Multimedia.Recorder/Recorder/MuxedStreamEventArgs.cs53
-rwxr-xr-xsrc/Tizen.Multimedia.Recorder/Recorder/Recorder.cs482
-rwxr-xr-xsrc/Tizen.Multimedia.Recorder/Recorder/RecorderEnums.cs241
-rw-r--r--src/Tizen.Multimedia.Recorder/Recorder/RecorderErrorFactory.cs83
-rwxr-xr-xsrc/Tizen.Multimedia.Recorder/Recorder/RecorderFeatures.cs192
-rwxr-xr-xsrc/Tizen.Multimedia.Recorder/Recorder/RecorderInterruptedEventArgs.cs53
-rwxr-xr-xsrc/Tizen.Multimedia.Recorder/Recorder/RecorderSettings.cs451
-rwxr-xr-xsrc/Tizen.Multimedia.Recorder/Recorder/RecorderStateChangedEventArgs.cs53
-rwxr-xr-xsrc/Tizen.Multimedia.Recorder/Recorder/RecordingErrorOccurredEventArgs.cs46
-rwxr-xr-xsrc/Tizen.Multimedia.Recorder/Recorder/RecordingLimitReachedEventArgs.cs37
-rwxr-xr-xsrc/Tizen.Multimedia.Recorder/Recorder/RecordingProgressEventArgs.cs44
-rw-r--r--src/Tizen.Multimedia.Recorder/Tizen.Multimedia.Recorder.csproj15
-rw-r--r--src/Tizen.Multimedia.Remoting/Interop/Interop.Libraries.cs25
-rw-r--r--src/Tizen.Multimedia.Remoting/Interop/Interop.MediaController.cs202
-rw-r--r--src/Tizen.Multimedia.Remoting/Interop/Interop.ScreenMirroring.cs90
-rwxr-xr-xsrc/Tizen.Multimedia.Remoting/MediaController/CustomCommandEventArgs.cs57
-rwxr-xr-xsrc/Tizen.Multimedia.Remoting/MediaController/CustomCommandReplyEventArgs.cs57
-rwxr-xr-xsrc/Tizen.Multimedia.Remoting/MediaController/MediaControllerClient.cs595
-rwxr-xr-xsrc/Tizen.Multimedia.Remoting/MediaController/MediaControllerEnums.cs236
-rw-r--r--src/Tizen.Multimedia.Remoting/MediaController/MediaControllerError.cs57
-rw-r--r--src/Tizen.Multimedia.Remoting/MediaController/MediaControllerLog.cs25
-rwxr-xr-xsrc/Tizen.Multimedia.Remoting/MediaController/MediaControllerMetadata.cs123
-rwxr-xr-xsrc/Tizen.Multimedia.Remoting/MediaController/MediaControllerPlayback.cs76
-rwxr-xr-xsrc/Tizen.Multimedia.Remoting/MediaController/MediaControllerServer.cs302
-rwxr-xr-xsrc/Tizen.Multimedia.Remoting/MediaController/MetadataUpdatedEventArgs.cs49
-rwxr-xr-xsrc/Tizen.Multimedia.Remoting/MediaController/PlaybackStateCommandEventArgs.cs49
-rwxr-xr-xsrc/Tizen.Multimedia.Remoting/MediaController/PlaybackUpdatedEventArgs.cs49
-rwxr-xr-xsrc/Tizen.Multimedia.Remoting/MediaController/RepeatModeUpdatedEventArgs.cs49
-rwxr-xr-xsrc/Tizen.Multimedia.Remoting/MediaController/ServerInformation.cs45
-rwxr-xr-xsrc/Tizen.Multimedia.Remoting/MediaController/ServerUpdatedEventArgs.cs42
-rwxr-xr-xsrc/Tizen.Multimedia.Remoting/MediaController/ShuffleModeUpdatedEventArgs.cs49
-rw-r--r--src/Tizen.Multimedia.Remoting/ScreenMirroring/AudioInformation.cs125
-rw-r--r--src/Tizen.Multimedia.Remoting/ScreenMirroring/ScreenMirroring.cs497
-rw-r--r--src/Tizen.Multimedia.Remoting/ScreenMirroring/ScreenMirroringEnumerations.cs140
-rw-r--r--src/Tizen.Multimedia.Remoting/ScreenMirroring/ScreenMirroringErrorFactory.cs74
-rw-r--r--src/Tizen.Multimedia.Remoting/ScreenMirroring/StateChangedEventArgs.cs67
-rw-r--r--src/Tizen.Multimedia.Remoting/ScreenMirroring/VideoInformation.cs126
-rw-r--r--src/Tizen.Multimedia.Remoting/Tizen.Multimedia.Remoting.csproj13
-rw-r--r--src/Tizen.Multimedia.StreamRecorder/Interop/Interop.Libraries.cs23
-rw-r--r--src/Tizen.Multimedia.StreamRecorder/Interop/Interop.StreamRecorder.cs186
-rw-r--r--src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorder.cs1054
-rw-r--r--src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderEnums.cs197
-rw-r--r--src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderErrorFactory.cs60
-rw-r--r--src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderNotifiedEventArgs.cs66
-rw-r--r--src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderVideoResolution.cs87
-rw-r--r--src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecordingBufferConsumedEventArgs.cs42
-rw-r--r--src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecordingErrorOccurredEventArgs.cs55
-rw-r--r--src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecordingLimitReachedEventArgs.cs42
-rw-r--r--src/Tizen.Multimedia.StreamRecorder/Tizen.Multimedia.StreamRecorder.csproj13
-rw-r--r--src/Tizen.Multimedia.Util/ImageUtil/BitmapFrame.cs50
-rw-r--r--src/Tizen.Multimedia.Util/ImageUtil/GifFrame.cs61
-rw-r--r--src/Tizen.Multimedia.Util/ImageUtil/ImageColorSpace.cs172
-rw-r--r--src/Tizen.Multimedia.Util/ImageUtil/ImageDecoder.cs380
-rw-r--r--src/Tizen.Multimedia.Util/ImageUtil/ImageEncoder.cs451
-rw-r--r--src/Tizen.Multimedia.Util/ImageUtil/ImageFormat.cs41
-rw-r--r--src/Tizen.Multimedia.Util/ImageUtil/ImageRotation.cs50
-rw-r--r--src/Tizen.Multimedia.Util/ImageUtil/ImageTransform.cs486
-rw-r--r--src/Tizen.Multimedia.Util/ImageUtil/ImageTransformer.cs97
-rw-r--r--src/Tizen.Multimedia.Util/ImageUtil/ImageUtil.cs128
-rw-r--r--src/Tizen.Multimedia.Util/ImageUtil/ImageUtilError.cs81
-rw-r--r--src/Tizen.Multimedia.Util/ImageUtil/JpegDownscale.cs41
-rw-r--r--src/Tizen.Multimedia.Util/ImageUtil/PngCompression.cs65
-rw-r--r--src/Tizen.Multimedia.Util/Interop/Interop.ImageUtil.Decode.cs80
-rw-r--r--src/Tizen.Multimedia.Util/Interop/Interop.ImageUtil.Encode.cs91
-rw-r--r--src/Tizen.Multimedia.Util/Interop/Interop.ImageUtil.Transform.cs92
-rw-r--r--src/Tizen.Multimedia.Util/Interop/Interop.ImageUtil.cs38
-rw-r--r--src/Tizen.Multimedia.Util/Interop/Interop.Libraries.cs24
-rw-r--r--src/Tizen.Multimedia.Util/Interop/Interop.ThumbnailExtractor.cs27
-rwxr-xr-xsrc/Tizen.Multimedia.Util/ThumbnailExtractor/ThumbnailData.cs49
-rwxr-xr-xsrc/Tizen.Multimedia.Util/ThumbnailExtractor/ThumbnailExtractor.cs245
-rw-r--r--src/Tizen.Multimedia.Util/ThumbnailExtractor/ThumbnailExtractorErrorFactory.cs63
-rw-r--r--src/Tizen.Multimedia.Util/Tizen.Multimedia.Util.csproj13
-rw-r--r--src/Tizen.Multimedia.Vision/Interop/Interop.Libraries.cs23
-rw-r--r--src/Tizen.Multimedia.Vision/Interop/Interop.MediaVision.BarCode.cs68
-rw-r--r--src/Tizen.Multimedia.Vision/Interop/Interop.MediaVision.Common.cs192
-rw-r--r--src/Tizen.Multimedia.Vision/Interop/Interop.MediaVision.Face.cs153
-rw-r--r--src/Tizen.Multimedia.Vision/Interop/Interop.MediaVision.Image.cs111
-rw-r--r--src/Tizen.Multimedia.Vision/Interop/Interop.MediaVision.Surveillance.cs91
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/Barcode.cs57
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/BarcodeDetectionConfiguration.cs56
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/BarcodeDetectionTarget.cs43
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/BarcodeDetector.cs119
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/BarcodeGenerationConfiguration.cs106
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/BarcodeGenerator.cs357
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/BarcodeImageConfiguration.cs135
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/BarcodeImageFormat.cs42
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/BarcodeType.cs71
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/Colorspace.cs86
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/EngineConfiguration.cs178
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/ErrorCorrectionLevel.cs46
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/EyeCondition.cs43
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/FaceDetectionConfiguration.cs196
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/FaceDetector.cs105
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/FaceRecognitionConfiguration.cs56
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/FaceRecognitionModel.cs301
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/FaceRecognitionModelType.cs43
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/FaceRecognitionResult.cs60
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/FaceRecognizer.cs327
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/FaceTracker.cs104
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/FaceTrackingModel.cs173
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/FaceTrackingResult.cs51
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/FacialExpression.cs73
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/ImageFillConfiguration.cs88
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/ImageObject.cs290
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/ImageRecognitionConfiguration.cs214
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/ImageRecognitionResult.cs44
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/ImageRecognizer.cs156
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/ImageTracker.cs130
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/ImageTrackingConfiguration.cs226
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/ImageTrackingModel.cs164
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/MediaVisionError.cs128
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/MediaVisionSource.cs239
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/MovementDetectedEventArgs.cs43
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/MovementDetectionConfiguration.cs81
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/MovementDetector.cs118
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/PersonAppearanceDetectedEventArgs.cs58
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/PersonAppearanceDetectionConfiguration.cs75
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/PersonAppearanceDetector.cs122
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/PersonRecognitionConfiguration.cs63
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/PersonRecognitionInfo.cs54
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/PersonRecognizedEventArgs.cs43
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/PersonRecognizer.cs128
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/QrConfiguration.cs80
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/QrMode.cs46
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/Quadrangle.cs54
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/SurveillanceConfiguration.cs29
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/SurveillanceEngine.cs149
-rwxr-xr-xsrc/Tizen.Multimedia.Vision/MediaVision/SurveillanceSource.cs76
-rw-r--r--src/Tizen.Multimedia.Vision/Tizen.Multimedia.Vision.csproj13
-rw-r--r--src/Tizen.Multimedia/AssemblyAttrs.cs68
-rwxr-xr-xsrc/Tizen.Multimedia/AudioManager/AudioDevice.cs110
-rw-r--r--src/Tizen.Multimedia/AudioManager/AudioDeviceConnectionChangedEventArgs.cs42
-rw-r--r--src/Tizen.Multimedia/AudioManager/AudioDeviceStateChangedEventArgs.cs42
-rwxr-xr-xsrc/Tizen.Multimedia/AudioManager/AudioManager.cs198
-rwxr-xr-xsrc/Tizen.Multimedia/AudioManager/AudioManagerEnumerations.cs326
-rw-r--r--src/Tizen.Multimedia/AudioManager/AudioManagerErrorFactory.cs120
-rwxr-xr-xsrc/Tizen.Multimedia/AudioManager/AudioStreamPolicy.cs334
-rwxr-xr-xsrc/Tizen.Multimedia/AudioManager/AudioVolume.cs107
-rw-r--r--src/Tizen.Multimedia/AudioManager/FocusStateChangedEventArgs.cs48
-rw-r--r--src/Tizen.Multimedia/AudioManager/MaxVolumeLevel.cs46
-rwxr-xr-xsrc/Tizen.Multimedia/AudioManager/StreamFocusStateChangedEventArgs.cs43
-rwxr-xr-xsrc/Tizen.Multimedia/AudioManager/VolumeChangedEventArgs.cs42
-rw-r--r--src/Tizen.Multimedia/AudioManager/VolumeLevel.cs55
-rw-r--r--src/Tizen.Multimedia/Common.Internal/Features.cs34
-rw-r--r--src/Tizen.Multimedia/Common.Internal/FileUtil.cs44
-rw-r--r--src/Tizen.Multimedia/Common.Internal/IBufferOwner.cs64
-rw-r--r--src/Tizen.Multimedia/Common.Internal/LibcSupport.cs13
-rw-r--r--src/Tizen.Multimedia/Common.Internal/MultimediaDebug.cs31
-rw-r--r--src/Tizen.Multimedia/Common.Internal/MultimediaLog.cs76
-rw-r--r--src/Tizen.Multimedia/Common.Internal/ObjectKeeper.cs77
-rw-r--r--src/Tizen.Multimedia/Common.Internal/ValdiationUtil.cs47
-rw-r--r--src/Tizen.Multimedia/Common/CodecNotSupportedException.cs66
-rw-r--r--src/Tizen.Multimedia/Common/ColorSpace.cs112
-rw-r--r--src/Tizen.Multimedia/Common/Display.cs100
-rw-r--r--src/Tizen.Multimedia/Common/FileFormatException.cs41
-rw-r--r--src/Tizen.Multimedia/Common/IMediaBuffer.cs219
-rw-r--r--src/Tizen.Multimedia/Common/Point.cs76
-rw-r--r--src/Tizen.Multimedia/Common/Range.cs98
-rw-r--r--src/Tizen.Multimedia/Common/Rectangle.cs147
-rw-r--r--src/Tizen.Multimedia/Common/Size.cs72
-rw-r--r--src/Tizen.Multimedia/Common/Visibility.cs33
-rw-r--r--src/Tizen.Multimedia/Interop/Interop.Device.cs53
-rw-r--r--src/Tizen.Multimedia/Interop/Interop.EvasObject.cs18
-rw-r--r--src/Tizen.Multimedia/Interop/Interop.Libc.cs25
-rw-r--r--src/Tizen.Multimedia/Interop/Interop.Libraries.cs28
-rw-r--r--src/Tizen.Multimedia/Interop/Interop.MediaTool.cs157
-rw-r--r--src/Tizen.Multimedia/Interop/Interop.StreamPolicy.cs56
-rw-r--r--src/Tizen.Multimedia/Interop/Interop.Volume.cs32
-rwxr-xr-xsrc/Tizen.Multimedia/MediaTool/MediaFormat.cs808
-rw-r--r--src/Tizen.Multimedia/MediaTool/MediaFormatAacType.cs37
-rwxr-xr-xsrc/Tizen.Multimedia/MediaTool/MediaFormatMimeType.cs372
-rwxr-xr-xsrc/Tizen.Multimedia/MediaTool/MediaFormatTextType.cs39
-rw-r--r--src/Tizen.Multimedia/MediaTool/MediaPacket.cs744
-rw-r--r--src/Tizen.Multimedia/MediaTool/MediaPacketBuffer.cs172
-rw-r--r--src/Tizen.Multimedia/MediaTool/MediaPacketBufferFlags.cs45
-rw-r--r--src/Tizen.Multimedia/MediaTool/MediaPacketVideoPlane.cs93
-rwxr-xr-xsrc/Tizen.Multimedia/MediaView/MediaView.cs22
-rw-r--r--src/Tizen.Multimedia/Tizen.Multimedia.csproj15
-rwxr-xr-xsrc/Tizen.Network.Bluetooth/Interop/Interop.Bluetooth.cs597
-rw-r--r--src/Tizen.Network.Bluetooth/Interop/Interop.Glib.cs30
-rw-r--r--src/Tizen.Network.Bluetooth/Interop/Interop.Libc.cs27
-rw-r--r--src/Tizen.Network.Bluetooth/Interop/Interop.Libraries.cs25
-rw-r--r--src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth.csproj16
-rw-r--r--src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAdapter.cs459
-rw-r--r--src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAdapterImpl.cs636
-rw-r--r--src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAudio.cs99
-rw-r--r--src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAudioImpl.cs174
-rw-r--r--src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAvrcp.cs240
-rw-r--r--src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAvrcpImpl.cs419
-rwxr-xr-xsrc/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothData.cs499
-rw-r--r--src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothDevice.cs677
-rwxr-xr-xsrc/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothEnumerations.cs1202
-rw-r--r--src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothError.cs103
-rwxr-xr-xsrc/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothEventArgs.cs1044
-rwxr-xr-xsrc/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothGatt.cs928
-rwxr-xr-xsrc/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothGattImpl.cs707
-rw-r--r--src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothHid.cs75
-rw-r--r--src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothHidImpl.cs148
-rw-r--r--src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothLeAdapter.cs774
-rwxr-xr-xsrc/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothLeAdapterImpl.cs452
-rw-r--r--src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothProfile.cs28
-rwxr-xr-xsrc/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothServerSocket.cs145
-rwxr-xr-xsrc/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothSocket.cs255
-rwxr-xr-xsrc/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothStructs.cs390
-rwxr-xr-xsrc/Tizen.Network.Connection/Interop/Interop.Connection.cs337
-rw-r--r--src/Tizen.Network.Connection/Interop/Interop.Libraries.cs30
-rw-r--r--src/Tizen.Network.Connection/Tizen.Network.Connection.csproj15
-rwxr-xr-xsrc/Tizen.Network.Connection/Tizen.Network.Connection/CellularProfile.cs399
-rwxr-xr-xsrc/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionError.cs93
-rwxr-xr-xsrc/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionInternalManager.cs945
-rwxr-xr-xsrc/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionManager.cs628
-rwxr-xr-xsrc/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionProfile.cs450
-rwxr-xr-xsrc/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionProfileManager.cs268
-rwxr-xr-xsrc/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionTypes.cs284
-rwxr-xr-xsrc/Tizen.Network.Connection/Tizen.Network.Connection/IAddressInformation.cs383
-rwxr-xr-xsrc/Tizen.Network.Connection/Tizen.Network.Connection/WiFiProfile.cs247
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Interop/Interop.IoTConnectivity.Client.cs244
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Interop/Interop.IoTConnectivity.Common.cs368
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Interop/Interop.IoTConnectivity.Server.cs169
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Interop/Interop.Libraries.cs25
-rw-r--r--src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity.csproj15
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/Attributes.cs860
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/CacheUpdatedEventArgs.cs37
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/DeviceInformationFoundEventArgs.cs70
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/FindingError.cs74
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/FindingErrorOccurredEventArgs.cs44
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/IoTConnectivityClientManager.cs966
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/IoTConnectivityErrorFactory.cs103
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/IoTConnectivityServerManager.cs315
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/LiteResource.cs179
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/NamespaceDoc.cs12
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ObservePolicy.cs37
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ObserveType.cs45
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ObserverNotifiedEventArgs.cs44
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/PlatformInformationFoundEventArgs.cs119
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/PresenceEventType.cs42
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/PresenceReceivedEventArgs.cs58
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/QualityOfService.cs37
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/RemoteResource.cs893
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/RemoteResponse.cs50
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/Representation.cs362
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/Request.cs103
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/Resource.cs510
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResourceFoundEventArgs.cs54
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResourceInterfaces.cs312
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResourceOptions.cs474
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResourcePolicy.cs64
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResourceQuery.cs563
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResourceState.cs37
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResourceTypes.cs268
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/Response.cs148
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResponseCode.cs62
-rwxr-xr-xsrc/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/StateChangedEventArgs.cs37
-rw-r--r--src/Tizen.Network.Nfc/Interop/Interop.Glib.cs30
-rw-r--r--src/Tizen.Network.Nfc/Interop/Interop.Libc.cs27
-rw-r--r--src/Tizen.Network.Nfc/Interop/Interop.Libraries.cs25
-rw-r--r--src/Tizen.Network.Nfc/Interop/Interop.Nfc.cs281
-rw-r--r--src/Tizen.Network.Nfc/Tizen.Network.Nfc.csproj15
-rwxr-xr-xsrc/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcCallbackData.cs114
-rwxr-xr-xsrc/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcCardEmulationAdapter.cs464
-rw-r--r--src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcEnumerations.cs441
-rw-r--r--src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcErrorFactory.cs90
-rw-r--r--src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcEventArgs.cs320
-rwxr-xr-xsrc/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcManager.cs429
-rw-r--r--src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcManagerEvent.cs139
-rwxr-xr-xsrc/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcManagerImpl.cs271
-rwxr-xr-xsrc/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcNdefMessage.cs207
-rwxr-xr-xsrc/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcNdefRecord.cs322
-rwxr-xr-xsrc/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcP2p.cs181
-rwxr-xr-xsrc/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcP2pAdapter.cs126
-rw-r--r--src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcSecureElement.cs85
-rwxr-xr-xsrc/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcTag.cs293
-rwxr-xr-xsrc/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcTagAdapter.cs126
-rw-r--r--src/Tizen.Network.Smartcard/Interop/Interop.Glib.cs30
-rw-r--r--src/Tizen.Network.Smartcard/Interop/Interop.Libc.cs27
-rw-r--r--src/Tizen.Network.Smartcard/Interop/Interop.Libraries.cs25
-rw-r--r--src/Tizen.Network.Smartcard/Interop/Interop.Smartcard.cs83
-rw-r--r--src/Tizen.Network.Smartcard/Tizen.Network.Smartcard.csproj15
-rw-r--r--src/Tizen.Network.Smartcard/Tizen.Network.Smartcard/SmartcardChannel.cs252
-rw-r--r--src/Tizen.Network.Smartcard/Tizen.Network.Smartcard/SmartcardErrorFactory.cs74
-rwxr-xr-xsrc/Tizen.Network.Smartcard/Tizen.Network.Smartcard/SmartcardManager.cs47
-rwxr-xr-xsrc/Tizen.Network.Smartcard/Tizen.Network.Smartcard/SmartcardManagerImpl.cs121
-rw-r--r--src/Tizen.Network.Smartcard/Tizen.Network.Smartcard/SmartcardReader.cs155
-rw-r--r--src/Tizen.Network.Smartcard/Tizen.Network.Smartcard/SmartcardSession.cs242
-rwxr-xr-xsrc/Tizen.Network.WiFi/Interop/Interop.Libraries.cs25
-rwxr-xr-xsrc/Tizen.Network.WiFi/Interop/Interop.WiFi.cs331
-rw-r--r--src/Tizen.Network.WiFi/Tizen.Network.WiFi.csproj14
-rwxr-xr-xsrc/Tizen.Network.WiFi/Tizen.Network.WiFi/ConnectionStateChangedEventArgs.cs60
-rw-r--r--src/Tizen.Network.WiFi/Tizen.Network.WiFi/DeviceStateChangedEventArgs.cs46
-rwxr-xr-xsrc/Tizen.Network.WiFi/Tizen.Network.WiFi/IWiFiEap.cs45
-rwxr-xr-xsrc/Tizen.Network.WiFi/Tizen.Network.WiFi/RssiLevelChangedEventArgs.cs46
-rwxr-xr-xsrc/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiAP.cs524
-rwxr-xr-xsrc/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiAddressInformation.cs271
-rwxr-xr-xsrc/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiConfiguration.cs232
-rwxr-xr-xsrc/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiEap.cs325
-rwxr-xr-xsrc/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiEapConfiguration.cs266
-rwxr-xr-xsrc/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiEnumerations.cs198
-rwxr-xr-xsrc/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiErrorFactory.cs100
-rwxr-xr-xsrc/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiManager.cs378
-rwxr-xr-xsrc/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiManagerImpl.cs434
-rwxr-xr-xsrc/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiNetwork.cs336
-rwxr-xr-xsrc/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiNetworkChange.cs234
-rwxr-xr-xsrc/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiSecurity.cs174
-rw-r--r--src/Tizen.Network.WiFiDirect/Interop/Interop.Libraries.cs25
-rw-r--r--src/Tizen.Network.WiFiDirect/Interop/Interop.WiFiDirect.cs231
-rw-r--r--src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect.csproj19
-rw-r--r--src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/NamespaceDoc.cs7
-rw-r--r--src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectData.cs160
-rw-r--r--src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectEnumerations.cs649
-rw-r--r--src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectError.cs65
-rw-r--r--src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectEventArgs.cs382
-rw-r--r--src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectManager.cs1628
-rw-r--r--src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectManagerImpl.cs1248
-rw-r--r--src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectPeer.cs754
-rw-r--r--src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectPersistentGroup.cs57
-rw-r--r--src/Tizen.Security.SecureRepository/Interop/Interop.CkmcErrors.cs46
-rw-r--r--src/Tizen.Security.SecureRepository/Interop/Interop.CkmcManager.cs140
-rw-r--r--src/Tizen.Security.SecureRepository/Interop/Interop.CkmcTypes.cs214
-rw-r--r--src/Tizen.Security.SecureRepository/Interop/Interop.Libraries.cs23
-rw-r--r--src/Tizen.Security.SecureRepository/NamespaceDoc.cs41
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository.csproj15
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Certificate.cs129
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/CertificateManager.cs306
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/AesCbcCipherParameters.cs34
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/AesCfbCipherParameters.cs34
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/AesCipherParameters.cs44
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/AesCtrCipherParameters.cs57
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/AesGcmCipherParameters.cs73
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/Cipher.cs158
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/CipherAlgorithmType.cs67
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/CipherParameterName.cs51
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/CipherParameters.cs77
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/DsaSignatureParameters.cs33
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/EcdsaSignatureParameters.cs33
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/HashAlgorithm.cs46
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/RsaOaepCipherParameters.cs34
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/RsaPaddingAlgorithm.cs38
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/RsaSignatureParameters.cs44
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/SafeCipherParametersHandle.cs113
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/Signature.cs184
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/SignatureAlgorithmType.cs38
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/SignatureParameterName.cs38
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/SignatureParameters.cs73
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/DataFormat.cs39
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/DataManager.cs130
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/EllipticCurveType.cs38
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Key.cs120
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/KeyManager.cs304
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/KeyType.cs58
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Manager.cs114
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/OcspStatus.cs68
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Permission.cs39
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/PinnedObject.cs56
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Pkcs12.cs192
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Pkcs12Manager.cs125
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Policy.cs75
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/SafeAliasListHandle.cs45
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/SafeCertificateListHandle.cs102
-rw-r--r--src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/SafeRawBufferHandle.cs62
-rw-r--r--src/Tizen.Security.TEEC/.gitignore1
-rw-r--r--src/Tizen.Security.TEEC/Interop/Interop.Errors.cs39
-rw-r--r--src/Tizen.Security.TEEC/Interop/Interop.Libraries.cs23
-rw-r--r--src/Tizen.Security.TEEC/Interop/Interop.Libteec.cs130
-rw-r--r--src/Tizen.Security.TEEC/Interop/Interop.Types.cs79
-rw-r--r--src/Tizen.Security.TEEC/Tizen.Security.TEEC.csproj15
-rw-r--r--src/Tizen.Security.TEEC/Tizen.Security.TEEC/Libteec.cs608
-rw-r--r--src/Tizen.Security.TEEC/Tizen.Security.TEEC/NamespaceDoc.cs78
-rw-r--r--src/Tizen.Security/.gitignore2
-rw-r--r--src/Tizen.Security/Interop/Interop.Libraries.cs23
-rwxr-xr-xsrc/Tizen.Security/Interop/Interop.Privilege.cs46
-rw-r--r--src/Tizen.Security/Tizen.Security.csproj14
-rwxr-xr-xsrc/Tizen.Security/Tizen.Security/Privilege.cs205
-rw-r--r--src/Tizen.Sensor/Interop/Interop.Libraries.cs24
-rw-r--r--src/Tizen.Sensor/Interop/Interop.Sensor.cs136
-rw-r--r--src/Tizen.Sensor/Tizen.Sensor.csproj16
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/EventArgs/AccelerometerDataUpdatedEventArgs.cs54
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/EventArgs/FaceDownGestureDetectorDataUpdatedEventArgs.cs38
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/EventArgs/GravitySensorDataUpdatedEventArgs.cs54
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/EventArgs/GyroscopeDataUpdatedEventArgs.cs54
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/EventArgs/GyroscopeRotationVectorSensorDataUpdatedEventArgs.cs70
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/EventArgs/HeartRateMonitorDataUpdatedEventArgs.cs38
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/EventArgs/HumiditySensorDataUpdatedEventArgs.cs38
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/EventArgs/InVehicleActivityDetectorDataUpdatedEventArgs.cs38
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/EventArgs/LightSensorDataUpdatedEventArgs.cs38
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/EventArgs/LinearAccelerationSensorDataUpdatedEventArgs.cs54
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/EventArgs/MagnetometerDataUpdatedEventArgs.cs54
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/EventArgs/MagnetometerRotationVectorSensorDataUpdatedEventArgs.cs70
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/EventArgs/OrientationSensorDataUpdatedEventArgs.cs54
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/EventArgs/PedometerDataUpdatedEventArgs.cs94
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/EventArgs/PickUpGestureDetectorDataUpdatedEventArgs.cs38
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/EventArgs/PressureSensorDataUpdatedEventArgs.cs38
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/EventArgs/ProximitySensorDataUpdatedEventArgs.cs38
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/EventArgs/RotationVectorSensorDataUpdatedEventArgs.cs70
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/EventArgs/RunningActivityDetectorDataUpdatedEventArgs.cs38
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/EventArgs/SensorAccuracyChangedEventArgs.cs46
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/EventArgs/SleepMonitorDataUpdatedEventArgs.cs38
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/EventArgs/StationaryActivityDetectorDataUpdatedEventArgs.cs38
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/EventArgs/TemperatureSensorDataUpdatedEventArgs.cs38
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/EventArgs/UltravioletSensorDataUpdatedEventArgs.cs38
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/EventArgs/UncalibratedGyroscopeDataUpdatedEventArgs.cs78
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/EventArgs/UncalibratedMagnetometerDataUpdatedEventArgs.cs78
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/EventArgs/WalkingActivityDetectorDataUpdatedEventArgs.cs38
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/EventArgs/WristUpGestureDetectorDataUpdatedEventArgs.cs38
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/Plugins/Accelerometer.cs152
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/Plugins/ActivityDetector.cs49
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/Plugins/FaceDownGestureDetector.cs136
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/Plugins/GravitySensor.cs205
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/Plugins/Gyroscope.cs153
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/Plugins/GyroscopeRotationVectorSensor.cs169
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/Plugins/HeartRateMonitor.cs139
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/Plugins/HumiditySensor.cs137
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/Plugins/InVehicleActivityDetector.cs138
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/Plugins/LightSensor.cs137
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/Plugins/LinearAccelerationSensor.cs205
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/Plugins/Magnetometer.cs205
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/Plugins/MagnetometerRotationVectorSensor.cs234
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/Plugins/OrientationSensor.cs205
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/Plugins/Pedometer.cs196
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/Plugins/PickUpGestureDetector.cs148
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/Plugins/PressureSensor.cs138
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/Plugins/ProximitySensor.cs137
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/Plugins/RotationVectorSensor.cs222
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/Plugins/RunningActivityDetector.cs138
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/Plugins/SleepMonitor.cs141
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/Plugins/StationaryActivityDetector.cs138
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/Plugins/TemperatureSensor.cs138
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/Plugins/UltravioletSensor.cs138
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/Plugins/UncalibratedGyroscope.cs177
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/Plugins/UncalibratedMagnetometer.cs229
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/Plugins/WalkingActivityDetector.cs138
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/Plugins/WristUpGestureDetector.cs136
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/Sensor.cs533
-rwxr-xr-xsrc/Tizen.Sensor/Tizen.Sensor/SensorEnumerations.cs322
-rw-r--r--src/Tizen.Sensor/Tizen.Sensor/SensorErrorFactory.cs62
-rw-r--r--src/Tizen.System.Feedback/Feedback/Feedback.cs375
-rw-r--r--src/Tizen.System.Feedback/Feedback/FeedbackPattern.cs33
-rw-r--r--src/Tizen.System.Feedback/Feedback/FeedbackType.cs41
-rw-r--r--src/Tizen.System.Feedback/Interop/Interop.Feedback.cs59
-rw-r--r--src/Tizen.System.Feedback/Interop/Interop.Libraries.cs23
-rw-r--r--src/Tizen.System.Feedback/Tizen.System.Feedback.csproj15
-rw-r--r--src/Tizen.System.Information/Interop/Interop.Libraries.cs24
-rw-r--r--src/Tizen.System.Information/Interop/Interop.RuntimeInfo.cs104
-rw-r--r--src/Tizen.System.Information/Interop/Interop.SystemInfo.cs79
-rwxr-xr-xsrc/Tizen.System.Information/RuntimeInfo/CpuUsage.cs77
-rwxr-xr-xsrc/Tizen.System.Information/RuntimeInfo/Enumerations.cs143
-rwxr-xr-xsrc/Tizen.System.Information/RuntimeInfo/MemoryInformation.cs107
-rwxr-xr-xsrc/Tizen.System.Information/RuntimeInfo/RuntimeInfoErrorFactory.cs75
-rwxr-xr-xsrc/Tizen.System.Information/RuntimeInfo/RuntimeInformation.cs891
-rwxr-xr-xsrc/Tizen.System.Information/RuntimeInfo/RuntimeKeyStatusChangedEventArgs.cs35
-rwxr-xr-xsrc/Tizen.System.Information/SystemInfo/SystemInfo.cs272
-rw-r--r--src/Tizen.System.Information/Tizen.System.Information.csproj14
-rwxr-xr-xsrc/Tizen.System.MediaKey/Interop/Interop.Libraries.cs23
-rwxr-xr-xsrc/Tizen.System.MediaKey/Interop/Interop.MediaKey.cs60
-rw-r--r--src/Tizen.System.MediaKey/Tizen.System.MediaKey.csproj14
-rwxr-xr-xsrc/Tizen.System.MediaKey/Tizen.System/MediaKey.cs176
-rw-r--r--src/Tizen.System.Storage/Interop/Interop.Libraries.cs23
-rw-r--r--src/Tizen.System.Storage/Interop/Interop.Storage.cs96
-rw-r--r--src/Tizen.System.Storage/Storage/DirectoryType.cs71
-rw-r--r--src/Tizen.System.Storage/Storage/Storage.cs224
-rw-r--r--src/Tizen.System.Storage/Storage/StorageArea.cs36
-rw-r--r--src/Tizen.System.Storage/Storage/StorageManager.cs53
-rw-r--r--src/Tizen.System.Storage/Storage/StorageState.cs46
-rw-r--r--src/Tizen.System.Storage/Tizen.System.Storage.csproj14
-rw-r--r--src/Tizen.System.SystemSettings/Interop/Interop.SystemSettings.cs52
-rw-r--r--src/Tizen.System.SystemSettings/Tizen.System.SystemSettings.csproj14
-rwxr-xr-xsrc/Tizen.System.SystemSettings/Tizen.System.SystemSettings/SystemSettings.cs1929
-rwxr-xr-xsrc/Tizen.System.SystemSettings/Tizen.System.SystemSettings/SystemSettingsEnums.cs216
-rwxr-xr-xsrc/Tizen.System.SystemSettings/Tizen.System.SystemSettings/SystemSettingsEventArgs.cs712
-rw-r--r--src/Tizen.System.SystemSettings/Tizen.System.SystemSettings/SystemSettingsExceptionFactory.cs61
-rwxr-xr-xsrc/Tizen.System/Device/Battery.cs339
-rw-r--r--src/Tizen.System/Device/DeviceEventArgs.cs86
-rw-r--r--src/Tizen.System/Device/DeviceExceptionFactory.cs73
-rw-r--r--src/Tizen.System/Device/Display.cs255
-rw-r--r--src/Tizen.System/Device/Haptic.cs202
-rw-r--r--src/Tizen.System/Device/IR.cs89
-rw-r--r--src/Tizen.System/Device/Led.cs220
-rw-r--r--src/Tizen.System/Device/Power.cs78
-rw-r--r--src/Tizen.System/Interop/Interop.Device.cs101
-rw-r--r--src/Tizen.System/Interop/Interop.Libraries.cs23
-rw-r--r--src/Tizen.System/Tizen.System.csproj15
-rwxr-xr-xsrc/Tizen.Telephony/Interop/Interop.Call.cs87
-rwxr-xr-xsrc/Tizen.Telephony/Interop/Interop.Libraries.cs29
-rwxr-xr-xsrc/Tizen.Telephony/Interop/Interop.Modem.cs39
-rwxr-xr-xsrc/Tizen.Telephony/Interop/Interop.Network.cs90
-rwxr-xr-xsrc/Tizen.Telephony/Interop/Interop.Sim.cs66
-rwxr-xr-xsrc/Tizen.Telephony/Interop/Interop.Telephony.cs78
-rw-r--r--src/Tizen.Telephony/Tizen.Telephony.csproj14
-rw-r--r--src/Tizen.Telephony/Tizen.Telephony/Call.cs124
-rw-r--r--src/Tizen.Telephony/Tizen.Telephony/CallHandle.cs257
-rw-r--r--src/Tizen.Telephony/Tizen.Telephony/ChangeNotificationEventArgs.cs319
-rw-r--r--src/Tizen.Telephony/Tizen.Telephony/ExceptionFactory.cs77
-rw-r--r--src/Tizen.Telephony/Tizen.Telephony/Modem.cs154
-rw-r--r--src/Tizen.Telephony/Tizen.Telephony/Network.cs831
-rw-r--r--src/Tizen.Telephony/Tizen.Telephony/Sim.cs465
-rw-r--r--src/Tizen.Telephony/Tizen.Telephony/SlotHandle.cs309
-rw-r--r--src/Tizen.Telephony/Tizen.Telephony/StateEventArgs.cs40
-rw-r--r--src/Tizen.Telephony/Tizen.Telephony/Telephony.cs241
-rwxr-xr-xsrc/Tizen.Tracer/Interop/Interop.Libraries.cs15
-rwxr-xr-xsrc/Tizen.Tracer/Interop/Interop.Tracer.cs31
-rw-r--r--src/Tizen.Tracer/Tizen.Tracer.csproj14
-rwxr-xr-xsrc/Tizen.Tracer/Tizen/Tracer.cs95
-rwxr-xr-xsrc/Tizen.Uix.InputMethodManager/Interop/Interop.InputMethodManager.cs58
-rwxr-xr-xsrc/Tizen.Uix.InputMethodManager/Interop/Interop.Libraries.cs30
-rw-r--r--src/Tizen.Uix.InputMethodManager/Tizen.Uix.InputMethodManager.csproj14
-rwxr-xr-xsrc/Tizen.Uix.InputMethodManager/Tizen.Uix.InputMethodManager/InputMethodManager.cs158
-rwxr-xr-xsrc/Tizen.Uix.InputMethodManager/Tizen.Uix.InputMethodManager/InputMethodManagerExceptionFactory.cs64
-rwxr-xr-xsrc/Tizen.Uix.Stt/Interop/Interop.Libraries.cs30
-rwxr-xr-xsrc/Tizen.Uix.Stt/Interop/Interop.Stt.cs188
-rw-r--r--src/Tizen.Uix.Stt/Tizen.Uix.Stt.csproj14
-rwxr-xr-xsrc/Tizen.Uix.Stt/Tizen.Uix.Stt/DefaultLanguageChangedEventArgs.cs53
-rwxr-xr-xsrc/Tizen.Uix.Stt/Tizen.Uix.Stt/EngineChangedEventArgs.cs74
-rwxr-xr-xsrc/Tizen.Uix.Stt/Tizen.Uix.Stt/ErrorOccuredEventArgs.cs193
-rwxr-xr-xsrc/Tizen.Uix.Stt/Tizen.Uix.Stt/ExceptionFactory.cs151
-rwxr-xr-xsrc/Tizen.Uix.Stt/Tizen.Uix.Stt/RecognitionResultEventArgs.cs149
-rwxr-xr-xsrc/Tizen.Uix.Stt/Tizen.Uix.Stt/ResultTime.cs87
-rwxr-xr-xsrc/Tizen.Uix.Stt/Tizen.Uix.Stt/StateChangedEventArgs.cs51
-rw-r--r--src/Tizen.Uix.Stt/Tizen.Uix.Stt/SttClient.cs1519
-rwxr-xr-xsrc/Tizen.Uix.Stt/Tizen.Uix.Stt/SupportedEngine.cs64
-rwxr-xr-xsrc/Tizen.Uix.Tts/Interop/Interop.Libraries.cs29
-rwxr-xr-xsrc/Tizen.Uix.Tts/Interop/Interop.Tts.cs172
-rw-r--r--src/Tizen.Uix.Tts/Tizen.Uix.Tts.csproj14
-rwxr-xr-xsrc/Tizen.Uix.Tts/Tizen.Uix.Tts/DefaultVoiceChangedEventArgs.cs52
-rwxr-xr-xsrc/Tizen.Uix.Tts/Tizen.Uix.Tts/EngineChangedEventArgs.cs65
-rwxr-xr-xsrc/Tizen.Uix.Tts/Tizen.Uix.Tts/ErrorOccuredEventArgs.cs161
-rwxr-xr-xsrc/Tizen.Uix.Tts/Tizen.Uix.Tts/ExceptionFactory.cs127
-rwxr-xr-xsrc/Tizen.Uix.Tts/Tizen.Uix.Tts/SpeedRange.cs63
-rwxr-xr-xsrc/Tizen.Uix.Tts/Tizen.Uix.Tts/StateChangedEventArgs.cs52
-rwxr-xr-xsrc/Tizen.Uix.Tts/Tizen.Uix.Tts/SupportedVoice.cs72
-rwxr-xr-xsrc/Tizen.Uix.Tts/Tizen.Uix.Tts/TtsClient.cs1069
-rwxr-xr-xsrc/Tizen.Uix.Tts/Tizen.Uix.Tts/UtteranceEventArgs.cs41
-rwxr-xr-xsrc/Tizen.Uix.VoiceControl/Interop/Interop.Libraries.cs29
-rwxr-xr-xsrc/Tizen.Uix.VoiceControl/Interop/Interop.VoiceControl.cs156
-rwxr-xr-xsrc/Tizen.Uix.VoiceControl/Interop/Interop.VoiceControlCommand.cs169
-rw-r--r--src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl.csproj14
-rwxr-xr-xsrc/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/CurrentLanguageChangedEventArgs.cs51
-rwxr-xr-xsrc/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/ErrorOccuredEventArgs.cs158
-rwxr-xr-xsrc/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/ExceptionFactory.cs148
-rwxr-xr-xsrc/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/RecognitionResult.cs83
-rwxr-xr-xsrc/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/RecognitionResultEventArgs.cs46
-rwxr-xr-xsrc/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/ServiceStateChangedEventArgs.cs51
-rwxr-xr-xsrc/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/StateChangedEventArgs.cs51
-rwxr-xr-xsrc/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/VoiceCommand.cs209
-rwxr-xr-xsrc/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/VoiceCommandList.cs337
-rwxr-xr-xsrc/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/VoiceControlClient.cs958
-rw-r--r--src/Tizen.WebView/Interop/Interop.ChromiumEwk.Context.cs41
-rw-r--r--src/Tizen.WebView/Interop/Interop.ChromiumEwk.CookieManager.cs46
-rw-r--r--src/Tizen.WebView/Interop/Interop.ChromiumEwk.Error.cs49
-rw-r--r--src/Tizen.WebView/Interop/Interop.ChromiumEwk.Settings.cs60
-rw-r--r--src/Tizen.WebView/Interop/Interop.ChromiumEwk.View.cs127
-rw-r--r--src/Tizen.WebView/Interop/Interop.ChromiumEwk.cs29
-rw-r--r--src/Tizen.WebView/Interop/Interop.Elementary.cs37
-rw-r--r--src/Tizen.WebView/Interop/Interop.Evas.cs27
-rw-r--r--src/Tizen.WebView/Interop/Interop.Libraries.cs24
-rw-r--r--src/Tizen.WebView/Tizen.WebView.csproj13
-rw-r--r--src/Tizen.WebView/Tizen.WebView/Chromium.cs39
-rw-r--r--src/Tizen.WebView/Tizen.WebView/Context.cs78
-rw-r--r--src/Tizen.WebView/Tizen.WebView/CookieManager.cs82
-rw-r--r--src/Tizen.WebView/Tizen.WebView/JavaScriptMessage.cs104
-rw-r--r--src/Tizen.WebView/Tizen.WebView/Settings.cs94
-rw-r--r--src/Tizen.WebView/Tizen.WebView/SmartCallbackArgs.cs93
-rw-r--r--src/Tizen.WebView/Tizen.WebView/SmartCallbackLoadErrorArgs.cs150
-rw-r--r--src/Tizen.WebView/Tizen.WebView/WebView.cs342
-rw-r--r--src/Tizen/Interop/Interop.CommonError.cs35
-rw-r--r--src/Tizen/Interop/Interop.Dlog.cs48
-rw-r--r--src/Tizen/Tizen.Common/Color.cs349
-rw-r--r--src/Tizen/Tizen.Internals.Errors/ErrorCode.cs122
-rw-r--r--src/Tizen/Tizen.Internals.Errors/ErrorFacts.cs47
-rw-r--r--src/Tizen/Tizen.csproj9
1280 files changed, 194157 insertions, 0 deletions
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..ed9502e
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,8 @@
+root = true
+
+[*]
+end_of_line = lf
+
+[*.{cs,xaml}]
+indent_style = space
+indent_size = 4
diff --git a/.gitattributes b/.gitattributes
new file mode 100755
index 0000000..8a97853
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,14 @@
+# Set default behaviour, in case users don't have core.autocrlf set.
+* text=auto
+
+# Explicitly declare text files we want to always be normalized and converted
+# to native line endings on checkout.
+*.cs text
+
+# Declare files that will always have CRLF line endings on checkout.
+*.sln text eol=crlf
+
+# Denote all files that are truly binary and should not be modified.
+*.png binary
+*.jpg binary
+*.jpeg binary
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9903f26
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,210 @@
+# Download this file using PowerShell v3 under Windows with the following comand:
+# Invoke-WebRequest https://gist.githubusercontent.com/kmorcinek/2710267/raw/ -OutFile .gitignore
+# or wget:
+# wget --no-check-certificate http://gist.githubusercontent.com/kmorcinek/2710267/raw/.gitignore
+
+# User-specific files
+*.suo
+*.user
+*.sln.docstates
+
+# Build results
+
+[Dd]ebug/
+[Rr]elease/
+x64/
+[Bb]in/
+[Oo]bj/
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+*_i.c
+*_p.c
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.log
+*.scc
+
+# OS generated files #
+.DS_Store*
+Icon?
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opensdf
+*.sdf
+*.cachefile
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+*.ncrunch*
+.*crunch*.local.xml
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.Publish.xml
+
+# Windows Azure Build Output
+csx
+*.build.csdef
+
+# Windows Store app package directory
+AppPackages/
+
+# Others
+*.Cache
+ClientBin/
+[Ss]tyle[Cc]op.*
+~$*
+*~
+*.dbmdl
+*.[Pp]ublish.xml
+*.pfx
+*.publishsettings
+modulesbin/
+tempbin/
+
+# EPiServer Site file (VPP)
+AppData/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file to a newer
+# Visual Studio version. Backup files are not needed, because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# vim
+*.txt~
+*.swp
+*.swo
+
+# svn
+.svn
+
+# Remainings from resolvings conflicts in Source Control
+*.orig
+
+# SQL Server files
+**/App_Data/*.mdf
+**/App_Data/*.ldf
+**/App_Data/*.sdf
+
+
+#LightSwitch generated files
+GeneratedArtifacts/
+_Pvt_Extensions/
+ModelManifest.xml
+
+# =========================
+# Windows detritus
+# =========================
+
+# Windows image file caches
+Thumbs.db
+ehthumbs.db
+
+# Folder config file
+Desktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Mac desktop service store files
+.DS_Store
+
+# SASS Compiler cache
+.sass-cache
+
+# Visual Studio 2014 CTP
+**/*.sln.ide
+
+# Visual Studio temp something
+.vs/
+
+#####
+# End of core ignore list, below put you custom 'per project' settings (patterns or path)
+#####
+
+bin/
+obj/
+*.exe
+*.dll
+*.csproj.user
+*.lock.json
+
+# cscope/ctags
+cscope.files
+cscope.out
+tags
+
+# svace files
+warnings.txt
+warn-settings.csharp.txt
+.svace-dir
+CompilationErrors-*.txt
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..910375e
--- /dev/null
+++ b/README.md
@@ -0,0 +1,2 @@
+# tizenfx
+[WIP] Unified repository for Tizen .NET Device APIs
diff --git a/build/Open.snk b/build/Open.snk
new file mode 100644
index 0000000..4aed427
--- /dev/null
+++ b/build/Open.snk
Binary files differ
diff --git a/build/common.props b/build/common.props
new file mode 100644
index 0000000..2476535
--- /dev/null
+++ b/build/common.props
@@ -0,0 +1,18 @@
+<Project>
+
+ <PropertyGroup>
+ <AllowUnsafeBlocks>True</AllowUnsafeBlocks>
+ <GenerateDocumentationFile>True</GenerateDocumentationFile>
+ </PropertyGroup>
+
+ <PropertyGroup>
+ <SignAssembly>True</SignAssembly>
+ <AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)Open.snk</AssemblyOriginatorKeyFile>
+ <PublicSign Condition="'$(OS)' != 'Windows_NT'">true</PublicSign>
+ </PropertyGroup>
+
+ <Import Project="$(MSBuildThisFileDirectory)version.props" />
+
+ <Import Project="$(MSBuildThisFileDirectory)dependencies.props" />
+
+</Project> \ No newline at end of file
diff --git a/build/common.targets b/build/common.targets
new file mode 100644
index 0000000..4de98b5
--- /dev/null
+++ b/build/common.targets
@@ -0,0 +1,3 @@
+<Project>
+
+</Project> \ No newline at end of file
diff --git a/build/dependencies.props b/build/dependencies.props
new file mode 100644
index 0000000..cbab6eb
--- /dev/null
+++ b/build/dependencies.props
@@ -0,0 +1,7 @@
+<Project>
+
+ <PropertyGroup>
+ <SystemPackageVersion>4.3.0</SystemPackageVersion>
+ </PropertyGroup>
+
+</Project> \ No newline at end of file
diff --git a/build/version.props b/build/version.props
new file mode 100644
index 0000000..9115119
--- /dev/null
+++ b/build/version.props
@@ -0,0 +1,8 @@
+<Project>
+
+ <PropertyGroup>
+ <VersionPrefix>4.0.0</VersionPrefix>
+ <VersionSuffix>preview1</VersionSuffix>
+ </PropertyGroup>
+
+</Project> \ No newline at end of file
diff --git a/pkg/Tizen.NET/Tizen.NET.csproj b/pkg/Tizen.NET/Tizen.NET.csproj
new file mode 100644
index 0000000..b0093e7
--- /dev/null
+++ b/pkg/Tizen.NET/Tizen.NET.csproj
@@ -0,0 +1,42 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <Import Project="../../build/version.props" />
+
+ <PropertyGroup>
+ <Authors>Samsung Electronics</Authors>
+ <Copyright>© Samsung Electronics Co., Ltd All Rights Reserved</Copyright>
+ <PackageProjectUrl>https://www.tizen.org/</PackageProjectUrl>
+ <PackageLicenseUrl>https://www.apache.org/licenses/LICENSE-2.0</PackageLicenseUrl>
+ <PackageIconUrl>https://developer.tizen.org/sites/default/files/images/tizen-pinwheel-on-light-rgb_64_64.png</PackageIconUrl>
+ <Description>A set of Tizen .NET APIs. This includes all of the APIs built on top of Tizen Platform.</Description>
+ </PropertyGroup>
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ <GenerateDependencyFile>false</GenerateDependencyFile>
+ <IncludeBuildOutput>false</IncludeBuildOutput>
+ <NoPackageAnalysis>true</NoPackageAnalysis>
+ <CopyBuildOutputToOutputDirectory>false</CopyBuildOutputToOutputDirectory>
+ <CopyOutputSymbolsToOutputDirectory>false</CopyOutputSymbolsToOutputDirectory>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\..\src\**\*.csproj">
+ <PrivateAssets>all</PrivateAssets>
+ </ProjectReference>
+ </ItemGroup>
+
+ <Target Name="_PackLayout" BeforeTargets="$(GenerateNuspecDependsOn)">
+ <ItemGroup>
+ <Content Include="$(OutputPath)**\*.dll" PackagePath="lib\$(TargetFramework)" />
+ <Content Include="$(OutputPath)**\*.pdb" PackagePath="lib\$(TargetFramework)" />
+ <Content Include="$(OutputPath)**\*.xml" PackagePath="lib\$(TargetFramework)" />
+ </ItemGroup>
+ </Target>
+
+ <Target Name="_GenerateNuspecBuildAfterTarget"
+ AfterTargets="Build"
+ DependsOnTargets="GenerateNuspec">
+ </Target>
+
+</Project>
diff --git a/pkg/descriptions.json b/pkg/descriptions.json
new file mode 100644
index 0000000..80e35e8
--- /dev/null
+++ b/pkg/descriptions.json
@@ -0,0 +1,262 @@
+[
+ {
+ "Name": "ElmSharp",
+ "Description": "ElmSharp is the top-most library based on the Tizen Native UI Framwork (EFL). It provides a variety of pre-built UI components, such as layout objects and widgets, that allow you to build rich graphical user interfaces. This is in the beta stage and will be refined based on developer feedback. Backward compatibility issues may be raised when updating the platform version."
+ },
+ {
+ "Name": "Tizen",
+ "Description": "Provides the basic structures and classes that are used in the other Tizen Device API."
+ },
+ {
+ "Name": "Tizen.Account.AccountManager",
+ "Description": "Account Service APIs for Tizen.Account.AccountManager"
+ },
+ {
+ "Name": "Tizen.Account.FidoClient",
+ "Description": "FIDO UAF API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Account.OAuth2",
+ "Description": "OAuth2.0 API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Applications.Alarm",
+ "Description": "Provides the Application Frameworks API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Applications.Badge",
+ "Description": "Provides the Badge API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Applications.Common",
+ "Description": "Provides the Application Frameworks API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Applications.DataControl",
+ "Description": "Provides the Data Control API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Applications.MessagePort",
+ "Description": "Provides the Application Frameworks API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Applications.Notification",
+ "Description": "Provides the Application Frameworks API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Applications.NotificationEventListener",
+ "Description": "Provides the Application Frameworks API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Applications.PackageManager",
+ "Description": "Provides the Application Frameworks API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Applications.Preference",
+ "Description": "Provides the Application Frameworks API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Applications.RemoteView",
+ "Description": "Provides the Widget Viewer API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Applications.Service",
+ "Description": "Provides the Application Frameworks API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Applications.ToastMessage",
+ "Description": "Provides the Application Frameworks API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Applications.UI",
+ "Description": "Provides the Application Frameworks API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Applications.WidgetApplication",
+ "Description": "Provides the Widget Application API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Applications.WidgetControl",
+ "Description": "Provides the Widget control API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Content.Download",
+ "Description": "Provides the Download API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Content.MediaContent",
+ "Description": "Media Content API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Content.MimeType",
+ "Description": "Provides the MimeType API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Location",
+ "Description": "Provides the Location API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Location.Geofence",
+ "Description": "Geofence management APIs for Tizen.Location"
+ },
+ {
+ "Name": "Tizen.Log",
+ "Description": "Provides functions for sending log output."
+ },
+ {
+ "Name": "Tizen.Maps",
+ "Description": "Map Services API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Messaging",
+ "Description": "Provides the Messaging APIs for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Messaging.Push",
+ "Description": "Push API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Multimedia",
+ "Description": "Common classes and interfaces for the Tizen .NET Multimedia"
+ },
+ {
+ "Name": "Tizen.Multimedia.AudioIO",
+ "Description": "Provides the Multimedia AudioIO API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Multimedia.Camera",
+ "Description": "Provides the Multimedia Camera API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Multimedia.MediaCodec",
+ "Description": "Provides the Multimedia MediaCodec API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Multimedia.MediaPlayer",
+ "Description": "Provides the Multimedia Player API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Multimedia.Metadata",
+ "Description": "Provides the Multimedia Metadata API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Multimedia.Radio",
+ "Description": "Provides the Multimedia Radio API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Multimedia.Recorder",
+ "Description": "Provides the Multimedia Recorder API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Multimedia.Remoting",
+ "Description": "Provides the Multimedia Remoting API(MediaController, ScreenMirroring) for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Multimedia.StreamRecorder",
+ "Description": "Provides the Multimedia StreamRecorder API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Multimedia.Util",
+ "Description": "Provides the Multimedia Util API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Multimedia.Vision",
+ "Description": "Provides the Multimedia Vision API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Network.Bluetooth",
+ "Description": "Provides the Bluetooth API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Network.Connection",
+ "Description": "Provides the Connection APIs for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Network.IoTConnectivity",
+ "Description": "Provides the IoTConnectivity API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Network.Nfc",
+ "Description": "Provides the Nfc API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Network.Smartcard",
+ "Description": "Provides the Smartcard API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Network.WiFi",
+ "Description": "Provides the Wi-Fi APIs for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Network.WiFiDirect",
+ "Description": "Provides the Wi-Fi Direct APIs for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Security",
+ "Description": "Provides the display name or description of privileges."
+ },
+ {
+ "Name": "Tizen.Security.SecureRepository",
+ "Description": "Provides the secure repository protected by Tizen platform for keys, certificates, and sensitive data of users and/or their apps. Additionally, secure cryptographic operations for non-exportable keys without revealing key values to clients are provided."
+ },
+ {
+ "Name": "Tizen.Security.TEEC",
+ "Description": "Security TEEC API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Sensor",
+ "Description": "Provides the classes to control and get data from the sensors supported by the device."
+ },
+ {
+ "Name": "Tizen.System",
+ "Description": "Provide Device API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.System.Feedback",
+ "Description": "Provides the Feedback API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.System.Information",
+ "Description": "Provide classes for SystemInformation and RuntimeInformation APIs"
+ },
+ {
+ "Name": "Tizen.System.MediaKey",
+ "Description": "Provides the MediaKey API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.System.Storage",
+ "Description": "Provide classes for Storage API"
+ },
+ {
+ "Name": "Tizen.System.SystemSettings",
+ "Description": "System Settings API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Telephony",
+ "Description": "Telephony API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Tracer",
+ "Description": "Provides the colllection of event tracing APIs that are used for runtime behavior analysis in Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Uix.InputMethodManager",
+ "Description": "InputMethodManager API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Uix.Stt",
+ "Description": "STT Uix API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Uix.Tts",
+ "Description": "TTS Uix API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.Uix.VoiceControl",
+ "Description": "VoiceControl API for Tizen .NET"
+ },
+ {
+ "Name": "Tizen.WebView",
+ "Description": "Provides the WebView API for Tizen .NET"
+ }
+] \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp.csproj b/src/ElmSharp/ElmSharp.csproj
new file mode 100644
index 0000000..88c3f81
--- /dev/null
+++ b/src/ElmSharp/ElmSharp.csproj
@@ -0,0 +1,9 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/ElmSharp/ElmSharp/AccessRole.cs b/src/ElmSharp/ElmSharp/AccessRole.cs
new file mode 100755
index 0000000..b49b2a2
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/AccessRole.cs
@@ -0,0 +1,438 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+namespace ElmSharp.Accessible
+{
+ /// <summary>
+ /// Enumeration for AccessRole.
+ /// </summary>
+ public enum AccessRole
+ {
+ /// <summary>
+ /// Invalid
+ /// </summary>
+ Invalid,
+ /// <summary>
+ /// AcceleratorLabel role
+ /// </summary>
+ AcceleratorLabel,
+ /// <summary>
+ /// Alert role
+ /// </summary>
+ Alert,
+ /// <summary>
+ /// Animation role
+ /// </summary>
+ Animation,
+ /// <summary>
+ /// Arrow role
+ /// </summary>
+ Arrow,
+ /// <summary>
+ /// Calendar role
+ /// </summary>
+ Calendar,
+ /// <summary>
+ /// Canvas role
+ /// </summary>
+ Canvas,
+ /// <summary>
+ /// CheckBox role
+ /// </summary>
+ CheckBox,
+ /// <summary>
+ /// CheckMenuItem role
+ /// </summary>
+ CheckMenuItem,
+ /// <summary>
+ /// ColorChooser role
+ /// </summary>
+ ColorChooser,
+ /// <summary>
+ /// ColumnHeader role
+ /// </summary>
+ ColumnHeader,
+ /// <summary>
+ /// ComboBox role
+ /// </summary>
+ ComboBox,
+ /// <summary>
+ /// DateEditor role
+ /// </summary>
+ DateEditor,
+ /// <summary>
+ /// DesktopIcon role
+ /// </summary>
+ DesktopIcon,
+ /// <summary>
+ /// DesktopFrame role
+ /// </summary>
+ DesktopFrame,
+ /// <summary>
+ /// Dial role
+ /// </summary>
+ Dial,
+ /// <summary>
+ /// Dialog role
+ /// </summary>
+ Dialog,
+ /// <summary>
+ /// DirectoryPane role
+ /// </summary>
+ DirectoryPane,
+ /// <summary>
+ /// DrawingArea role
+ /// </summary>
+ DrawingArea,
+ /// <summary>
+ /// FileChooser role
+ /// </summary>
+ FileChooser,
+ /// <summary>
+ /// Filler role
+ /// </summary>
+ Filler,
+ /// <summary>
+ /// FocusTraversable role
+ /// </summary>
+ FocusTraversable,
+ /// <summary>
+ /// FontChooser role
+ /// </summary>
+ FontChooser,
+ /// <summary>
+ /// Frame role
+ /// </summary>
+ Frame,
+ /// <summary>
+ /// GlassPane role
+ /// </summary>
+ GlassPane,
+ /// <summary>
+ /// HtmlContainer role
+ /// </summary>
+ HtmlContainer,
+ /// <summary>
+ /// Icon role
+ /// </summary>
+ Icon,
+ /// <summary>
+ /// Image role
+ /// </summary>
+ Image,
+ /// <summary>
+ /// InternalFrame role
+ /// </summary>
+ InternalFrame,
+ /// <summary>
+ /// Label role
+ /// </summary>
+ Label,
+ /// <summary>
+ /// LayeredPane role
+ /// </summary>
+ LayeredPane,
+ /// <summary>
+ /// List role
+ /// </summary>
+ List,
+ /// <summary>
+ /// ListItem role
+ /// </summary>
+ ListItem,
+ /// <summary>
+ /// Menu role
+ /// </summary>
+ Menu,
+ /// <summary>
+ /// MenuBar role
+ /// </summary>
+ MenuBar,
+ /// <summary>
+ /// MenuItem role
+ /// </summary>
+ MenuItem,
+ /// <summary>
+ /// OptionPane role
+ /// </summary>
+ OptionPane,
+ /// <summary>
+ /// PageTab role
+ /// </summary>
+ PageTab,
+ /// <summary>
+ /// PageTabList role
+ /// </summary>
+ PageTabList,
+ /// <summary>
+ /// Panel role
+ /// </summary>
+ Panel,
+ /// <summary>
+ /// PasswordText role
+ /// </summary>
+ PasswordText,
+ /// <summary>
+ /// PopupMenu role
+ /// </summary>
+ PopupMenu,
+ /// <summary>
+ /// ProgressBar role
+ /// </summary>
+ ProgressBar,
+ /// <summary>
+ /// PushButton role
+ /// </summary>
+ PushButton,
+ /// <summary>
+ /// RadioButton role
+ /// </summary>
+ RadioButton,
+ /// <summary>
+ /// RadioMenuItem role
+ /// </summary>
+ RadioMenuItem,
+ /// <summary>
+ /// RootPane role
+ /// </summary>
+ RootPane,
+ /// <summary>
+ /// RowHeader role
+ /// </summary>
+ RowHeader,
+ /// <summary>
+ /// ScrollBar role
+ /// </summary>
+ ScrollBar,
+ /// <summary>
+ /// ScrollPane role
+ /// </summary>
+ ScrollPane,
+ /// <summary>
+ /// Separator role
+ /// </summary>
+ Separator,
+ /// <summary>
+ /// Slider role
+ /// </summary>
+ Slider,
+ /// <summary>
+ /// SpinButton role
+ /// </summary>
+ SpinButton,
+ /// <summary>
+ /// SplitPane role
+ /// </summary>
+ SplitPane,
+ /// <summary>
+ /// StatusBar role
+ /// </summary>
+ StatusBar,
+ /// <summary>
+ /// Table role
+ /// </summary>
+ Table,
+ /// <summary>
+ /// TableCell role
+ /// </summary>
+ TableCell,
+ /// <summary>
+ /// TableColumnHeader role
+ /// </summary>
+ TableColumnHeader,
+ /// <summary>
+ /// TableRowHeader role
+ /// </summary>
+ TableRowHeader,
+ /// <summary>
+ /// TearoffMenuItem role
+ /// </summary>
+ TearoffMenuItem,
+ /// <summary>
+ /// Terminal role
+ /// </summary>
+ Terminal,
+ /// <summary>
+ /// Text role
+ /// </summary>
+ Text,
+ /// <summary>
+ /// ToggleButton role
+ /// </summary>
+ ToggleButton,
+ /// <summary>
+ /// ToolBar role
+ /// </summary>
+ ToolBar,
+ /// <summary>
+ /// ToolTip role
+ /// </summary>
+ ToolTip,
+ /// <summary>
+ /// Tree role
+ /// </summary>
+ Tree,
+ /// <summary>
+ /// TreeTable role
+ /// </summary>
+ TreeTable,
+ /// <summary>
+ /// Unknown
+ /// </summary>
+ Unknown,
+ /// <summary>
+ /// Viewport role
+ /// </summary>
+ Viewport,
+ /// <summary>
+ /// Window role
+ /// </summary>
+ Window,
+ /// <summary>
+ /// Extended role
+ /// </summary>
+ Extended,
+ /// <summary>
+ /// Header role
+ /// </summary>
+ Header,
+ /// <summary>
+ /// Footer role
+ /// </summary>
+ Footer,
+ /// <summary>
+ /// Paragraph
+ /// </summary>
+ Paragraph,
+ /// <summary>
+ /// Ruler role
+ /// </summary>
+ Ruler,
+ /// <summary>
+ /// Application role
+ /// </summary>
+ Application,
+ /// <summary>
+ /// Autocomplete role
+ /// </summary>
+ Autocomplete,
+ /// <summary>
+ /// Editbar role
+ /// </summary>
+ Editbar,
+ /// <summary>
+ /// Embedded role
+ /// </summary>
+ Embedded,
+ /// <summary>
+ /// Entry role
+ /// </summary>
+ Entry,
+ /// <summary>
+ /// Chart role
+ /// </summary>
+ Chart,
+ /// <summary>
+ /// Caption role
+ /// </summary>
+ Caption,
+ /// <summary>
+ /// DocumentFrame role
+ /// </summary>
+ DocumentFrame,
+ /// <summary>
+ /// Heading role
+ /// </summary>
+ Heading,
+ /// <summary>
+ /// Page role
+ /// </summary>
+ Page,
+ /// <summary>
+ /// Section role
+ /// </summary>
+ Section,
+ /// <summary>
+ /// RedundantObject role
+ /// </summary>
+ RedundantObject,
+ /// <summary>
+ /// Form role
+ /// </summary>
+ Form,
+ /// <summary>
+ /// Link role
+ /// </summary>
+ Link,
+ /// <summary>
+ /// InputMethodWindow role
+ /// </summary>
+ InputMethodWindow,
+ /// <summary>
+ /// TableRow role
+ /// </summary>
+ TableRow,
+ /// <summary>
+ /// TreeItem role
+ /// </summary>
+ TreeItem,
+ /// <summary>
+ /// DocumentSpreadsheet role
+ /// </summary>
+ DocumentSpreadsheet,
+ /// <summary>
+ /// DocumentPresentation role
+ /// </summary>
+ DocumentPresentation,
+ /// <summary>
+ /// DocumentText role
+ /// </summary>
+ DocumentText,
+ /// <summary>
+ /// DocumentWeb role
+ /// </summary>
+ DocumentWeb,
+ /// <summary>
+ /// DocumentEmail role
+ /// </summary>
+ DocumentEmail,
+ /// <summary>
+ /// Comment role
+ /// </summary>
+ Comment,
+ /// <summary>
+ /// ListBox role
+ /// </summary>
+ ListBox,
+ /// <summary>
+ /// Grouping role
+ /// </summary>
+ Grouping,
+ /// <summary>
+ /// ImageMap role
+ /// </summary>
+ ImageMap,
+ /// <summary>
+ /// Notification role
+ /// </summary>
+ Notification,
+ /// <summary>
+ /// InfoBar role
+ /// </summary>
+ InfoBar
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/AccessibleObject.cs b/src/ElmSharp/ElmSharp/AccessibleObject.cs
new file mode 100755
index 0000000..08eedcb
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/AccessibleObject.cs
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp.Accessible
+{
+ /// <summary>
+ /// The delegate to define how to provide informations for <see cref="IAccessibleObject.Name"/> or <see cref="IAccessibleObject.Description"/>.
+ /// </summary>
+ /// <param name="obj">The sender obj.</param>
+ /// <returns>Return information for Name or Description.</returns>
+ public delegate string AccessibleInfoProvider (AccessibleObject obj);
+
+ /// <summary>
+ /// It's a base abstract class for <see cref="Widget"/>.
+ /// It provides available definitions for the screen reader, such as <see cref="IAccessibleObject.Name"/>, <see cref="IAccessibleObject.Description"/>, <see cref="IAccessibleObject.ReadingInfoType"/>, etc.
+ /// There's many the relationship between two accessible objects, like <see cref="ChildOf"/>, <see cref="ParentOf"/>, <see cref="FlowsTo"/>, <see cref="FlowsFrom"/>, etc.
+ /// </summary>
+ public abstract class AccessibleObject : EvasObject, IAccessibleObject
+ {
+
+ AccessibleInfoProvider _nameProvider;
+ AccessibleInfoProvider _descriptionProvider;
+
+ Interop.Elementary.Elm_Atspi_Reading_Info_Cb _nameProviderInternal;
+ Interop.Elementary.Elm_Atspi_Reading_Info_Cb _descriptionProviderInternal;
+
+ /// <summary>
+ /// Gets or sets the reading information types of an accessible object.
+ /// </summary>
+ ReadingInfoType IAccessibleObject.ReadingInfoType
+ {
+ get
+ {
+ return (ReadingInfoType)Interop.Elementary.elm_atspi_accessible_reading_info_type_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_atspi_accessible_reading_info_type_set(RealHandle,
+ (Interop.Elementary.Elm_Accessible_Reading_Info_Type)value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the role of the object in accessibility domain.
+ /// </summary>
+ AccessRole IAccessibleObject.Role
+ {
+ get
+ {
+ return (AccessRole)Interop.Elementary.elm_atspi_accessible_role_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_atspi_accessible_role_set(RealHandle,
+ (Interop.Elementary.Elm_Atspi_Role)value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets highlightable of given widget.
+ /// </summary>
+ bool IAccessibleObject.CanHighlight
+ {
+ get
+ {
+ return Interop.Elementary.elm_atspi_accessible_can_highlight_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_atspi_accessible_can_highlight_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the translation domain of "name" and "description" properties.
+ /// Translation domain should be set if application wants to support i18n for accessibily "name" and "description" properties.
+ /// When translation domain is set values of "name" and "description" properties will be translated with dgettext function using current translation domain as "domainname" parameter.
+ /// It is application developer responsibility to ensure that translation files are loaded and binded to translation domain when accessibility is enabled.
+ /// </summary>
+ string IAccessibleObject.TranslationDomain
+ {
+ get
+ {
+ return Interop.Elementary.elm_atspi_accessible_translation_domain_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_atspi_accessible_translation_domain_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets an accessible name of the object.
+ /// </summary>
+ string IAccessibleObject.Name
+ {
+ get
+ {
+ return Interop.Elementary.elm_atspi_accessible_name_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_atspi_accessible_name_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets contextual information about object.
+ /// </summary>
+ string IAccessibleObject.Description
+ {
+ get
+ {
+ return Interop.Elementary.elm_atspi_accessible_description_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_atspi_accessible_description_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the delegate for <see cref="IAccessibleObject.Name"/>.
+ /// </summary>
+ AccessibleInfoProvider IAccessibleObject.NameProvider
+ {
+ get
+ {
+ return _nameProvider;
+ }
+
+ set
+ {
+ if (_nameProviderInternal == null)
+ {
+ _nameProviderInternal = (data, obj) => _nameProvider(this);
+ }
+ if (value == null)
+ {
+ _nameProvider = null;
+ Interop.Elementary.elm_atspi_accessible_name_cb_set(RealHandle, null, IntPtr.Zero);
+ }
+ else
+ {
+ _nameProvider = new AccessibleInfoProvider(value);
+ Interop.Elementary.elm_atspi_accessible_name_cb_set(RealHandle, _nameProviderInternal, IntPtr.Zero);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the delegate for <see cref = "IAccessibleObject.Description" />.
+ /// </summary>
+ AccessibleInfoProvider IAccessibleObject.DescriptionProvider
+ {
+ get
+ {
+ return _descriptionProvider;
+ }
+
+ set
+ {
+ if (_descriptionProviderInternal == null)
+ {
+ _descriptionProviderInternal = (data, obj) => _descriptionProvider(this);
+ }
+ if (value == null)
+ {
+ _descriptionProvider = null;
+ Interop.Elementary.elm_atspi_accessible_description_cb_set(RealHandle, null, IntPtr.Zero);
+ }
+ else
+ {
+ _descriptionProvider = new AccessibleInfoProvider(value);
+ Interop.Elementary.elm_atspi_accessible_description_cb_set(RealHandle, _descriptionProviderInternal, IntPtr.Zero);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Creates and initializes a new instance of the AccessibleObject class with parent EvasObject class parameter.
+ /// </summary>
+ /// <param name="parent">Parent EvasObject class </param>
+ public AccessibleObject(EvasObject parent) : base(parent)
+ {
+ }
+
+ /// <summary>
+ /// Creates and initializes a new instance of the AccessibleObject class.
+ /// </summary>
+ public AccessibleObject() : base()
+ {
+ }
+
+ /// <summary>
+ /// Defines the relationship between two accessible objects.
+ /// Relationships can be queried by Assistive Technology clients to provide customized feedback, improving overall user experience.
+ /// AppendRelation API is asymmetric, which means that appending, for example, relation <see cref="FlowsTo"/> from object A to B, do not append relation <see cref="FlowsFrom"/> from object B to object A.
+ /// </summary>
+ /// <param name="relation">The relationship between source object and target object of a given type.</param>
+ void IAccessibleObject.AppendRelation(IAccessibleRelation relation)
+ {
+ if (relation.Target == null) throw new ArgumentException("Target of Accessibility relation can not be null");
+ Interop.Elementary.elm_atspi_accessible_relationship_append(RealHandle, relation.Type, relation.Target.Handle);
+ }
+
+ /// <summary>
+ /// Removes the relationship between two accessible objects.
+ /// </summary>
+ /// <param name="relation">The relationship between source object and target object of a given type.</param>
+ void IAccessibleObject.RemoveRelation(IAccessibleRelation relation)
+ {
+ if (relation.Target == null) throw new ArgumentException("Target of Accessibility relation can not be null");
+ Interop.Elementary.elm_atspi_accessible_relationship_remove(RealHandle, relation.Type, relation.Target.Handle);
+ }
+
+ /// <summary>
+ /// Highlights accessible widget.
+ /// </summary>
+ public void Highlight()
+ {
+ Interop.Elementary.elm_atspi_component_highlight_grab(RealHandle);
+ }
+
+ /// <summary>
+ /// Clears highlight of accessible widget.
+ /// </summary>
+ public void Unhighlight()
+ {
+ Interop.Elementary.elm_atspi_component_highlight_clear(RealHandle);
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/AccessibleRelation.cs b/src/ElmSharp/ElmSharp/AccessibleRelation.cs
new file mode 100755
index 0000000..4d24e98
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/AccessibleRelation.cs
@@ -0,0 +1,371 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+namespace ElmSharp.Accessible
+{
+ /// <summary>
+ /// IAccessibleRelation is a interface which defines the relationship between two accessible objects.
+ /// </summary>
+ public interface IAccessibleRelation
+ {
+
+ AccessibleObject Target { get; set; }
+ int Type { get; }
+ }
+
+ /// <summary>
+ /// To define label info for accessible object.
+ /// </summary>
+ public class LabelledBy : IAccessibleRelation
+ {
+ /// <summary>
+ /// Gets or sets the target object which is LabelledBy.
+ /// </summary>
+ public AccessibleObject Target { get; set; }
+
+ /// <summary>
+ /// Gets the LabelledBy type.
+ /// </summary>
+ public int Type
+ {
+ get { return (int)Interop.Elementary.Elm_Atspi_Relation_Type.ELM_ATSPI_RELATION_LABELLED_BY; }
+ }
+ }
+
+ /// <summary>
+ /// To define label info for accessible object.
+ /// </summary>
+ public class LabelFor : IAccessibleRelation
+ {
+ /// <summary>
+ /// Gets or sets the target object which is LabelFor.
+ /// </summary>
+ public AccessibleObject Target { get; set; }
+
+ /// <summary>
+ /// Gets the LabelFor type.
+ /// </summary>
+ public int Type
+ {
+ get { return (int)Interop.Elementary.Elm_Atspi_Relation_Type.ELM_ATSPI_RELATION_LABEL_FOR; }
+ }
+ }
+
+ /// <summary>
+ /// To define control relationship for accessible object.
+ /// </summary>
+ public class ControllerFor : IAccessibleRelation
+ {
+ /// <summary>
+ /// Gets or sets the target object which is ControllerFor.
+ /// </summary>
+ public AccessibleObject Target { get; set; }
+
+ /// <summary>
+ /// Gets the ControllerFor type.
+ /// </summary>
+ public int Type
+ {
+ get { return (int)Interop.Elementary.Elm_Atspi_Relation_Type.ELM_ATSPI_RELATION_CONTROLLER_FOR; }
+ }
+ }
+
+ /// <summary>
+ /// To define control relationship for accessible object.
+ /// </summary>
+ public class ControlledBy : IAccessibleRelation
+ {
+ /// <summary>
+ /// Gets or sets the target object which is ControlledBy.
+ /// </summary>
+ public AccessibleObject Target { get; set; }
+
+ /// <summary>
+ /// Gets the ControlledBy type.
+ /// </summary>
+ public int Type
+ {
+ get { return (int)Interop.Elementary.Elm_Atspi_Relation_Type.ELM_ATSPI_RELATION_CONTROLLED_BY; }
+ }
+ }
+
+ /// <summary>
+ /// To define member relationship for accessible object.
+ /// </summary>
+ public class MemberOf : IAccessibleRelation
+ {
+ /// <summary>
+ /// Gets or sets the target object which is MemberOf.
+ /// </summary>
+ public AccessibleObject Target { get; set; }
+
+ /// <summary>
+ /// Gets the MemberOf type.
+ /// </summary>
+ public int Type
+ {
+ get { return (int)Interop.Elementary.Elm_Atspi_Relation_Type.ELM_ATSPI_RELATION_MEMBER_OF; }
+ }
+ }
+
+ /// <summary>
+ /// To define tooltip for accessible object.
+ /// </summary>
+ public class TooltipFor : IAccessibleRelation
+ {
+ /// <summary>
+ /// Gets or sets the target object which is TooltipFor.
+ /// </summary>
+ public AccessibleObject Target { get; set; }
+
+ /// <summary>
+ /// Gets the TooltipFor type.
+ /// </summary>
+ public int Type
+ {
+ get { return (int)Interop.Elementary.Elm_Atspi_Relation_Type.ELM_ATSPI_RELATION_TOOLTIP_FOR; }
+ }
+ }
+
+ /// <summary>
+ /// To define child for accessible object.
+ /// </summary>
+ public class ChildOf : IAccessibleRelation
+ {
+ /// <summary>
+ /// Gets or sets the target object which is ChildOf.
+ /// </summary>
+ public AccessibleObject Target { get; set; }
+
+ /// <summary>
+ /// Gets the ChildOf type.
+ /// </summary>
+ public int Type
+ {
+ get { return (int)Interop.Elementary.Elm_Atspi_Relation_Type.ELM_ATSPI_RELATION_NODE_CHILD_OF; }
+ }
+ }
+
+ /// <summary>
+ /// To define parent for accessible object.
+ /// </summary>
+ public class ParentOf : IAccessibleRelation
+ {
+ /// <summary>
+ /// Gets or sets the target object which is ParentOf.
+ /// </summary>
+ public AccessibleObject Target { get; set; }
+
+ /// <summary>
+ /// Gets the ParentOf type.
+ /// </summary>
+ public int Type
+ {
+ get { return (int)Interop.Elementary.Elm_Atspi_Relation_Type.ELM_ATSPI_RELATION_NODE_PARENT_OF; }
+ }
+ }
+
+ /// <summary>
+ /// To define extend for accessible object.
+ /// </summary>
+ public class Extended : IAccessibleRelation
+ {
+ /// <summary>
+ /// Gets or sets the target object which is Extended.
+ /// </summary>
+ public AccessibleObject Target { get; set; }
+
+ /// <summary>
+ /// Gets the Extended type.
+ /// </summary>
+ public int Type
+ {
+ get { return (int)Interop.Elementary.Elm_Atspi_Relation_Type.ELM_ATSPI_RELATION_EXTENDED; }
+ }
+ }
+
+ /// <summary>
+ /// To define the custom reading order.
+ /// </summary>
+ public class FlowsTo : IAccessibleRelation
+ {
+ /// <summary>
+ /// Gets or sets the target object which is FlowsTo.
+ /// </summary>
+ public AccessibleObject Target { get; set; }
+
+ /// <summary>
+ /// Gets the FlowsTo type.
+ /// </summary>
+ public int Type
+ {
+ get { return (int)Interop.Elementary.Elm_Atspi_Relation_Type.ELM_ATSPI_RELATION_FLOWS_TO; }
+ }
+ }
+
+ /// <summary>
+ /// To define the custom reading order.
+ /// </summary>
+ public class FlowsFrom : IAccessibleRelation
+ {
+ /// <summary>
+ /// Gets or sets the target object which is FlowsFrom.
+ /// </summary>
+ public AccessibleObject Target { get; set; }
+
+ /// <summary>
+ /// Gets the FlowsFrom type.
+ /// </summary>
+ public int Type
+ {
+ get { return (int)Interop.Elementary.Elm_Atspi_Relation_Type.ELM_ATSPI_RELATION_FLOWS_FROM; }
+ }
+ }
+
+ /// <summary>
+ /// To define subwindow for accessible object.
+ /// </summary>
+ public class SubwindowOf : IAccessibleRelation
+ {
+ /// <summary>
+ /// Gets or sets the target object which is SubwindowOf.
+ /// </summary>
+ public AccessibleObject Target { get; set; }
+
+ /// <summary>
+ /// Gets the SubwindowOf type.
+ /// </summary>
+ public int Type
+ {
+ get { return (int)Interop.Elementary.Elm_Atspi_Relation_Type.ELM_ATSPI_RELATION_SUBWINDOW_OF; }
+ }
+ }
+
+ /// <summary>
+ /// To define embed for accessible object.
+ /// </summary>
+ public class Embeds : IAccessibleRelation
+ {
+ /// <summary>
+ /// Gets or sets the target object which is Embeds.
+ /// </summary>
+ public AccessibleObject Target { get; set; }
+
+ /// <summary>
+ /// Gets the Embeds type.
+ /// </summary>
+ public int Type
+ {
+ get { return (int)Interop.Elementary.Elm_Atspi_Relation_Type.ELM_ATSPI_RELATION_EMBEDS; }
+ }
+ }
+
+ /// <summary>
+ /// To define embed for accessible object.
+ /// </summary>
+ public class EmbeddedBy : IAccessibleRelation
+ {
+ /// <summary>
+ /// Gets or sets the target object which is EmbeddedBy.
+ /// </summary>
+ public AccessibleObject Target { get; set; }
+
+ /// <summary>
+ /// Gets the EmbeddedBy type.
+ /// </summary>
+ public int Type
+ {
+ get { return (int)Interop.Elementary.Elm_Atspi_Relation_Type.ELM_ATSPI_RELATION_EMBEDDED_BY; }
+ }
+ }
+
+ /// <summary>
+ /// To define popup for accessible object.
+ /// </summary>
+ public class PopupFor : IAccessibleRelation
+ {
+ /// <summary>
+ /// Gets or sets the target object which is PopupFor.
+ /// </summary>
+ public AccessibleObject Target { get; set; }
+
+ /// <summary>
+ /// Gets the PopupFor type.
+ /// </summary>
+ public int Type
+ {
+ get { return (int)Interop.Elementary.Elm_Atspi_Relation_Type.ELM_ATSPI_RELATION_POPUP_FOR; }
+ }
+ }
+
+ /// <summary>
+ /// To define parent window for accessible object.
+ /// </summary>
+ public class ParentWindowOf : IAccessibleRelation
+ {
+ /// <summary>
+ /// Gets or sets the target object which is ParentWindowOf.
+ /// </summary>
+ public AccessibleObject Target { get; set; }
+
+ /// <summary>
+ /// Gets the ParentWindowOf type.
+ /// </summary>
+ public int Type
+ {
+ get { return (int)Interop.Elementary.Elm_Atspi_Relation_Type.ELM_ATSPI_RELATION_PARENT_WINDOW_OF; }
+ }
+ }
+
+ /// <summary>
+ /// To define description for accessible object.
+ /// </summary>
+ public class DescriptionFor : IAccessibleRelation
+ {
+ /// <summary>
+ /// Gets or sets the target object which is DescriptionFor.
+ /// </summary>
+ public AccessibleObject Target { get; set; }
+
+ /// <summary>
+ /// Gets the DescriptionFor type.
+ /// </summary>
+ public int Type
+ {
+ get { return (int)Interop.Elementary.Elm_Atspi_Relation_Type.ELM_ATSPI_RELATION_DESCRIPTION_FOR; }
+ }
+ }
+
+ /// <summary>
+ /// To define description for accessible object.
+ /// </summary>
+ public class DescribedBy : IAccessibleRelation
+ {
+ /// <summary>
+ /// Gets or sets the target object which is DescribedBy.
+ /// </summary>
+ public AccessibleObject Target { get; set; }
+
+ /// <summary>
+ /// Gets the DescribedBy type.
+ /// </summary>
+ public int Type
+ {
+ get { return (int)Interop.Elementary.Elm_Atspi_Relation_Type.ELM_ATSPI_RELATION_DESCRIBED_BY; }
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/AccessibleUtil.cs b/src/ElmSharp/ElmSharp/AccessibleUtil.cs
new file mode 100755
index 0000000..720fca4
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/AccessibleUtil.cs
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+
+namespace ElmSharp.Accessible
+{
+ /// <summary>
+ /// Enumeration for ReadingStatus.
+ /// </summary>
+ public enum ReadingStatus
+ {
+ /// <summary>
+ /// Unknown status
+ /// </summary>
+ Unknown,
+ /// <summary>
+ /// Cancelled status
+ /// </summary>
+ Cancelled,
+ /// <summary>
+ /// Stopped status
+ /// </summary>
+ Stoppped,
+ /// <summary>
+ /// Skipped status
+ /// </summary>
+ Skipped
+ }
+
+ /// <summary>
+ /// AccessibleUtil provides a method to set the reading information.
+ /// </summary>
+ public static class AccessibleUtil
+ {
+
+ static void AtspiSignalCallback(IntPtr data, string say_signal)
+ {
+ GCHandle gch = GCHandle.FromIntPtr(data);
+ TaskCompletionSource<ReadingStatus> tcs = (TaskCompletionSource<ReadingStatus>) gch.Target;
+ if (say_signal.Equals("ReadingCancelled"))
+ {
+ tcs.SetResult(ReadingStatus.Cancelled);
+ }
+ else if (say_signal.Equals("ReadingStopped"))
+ {
+ tcs.SetResult(ReadingStatus.Stoppped);
+ }
+ else if (say_signal.Equals("ReadingSkipped"))
+ {
+ tcs.SetResult(ReadingStatus.Skipped);
+ }
+ else
+ {
+ tcs.SetException(new InvalidOperationException("unknown signal : " + say_signal));
+ }
+
+ gch.Free();
+ }
+
+ /// <summary>
+ /// Reads given text by screen reader.
+ /// </summary>
+ /// <param name="text">The reading text.</param>
+ /// <param name="discardable">If true, reading can be discarded by subsequent reading requests, if false the reading must finish before next reading request can be started.</param>
+ /// <returns>Return a task with reading status.</returns>
+ public static Task<ReadingStatus> Say(string text, bool discardable)
+ {
+ var tcs = new TaskCompletionSource<ReadingStatus>();
+ GCHandle gch = GCHandle.Alloc(tcs);
+ Interop.Elementary.elm_atspi_bridge_utils_say(text, discardable, AtspiSignalCallback, GCHandle.ToIntPtr(gch));
+ return tcs.Task;
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/Background.cs b/src/ElmSharp/ElmSharp/Background.cs
new file mode 100644
index 0000000..e5348b0
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Background.cs
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The Background is a widget that use for setting (solid) background decorations to a window (unless it has transparency enabled)
+ /// or to any container object.
+ /// </summary>
+ public class Background : Layout
+ {
+ /// <summary>
+ /// Creates and initializes a new instance of the Background class.
+ /// </summary>
+ /// <param name="parent">The EvasObject to which the new Background will be attached as a child.</param>
+ public Background(EvasObject parent) : base(parent)
+ {
+ Style = "transparent";
+ }
+
+ /// <summary>
+ /// Sets or gets color to Background.
+ /// </summary>
+ public override Color Color
+ {
+ get
+ {
+ int r = 0;
+ int g = 0;
+ int b = 0;
+ int a = 0;
+ var swallowContent = GetPartContent("elm.swallow.rectangle");
+ if (swallowContent != IntPtr.Zero)
+ {
+ Interop.Evas.evas_object_color_get(swallowContent, out r, out g, out b, out a);
+ }
+ return new Color(r, g, b, a);
+ }
+ set
+ {
+ var swallowContent = GetPartContent("elm.swallow.rectangle");
+ if (swallowContent == IntPtr.Zero)
+ {
+ Interop.Elementary.elm_bg_color_set(RealHandle, value.R, value.G, value.B);
+ swallowContent = GetPartContent("elm.swallow.rectangle");
+ }
+ Interop.Evas.evas_object_color_set(swallowContent, value.R, value.G, value.B, value.A);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets image to Background.
+ /// </summary>
+ public string File
+ {
+ get
+ {
+ return Interop.Elementary.BackgroundFileGet(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_bg_file_set(RealHandle, value, IntPtr.Zero);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the mode of display for a given background widget's image.
+ /// </summary>
+ /// <remarks>
+ /// This sets how the background widget will display its image.
+ /// This will only work if the File was previously set with an image file on obj.
+ /// The image can be display tiled, scaled, centered or stretched. scaled by default.
+ /// </remarks>
+ public BackgroundOptions BackgroundOption
+ {
+ get
+ {
+ return (BackgroundOptions)Interop.Elementary.elm_bg_option_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_bg_option_set(RealHandle, (Interop.Elementary.BackgroundOptions)value);
+ }
+ }
+
+ /// <summary>
+ /// Set the size of the pixmap representation of the image set on a given background widget.
+ /// This method just makes sense if an image file was set.
+ /// This is just a hint for the underlying system.
+ /// The real size of the pixmap may differ depending on the type of image being loaded, being bigger than requested.
+ /// </summary>
+ /// <param name="w">The new width of the image pixmap representation.</param>
+ /// <param name="h">The new height of the image pixmap representation.</param>
+ public void SetFileLoadSize(int w, int h)
+ {
+ if (File != null)
+ {
+ Interop.Elementary.elm_bg_load_size_set(RealHandle, w, h);
+ }
+ else
+ {
+ throw new Exception("This method just makes sense if an image file was set.");
+ }
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ IntPtr handle = Interop.Elementary.elm_layout_add(parent.Handle);
+ Interop.Elementary.elm_layout_theme_set(handle, "layout", "elm_widget", "default");
+
+ RealHandle = Interop.Elementary.elm_bg_add(handle);
+ Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
+
+ return handle;
+ }
+ }
+
+ /// <summary>
+ /// Enumeration for the background type.
+ /// </summary>
+ public enum BackgroundOptions
+ {
+ /// <summary>
+ /// Centers the background image
+ /// </summary>
+ Center,
+
+ /// <summary>
+ /// Scales the background image, retaining the aspect ratio
+ /// </summary>
+ Scale,
+
+ /// <summary>
+ /// Stretches the background image to fill the UI component's area.
+ /// </summary>
+ Stretch,
+
+ /// <summary>
+ /// Tiles the background image at its original size
+ /// </summary>
+ Tile
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/Box.cs b/src/ElmSharp/ElmSharp/Box.cs
new file mode 100644
index 0000000..3436c64
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Box.cs
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The Box is a container used to arranges UI components in a linear order.
+ /// </summary>
+ public class Box : Container
+ {
+ private Interop.Elementary.BoxLayoutCallback _layoutCallback;
+
+ /// <summary>
+ /// Creates and initializes a new instance of the Box class.
+ /// </summary>
+ /// <param name="parent">The EvasObject to which the new Box will be attached as a child.</param>
+ public Box(EvasObject parent) : base(parent)
+ {
+ }
+
+ /// <summary>
+ /// Sets or gets IsHorizontal value which describe pack direction, vertical is default.
+ /// </summary>
+ public bool IsHorizontal
+ {
+ get
+ {
+ return Interop.Elementary.elm_box_horizontal_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_box_horizontal_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets whether the box to arrange its children homogeneously.
+ /// </summary>
+ public bool IsHomogeneous
+ {
+ get
+ {
+ return Interop.Elementary.elm_box_homogeneous_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_box_homogeneous_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Adds an object at the end of the pack list.
+ /// </summary>
+ /// <remarks>
+ /// Packs "content" object into the Box, placing it last in the list of children objects.
+ /// The actual position the object will get on screen depends on the layout used.
+ /// If no custom layout is set, it will be at the bottom or right,
+ /// depending if the Box is vertical or horizontal, respectively.
+ /// </remarks>
+ /// <param name="content">The oject be packed</param>
+ public void PackEnd(EvasObject content)
+ {
+ Interop.Elementary.elm_box_pack_end(RealHandle, content);
+ AddChild(content);
+ }
+
+ /// <summary>
+ /// Adds an "content" object to the beginning of the pack list.
+ /// </summary>
+ /// <remarks>
+ /// Pack "content" object into the Box obj, placing it first in the list of children objects.
+ /// The actual position the object will get on screen depends on the layout used.
+ /// If no custom layout is set, it will be at the top or left,
+ /// depending if the Box is vertical or horizontal, respectively.
+ /// </remarks>
+ /// <param name="content">The object to be packed.</param>
+ public void PackStart(EvasObject content)
+ {
+ Interop.Elementary.elm_box_pack_start(RealHandle, content);
+ AddChild(content);
+ }
+
+ /// <summary>
+ /// Adds an "content "object to the Box after the "after" object.
+ /// </summary>
+ /// <remarks>
+ /// This will add the "content" to the Box indicated after the object indicated with "after".
+ /// If "after" is not already in the Box, results are undefined.
+ /// After means either to the right of the "after" object or below it depending on orientation.
+ /// </remarks>
+ /// <param name="content">The object will be added in Box</param>
+ /// <param name="after">The object has been added in Box</param>
+ public void PackAfter(EvasObject content, EvasObject after)
+ {
+ Interop.Elementary.elm_box_pack_after(RealHandle, content, after);
+ AddChild(content);
+ }
+
+ /// <summary>
+ /// Adds an "content "object to the Box before the "before" object.
+ /// </summary>
+ /// <remarks>
+ /// This will add the "content" to the Box indicated before the object indicated with "before".
+ /// If "before" is not already in the Box, results are undefined.
+ /// before means either to the left of the "before" object or below it depending on orientation.
+ /// </remarks>
+ /// <param name="content">The object will be added in Box</param>
+ /// <param name="before">The object has been added in Box</param>
+ public void PackBefore(EvasObject content, EvasObject before)
+ {
+ Interop.Elementary.elm_box_pack_before(RealHandle, content, before);
+ AddChild(content);
+ }
+
+ /// <summary>
+ /// Remove the "content" oject from Box without deleting it.
+ /// </summary>
+ /// <param name="content">The object to unpack</param>
+ public void UnPack(EvasObject content)
+ {
+ Interop.Elementary.elm_box_unpack(RealHandle, content);
+ RemoveChild(content);
+ }
+
+ /// <summary>
+ /// Removes all objects from Box container.
+ /// </summary>
+ public void UnPackAll()
+ {
+ Interop.Elementary.elm_box_unpack_all(RealHandle);
+ ClearChildren();
+ }
+
+ /// <summary>
+ /// Whenever anything changes that requires the Box in obj to recalculate the size and position of its elements,
+ /// the function cb will be called to determine what the layout of the children will be.
+ /// </summary>
+ /// <param name="action">The callback function used for layout </param>
+ public void SetLayoutCallback(Action action)
+ {
+ _layoutCallback = (obj, priv, data) =>
+ {
+ action();
+ };
+ Interop.Elementary.elm_box_layout_set(RealHandle, _layoutCallback, IntPtr.Zero, null);
+ }
+
+ /// <summary>
+ /// Sets the color of exact part to Box's layout parent.
+ /// </summary>
+ /// <param name="part">The name of part class, it could be 'bg', 'elm.swllow.content'.</param>
+ /// <param name="color">The color value.</param>
+ public override void SetPartColor(string part, Color color)
+ {
+ Interop.Elementary.elm_object_color_class_color_set(Handle, part, color.R * color.A / 255,
+ color.G * color.A / 255,
+ color.B * color.A / 255,
+ color.A);
+ }
+
+ /// <summary>
+ /// Gets the color of exact part of Box's layout parent.
+ /// </summary>
+ /// <param name="part">The name of part class, it could be 'bg', 'elm.swllow.content'.</param>
+ /// <returns></returns>
+ public override Color GetPartColor(string part)
+ {
+ int r, g, b, a;
+ Interop.Elementary.elm_object_color_class_color_get(Handle, part, out r, out g, out b, out a);
+ return new Color((int)(r / (a / 255.0)), (int)(g / (a / 255.0)), (int)(b / (a / 255.0)), a);
+ }
+
+ /// <summary>
+ /// Force the box to recalculate its children packing.
+ /// If any children was added or removed, box will not calculate the values immediately rather leaving it to the next main loop iteration.
+ /// While this is great as it would save lots of recalculation, whenever you need to get the position of a just added item you must force recalculate before doing so.
+ /// </summary>
+ public void Recalculate()
+ {
+ Interop.Elementary.elm_box_recalculate(RealHandle);
+ }
+
+ /// <summary>
+ /// Clear the box of all children.
+ /// Remove all the elements contained by the box, deleting the respective objects.
+ /// </summary>
+ public void Clear()
+ {
+ Interop.Elementary.elm_box_clear(RealHandle);
+ ClearChildren();
+ }
+
+ /// <summary>
+ /// Sets or gets the alignment of the whole bounding box of contents.
+ /// </summary>
+ /// <param name="horizontal">Horizontal alignment</param>
+ /// <param name="vertical">Vertical alignment</param>
+ public void SetBoxAlignment(double horizontal, double vertical)
+ {
+ Interop.Elementary.elm_box_align_set(RealHandle, horizontal, vertical);
+ }
+
+ /// <summary>
+ /// Sets or gets the space(padding) between the box's elements.
+ /// </summary>
+ /// <param name="horizontal">Horizontal padding</param>
+ /// <param name="vertical">vertical padding</param>
+ public void SetPadding(int horizontal, int vertical)
+ {
+ Interop.Elementary.elm_box_padding_set(RealHandle, horizontal, vertical);
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ IntPtr handle = Interop.Elementary.elm_layout_add(parent.Handle);
+ Interop.Elementary.elm_layout_theme_set(handle, "layout", "background", "default");
+
+ RealHandle = Interop.Elementary.elm_box_add(handle);
+ Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
+
+ return handle;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/Button.cs b/src/ElmSharp/ElmSharp/Button.cs
new file mode 100644
index 0000000..3ed6aa8
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Button.cs
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The Button is a widget works as a clickable input element to trigger events.
+ /// </summary>
+ public class Button : Layout
+ {
+ private SmartEvent _clicked;
+ private SmartEvent _repeated;
+ private SmartEvent _pressed;
+ private SmartEvent _released;
+
+ /// <summary>
+ /// Creates and initializes a new instance of the Button class.
+ /// </summary>
+ /// <param name="parent">
+ /// The EvasObject to which the new Button will be attached as a child.
+ /// </param>
+ public Button(EvasObject parent) : base(parent)
+ {
+ _clicked = new SmartEvent(this, this.RealHandle, "clicked");
+ _repeated = new SmartEvent(this, this.RealHandle, "repeated");
+ _pressed = new SmartEvent(this, this.RealHandle, "pressed");
+ _released = new SmartEvent(this, this.RealHandle, "unpressed");
+
+ _clicked.On += (sender, e) =>
+ {
+ Clicked?.Invoke(this, EventArgs.Empty);
+ };
+
+ _repeated.On += (sender, e) =>
+ {
+ Repeated?.Invoke(this, EventArgs.Empty);
+ };
+
+ _pressed.On += (sender, e) =>
+ {
+ Pressed?.Invoke(this, EventArgs.Empty);
+ };
+
+ _released.On += (sender, e) =>
+ {
+ Released?.Invoke(this, EventArgs.Empty);
+ };
+ }
+
+ /// <summary>
+ /// Clicked will be triggered when Button is clicked.
+ /// </summary>
+ public event EventHandler Clicked;
+
+ /// <summary>
+ /// Repeated will be triggered when Button is pressed without releasing it.
+ /// </summary>
+ public event EventHandler Repeated;
+
+ /// <summary>
+ /// Pressed will be triggered when the Button is pressed.
+ /// </summary>
+ public event EventHandler Pressed;
+
+ /// <summary>
+ /// Released will be triggered when the Button is released after being pressed.
+ /// </summary>
+ public event EventHandler Released;
+
+ /// <summary>
+ /// Sets or gets the autorepeat feature of a given Button.
+ /// </summary>
+ /// <remarks>
+ /// Autorepeat feature means autorepeat event generated when the button is kept pressed.
+ /// When set AutoRepeat to false, no autorepeat is performed and buttons will trigger Clicked event when they are clicked.
+ /// When set to true, keeping a button pressed continuously trigger Repeated event until the button is released.
+ /// The time it takes until it starts triggering Repeated is given by AutoRepeatInitialTime,
+ /// and the time between each new emission is given by AutoRepeatGapTimeout.
+ /// </remarks>
+ public bool AutoRepeat
+ {
+ get
+ {
+ return !Interop.Elementary.elm_button_autorepeat_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_button_autorepeat_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the initial timeout before the Repeat event is generated.
+ /// </summary>
+ public double AutoRepeatInitialTime
+ {
+ get
+ {
+ return Interop.Elementary.elm_button_autorepeat_initial_timeout_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_button_autorepeat_initial_timeout_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the interval between each generated Repeat event.
+ /// </summary>
+ public double AutoRepeatGapTimeout
+ {
+ get
+ {
+ return Interop.Elementary.elm_button_autorepeat_gap_timeout_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_button_autorepeat_gap_timeout_set(RealHandle, value);
+ }
+ }
+
+ [Obsolete("DeleteColorClass is obsolete, please use EdjeObject.DeleteColorClass(string)")]
+ public void DeleteColorClass(string part)
+ {
+ Interop.Elementary.edje_object_color_class_del(Handle, part);
+ }
+
+ /// <summary>
+ /// Sets or gets the BackgroundColor of a given Button in normal and pressed status.
+ /// </summary>
+ public override Color BackgroundColor
+ {
+ set
+ {
+ if (value.IsDefault)
+ {
+ EdjeObject.DeleteColorClass("button/bg");
+ EdjeObject.DeleteColorClass("button/bg_pressed");
+ EdjeObject.DeleteColorClass("button/bg_disabled");
+ }
+ else
+ {
+ SetPartColor("bg", value);
+ SetPartColor("bg_pressed", value);
+ SetPartColor("bg_disabled", value);
+ }
+ _backgroundColor = value;
+ }
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ IntPtr handle = Interop.Elementary.elm_layout_add(parent.Handle);
+ Interop.Elementary.elm_layout_theme_set(handle, "layout", "elm_widget", "default");
+
+ RealHandle = Interop.Elementary.elm_button_add(handle);
+ Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
+
+ return handle;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/Calendar.cs b/src/ElmSharp/ElmSharp/Calendar.cs
new file mode 100755
index 0000000..ef87281
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Calendar.cs
@@ -0,0 +1,479 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// Enumeration for event periodicity, used to define if a mark should be repeated beyond event's day. It's set when a mark is added.
+ /// </summary>
+ public enum CalendarMarkRepeatType
+ {
+ /// <summary>
+ /// Default value. Marks will be displayed only on event day.
+ /// </summary>
+ Unique,
+
+ /// <summary>
+ /// Marks will be displayed every day after event day.
+ /// </summary>
+ Daily,
+
+ /// <summary>
+ /// Marks will be displayed every week after event day.
+ /// </summary>
+ Weekly,
+
+ /// <summary>
+ /// Marks will be displayed every month day that coincides to event day.
+ /// </summary>
+ Monthly,
+
+ /// <summary>
+ /// Marks will be displayed every year that coincides to event day.
+ /// </summary>
+ Annually,
+
+ /// <summary>
+ /// Marks will be displayed every last day of month after event day.
+ /// </summary>
+ LastDayOfMonth
+ }
+
+ /// <summary>
+ /// Enumeration for the mode, which determine how user could select a day.
+ /// </summary>
+ public enum CalendarSelectMode
+ {
+ /// <summary>
+ /// Default value. a day is always selected.
+ /// </summary>
+ Default,
+
+ /// <summary>
+ /// A day is always selected.
+ /// </summary>
+ Always,
+
+ /// <summary>
+ /// None of the days can be selected.
+ /// </summary>
+ None,
+
+ /// <summary>
+ /// User may have selected a day or not.
+ /// </summary>
+ OnDemand
+ }
+
+ /// <summary>
+ /// Enumeration used to define which fields of a tm struct will be taken into account
+ /// </summary>
+ [Flags]
+ public enum CalendarSelectable
+ {
+ /// <summary>
+ /// None will be taken into account
+ /// </summary>
+ None = 0,
+ /// <summary>
+ /// Year will be taken into account
+ /// </summary>
+ Year = 1 << 0,
+ /// <summary>
+ /// Month will be taken into account
+ /// </summary>
+ Month = 1 << 1,
+ /// <summary>
+ /// Day will be taken into account
+ /// </summary>
+ Day = 1 << 2
+ }
+
+ /// <summary>
+ /// The CalendarMark is a Item for marking a Calendar's type,date and repeat type.
+ /// </summary>
+ public class CalendarMark
+ {
+ internal IntPtr Handle;
+
+ /// <summary>
+ /// A string used to define the type of mark.
+ /// </summary>
+ public string Type;
+
+ /// <summary>
+ /// A time struct to represent the date of inclusion of the mark.
+ /// </summary>
+ public DateTime Date;
+
+ /// <summary>
+ /// Repeat the event following this periodicity.
+ /// </summary>
+ public CalendarMarkRepeatType Repeat;
+
+ /// <summary>
+ /// Creates and initializes a new instance of the CalendarMark class.
+ /// </summary>
+ /// <param name="type">Type of mark</param>
+ /// <param name="date">Date of inclusion of the mark</param>
+ /// <param name="repeat">Repeat type</param>
+ public CalendarMark(string type, DateTime date, CalendarMarkRepeatType repeat)
+ {
+ Handle = IntPtr.Zero;
+ Type = type;
+ Date = date;
+ Repeat = repeat;
+ }
+ }
+
+ /// <summary>
+ /// The Calendar is a widget that helps applications to flexibly display a calender with day of the week, date, year and month.
+ /// </summary>
+ public class Calendar : Layout
+ {
+ SmartEvent _changed;
+ DateTime _cacheSelectedDate;
+ SmartEvent _displayedMonthChanged;
+ int _cacheDisplayedMonth;
+
+ Interop.Elementary.Elm_Calendar_Format_Cb _calendarFormat;
+ DateFormatDelegate _dateFormatDelegate = null;
+
+ /// <summary>
+ /// Creates and initializes a new instance of the Calendar class.
+ /// </summary>
+ /// <param name="parent">
+ /// The EvasObject to which the new Calendar will be attached as a child.
+ /// </param>
+ public Calendar(EvasObject parent) : base(parent)
+ {
+ _changed = new SmartEvent(this, this.RealHandle, "changed");
+ _changed.On += (sender, e) =>
+ {
+ DateTime selectedDate = SelectedDate;
+ DateChanged?.Invoke(this, new DateChangedEventArgs(_cacheSelectedDate, selectedDate));
+ _cacheSelectedDate = selectedDate;
+ };
+
+ _displayedMonthChanged = new SmartEvent(this, this.RealHandle, "display,changed");
+ _displayedMonthChanged.On += (sender, e) =>
+ {
+ int currentDisplayedMonth = DisplayedTime.Month;
+ DisplayedMonthChanged?.Invoke(this, new DisplayedMonthChangedEventArgs(_cacheDisplayedMonth, currentDisplayedMonth));
+ _cacheDisplayedMonth = currentDisplayedMonth;
+ };
+
+ _calendarFormat = (t) => { return _dateFormatDelegate(t); };
+ }
+
+ /// <summary>
+ /// DateChanged will be triggered when the date in the calendar is changed.
+ /// </summary>
+ public event EventHandler<DateChangedEventArgs> DateChanged;
+
+ /// <summary>
+ /// DisplayedMonthChanged will be triggered when the current month displayed in the calendar is changed.
+ /// </summary>
+ public event EventHandler<DisplayedMonthChangedEventArgs> DisplayedMonthChanged;
+
+ /// <summary>
+ /// This delegate type is used to format the string that will be used to display month and year.
+ /// </summary>
+ /// <param name="time">DateTime</param>
+ /// <returns></returns>
+ public delegate string DateFormatDelegate(DateTime time);
+
+ /// <summary>
+ /// Sets or gets the minimum for year.
+ /// </summary>
+ public int MinimumYear
+ {
+ get
+ {
+ int minimumYear;
+ int unused;
+ Interop.Elementary.elm_calendar_min_max_year_get(RealHandle, out minimumYear, out unused);
+ return minimumYear;
+ }
+ set
+ {
+ int maximumYear;
+ int unused;
+ Interop.Elementary.elm_calendar_min_max_year_get(RealHandle, out unused, out maximumYear);
+ if (maximumYear < 1902)
+ {
+ maximumYear = DateTime.MaxValue.Year;
+ }
+ Interop.Elementary.elm_calendar_min_max_year_set(RealHandle, value, maximumYear);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the maximum for the year.
+ /// </summary>
+ public int MaximumYear
+ {
+ get
+ {
+ int maximumYear;
+ int unused;
+ Interop.Elementary.elm_calendar_min_max_year_get(RealHandle, out unused, out maximumYear);
+ return maximumYear;
+ }
+ set
+ {
+ int minimumYear;
+ int unused;
+ Interop.Elementary.elm_calendar_min_max_year_get(RealHandle, out minimumYear, out unused);
+ Interop.Elementary.elm_calendar_min_max_year_set(RealHandle, minimumYear, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the first day of week, who are used on Calendar.
+ /// </summary>
+ public DateTime DisplayedTime
+ {
+ get
+ {
+ var tm = new Interop.Libc.SystemTime();
+ Interop.Elementary.elm_calendar_displayed_time_get(RealHandle, out tm);
+ ///TODO
+ ///If the defect is fixed, it will be removed.
+ var daysInMonth = DateTime.DaysInMonth(tm.tm_year + 1900, tm.tm_mon + 1);
+ var day = tm.tm_mday;
+
+ if (day > daysInMonth)
+ {
+ day = daysInMonth;
+ }
+
+ DateTime date = new DateTime(tm.tm_year + 1900, tm.tm_mon + 1, day, tm.tm_hour, tm.tm_min, tm.tm_sec);
+
+ return date;
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the first day of week, who are used on Calendar.
+ /// </summary>
+ public DayOfWeek FirstDayOfWeek
+ {
+ get
+ {
+ return (DayOfWeek)Interop.Elementary.elm_calendar_first_day_of_week_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_calendar_first_day_of_week_set(RealHandle, (int)value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the weekdays names to be displayed by the Calendar.
+ /// </summary>
+ /// <remarks>
+ /// The usage should be like this;
+ /// List<string> weekDayNames = new List<string>() { "S", "M", "T", "W", "T", "F", "S" };
+ /// Calendar.WeekDayNames = weekDayNames;
+ /// </remarks>
+ public IReadOnlyList<string> WeekDayNames
+ {
+ get
+ {
+ IntPtr stringArrayPtr = Interop.Elementary.elm_calendar_weekdays_names_get(RealHandle);
+ string[] stringArray;
+ IntPtrToStringArray(stringArrayPtr, 7, out stringArray);
+ return stringArray;
+ }
+ set
+ {
+ if (value != null && value.Count == 7)
+ {
+ Interop.Elementary.elm_calendar_weekdays_names_set(RealHandle, value.ToArray());
+ }
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the selected date.
+ /// </summary>
+ /// <remarks>
+ /// Selected date changes when the user goes to next/previous month or select a day pressing over it on calendar.
+ /// </remarks>
+ public DateTime SelectedDate
+ {
+ get
+ {
+ var tm = new Interop.Libc.SystemTime();
+ Interop.Elementary.elm_calendar_selected_time_get(RealHandle, ref tm);
+ if (tm.tm_year == 0 && tm.tm_mon == 0 && tm.tm_mday == 0)
+ {
+ return DateTime.Now;
+ }
+ return tm;
+ }
+ set
+ {
+ Interop.Libc.SystemTime tm = value;
+ Interop.Elementary.elm_calendar_selected_time_set(RealHandle, ref tm);
+ _cacheSelectedDate = value;
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the interval on time updates for an user mouse button
+ /// hold on calendar widgets' month/year selection.
+ /// </summary>
+ public double Interval
+ {
+ get
+ {
+ return Interop.Elementary.elm_calendar_interval_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_calendar_interval_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the select day mode used.
+ /// </summary>
+ public CalendarSelectMode SelectMode
+ {
+ get
+ {
+ return (CalendarSelectMode)Interop.Elementary.elm_calendar_select_mode_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_calendar_select_mode_set(RealHandle, (Interop.Elementary.Elm_Calendar_Select_Mode)value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets fields of a datetime will be taken into account, when SelectedDate set is invoked.
+ /// </summary>
+ public CalendarSelectable Selectable
+ {
+ get
+ {
+ return (CalendarSelectable)Interop.Elementary.elm_calendar_selectable_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_calendar_selectable_set(RealHandle, (int)value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets date format the string that will be used to display month and year.
+ /// By default it uses strftime with "%B %Y" format string.
+ /// It should allocate the memory that will be used by the string, that will be freed by the widget after usage.A pointer to the string and a pointer to the time struct will be provided.
+ /// </summary>
+ public DateFormatDelegate DateFormat
+ {
+ get
+ {
+ return _dateFormatDelegate;
+ }
+ set
+ {
+ _dateFormatDelegate = value;
+ if (value != null)
+ {
+ Interop.Elementary.elm_calendar_format_function_set(RealHandle, _calendarFormat);
+ }
+ else
+ {
+ Interop.Elementary.elm_calendar_format_function_set(RealHandle, null);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Add a new mark to the calendar.
+ /// </summary>
+ /// <param name="type">A string used to define the type of mark. It will be emitted to the theme, that should display a related modification on these days representation.</param>
+ /// <param name="date">A time struct to represent the date of inclusion of the mark. For marks that repeats it will just be displayed after the inclusion date in the calendar.</param>
+ /// <param name="repeat">Repeat the event following this periodicity. Can be a unique mark (that don't repeat), daily, weekly, monthly or annually.</param>
+ /// <returns>Item for a calendar mark.</returns>
+ public CalendarMark AddMark(string type, DateTime date, CalendarMarkRepeatType repeat)
+ {
+ CalendarMark mark = new CalendarMark(type, date, repeat);
+ Interop.Libc.SystemTime tm = date;
+ IntPtr nativeHandle = Interop.Elementary.elm_calendar_mark_add(RealHandle, type, ref tm, (Interop.Elementary.Elm_Calendar_Mark_Repeat_Type)repeat);
+ mark.Handle = nativeHandle;
+
+ return mark;
+ }
+
+ /// <summary>
+ /// Delete mark from the calendar.
+ /// </summary>
+ /// <param name="mark">Item for a calendar mark</param>
+ public void DeleteMark(CalendarMark mark)
+ {
+ Interop.Elementary.elm_calendar_mark_del(mark.Handle);
+ }
+
+ /// <summary>
+ /// Draw calendar marks.
+ /// </summary>
+ public void DrawMarks()
+ {
+ Interop.Elementary.elm_calendar_marks_draw(RealHandle);
+ }
+
+ /// <summary>
+ /// Remove all calendar's marks.
+ /// </summary>
+ public void ClearMarks()
+ {
+ Interop.Elementary.elm_calendar_marks_clear(RealHandle);
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ IntPtr handle = Interop.Elementary.elm_layout_add(parent.Handle);
+ Interop.Elementary.elm_layout_theme_set(handle, "layout", "elm_widget", "default");
+
+ RealHandle = Interop.Elementary.elm_calendar_add(handle);
+ Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
+
+ return handle;
+ }
+
+ static void IntPtrToStringArray(IntPtr unmanagedArray, int size, out string[] managedArray)
+ {
+ managedArray = new string[size];
+ IntPtr[] IntPtrArray = new IntPtr[size];
+
+ Marshal.Copy(unmanagedArray, IntPtrArray, 0, size);
+
+ for (int iterator = 0; iterator < size; iterator++)
+ {
+ managedArray[iterator] = Marshal.PtrToStringAnsi(IntPtrArray[iterator]);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/Check.cs b/src/ElmSharp/ElmSharp/Check.cs
new file mode 100755
index 0000000..ae153d8
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Check.cs
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The check is a widget allows for toggling a value between true and false.
+ /// </summary>
+ public class Check : Layout
+ {
+ private SmartEvent _changed;
+ private bool _currentState;
+
+ /// <summary>
+ /// Creates and initializes a new instance of the Check class.
+ /// </summary>
+ /// <param name="parent">
+ /// The EvasObject to which the new Check will be attached as a child.
+ /// </param>
+ public Check(EvasObject parent) : base(parent)
+ {
+ _changed = new SmartEvent(this, this.RealHandle, "changed");
+ _changed.On += (sender, e) =>
+ {
+ StateChanged?.Invoke(this, new CheckStateChangedEventArgs(_currentState, IsChecked));
+ };
+ }
+
+ /// <summary>
+ /// StateChanged will be triggered when the IsChecked in the Check is changed.
+ /// </summary>
+ public event EventHandler<CheckStateChangedEventArgs> StateChanged;
+
+ /// <summary>
+ /// Sets or gets whether the given Check is checked or not.
+ /// </summary>
+ /// <remarks>
+ /// When object is checked, the value will set to true, Conversely will set to false.
+ /// </remarks>
+ public bool IsChecked
+ {
+ get
+ {
+ _currentState = Interop.Elementary.elm_check_state_get(RealHandle);
+ return _currentState;
+ }
+ set
+ {
+ Interop.Elementary.elm_check_state_set(RealHandle, value);
+ }
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ IntPtr handle = Interop.Elementary.elm_layout_add(parent.Handle);
+ Interop.Elementary.elm_layout_theme_set(handle, "layout", "elm_widget", "default");
+
+ RealHandle = Interop.Elementary.elm_check_add(handle);
+ Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
+
+ return handle;
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/CheckStateChangedEventArgs.cs b/src/ElmSharp/ElmSharp/CheckStateChangedEventArgs.cs
new file mode 100755
index 0000000..461798f
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/CheckStateChangedEventArgs.cs
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// It inherits System.EventArgs.
+ /// The CheckStateChangedEventArgs is EventArgs to record Check's state.
+ /// Include old state and new state.
+ /// </summary>
+ public class CheckStateChangedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Gets the OldState property.The return type is bool.
+ /// </summary>
+ public bool OldState { get; private set; }
+
+ /// <summary>
+ /// Gets the NewState property.The return type is bool.
+ /// </summary>
+ public bool NewState { get; private set; }
+
+ /// <summary>
+ /// Creates and initializes a new instance of the CheckStateChangedEventArgs class.
+ /// </summary>
+ /// <param name="oldState">Old state of Check which to use this CheckStateChangedEventArgs.</param>
+ /// <param name="newState">New state of Check which to use this CheckStateChangedEventArgs.</param>
+ public CheckStateChangedEventArgs(bool oldState, bool newState)
+ {
+ this.OldState = oldState;
+ this.NewState = newState;
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/Color.cs b/src/ElmSharp/ElmSharp/Color.cs
new file mode 100644
index 0000000..9b27f0f
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Color.cs
@@ -0,0 +1,339 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Globalization;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The Color is a struct to record Check's state.
+ /// </summary>
+ public struct Color
+ {
+ readonly int _a;
+ readonly int _r;
+ readonly int _g;
+ readonly int _b;
+
+ readonly Mode _mode;
+
+ enum Mode
+ {
+ Default,
+ Rgb
+ }
+
+ /// <summary>
+ /// Gets a default Color instance.
+ /// </summary>
+ /// <remarks>
+ /// In default Color instance,Mode type is Default,RGBA all set as -1.
+ /// </remarks>
+ public static Color Default
+ {
+ get { return new Color(-1, -1, -1, -1, Mode.Default); }
+ }
+
+ /// <summary>
+ /// Gets whether the Color instance's mode is default or not.
+ /// Return type is bool.
+ /// </summary>
+ public bool IsDefault
+ {
+ get { return _mode == Mode.Default; }
+ }
+
+ /// <summary>
+ /// Gets A value of RGBA.
+ /// A means the Alpha in color.
+ /// </summary>
+ public int A
+ {
+ get { return _a; }
+ }
+
+ /// <summary>
+ /// Gets R value of RGBA.
+ /// R means the Red in color.
+ /// </summary>
+ public int R
+ {
+ get { return _r; }
+ }
+
+ /// <summary>
+ /// Gets G value of RGBA.
+ /// G means the Green in color.
+ /// </summary>
+ public int G
+ {
+ get { return _g; }
+ }
+
+ /// <summary>
+ /// Gets B value of RGBA.
+ /// B means the Blue in color.
+ /// </summary>
+ public int B
+ {
+ get { return _b; }
+ }
+
+ /// <summary>
+ /// Creates and initializes a new instance of the Color class.
+ /// With RGB parameters.
+ /// </summary>
+ /// <param name="r">Red of RGB</param>
+ /// <param name="g">Green of RGB</param>
+ /// <param name="b">Blue of RGB</param>
+ public Color(int r, int g, int b) : this(r, g, b, 255)
+ {
+ }
+
+ /// <summary>
+ /// Creates and initializes a new instance of the Color class.
+ /// With RGBA parameters.
+ /// </summary>
+ /// <param name="r">Red of RGBA</param>
+ /// <param name="g">Green of RGBA<</param>
+ /// <param name="b">Blue of RGBA<</param>
+ /// <param name="a">Alpha of RGBA<</param>
+ public Color(int r, int g, int b, int a) : this(r, g, b, a, Mode.Rgb)
+ {
+ }
+
+ Color(int r, int g, int b, int a, Mode mode)
+ {
+ _mode = mode;
+ if (mode == Mode.Rgb)
+ {
+ _r = Clamp(r, 0, 255);
+ _g = Clamp(g, 0, 255);
+ _b = Clamp(b, 0, 255);
+ _a = Clamp(a, 0, 255);
+ }
+ else // Default
+ {
+ _r = _g = _b = _a = -1;
+ }
+ }
+
+ public override int GetHashCode()
+ {
+ int hashcode = _r.GetHashCode();
+ hashcode = (hashcode * 397) ^ _g.GetHashCode();
+ hashcode = (hashcode * 397) ^ _b.GetHashCode();
+ hashcode = (hashcode * 397) ^ _a.GetHashCode();
+ return hashcode;
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (obj is Color)
+ {
+ return EqualsInner(this, (Color)obj);
+ }
+ return base.Equals(obj);
+ }
+
+ /// <summary>
+ /// Compare whether two Color instance is same or not.
+ /// </summary>
+ /// <param name="a">A Color instance.</param>
+ /// <param name="b">A Color instance.</param>
+ /// <returns>The result whether two instance is same or not.
+ /// Return type is bool.If they are same, return true.
+ /// </returns>
+ public static bool operator ==(Color a, Color b)
+ {
+ if (ReferenceEquals(a, b))
+ return true;
+
+ if ((object)a == null || (object)b == null)
+ return false;
+
+ return EqualsInner(a, b);
+ }
+
+ /// <summary>
+ /// Compare whether two Color instance is different or not.
+ /// </summary>
+ /// <param name="a">A Color instance.</param>
+ /// <param name="b">A Color instance.</param>
+ /// <returns>The result whether two instance is different or not.
+ /// Return type is bool.If they are different, return true.
+ /// </returns>
+ public static bool operator !=(Color a, Color b)
+ {
+ return !(a == b);
+ }
+
+ static bool EqualsInner(Color color1, Color color2)
+ {
+ if (color1._mode == Mode.Default && color2._mode == Mode.Default)
+ return true;
+ return color1._r == color2._r && color1._g == color2._g && color1._b == color2._b && color1._a == color2._a;
+ }
+
+ public override string ToString()
+ {
+ return string.Format(CultureInfo.InvariantCulture, "[Color: R={0}, G={1}, B={2}, A={3}]", R, G, B, A);
+ }
+
+ /// <summary>
+ /// Gets a Color instance with a hexadecimal string parameter.
+ /// </summary>
+ /// <param name="hex">Hexadecimal string.</param>
+ /// <returns>New instance of Color struct.</returns>
+ public static Color FromHex(string hex)
+ {
+ hex = hex.Replace("#", "");
+ switch (hex.Length)
+ {
+ case 3: //#rgb => ffrrggbb
+ hex = string.Format("ff{0}{1}{2}{3}{4}{5}", hex[0], hex[0], hex[1], hex[1], hex[2], hex[2]);
+ break;
+ case 4: //#argb => aarrggbb
+ hex = string.Format("{0}{1}{2}{3}{4}{5}{6}{7}", hex[0], hex[0], hex[1], hex[1], hex[2], hex[2], hex[3], hex[3]);
+ break;
+ case 6: //#rrggbb => ffrrggbb
+ hex = string.Format("ff{0}", hex);
+ break;
+ }
+ return FromUint(Convert.ToUInt32(hex.Replace("#", ""), 16));
+ }
+
+ /// <summary>
+ /// Gets a Color instance with a Unsigned integer parameter.
+ /// </summary>
+ /// <param name="argb">Unsigned integer indicates RGBA.</param>
+ /// <returns>New instance of Color struct.</returns>
+ public static Color FromUint(uint argb)
+ {
+ return FromRgba((byte)((argb & 0x00ff0000) >> 0x10), (byte)((argb & 0x0000ff00) >> 0x8), (byte)(argb & 0x000000ff), (byte)((argb & 0xff000000) >> 0x18));
+ }
+
+ /// <summary>
+ /// Gets a Color instance with R,G,B,A parameters.
+ /// </summary>
+ /// <param name="r">Red in RGBA.</param>
+ /// <param name="g">Green in RGBA.</param>
+ /// <param name="b">Blue in RGBA.</param>
+ /// <param name="a">Alpha in RGBA.</param>
+ /// <returns>New instance of Color struct.</returns>
+ public static Color FromRgba(int r, int g, int b, int a)
+ {
+ return new Color(r, g, b, a);
+ }
+
+ /// <summary>
+ /// Gets a Color instance with R,G,B,A parameters.
+ /// </summary>
+ /// <param name="r">Red in RGB.</param>
+ /// <param name="g">Green in RGB.</param>
+ /// <param name="b">Blue in RGB.</param>
+ /// <returns>New instance of Color struct.</returns>
+ public static Color FromRgb(int r, int g, int b)
+ {
+ return FromRgba(r, g, b, 255);
+ }
+
+ internal static int Clamp(int self, int min, int max)
+ {
+ return Math.Min(max, Math.Max(self, min));
+ }
+
+ #region Color Definitions
+ /// <summary>
+ /// The Tansparent is a predefined Color, it's rgba value is (0, 0, 0, 0).
+ /// </summary>
+ public static readonly Color Transparent = FromRgba(0, 0, 0, 0);
+ /// <summary>
+ /// The Aqua is a predefined Color instance, it's rgb value is (0, 255, 255).
+ /// </summary>
+ public static readonly Color Aqua = FromRgb(0, 255, 255);
+ /// <summary>
+ /// The Black is a predefined Color instance, it's rgb value is (0, 0, 0).
+ /// </summary>
+ public static readonly Color Black = FromRgb(0, 0, 0);
+ /// <summary>
+ /// The Blue is a predefined Color instance, it's rgb value is (0, 0, 255).
+ /// </summary>
+ public static readonly Color Blue = FromRgb(0, 0, 255);
+ /// <summary>
+ /// The Fuchsia is a predefined Color instance, it's rgb value is (255, 0, 255).
+ /// </summary>
+ public static readonly Color Fuchsia = FromRgb(255, 0, 255);
+ /// <summary>
+ /// The Gray is a predefined Color instance, it's rgb value is (128, 128, 128).
+ /// </summary>
+ public static readonly Color Gray = FromRgb(128, 128, 128);
+ /// <summary>
+ /// The Green is a predefined Color instance, it's rgb value is (0, 128, 0).
+ /// </summary>
+ public static readonly Color Green = FromRgb(0, 128, 0);
+ /// <summary>
+ /// The Lime is a predefined Color instance, it's rgb value is (0, 255, 0).
+ /// </summary>
+ public static readonly Color Lime = FromRgb(0, 255, 0);
+ /// <summary>
+ /// The Maroon is a predefined Color instance, it's rgb value is (128, 0, 0).
+ /// </summary>
+ public static readonly Color Maroon = FromRgb(128, 0, 0);
+ /// <summary>
+ /// The Navy is a predefined Color instance, it's rgb value is (0, 0, 128).
+ /// </summary>
+ public static readonly Color Navy = FromRgb(0, 0, 128);
+ /// <summary>
+ /// The Olive is a predefined Color instance, it's rgb value is (128, 128, 0).
+ /// </summary>
+ public static readonly Color Olive = FromRgb(128, 128, 0);
+ /// <summary>
+ /// The Orange is a predefined Color instance, it's rgb value is (255, 165, 0).
+ /// </summary>
+ public static readonly Color Orange = FromRgb(255, 165, 0);
+ /// <summary>
+ /// The Purple is a predefined Color instance, it's rgb value is (128, 0, 128).
+ /// </summary>
+ public static readonly Color Purple = FromRgb(128, 0, 128);
+ /// <summary>
+ /// The Pink is a predefined Color instance, it's rgb value is (255, 102, 255).
+ /// </summary>
+ public static readonly Color Pink = FromRgb(255, 102, 255);
+ /// <summary>
+ /// The Red is a predefined Color instance, it's rgb value is (255, 0, 0).
+ /// </summary>
+ public static readonly Color Red = FromRgb(255, 0, 0);
+ /// <summary>
+ /// The Silver is a predefined Color instance, it's rgb value is (192, 192, 192).
+ /// </summary>
+ public static readonly Color Silver = FromRgb(192, 192, 192);
+ /// <summary>
+ /// The Teal is a predefined Color instance, it's rgb value is (0, 128, 128).
+ /// </summary>
+ public static readonly Color Teal = FromRgb(0, 128, 128);
+ /// <summary>
+ /// The White is a predefined Color instance, it's rgb value is (255, 255, 255).
+ /// </summary>
+ public static readonly Color White = FromRgb(255, 255, 255);
+ /// <summary>
+ /// The Yellow is a predefined Color instance, it's rgb value is (255, 255, 0).
+ /// </summary>
+ public static readonly Color Yellow = FromRgb(255, 255, 0);
+ #endregion
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/ColorChangedEventArgs.cs b/src/ElmSharp/ElmSharp/ColorChangedEventArgs.cs
new file mode 100755
index 0000000..b1090de
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/ColorChangedEventArgs.cs
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// It inherits System.EventArgs.
+ /// Event ColorChanged of ColorSelector contain ColorChangedEventArgs as a parameter.
+ /// Refer to <see cref="ColorSelector"/>type.
+ /// </summary>
+ public class ColorChangedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Gets old color in color changed event.
+ /// </summary>
+ public Color OldColor { get; private set; }
+
+ /// <summary>
+ /// Gets new color in color changed event.
+ /// </summary>
+ public Color NewColor { get; private set; }
+
+ /// <summary>
+ /// Creates and initializes a new instance of the ColorChangedEventArgs class.
+ /// </summary>
+ /// <param name="oldColor">old color</param>
+ /// <param name="newColor">new color</param>
+ public ColorChangedEventArgs(Color oldColor, Color newColor)
+ {
+ this.OldColor = oldColor;
+ this.NewColor = newColor;
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/ColorSelector.cs b/src/ElmSharp/ElmSharp/ColorSelector.cs
new file mode 100755
index 0000000..cf16a99
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/ColorSelector.cs
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// Enumeration for mode of ColorSelector
+ /// </summary>
+ public enum ColorSelectorMode
+ {
+ /// <summary>
+ /// Only color palette is displayed, default
+ /// </summary>
+ Palette,
+ /// <summary>
+ /// Only color selector is displayed
+ /// </summary>
+ [Obsolete("Components is obsolete as of version 1.2.3 and is no longer supported.")]
+ Components,
+ /// <summary>
+ /// Both Palette and selector is displayed
+ /// </summary>
+ [Obsolete("Both is obsolete as of version 1.2.3 and is no longer supported.")]
+ Both,
+ /// <summary>
+ /// Only color picker is displayed
+ /// </summary>
+ [Obsolete("Picker is obsolete as of version 1.2.3 and is no longer supported.")]
+ Picker,
+ /// <summary>
+ /// This mode is not supported. If you use this, nothing will be shown
+ /// </summary>
+ [Obsolete("Plane is obsolete as of version 1.2.3 and is no longer supported.")]
+ Plane,
+ /// <summary>
+ /// This mode is not supported. If you use this, it will be shown same with Palette mode
+ /// </summary>
+ [Obsolete("PallettePlane is obsolete as of version 1.2.3 and is no longer supported.")]
+ PallettePlane,
+ /// <summary>
+ /// This mode is not supported. If you use this, it will be shown same with Palette mode
+ /// </summary>
+ [Obsolete("All is obsolete as of version 1.2.3 and is no longer supported.")]
+ All
+ }
+
+ /// <summary>
+ /// The ColorSelector is a widget to set a series of colors.
+ /// It also allows to load/save colors from/to config with a unique identifier.
+ /// </summary>
+ /// <remarks>
+ /// By default, the colors are loaded/saved from/to config using "default" identifier.
+ /// The colors can be picked by user from the color set by clicking on individual
+ /// color item on the palette or by selecting it from selector.
+ /// </remarks>
+ public class ColorSelector : Layout
+ {
+ private readonly SmartEvent<ColorChangedEventArgs> _changed;
+ private Color _currentColor;
+
+ /// <summary>
+ /// Creates and initializes a new instance of the ColorSelector class.
+ /// </summary>
+ /// <param name="parent"></param>
+ public ColorSelector(EvasObject parent) : base(parent)
+ {
+ _changed = new SmartEvent<ColorChangedEventArgs>(this, "changed", (data, obj, info) =>
+ {
+ return new ColorChangedEventArgs(_currentColor, SelectedColor);
+ });
+ }
+
+ /// <summary>
+ /// ColorChanged will be triggered when the SelectedColor changed.
+ /// </summary>
+ public event EventHandler<ColorChangedEventArgs> ColorChanged
+ {
+ add { _changed.On += value; }
+ remove { _changed.On -= value; }
+ }
+
+ /// <summary>
+ /// Gets or sets color of colorselector.
+ /// </summary>
+ public Color SelectedColor
+ {
+ get
+ {
+ int r, g, b, a;
+ Interop.Elementary.elm_colorselector_color_get(Handle, out r, out g, out b, out a);
+ _currentColor = new Color(r, g, b, a);
+ return _currentColor;
+ }
+ set
+ {
+ Interop.Elementary.elm_colorselector_color_set(Handle, value.R, value.G, value.B, value.A);
+ _currentColor = new Color(value.R, value.G, value.B, value.A);
+ }
+ }
+
+ /// <summary>
+ /// Gets Alpha of a default Color Class(Value is -1).
+ /// </summary>
+ public override int Opacity
+ {
+ get
+ {
+ return Color.Default.A;
+ }
+
+ set
+ {
+ Console.WriteLine("ColorSelector instance doesn't support to set Opacity.");
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets Colorselector's mode.
+ /// </summary>
+ public ColorSelectorMode Mode
+ {
+ get
+ {
+ return (ColorSelectorMode)Interop.Elementary.elm_colorselector_mode_get(Handle);
+ }
+ set
+ {
+ if (ColorSelectorMode.Palette == value)
+ {
+ Interop.Elementary.elm_colorselector_mode_set(Handle, (Interop.Elementary.Elm_Colorselector_Mode)value);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Get or set current palette's name.
+ /// </summary>
+ public string PaletteName
+ {
+ get
+ {
+ return Interop.Elementary.elm_colorselector_palette_name_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_colorselector_palette_name_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Adds a new color item to palette.
+ /// </summary>
+ /// <param name="color">Color item to add</param>
+ /// <returns>A new color palette Item.</returns>
+ public ColorSelectorItem AddPaletteColor(Color color)
+ {
+ ColorSelectorItem item = new ColorSelectorItem();
+ item.Handle = Interop.Elementary.elm_colorselector_palette_color_add(Handle, color.R, color.G, color.B, color.A);
+ return item;
+ }
+
+ /// <summary>
+ /// Clear the palette items.
+ /// </summary>
+ public void ClearPalette()
+ {
+ Interop.Elementary.elm_colorselector_palette_clear(Handle);
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ return Interop.Elementary.elm_colorselector_add(parent.Handle);
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/ColorSelectorItem.cs b/src/ElmSharp/ElmSharp/ColorSelectorItem.cs
new file mode 100755
index 0000000..10205e2
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/ColorSelectorItem.cs
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// A instance to the ColorSelector item added.
+ /// </summary>
+ public class ColorSelectorItem : ItemObject
+ {
+ internal ColorSelectorItem() : base(IntPtr.Zero)
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the Palette item's color
+ /// </summary>
+ public Color Color
+ {
+ get
+ {
+ int r, g, b, a;
+ Interop.Elementary.elm_colorselector_palette_item_color_get(Handle, out r, out g, out b, out a);
+ return Color.FromRgba(r, g, b, a);
+ }
+ set
+ {
+ if (Handle != IntPtr.Zero)
+ {
+ Interop.Elementary.elm_colorselector_palette_item_color_set(Handle, value.R, value.G, value.B, value.A);
+ }
+ }
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/Conformant.cs b/src/ElmSharp/ElmSharp/Conformant.cs
new file mode 100755
index 0000000..84da0e3
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Conformant.cs
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The check is a widget that can be used in elementary apps
+ /// to account for space taken up by the indicator,
+ /// virtual keypad & softkey windows when running the illume2 module of E17.
+ /// </summary>
+ public class Conformant : Widget
+ {
+ /// <summary>
+ /// Creates and initializes a new instance of the Conformant class.
+ /// </summary>
+ /// <param name="parent">The parent is a given container which will be attached by Conformant
+ /// as a child.It's <see cref="EvasObject"/> type.</param>
+ public Conformant(Window parent) : base(parent)
+ {
+ Interop.Evas.evas_object_size_hint_weight_set(Handle, 1.0, 1.0);
+ Interop.Elementary.elm_win_conformant_set(parent.Handle, true);
+ parent.AddResizeObject(this);
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ return Interop.Elementary.elm_conformant_add(parent.Handle);
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/Container.cs b/src/ElmSharp/ElmSharp/Container.cs
new file mode 100755
index 0000000..5701fe6
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Container.cs
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// It inherits <see cref="Widget"/>.
+ /// The Container is a abstract class.
+ /// Other class inherits it to Elementary is about displaying
+ /// its widgets in a nice layout.
+ /// </summary>
+ public abstract class Container : Widget
+ {
+ HashSet<EvasObject> _children = new HashSet<EvasObject>();
+
+ /// <summary>
+ /// Creates and initializes a new instance of class which inherit from Container.
+ /// </summary>
+ /// <param name="parent">The parent is a given object which will be attached by Container
+ /// as a child.It's <see cref="EvasObject"/> type.</param>
+ public Container(EvasObject parent) : base(parent)
+ {
+ }
+
+ /// <summary>
+ /// Sets the background color of a given Container.
+ /// </summary>
+ public override Color BackgroundColor
+ {
+ set
+ {
+ if (value.IsDefault)
+ {
+ SetPartColor("bg", Color.Transparent);
+ }
+ else
+ {
+ SetPartColor("bg", value);
+ }
+ _backgroundColor = value;
+ }
+ }
+
+ protected void AddChild(EvasObject obj)
+ {
+ _children.Add(obj);
+ obj.Deleted += OnChildDeleted;
+ }
+
+ protected void RemoveChild(EvasObject obj)
+ {
+ _children.Remove(obj);
+ }
+
+ protected void ClearChildren()
+ {
+ _children.Clear();
+ }
+
+ void OnChildDeleted(object sender, EventArgs a)
+ {
+ _children.Remove((EvasObject)sender);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/ContextPopup.cs b/src/ElmSharp/ElmSharp/ContextPopup.cs
new file mode 100755
index 0000000..3be2baa
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/ContextPopup.cs
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// Enumeration of ContextPopup direction type.
+ /// </summary>
+ public enum ContextPopupDirection
+ {
+ /// <summary>
+ /// ContextPopup show appear below clicked area
+ /// /// </summary>
+ Down,
+ /// <summary>
+ /// ContextPopup show appear to the right of the clicked area
+ /// </summary>
+ Right,
+ /// <summary>
+ /// ContextPopup show appear to the left of the clicked area
+ /// </summary>
+ Left,
+ /// <summary>
+ /// ContextPopup show appear above the clicked area
+ /// </summary>
+ Up,
+ /// <summary>
+ /// ContextPopup does not determine it's direction yet
+ /// </summary>
+ Unknown
+ }
+
+ /// <summary>
+ /// It inherits <see cref="Layout"/>.
+ /// The ContextPopup is a widget that when it shown, pops up a list of items.
+ /// </summary>
+ public class ContextPopup : Layout
+ {
+ HashSet<ContextPopupItem> _children = new HashSet<ContextPopupItem>();
+ SmartEvent _dismissed;
+ Interop.Evas.SmartCallback _onSelected;
+
+ /// <summary>
+ /// Creates and initializes a new instance of the ContextPopup class.
+ /// </summary>
+ /// <param name="parent">The parent is a given container which will be attached by ContextPopup
+ /// as a child.It's <see cref="EvasObject"/> type.</param>
+ public ContextPopup(EvasObject parent) : base(parent)
+ {
+ _dismissed = new SmartEvent(this, this.RealHandle, "dismissed");
+ _dismissed.On += (sender, e) =>
+ {
+ Dismissed?.Invoke(this, EventArgs.Empty);
+ };
+ _onSelected = (data, obj, info) =>
+ {
+ ContextPopupItem item = ItemObject.GetItemById((int)data) as ContextPopupItem;
+ item?.SendSelected();
+ };
+ }
+
+ /// <summary>
+ /// Dismissed is raised when the ContextPopup item is dismissed.
+ /// </summary>
+ /// <remarks>
+ /// Outside of ContextPopup was clicked or it's parent area is changed or the language is changed. and then ContextPopup is dismissed.
+ /// </remarks>
+ public event EventHandler Dismissed;
+
+ /// <summary>
+ /// Gets the current direction of a ContextPopup.
+ /// </summary>
+ /// <remarks>
+ /// Once the ContextPopup showed up, the direction would be determined.
+ /// </remarks>
+ public ContextPopupDirection Direction
+ {
+ get
+ {
+ return (ContextPopupDirection)Interop.Elementary.elm_ctxpopup_direction_get(RealHandle);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the value of current ContextPopup object's orientation.
+ /// True for horizontal mode, False for vertical mode (or errors)
+ /// </summary>
+ public bool IsHorizontal
+ {
+ get
+ {
+ return Interop.Elementary.elm_ctxpopup_horizontal_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_ctxpopup_horizontal_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets whether ContextPopup hide automatically
+ /// or not when parent of ContextPopup is resized.
+ /// </summary>
+ /// <remarks>
+ /// Default value of AutoHide is False.
+ /// </remarks>
+ public bool AutoHide
+ {
+ get
+ {
+ return !Interop.Elementary.elm_ctxpopup_auto_hide_disabled_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_ctxpopup_auto_hide_disabled_set(RealHandle, !value);
+ }
+ }
+
+ /// <summary>
+ /// Clears all items in the given ContextPopup object.
+ /// </summary>
+ public void Clear()
+ {
+ Interop.Elementary.elm_ctxpopup_clear(Handle);
+ }
+
+ /// <summary>
+ /// Sets the direction priority of a ContextPopup.
+ /// </summary>
+ /// <param name="first">1st priority of direction </param>
+ /// <param name="second">2nd priority of direction </param>
+ /// <param name="third">3th priority of direction </param>
+ /// <param name="fourth">4th priority of direction</param>
+ public void SetDirectionPriorty(ContextPopupDirection first, ContextPopupDirection second, ContextPopupDirection third, ContextPopupDirection fourth)
+ {
+ Interop.Elementary.elm_ctxpopup_direction_priority_set(RealHandle, (int)first, (int)second, (int)third, (int)fourth);
+ }
+
+ /// <summary>
+ /// Gets the direction priority of a ContextPopup.
+ /// </summary>
+ /// <param name="first">1st priority of direction to be returned</param>
+ /// <param name="second">2nd priority of direction to be returned</param>
+ /// <param name="third">2nd priority of direction to be returned </param>
+ /// <param name="fourth">4th priority of direction to be returned</param>
+ public void GetDirectionPriority(out ContextPopupDirection first, out ContextPopupDirection second, out ContextPopupDirection third, out ContextPopupDirection fourth)
+ {
+ int firstOut, secondOut, thirdOut, fourthOut;
+ Interop.Elementary.elm_ctxpopup_direction_priority_get(Handle, out firstOut, out secondOut, out thirdOut, out fourthOut);
+ first = (ContextPopupDirection)firstOut;
+ second = (ContextPopupDirection)secondOut;
+ third = (ContextPopupDirection)thirdOut;
+ fourth = (ContextPopupDirection)fourthOut;
+ }
+
+ /// <summary>
+ /// Adds a new item to a ContextPopup object with label.
+ /// </summary>
+ /// <param name="label">The Label of the new item</param>
+ /// <returns>
+ /// A ContextPopupItem added or NULL, on errors
+ /// </returns>
+ public ContextPopupItem Append(string label)
+ {
+ return Append(label, null);
+ }
+
+ /// <summary>
+ /// Adds a new item to a ContextPopup object with label and icon.
+ /// </summary>
+ /// <param name="label">The Label of the new item</param>
+ /// <param name="icon">Icon to be set on new item</param>
+ /// <returns>A ContextPopupItem added or NULL, on errors</returns>
+ public ContextPopupItem Append(string label, EvasObject icon)
+ {
+ ContextPopupItem item = new ContextPopupItem(label, icon);
+ item.Handle = Interop.Elementary.elm_ctxpopup_item_append(RealHandle, label, icon, _onSelected, (IntPtr)item.Id);
+ AddInternal(item);
+ return item;
+ }
+
+ /// <summary>
+ /// Dismiss a ContextPopup object. The ContextPopup will be hidden and the "clicked" signal will be emitted.
+ /// </summary>
+ public void Dismiss()
+ {
+ Interop.Elementary.elm_ctxpopup_dismiss(RealHandle);
+ }
+
+ /// <summary>
+ /// Gets the possibility that the direction would be available
+ /// </summary>
+ /// <param name="direction">A direction user wants to check</param>
+ /// <returns>
+ /// Get false if you cannot put it in the direction. Gets true if it's possible.
+ /// </returns>
+ public bool IsAvailableDirection(ContextPopupDirection direction)
+ {
+ return Interop.Elementary.elm_ctxpopup_direction_available_get(RealHandle, (int)direction);
+ }
+
+ /// <summary>
+ /// Gets Alpha of a default Color Class.
+ /// </summary>
+ public override int Opacity
+ {
+ get
+ {
+ return Color.Default.A;
+ }
+
+ set
+ {
+ Console.WriteLine("ContextPopup instance doesn't support to set Opacity.");
+ }
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ return Interop.Elementary.elm_ctxpopup_add(parent.Handle);
+ }
+
+ void AddInternal(ContextPopupItem item)
+ {
+ _children.Add(item);
+ item.Deleted += Item_Deleted;
+ }
+
+ void Item_Deleted(object sender, EventArgs e)
+ {
+ _children.Remove((ContextPopupItem)sender);
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/ContextPopupItem.cs b/src/ElmSharp/ElmSharp/ContextPopupItem.cs
new file mode 100755
index 0000000..35c908b
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/ContextPopupItem.cs
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// It inherits <see cref="ItemObject"/>.
+ /// A instance to the ContextPopup item added.
+ /// </summary>
+ public class ContextPopupItem : ItemObject
+ {
+ internal ContextPopupItem(string text, EvasObject icon) : base(IntPtr.Zero)
+ {
+ Text = text;
+ Icon = icon;
+ }
+
+ /// <summary>
+ /// Gets the Text property of the given ContextPopupItem.
+ /// </summary>
+ public string Text { get; internal set; }
+
+ /// <summary>
+ /// Gets the Icon(type is <see cref="EvasObject"/>) property of the given ContextPopupItem.
+ /// </summary>
+ public EvasObject Icon { get; internal set; }
+
+ /// <summary>
+ /// Selected will be triggered when the ContextPopupItem is Selected.
+ /// </summary>
+ public event EventHandler Selected;
+
+ internal void SendSelected()
+ {
+ Selected?.Invoke(this, EventArgs.Empty);
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/DateChangedEventArgs.cs b/src/ElmSharp/ElmSharp/DateChangedEventArgs.cs
new file mode 100755
index 0000000..25d622c
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/DateChangedEventArgs.cs
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// It inherits System.EventArgs.
+ /// The DateChanged event in Calendar and DateTimeChanged event in DateTimeSelector.
+ /// contain DateChangedEventArgs as a parameter.
+ /// </summary>
+ public class DateChangedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Gets the OldDate property of the given DateChangedEventArgs.
+ /// </summary>
+ public DateTime OldDate { get; private set; }
+
+ /// <summary>
+ /// Gets the NewDate property of the given DateChangedEventArgs.
+ /// </summary>
+ public DateTime NewDate { get; private set; }
+
+ /// <summary>
+ /// Creates and initializes a new instance of the DateChangedEventArgs class.
+ /// </summary>
+ /// <param name="oldDate">
+ /// Old date when DateChanged event or DateTimeChanged event triggered
+ /// </param>
+ /// <param name="newDate">
+ /// New date when DateChanged event or DateTimeChanged event triggered
+ /// </param>
+ public DateChangedEventArgs(DateTime oldDate, DateTime newDate)
+ {
+ this.OldDate = oldDate;
+ this.NewDate = newDate;
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/DateTimeSelector.cs b/src/ElmSharp/ElmSharp/DateTimeSelector.cs
new file mode 100755
index 0000000..584c236
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/DateTimeSelector.cs
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// Enumeration of datetime field types for DateTimeSelector.
+ /// </summary>
+ public enum DateTimeFieldType
+ {
+ Year,
+ Month,
+ Date,
+ Hour,
+ Minute,
+ AmPm
+ }
+
+ /// <summary>
+ /// It inherits <see cref="Layout"/>
+ /// DateTimeSelector is a widget to display and input date & time values.
+ /// This widget displays date and time as per the system's locale settings
+ /// (Date includes Day, Month & Year along with the defined separators and Time includes Hour, Minute & AM/PM fields. Separator for AM/PM field is ignored.
+ /// </summary>
+ public class DateTimeSelector : Layout
+ {
+ SmartEvent _changed;
+ DateTime _cacheDateTime;
+
+ /// <summary>
+ /// Creates and initializes a new instance of the DateTimeSelector class.
+ /// </summary>
+ /// <param name="parent">The parent is a given container which will be attached by DateTimeSelector
+ ///as a child.It's <see cref="EvasObject"/> type.</param>
+ public DateTimeSelector(EvasObject parent) : base(parent)
+ {
+ _changed = new SmartEvent(this, this.RealHandle, "changed");
+ _changed.On += (s, e) =>
+ {
+ DateTime newDateTime = DateTime;
+ DateTimeChanged?.Invoke(this, new DateChangedEventArgs(_cacheDateTime, newDateTime));
+ DateTime = newDateTime;
+ };
+ }
+
+ /// <summary>
+ /// ItemSelected is raised when Datetime field value changed.
+ /// </summary>
+ public event EventHandler<DateChangedEventArgs> DateTimeChanged;
+
+ /// <summary>
+ /// Gets or sets the datetime format.
+ /// </summary>
+ /// <remarks>
+ /// format is a combination of allowed LIBC date format specifiers like: "%b %d, %Y %I : %M %p".
+ /// </remarks>
+ public string Format
+ {
+ get
+ {
+ return Interop.Elementary.elm_datetime_format_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_datetime_format_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the upper boundary of DateTime field.
+ /// </summary>
+ public DateTime MaximumDateTime
+ {
+ get
+ {
+ var tm = new Interop.Libc.SystemTime();
+ Interop.Elementary.elm_datetime_value_max_get(RealHandle, ref tm);
+ return tm;
+ }
+ set
+ {
+ Interop.Libc.SystemTime tm = value;
+ Interop.Elementary.elm_datetime_value_max_set(RealHandle, ref tm);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the lower boundary of DateTime field.
+ /// </summary>
+ public DateTime MinimumDateTime
+ {
+ get
+ {
+ var tm = new Interop.Libc.SystemTime();
+ Interop.Elementary.elm_datetime_value_min_get(RealHandle, ref tm);
+ return tm;
+ }
+ set
+ {
+ Interop.Libc.SystemTime tm = value;
+ Interop.Elementary.elm_datetime_value_min_set(RealHandle, ref tm);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the current value of DateTime field.
+ /// </summary>
+ public DateTime DateTime
+ {
+ get
+ {
+ var tm = new Interop.Libc.SystemTime();
+ Interop.Elementary.elm_datetime_value_get(RealHandle, ref tm);
+ return tm;
+ }
+ set
+ {
+ Interop.Libc.SystemTime tm = value;
+ Interop.Elementary.elm_datetime_value_set(RealHandle, ref tm);
+ _cacheDateTime = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets whether a field can be visible.
+ /// </summary>
+ /// <param name="type">Enumeration <see cref="DateTimeFieldType"/></param>
+ /// <returns>
+ /// The field is visible or not.
+ /// Type is bool.If visible, return true.
+ /// </returns>
+ public bool IsFieldVisible(DateTimeFieldType type)
+ {
+ return Interop.Elementary.elm_datetime_field_visible_get(RealHandle, (int)type);
+ }
+
+ /// <summary>
+ /// Sets the field limits of a field.
+ /// </summary>
+ /// <param name="type">Enumeration <see cref="DateTimeFieldType"/></param>
+ /// <param name="minimum">minimum limit</param>
+ /// <param name="maximum">maximum limit</param>
+ public void SetFieldLimit(DateTimeFieldType type, int minimum, int maximum)
+ {
+ Interop.Elementary.elm_datetime_field_limit_set(RealHandle, (int)type, minimum, maximum);
+ }
+
+ /// <summary>
+ /// Gets whether a field can be visible.
+ /// </summary>
+ /// <param name="type">Enumeration <see cref="DateTimeFieldType"/></param>
+ /// <param name="visible">When set as true, the field type visible.</param>
+ public void SetFieldVisible(DateTimeFieldType type, bool visible)
+ {
+ Interop.Elementary.elm_datetime_field_visible_set(RealHandle, (int)type, visible);
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ IntPtr handle = Interop.Elementary.elm_layout_add(parent.Handle);
+ Interop.Elementary.elm_layout_theme_set(handle, "layout", "elm_widget", "default");
+
+ RealHandle = Interop.Elementary.elm_datetime_add(handle);
+ Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
+
+ return handle;
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/DisplayedMonthChangedEventArgs.cs b/src/ElmSharp/ElmSharp/DisplayedMonthChangedEventArgs.cs
new file mode 100755
index 0000000..8407f6d
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/DisplayedMonthChangedEventArgs.cs
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// It inherits System.EventArgs.
+ /// The DisplayedMonthChangedEvent in Calendar contain
+ /// DisplayedMonthChangedEventArgs as a parameter.
+ /// </summary>
+ public class DisplayedMonthChangedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Gets the OldMonth property of the given DisplayedMonthChangedEventArgs.
+ /// </summary>
+ public int OldMonth { get; private set; }
+
+ /// <summary>
+ /// Gets the NewMonth property of the given DisplayedMonthChangedEventArgs.
+ /// </summary>
+ public int NewMonth { get; private set; }
+
+ /// <summary>
+ /// Creates and initializes a new instance of the DisplayedMonthChangedEventArgs class.
+ /// </summary>
+ /// <param name="oldMonth">
+ /// old month of date when DisplayedMonthChangedEvent triggered.
+ /// </param>
+ /// <param name="newMonth">
+ /// new month of date when DisplayedMonthChangedEvent triggered.
+ /// </param>
+ public DisplayedMonthChangedEventArgs(int oldMonth, int newMonth)
+ {
+ this.OldMonth = oldMonth;
+ this.NewMonth = newMonth;
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/EcoreAnimator.cs b/src/ElmSharp/ElmSharp/EcoreAnimator.cs
new file mode 100755
index 0000000..64a548d
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/EcoreAnimator.cs
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// EcoreAnimator is a helper class, it provides functions to manager animations.
+ /// </summary>
+ public static class EcoreAnimator
+ {
+ static readonly Dictionary<int, Func<bool>> _taskMap = new Dictionary<int, Func<bool>>();
+ static readonly Object _taskLock = new Object();
+ static int _newTaskId = 0;
+
+ static Interop.Ecore.EcoreTaskCallback _nativeHandler;
+
+ static EcoreAnimator()
+ {
+ _nativeHandler = NativeHandler;
+ }
+
+ /// <summary>
+ /// Gets current system time as a floating point value in seconds.
+ /// </summary>
+ /// <returns>Current system time</returns>
+ public static double GetCurrentTime()
+ {
+ return Interop.Ecore.ecore_time_get();
+ }
+
+ /// <summary>
+ /// Adds an animator to call <paramref name="handler"/> at every animation tick during main loop execution.
+ /// </summary>
+ /// <param name="handler">The function to call when it ticks off</param>
+ /// <returns>A handle to the new animator</returns>
+ public static IntPtr AddAnimator(Func<bool> handler)
+ {
+ int id = RegistHandler(handler);
+ return Interop.Ecore.ecore_animator_add(_nativeHandler, (IntPtr)id);
+ }
+
+ /// <summary>
+ /// Removes the specified animator from the animator list.
+ /// </summary>
+ /// <param name="anim">The specified animator handle</param>
+ public static void RemoveAnimator(IntPtr anim)
+ {
+ int taskId = (int)Interop.Ecore.ecore_animator_del(anim);
+ _taskMap.Remove(taskId);
+ }
+
+ static int RegistHandler(Func<bool> task)
+ {
+ int taskId;
+ lock (_taskLock)
+ {
+ taskId = _newTaskId++;
+ }
+ _taskMap[taskId] = task;
+ return taskId;
+ }
+
+ static bool NativeHandler(IntPtr userData)
+ {
+ int task_id = (int)userData;
+ Func<bool> userAction = null;
+ _taskMap.TryGetValue(task_id, out userAction);
+ return (userAction != null) ? userAction() : false;
+ }
+
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/EcoreEvent.cs b/src/ElmSharp/ElmSharp/EcoreEvent.cs
new file mode 100755
index 0000000..e42310c
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/EcoreEvent.cs
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The EcoreEventType is type of EcoreEvent.
+ /// It includes some predefined instance.
+ /// </summary>
+ public class EcoreEventType
+ {
+ /// <summary>
+ /// Key down Ecore event type.
+ /// </summary>
+ public static readonly EcoreEventType KeyDown = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_KEY_DOWN");
+ /// <summary>
+ /// Key Up Ecore event type.
+ /// </summary>
+ public static readonly EcoreEventType KeyUp = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_KEY_UP");
+ /// <summary>
+ /// Mouse Button Down Ecore event type.
+ /// </summary>
+ public static readonly EcoreEventType MouseButtonDown = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_BUTTON_DOWN");
+ /// <summary>
+ /// Mouse Button Up Ecore event type.
+ /// </summary>
+ public static readonly EcoreEventType MouseButtonUp = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_BUTTON_UP");
+ /// <summary>
+ /// Mouse Button Cancel Ecore event type.
+ /// </summary>
+ public static readonly EcoreEventType MouseButtonCancel = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_BUTTON_CANCEL");
+ /// <summary>
+ /// Mouse Move Ecore event type.
+ /// </summary>
+ public static readonly EcoreEventType MouseMove = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_MOVE");
+ /// <summary>
+ /// Mouse Wheel Ecore event type.
+ /// </summary>
+ public static readonly EcoreEventType MouseWheel = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_WHEEL");
+ /// <summary>
+ /// Mouse In Ecore event type.
+ /// </summary>
+ public static readonly EcoreEventType MouseIn = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_IN");
+ /// <summary>
+ /// Mouse Out Ecore event type.
+ /// </summary>
+ public static readonly EcoreEventType MouseOut = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_OUT");
+
+ private string _lib;
+ private string _name;
+ private int _typeValue;
+
+ private EcoreEventType(string lib, string name)
+ {
+ _lib = lib;
+ _name = name;
+ _typeValue = -1;
+ }
+
+ /// <summary>
+ /// Gets the value associated with the specified type.
+ /// </summary>
+ /// <returns>The value of type.</returns>
+ public int GetValue()
+ {
+ if (_typeValue < 0)
+ {
+ IntPtr hDll = Interop.Libdl.LoadLibrary(_lib);
+ if (hDll != IntPtr.Zero)
+ {
+ IntPtr pValue = Interop.Libdl.GetProcAddress(hDll, _name);
+ if (pValue != IntPtr.Zero)
+ {
+ _typeValue = Marshal.ReadInt32(pValue);
+ }
+ Interop.Libdl.FreeLibrary(hDll);
+ }
+ }
+ return _typeValue;
+ }
+ }
+
+ /// <summary>
+ /// The EcoreEvent is a class to help to create events are being notified of events.
+ /// </summary>
+ /// <typeparam name="TEventArgs">Kinds of EventArgs</typeparam>
+ public class EcoreEvent<TEventArgs> : IDisposable where TEventArgs : EventArgs
+ {
+ public delegate TEventArgs EventInfoParser(IntPtr data, EcoreEventType type, IntPtr info);
+
+ private bool _disposed = false;
+ private EcoreEventType _eventType;
+ private readonly EventInfoParser _parser;
+ private readonly List<NativeCallback> _nativeCallbacks = new List<NativeCallback>();
+
+ /// <summary>
+ /// Creates and initializes a new instance of the EcoreEvent class.
+ /// </summary>
+ /// <param name="type">EcoreEventType</param>
+ public EcoreEvent(EcoreEventType type) : this(type, null)
+ {
+ }
+
+ /// <summary>
+ /// Creates and initializes a new instance of the EcoreEvent class.
+ /// </summary>
+ /// <param name="type">EcoreEventType</param>
+ /// <param name="parser">EventInfoParser</param>
+ public EcoreEvent(EcoreEventType type, EventInfoParser parser)
+ {
+ _eventType = type;
+ _parser = parser;
+ }
+
+ ~EcoreEvent()
+ {
+ Dispose(false);
+ }
+
+ private struct NativeCallback
+ {
+ public Interop.Ecore.EcoreEventCallback callback;
+ public IntPtr nativeHandler;
+ public EventHandler<TEventArgs> eventHandler;
+ }
+
+ /// <summary>
+ /// On Event Handler of EcoreEvent.
+ /// </summary>
+ public event EventHandler<TEventArgs> On
+ {
+ add
+ {
+ EventHandler<TEventArgs> handler = value;
+ var cb = new Interop.Ecore.EcoreEventCallback((data, type, info) =>
+ {
+ TEventArgs ea = _parser == null ? (TEventArgs)EventArgs.Empty : _parser(data, _eventType, info);
+ handler(this, ea);
+ });
+ IntPtr hNative = Interop.Ecore.ecore_event_handler_add(_eventType.GetValue(), cb, IntPtr.Zero);
+ _nativeCallbacks.Add(new NativeCallback { callback = cb, eventHandler = handler, nativeHandler = hNative });
+ }
+ remove
+ {
+ EventHandler<TEventArgs> handler = value;
+ var callbacks = _nativeCallbacks.Where(cb => cb.eventHandler == handler);
+ foreach (var cb in callbacks)
+ {
+ Interop.Ecore.ecore_event_handler_del(cb.nativeHandler);
+ }
+ }
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (disposing)
+ {
+ // Place holder to dispose managed state (managed objects).
+ }
+ foreach (var cb in _nativeCallbacks)
+ {
+ Interop.Ecore.ecore_event_handler_del(cb.nativeHandler);
+ }
+ _nativeCallbacks.Clear();
+ _disposed = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ }
+
+ /// <summary>
+ /// Event class for EcoreEvent
+ /// </summary>
+ public class EcoreEvent : EcoreEvent<EventArgs>
+ {
+ /// <summary>
+ /// Creates and initializes a new instance of the EcoreEvent class.
+ /// </summary>
+ /// <param name="type">EcoreEventType</param>
+ public EcoreEvent(EcoreEventType type) : base(type)
+ {
+ }
+ }
+}
+
diff --git a/src/ElmSharp/ElmSharp/EcoreKeyEventArgs.cs b/src/ElmSharp/ElmSharp/EcoreKeyEventArgs.cs
new file mode 100755
index 0000000..d057716
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/EcoreKeyEventArgs.cs
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// It inherits System.EventArgs.
+ /// The EcoreKeyEventArgs is a EventArgs to record Ecore event's key name and key code.
+ /// </summary>
+ public class EcoreKeyEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Gets the KeyName property.The return type is string.
+ /// </summary>
+ public string KeyName { get; private set; }
+ /// <summary>
+ /// Gets the KeyCode property.The return type is int.
+ /// </summary>
+ public int KeyCode { get; private set; }
+
+ /// <summary>
+ /// Creates and initializes a new instance of the EcoreKeyEventArgs class.
+ /// </summary>
+ /// <param name="data">data</param>
+ /// <param name="type">type</param>
+ /// <param name="info">information </param>
+ /// <returns>new instance of the EcoreKeyEventArgs class</returns>
+ public static EcoreKeyEventArgs Create(IntPtr data, EcoreEventType type, IntPtr info)
+ {
+ var evt = Marshal.PtrToStructure<EcoreEventKey>(info);
+ return new EcoreKeyEventArgs { KeyName = evt.keyname, KeyCode = (int)evt.keycode };
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ struct EcoreEventKey
+ {
+ public string keyname;
+ public string key;
+ public string str;
+ public string compose;
+ public IntPtr window;
+ public IntPtr root_window;
+ public IntPtr event_window;
+ public uint timestamp;
+ public uint modifiers;
+ public int same_screen;
+ public uint keycode;
+ public IntPtr data;
+ public IntPtr dev;
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/EcoreMainloop.cs b/src/ElmSharp/ElmSharp/EcoreMainloop.cs
new file mode 100755
index 0000000..505e2c0
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/EcoreMainloop.cs
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// EcoreMainloop is a helper class, it provide functions relative Ecore's main loop.
+ /// </summary>
+ public static class EcoreMainloop
+ {
+ static readonly Dictionary<int, Func<bool>> _taskMap = new Dictionary<int, Func<bool>>();
+ static readonly Object _taskLock = new Object();
+ static int _newTaskId = 0;
+
+ static Interop.Ecore.EcoreTaskCallback _nativeHandler;
+
+ static EcoreMainloop()
+ {
+ Interop.Ecore.ecore_init();
+ Interop.Ecore.ecore_main_loop_glib_integrate();
+ _nativeHandler = NativeHandler;
+ }
+
+ /// <summary>
+ /// Checks if you are calling this function from the main thread.
+ /// </summary>
+ /// <remarks>True is the calling function is the same thread, false otherwise.</remarks>
+ public static bool IsMainThread => Interop.Eina.eina_main_loop_is();
+
+ /// <summary>
+ /// Runs the application main loop.
+ /// </summary>
+ public static void Begin()
+ {
+ Interop.Ecore.ecore_main_loop_begin();
+ }
+
+ /// <summary>
+ /// Quits the main loop once all the events currently on the queue have been processed.
+ /// </summary>
+ public static void Quit()
+ {
+ Interop.Ecore.ecore_main_loop_quit();
+ }
+
+ /// <summary>
+ /// Adds an idler handler.
+ /// </summary>
+ /// <param name="task">The action to call when idling</param>
+ public static void Post(Action task)
+ {
+ int id = RegistHandler(() => { task(); return false; });
+ Interop.Ecore.ecore_idler_add(_nativeHandler, (IntPtr)id);
+ }
+
+ /// <summary>
+ /// Calls callback asynchronously in the main loop.
+ /// </summary>
+ /// <param name="task">The action wanted to be called</param>
+ public static void PostAndWakeUp(Action task)
+ {
+ int id = RegistHandler(() => { task(); return false; });
+ Interop.Ecore.ecore_main_loop_thread_safe_call_async(_nativeHandler, (IntPtr)id);
+ }
+
+ /// <summary>
+ /// Calls callback synchronously in the main loop.
+ /// </summary>
+ /// <param name="task">The action wanted to be called</param>
+ public static void Send(Action task)
+ {
+ int id = RegistHandler(() => { task(); return false; });
+ Interop.Ecore.ecore_main_loop_thread_safe_call_sync(_nativeHandler, (IntPtr)id);
+ }
+
+ /// <summary>
+ /// Creates a timer to call the given function in the given period of time.
+ /// </summary>
+ /// <param name="interval">The interval in seconds.</param>
+ /// <param name="handler">The given function.</param>
+ /// <returns>A timer object handler on success, NULL on failure.</returns>
+ public static IntPtr AddTimer(double interval, Func<bool> handler)
+ {
+ int id = RegistHandler(handler);
+ return Interop.Ecore.ecore_timer_add(interval, _nativeHandler, (IntPtr)id);
+ }
+
+ /// <summary>
+ /// Removes the specified timer from the timer list.
+ /// </summary>
+ /// <param name="id">The specified timer handler</param>
+ public static void RemoveTimer(IntPtr id)
+ {
+ int taskId = (int)Interop.Ecore.ecore_timer_del(id);
+ _taskMap.Remove(taskId);
+ }
+
+ static int RegistHandler(Func<bool> task)
+ {
+ int taskId;
+ lock (_taskLock)
+ {
+ taskId = _newTaskId++;
+ }
+ _taskMap[taskId] = task;
+ return taskId;
+ }
+
+ static bool NativeHandler(IntPtr user_data)
+ {
+ int task_id = (int)user_data;
+ Func<bool> userAction = null;
+ if (_taskMap.TryGetValue(task_id, out userAction))
+ {
+ bool result = false;
+
+ if (userAction != null)
+ result = userAction();
+
+ if (result == false)
+ _taskMap.Remove(task_id);
+
+ return result;
+ }
+ return false;
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/EcoreSynchronizationContext.cs b/src/ElmSharp/ElmSharp/EcoreSynchronizationContext.cs
new file mode 100755
index 0000000..0fa013b
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/EcoreSynchronizationContext.cs
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System.Threading;
+
+namespace ElmSharp
+{
+
+ /// <summary>
+ /// Provides a synchronization context for the efl application.
+ /// </summary>
+ public class EcoreSynchronizationContext : SynchronizationContext
+ {
+ /// <summary>
+ /// Initializes a new instance of the EcoreSynchronizationContext class.
+ /// </summary>
+ public EcoreSynchronizationContext()
+ {
+ }
+
+ /// <summary>
+ /// Initilizes a new EcoreSynchronizationContext and install into current thread
+ /// </summary>
+ /// <remarks>
+ /// It is equivalent
+ /// <code>
+ /// SetSynchronizationContext(new EcoreSynchronizationContext());
+ /// </code>
+ /// </remarks>
+ public static void Initialize()
+ {
+ SetSynchronizationContext(new EcoreSynchronizationContext());
+ }
+
+ /// <summary>
+ /// Dispatches an asynchronous message to a Ecore main loop.
+ /// </summary>
+ /// <param name="d"><see cref="System.Threading.SendOrPostCallback"/>The SendOrPostCallback delegate to call.</param>
+ /// <param name="state"><see cref="System.Object"/>The object passed to the delegate.</param>
+ /// <remarks>The Post method starts an asynchronous request to post a message.</remarks>
+ public override void Post(SendOrPostCallback d, object state)
+ {
+ EcoreMainloop.PostAndWakeUp(() =>
+ {
+ d(state);
+ });
+ }
+
+ /// <summary>
+ /// Dispatches a synchronous message to a Ecore main loop
+ /// </summary>
+ /// <param name="d"><see cref="System.Threading.SendOrPostCallback"/>The SendOrPostCallback delegate to call.</param>
+ /// <param name="state"><see cref="System.Object"/>The object passed to the delegate.</param>
+ /// <remarks>
+ /// The Send method starts a synchronous request to send a message.</remarks>
+ public override void Send(SendOrPostCallback d, object state)
+ {
+ EcoreMainloop.Send(() =>
+ {
+ d(state);
+ });
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/EdjeObject.cs b/src/ElmSharp/ElmSharp/EdjeObject.cs
new file mode 100644
index 0000000..6bd1fb6
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/EdjeObject.cs
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The EdjeObject is a class that evas object exist in
+ /// </summary>
+ public class EdjeObject
+ {
+ IntPtr _edjeHandle;
+ Dictionary<SignalData, Interop.Elementary.Edje_Signal_Cb> _signalDatas = new Dictionary<SignalData, Interop.Elementary.Edje_Signal_Cb>();
+
+ internal EdjeObject(IntPtr handle)
+ {
+ _edjeHandle = handle;
+ }
+
+ /// <summary>
+ /// Checks whether an edje part exists in a given edje object's group definition.
+ /// This function returns if a given part exists in the edje group bound to object obj
+ /// </summary>
+ /// <remarks>This call is useful, for example, when one could expect a given GUI element, depending on the theme applied to obj.</remarks>
+ /// <param name="part">The part's name to check for existence in obj's group</param>
+ /// <returns>TRUE, if the edje part exists in obj's group, otherwise FALSE</returns>
+ public EdjeTextPartObject this[string part]
+ {
+ get
+ {
+ if (Interop.Elementary.edje_object_part_exists(_edjeHandle, part))
+ {
+ return new EdjeTextPartObject(_edjeHandle, part);
+ }
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Sends/emits an edje signal to a given edje object.
+ /// </summary>
+ /// <param name="emission">The signal's "emission" string</param>
+ /// <param name="source">The signal's "source" string</param>
+ public void EmitSignal(string emission, string source)
+ {
+ Interop.Elementary.edje_object_signal_emit(_edjeHandle, emission, source);
+ }
+
+ /// <summary>
+ /// Deletes the object color class.
+ /// This function deletes any values at the object level for the specified object and color class.
+ /// </summary>
+ /// <remarks>Deleting the color class defined in the theme file.</remarks>
+ /// <param name="part">The color class to be deleted</param>
+ public void DeleteColorClass(string part)
+ {
+ Interop.Elementary.edje_object_color_class_del(_edjeHandle, part);
+ }
+
+ /// <summary>
+ /// Sets the object color class.
+ /// </summary>
+ /// <param name="colorClass">The color class name.</param>
+ /// <param name="red">The object Red value.</param>
+ /// <param name="green">The object Green value.</param>
+ /// <param name="blue">The object Blue value.</param>
+ /// <param name="alpha">The object Alpha value.</param>
+ /// <param name="outlineRed">The outline Red value.</param>
+ /// <param name="outlineGreen">The outline Green value.</param>
+ /// <param name="outlineBlue">The outline Blue value.</param>
+ /// <param name="outlineAlpha">The outline Alpha value.</param>
+ /// <param name="shadowRed">The shadow Red value.</param>
+ /// <param name="shadowGreen">The shadow Green value.</param>
+ /// <param name="shadowBlue">The shadow Blue value.</param>
+ /// <param name="shadowAlpha">The shadow Alpha value.</param>
+ /// <returns>True if succeed, otherwise False</returns>
+ public bool SetColorClass(string colorClass, int red, int green, int blue, int alpha, int outlineRed, int outlineGreen, int outlineBlue, int outlineAlpha,
+ int shadowRed, int shadowGreen, int shadowBlue, int shadowAlpha)
+ {
+ return Interop.Elementary.edje_object_color_class_set(_edjeHandle, colorClass, red, green, blue, alpha, outlineRed, outlineGreen, outlineBlue, outlineAlpha,
+ shadowRed, shadowGreen, shadowBlue, shadowAlpha);
+ }
+
+ /// <summary>
+ /// Gets the object color class.
+ /// </summary>
+ /// <param name="colorClass">The color class name.</param>
+ /// <param name="red">The object Red value.</param>
+ /// <param name="green">The object Green value.</param>
+ /// <param name="blue">The object Blue value.</param>
+ /// <param name="alpha">The object Alpha value.</param>
+ /// <param name="outlineRed">The outline Red value.</param>
+ /// <param name="outlineGreen">The outline Green value.</param>
+ /// <param name="outlineBlue">The outline Blue value.</param>
+ /// <param name="outlineAlpha">The outline Alpha value.</param>
+ /// <param name="shadowRed">The shadow Red value.</param>
+ /// <param name="shadowGreen">The shadow Green value.</param>
+ /// <param name="shadowBlue">The shadow Blue value.</param>
+ /// <param name="shadowAlpha">The shadow Alpha value.</param>
+ /// <returns>True if succeed, otherwise False</returns>
+ public bool GetColorClass(string colorClass, out int red, out int green, out int blue, out int alpha, out int outlineRed, out int outlineGreen, out int outlineBlue, out int outlineAlpha,
+ out int shadowRed, out int shadowGreen, out int shadowBlue, out int shadowAlpha)
+ {
+ return Interop.Elementary.edje_object_color_class_get(_edjeHandle, colorClass, out red, out green, out blue, out alpha, out outlineRed, out outlineGreen, out outlineBlue, out outlineAlpha,
+ out shadowRed, out shadowGreen, out shadowBlue, out shadowAlpha);
+ }
+
+ /// <summary>
+ /// Sets Edje text class.
+ /// </summary>
+ /// <param name="textClass">The text class name.</param>
+ /// <param name="font"> Font name.</param>
+ /// <param name="fontSize">Font size.</param>
+ /// <returns>True if succeed, otherwise False</returns>
+ public bool SetTextClass(string textClass, string font, int fontSize)
+ {
+ return Interop.Elementary.edje_object_text_class_set(_edjeHandle, textClass, font, fontSize);
+ }
+
+ /// <summary>
+ /// Gets Edje text class.
+ /// </summary>
+ /// <param name="textClass">The text class name.</param>
+ /// <param name="font">Font name.</param>
+ /// <param name="fontSize">Font size.</param>
+ /// <returns>True if succeed, otherwise False</returns>
+ public bool GetTextClass(string textClass, out string font, out int fontSize)
+ {
+ return Interop.Elementary.edje_object_text_class_get(_edjeHandle, textClass, out font, out fontSize);
+ }
+
+ /// <summary>
+ /// Adds Action for an arriving edje signal, emitted by a given Ejde object.
+ /// </summary>
+ /// <param name="emission">The signal's "emission" string</param>
+ /// <param name="source">The signal's "source" string</param>
+ /// <param name="action">The action to be executed when the signal is emitted</param>
+ public void AddSignalAction(string emission, string source, Action<string, string> action)
+ {
+ if (emission != null && source != null && action != null)
+ {
+ var signalData = new SignalData(emission, source, action);
+ if (!_signalDatas.ContainsKey(signalData))
+ {
+ var signalCallback = new Interop.Elementary.Edje_Signal_Cb((d, o, e, s) =>
+ {
+ action(e, s);
+ });
+
+ Interop.Elementary.edje_object_signal_callback_add(_edjeHandle, emission, source, signalCallback, IntPtr.Zero);
+ _signalDatas.Add(signalData, signalCallback);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Deletes a signal-triggered action from an object.
+ /// </summary>
+ /// <param name="emission">The signal's "emission" string</param>
+ /// <param name="source">The signal's "source" string</param>
+ /// <param name="action">The action to be executed when the signal is emitted</param>
+ public void DeleteSignalAction(string emission, string source, Action<string, string> action)
+ {
+ if (emission != null && source != null && action != null)
+ {
+ var signalData = new SignalData(emission, source, action);
+
+ Interop.Elementary.Edje_Signal_Cb signalCallback = null;
+ _signalDatas.TryGetValue(signalData, out signalCallback);
+
+ if (signalCallback != null)
+ {
+ Interop.Elementary.edje_object_signal_callback_del(_edjeHandle, emission, source, signalCallback);
+ _signalDatas.Remove(signalData);
+ }
+ }
+ }
+
+ class SignalData
+ {
+ public string Emission { get; set; }
+ public string Source { get; set; }
+
+ public Action<string, string> Action { get; set; }
+
+ public SignalData(string emission, string source, Action<string, string> action)
+ {
+ Emission = emission;
+ Source = source;
+ Action = action;
+ }
+
+ public override bool Equals(object obj)
+ {
+ SignalData s = obj as SignalData;
+ if (s == null)
+ {
+ return false;
+ }
+ return (Emission == s.Emission) && (Source == s.Source) && (Action == s.Action);
+ }
+
+ public override int GetHashCode()
+ {
+ int hashCode = Emission.GetHashCode();
+ hashCode ^= Source.GetHashCode();
+ hashCode ^= Action.GetHashCode();
+ return hashCode;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An EdjeTextPartObject is a class dealing with parts of type text.
+ /// </summary>
+ public class EdjeTextPartObject
+ {
+ string _part;
+ IntPtr _edjeHandle;
+
+ internal EdjeTextPartObject(IntPtr edjeHandle, string part)
+ {
+ _edjeHandle = edjeHandle;
+ _part = part;
+ }
+
+ /// <summary>
+ /// Gets the name of the EdjeTextPartObject
+ /// </summary>
+ public string Name { get { return _part; } }
+
+ /// <summary>
+ /// Gets or sets the text for an object part.
+ /// </summary>
+ public string Text
+ {
+ get
+ {
+ return Interop.Elementary.edje_object_part_text_get(_edjeHandle, _part);
+ }
+ set
+ {
+ Interop.Elementary.edje_object_part_text_set(_edjeHandle, _part, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the style of the object part.
+ /// </summary>
+ public string TextStyle
+ {
+ get
+ {
+ return Interop.Elementary.edje_object_part_text_style_user_peek(_edjeHandle, _part);
+ }
+ set
+ {
+ if (value == null)
+ {
+ Interop.Elementary.edje_object_part_text_style_user_pop(_edjeHandle, _part);
+ }
+ else
+ {
+ Interop.Elementary.edje_object_part_text_style_user_push(_edjeHandle, _part, value);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the geometry of a given edje part, in a given edje object's group definition, relative to the object's area.
+ /// </summary>
+ public Rect Geometry
+ {
+ get
+ {
+ int x, y, w, h;
+ Interop.Elementary.edje_object_part_geometry_get(_edjeHandle, _part, out x, out y, out w, out h);
+ return new Rect(x, y, w, h);
+ }
+ }
+
+ /// <summary>
+ /// Gets the native width and height.
+ /// </summary>
+ public Size TextBlockNativeSize
+ {
+ get
+ {
+ int w;
+ int h;
+ IntPtr part = Interop.Elementary.edje_object_part_object_get(_edjeHandle, _part);
+ Interop.Evas.evas_object_textblock_size_native_get(part, out w, out h);
+ return new Size(w, h);
+ }
+ }
+
+ /// <summary>
+ /// Gets the formatted width and height.
+ /// </summary>
+ public Size TextBlockFormattedSize
+ {
+ get
+ {
+ int w;
+ int h;
+ IntPtr part = Interop.Elementary.edje_object_part_object_get(_edjeHandle, _part);
+ Interop.Evas.evas_object_textblock_size_formatted_get(part, out w, out h);
+ return new Size(w, h);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/EffectBase.cs b/src/ElmSharp/ElmSharp/EffectBase.cs
new file mode 100755
index 0000000..19eddb0
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/EffectBase.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// EffectBase class for the TransitEffect
+ /// </summary>
+ public abstract class EffectBase
+ {
+ /// <summary>
+ /// EffectEneded event will be triggered when be effect ended.
+ /// </summary>
+ public event EventHandler EffectEnded;
+
+ internal abstract IntPtr CreateEffect(IntPtr transit);
+
+ internal void SendEffectEnd()
+ {
+ EffectEnded?.Invoke(this, EventArgs.Empty);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/Elementary.cs b/src/ElmSharp/ElmSharp/Elementary.cs
new file mode 100644
index 0000000..cf26c57
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Elementary.cs
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.ComponentModel;
+using System.IO;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The Elementary is a General Elementary,a VERY SIMPLE toolkit.
+ /// </summary>
+ public static class Elementary
+ {
+ private static readonly string _themeFilePath = "/usr/share/elm-sharp/elm-sharp-theme.edj";
+
+ /// <summary>
+ /// Gets or sets the configured finger size.
+ /// </summary>
+ public static int FingerSize
+ {
+ get
+ {
+ return Interop.Elementary.elm_config_finger_size_get();
+ }
+ set
+ {
+ Interop.Elementary.elm_config_finger_size_set(value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the enable status of the focus highlight animation
+ /// </summary>
+ public static bool IsFocusHighlightAnimation
+ {
+ get
+ {
+ return Interop.Elementary.elm_config_focus_highlight_animate_get();
+ }
+ set
+ {
+ Interop.Elementary.elm_config_focus_highlight_animate_set(value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the system mirrored mode.
+ /// This determines the default mirrored mode of widgets.
+ /// </summary>
+ public static bool IsMirrored
+ {
+ get
+ {
+ return Interop.Elementary.elm_config_mirrored_get();
+ }
+ set
+ {
+ Interop.Elementary.elm_config_mirrored_set(value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the enable status of the focus highlight.
+ /// </summary>
+ public static bool CanFocusHighlight
+ {
+ get
+ {
+ return Interop.Elementary.elm_config_focus_highlight_enabled_get();
+ }
+ set
+ {
+ Interop.Elementary.elm_config_focus_highlight_enabled_set(value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the base scale of the application.
+ /// </summary>
+ public static double AppBaseScale
+ {
+ get
+ {
+ return Interop.Elementary.elm_app_base_scale_get();
+ }
+ set
+ {
+ Interop.Elementary.elm_app_base_scale_set(value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the global scaling factor.
+ /// </summary>
+ public static double Scale
+ {
+ get
+ {
+ return Interop.Elementary.elm_config_scale_get();
+ }
+ set
+ {
+ Interop.Elementary.elm_config_scale_set(value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the amount of inertia a scroller imposes during region bring animations.
+ /// </summary>
+ public static double BringInScrollFriction
+ {
+ get
+ {
+ return Interop.Elementary.elm_config_scroll_bring_in_scroll_friction_get();
+ }
+ set
+ {
+ Interop.Elementary.elm_config_scroll_bring_in_scroll_friction_set(value);
+ }
+ }
+
+ /// <summary>
+ /// Initializes Elementary.
+ /// </summary>
+ public static void Initialize()
+ {
+ Interop.Elementary.elm_init(0, null);
+ }
+
+ /// <summary>
+ /// Shuts down Elementary.
+ /// </summary>
+ public static void Shutdown()
+ {
+ Interop.Elementary.elm_shutdown();
+ }
+
+ /// <summary>
+ /// Runs Elementary's main loop.
+ /// </summary>
+ public static void Run()
+ {
+ Interop.Elementary.elm_run();
+ }
+
+ /// <summary>
+ /// Prepends a theme overlay to the list of overlays.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static void ThemeOverlay()
+ {
+ if (File.Exists(_themeFilePath))
+ {
+ AddThemeOverlay(_themeFilePath);
+ }
+ }
+
+ /// <summary>
+ /// Prepends a theme overlay to the list of overlays
+ /// </summary>
+ /// <param name="filePath">The Edje file path to be used.</param>
+ public static void AddThemeOverlay(string filePath)
+ {
+ Interop.Elementary.elm_theme_overlay_add(IntPtr.Zero, filePath);
+ }
+
+ /// <summary>
+ /// Delete a theme overlay from the list of overlays
+ /// </summary>
+ /// <param name="filePath">The name of the theme overlay.</param>
+ public static void DeleteThemeOverlay(string filePath)
+ {
+ Interop.Elementary.elm_theme_overlay_del(IntPtr.Zero, filePath);
+ }
+
+ /// <summary>
+ /// Free a theme
+ /// </summary>
+ public static void FreeTheme()
+ {
+ Interop.Elementary.elm_theme_free(IntPtr.Zero);
+ }
+
+ /// <summary>
+ /// Set the theme search order for the given theme
+ /// </summary>
+ /// <param name="theme">Theme search string</param>
+ /// <remarks>This sets the search string for the theme in path-notation from first theme to search, to last, delimited by the : character. Example:"shiny:/path/to/file.edj:default"</remarks>
+ public static void SetTheme(string theme)
+ {
+ Interop.Elementary.elm_theme_set(IntPtr.Zero, theme);
+ }
+
+ /// <summary>
+ /// Flush the current theme.
+ /// </summary>
+ public static void FlushTheme()
+ {
+ Interop.Elementary.elm_theme_flush(IntPtr.Zero);
+ }
+
+ /// <summary>
+ /// This flushes all themes (default and specific ones).
+ /// </summary>
+ public static void FlushAllThemes()
+ {
+ Interop.Elementary.elm_theme_full_flush();
+ }
+
+ /// <summary>
+ /// Deletes a theme extension from the list of extensions.
+ /// </summary>
+ /// <param name="item">The name of the theme extension.</param>
+ public static void DeleteThemeExtention(string item)
+ {
+ Interop.Elementary.elm_theme_extension_del(IntPtr.Zero, item);
+ }
+
+ /// <summary>
+ /// Gets the amount of inertia a scroller imposes during region bring animations.
+ /// </summary>
+ /// <returns>The bring in scroll friction</returns>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static double GetSystemScrollFriction()
+ {
+ return BringInScrollFriction;
+ }
+
+ /// <summary>
+ /// Sets the amount of inertia a scroller imposes during region bring animations.
+ /// </summary>
+ /// <param name="timeSet">The bring in scroll friction</param>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static void SetSystemScrollFriction(double timeSet)
+ {
+ BringInScrollFriction = timeSet;
+ }
+
+ /// <summary>
+ /// Gets Elementary's profile in use.
+ /// </summary>
+ /// <returns>The profile name</returns>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static string GetProfile()
+ {
+ return Interop.Elementary.elm_config_profile_get();
+ }
+
+ /// <summary>
+ /// Sets the global scaling factor.
+ /// This sets the globally configured scaling factor that is applied to all objects.
+ /// </summary>
+ /// <param name="scale">The scaling factor to set</param>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static void SetScale(double scale)
+ {
+ Scale = scale;
+ }
+
+ /// <summary>
+ /// Gets the global scaling factor.
+ /// This gets the globally configured scaling factor that is applied to all objects.
+ /// </summary>
+ /// <returns>The scaling factor</returns>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static double GetScale()
+ {
+ return Scale;
+ }
+
+ /// <summary>
+ /// Flush all caches.
+ /// Frees all data that was in cache and is not currently being used to reduce memory usage. This frees Edje's, Evas' and Eet's cache.
+ /// </summary>
+ public static void FlushAllCashe()
+ {
+ Interop.Elementary.elm_cache_all_flush();
+ }
+
+ /// <summary>
+ /// Changes the language of the current application.
+ /// </summary>
+ /// <param name="language">The language to set, must be the full name of the locale.</param>
+ public static void SetLanguage(string language)
+ {
+ Interop.Elementary.elm_language_set(language);
+ }
+
+ /// <summary>
+ /// Sets a new policy's value (for a given policy group/identifier).
+ /// </summary>
+ /// <param name="policy">The policy identifier</param>
+ /// <param name="value">The policy value, which depends on the identifier</param>
+ /// <returns></returns>
+ public static bool SetPolicy(uint policy, int value)
+ {
+ return Interop.Elementary.elm_policy_set(policy, value);
+ }
+
+ /// <summary>
+ /// Reloads Elementary's configuration, bounded to the current selected profile.
+ /// </summary>
+ public static void ReloadConfig()
+ {
+ Interop.Elementary.elm_config_reload();
+ }
+
+ /// <summary>
+ /// Flushes all config settings and then applies those settings to all applications using elementary on the current display.
+ /// </summary>
+ public static void FlushAllConfig()
+ {
+ Interop.Elementary.elm_config_all_flush();
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/ElmScrollConfig.cs b/src/ElmSharp/ElmSharp/ElmScrollConfig.cs
new file mode 100644
index 0000000..c3079e2
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/ElmScrollConfig.cs
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.ComponentModel;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The ElmScrollConfig is a scrollable views's config
+ /// </summary>
+ public static class ElmScrollConfig
+ {
+ /// <summary>
+ /// Gets or sets the amount of inertia a scroller imposes during region bring animations.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static double BringInScrollFriction
+ {
+ get
+ {
+ return Elementary.BringInScrollFriction;
+ }
+ set
+ {
+ Elementary.BringInScrollFriction = value;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/Entry.cs b/src/ElmSharp/ElmSharp/Entry.cs
new file mode 100755
index 0000000..67c7ff9
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Entry.cs
@@ -0,0 +1,1045 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// Enumeration for describing InputPanel layout type.
+ /// </summary>
+ public enum InputPanelLayout
+ {
+ /// <summary>
+ /// InputPanel layout type default.
+ /// </summary>
+ Normal,
+
+ /// <summary>
+ /// InputPanel layout type number.
+ /// </summary>
+ Number,
+
+ /// <summary>
+ /// InputPanel layout type email.
+ /// </summary>
+ Email,
+
+ /// <summary>
+ /// InputPanel layout type url.
+ /// </summary>
+ Url,
+
+ /// <summary>
+ /// InputPanel layout type phone.
+ /// </summary>
+ PhoneNumber,
+
+ /// <summary>
+ /// InputPanel layout type ip.
+ /// </summary>
+ Ip,
+
+ /// <summary>
+ /// InputPanel layout type month.
+ /// </summary>
+ Month,
+
+ /// <summary>
+ /// InputPanel layout type number.
+ /// </summary>
+ NumberOnly,
+
+ /// <summary>
+ /// InputPanel layout type error type. Do not use it directly!
+ /// </summary>
+ Invalid,
+
+ /// <summary>
+ /// InputPanel layout type hexadecimal.
+ /// </summary>
+ Hex,
+
+ /// <summary>
+ /// InputPanel layout type terminal type, esc, alt, ctrl, etc.
+ /// </summary>
+ Terminal,
+
+ /// <summary>
+ /// InputPanel layout type password.
+ /// </summary>
+ Password,
+
+ /// <summary>
+ /// Keyboard layout type date and time.
+ /// </summary>
+ DateTime,
+
+ /// <summary>
+ /// InputPanel layout type emoticons.
+ /// </summary>
+ Emoticon
+ }
+
+ /// <summary>
+ /// Enumeration that defines the "Return" key types on the input panel (virtual keyboard).
+ /// </summary>
+ public enum InputPanelReturnKeyType
+ {
+ /// <summary>
+ /// Default key type
+ /// </summary>
+ Default,
+
+ /// <summary>
+ /// Done key type
+ /// </summary>
+ Done,
+
+ /// <summary>
+ /// Go key type
+ /// </summary>
+ Go,
+
+ /// <summary>
+ /// Join key type
+ /// </summary>
+ Join,
+
+ /// <summary>
+ /// Login key type
+ /// </summary>
+ Login,
+
+ /// <summary>
+ /// Next key type
+ /// </summary>
+ Next,
+
+ /// <summary>
+ /// Search string or magnifier icon key type
+ /// </summary>
+ Search,
+
+ /// <summary>
+ /// Send key type
+ /// </summary>
+ Send,
+
+ /// <summary>
+ /// Sign-in key type
+ /// </summary>
+ Signin
+ }
+
+ /// <summary>
+ /// Enumeration that defines the autocapitalization types.
+ /// </summary>
+ public enum AutoCapital
+ {
+ /// <summary>
+ /// No autocapitalization when typing
+ /// </summary>
+ None,
+
+ /// <summary>
+ /// Autocapitalize each typed word
+ /// </summary>
+ Word,
+
+ /// <summary>
+ /// Autocapitalize the start of each sentence
+ /// </summary>
+ Sentence,
+
+ /// <summary>
+ /// Autocapitalize all letters
+ /// </summary>
+ All
+ }
+
+ /// <summary>
+ /// Enumeration that defines the entry's copy & paste policy.
+ /// </summary>
+ public enum CopyAndPasteMode
+ {
+ /// <summary>
+ /// Copy & paste text with markup tag
+ /// </summary>
+ Markup,
+
+ /// <summary>
+ /// Copy & paste text without item(image) tag
+ /// </summary>
+ NoImage,
+
+ /// <summary>
+ /// Copy & paste text without markup tag
+ /// </summary>
+ PlainText
+ }
+
+ /// <summary>
+ /// Enumeration that defines the text format types.
+ /// </summary>
+ public enum TextFormat
+ {
+ /// <summary>
+ /// Plain type
+ /// </summary>
+ Plain,
+
+ /// <summary>
+ /// Markup type
+ /// </summary>
+ Markup
+ }
+
+ /// <summary>
+ /// Enumeration that defines the types of Input Hints.
+ /// </summary>
+ public enum InputHints
+ {
+ /// <summary>
+ /// No active hints
+ /// </summary>
+ None,
+
+ /// <summary>
+ /// suggest word auto completion
+ /// </summary>
+ AutoComplete,
+
+ /// <summary>
+ /// typed text should not be stored.
+ /// </summary>
+ SensitiveData,
+ }
+
+ /// <summary>
+ /// Enumeration that defines the input panel (virtual keyboard) language modes.
+ /// </summary>
+ public enum InputPanelLanguage
+ {
+ /// <summary>
+ /// Automatic language mode
+ /// </summary>
+ Automatic,
+
+ /// <summary>
+ /// Alphabet language mode
+ /// </summary>
+ Alphabet,
+ }
+
+ /// <summary>
+ /// The entry is a convenience widget that shows a box in which the user can enter text.
+ /// </summary>
+ public class Entry : Layout
+ {
+ SmartEvent _clicked;
+ SmartEvent _changedByUser;
+ SmartEvent _cursorChanged;
+ SmartEvent _activated;
+
+ Dictionary<Func<string, EvasObject>, Interop.Elementary.Elm_Entry_Item_Provider_Cb> _itemsProvider = new Dictionary<Func<string, EvasObject>, Interop.Elementary.Elm_Entry_Item_Provider_Cb>();
+ Dictionary<Func<Entry, string, string>, Interop.Elementary.Elm_Entry_Filter_Cb> _textFilters = new Dictionary<Func<Entry, string, string>, Interop.Elementary.Elm_Entry_Filter_Cb>();
+
+ /// <summary>
+ /// Creates and initializes a new instance of the Entry class.
+ /// </summary>
+ /// <param name="parent">The EvasObject to which the new Entry will be attached as a child.</param>
+ public Entry(EvasObject parent) : base(parent)
+ {
+ _clicked = new SmartEvent(this, this.RealHandle, "clicked");
+ _clicked.On += (s, e) => Clicked?.Invoke(this, EventArgs.Empty);
+
+ _changedByUser = new SmartEvent(this, this.RealHandle, "changed,user");
+ _changedByUser.On += (s, e) => ChangedByUser?.Invoke(this, EventArgs.Empty);
+
+ _cursorChanged = new SmartEvent(this, this.RealHandle, "cursor,changed");
+ _cursorChanged.On += (s, e) => CursorChanged?.Invoke(this, EventArgs.Empty);
+
+ _activated = new SmartEvent(this, this.RealHandle, "activated");
+ _activated.On += (s, e) => Activated?.Invoke(this, EventArgs.Empty);
+ }
+
+ /// <summary>
+ /// Activated will be triggered when the entry in Activated stated.
+ /// </summary>
+ public event EventHandler Activated;
+
+ /// <summary>
+ /// Clicked will be triggered when the entry is clicked.
+ /// </summary>
+ public event EventHandler Clicked;
+
+ /// <summary>
+ /// ChangedByUser will be triggered when the entry changed by user.
+ /// </summary>
+ public event EventHandler ChangedByUser;
+
+ /// <summary>
+ /// CursorChanged will be triggered when the Cursor in the entry is changed.
+ /// </summary>
+ public event EventHandler CursorChanged;
+
+ /// <summary>
+ /// Sets or gets the entry to the single line mode.
+ /// </summary>
+ public bool IsSingleLine
+ {
+ get
+ {
+ return Interop.Elementary.elm_entry_single_line_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_entry_single_line_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the entry to the password mode.
+ /// </summary>
+ public bool IsPassword
+ {
+ get
+ {
+ return Interop.Elementary.elm_entry_password_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_entry_password_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets whether the entry is editable.
+ /// </summary>
+ public bool IsEditable
+ {
+ get
+ {
+ return Interop.Elementary.elm_entry_editable_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_entry_editable_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets whether the entry is empty.
+ /// </summary>
+ public bool IsEmpty
+ {
+ get
+ {
+ return Interop.Elementary.elm_entry_is_empty(RealHandle);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets text currently shown in the object entry.
+ /// </summary>
+ public override string Text
+ {
+ get
+ {
+ return Interop.Elementary.elm_entry_entry_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_entry_entry_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the style on the top of the user style stack.
+ /// </summary>
+ /// <remarks>If there is styles in the user style stack, the properties in the top style of user style stack will replace the properties in current theme. The input style is specified in format tag='property=value' (i.e. DEFAULT='font=Sans font_size=60'hilight=' + font_weight=Bold').</remarks>
+ public string TextStyle
+ {
+ get
+ {
+ return Interop.Elementary.elm_entry_text_style_user_peek(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_entry_text_style_user_push(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the current position of the cursor in the entry.
+ /// </summary>
+ public int CursorPosition
+ {
+ get
+ {
+ return Interop.Elementary.elm_entry_cursor_pos_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_entry_cursor_pos_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the scrollable state of the entry.
+ /// </summary>
+ public bool Scrollable
+ {
+ get
+ {
+ return Interop.Elementary.elm_entry_scrollable_get(RealHandle);
+ }
+ set
+ {
+ // HACK: Enabling the scrollable property of an entry causes its internal
+ // hierarchy to change, making the internal edje object inaccessible.
+ // Access it before the property is set, to cache the edje object's handle.
+ if (value)
+ {
+ var dummy = EdjeObject;
+ }
+ Interop.Elementary.elm_entry_scrollable_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or Gets the autocapitalization type on the immodule.
+ /// </summary>
+ public AutoCapital AutoCapital
+ {
+ get
+ {
+ return (AutoCapital)Interop.Elementary.elm_entry_autocapital_type_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_entry_autocapital_type_set(RealHandle, (Interop.Elementary.AutocapitalType)value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or Gets the entry object's 'autosave' status.
+ /// </summary>
+ public bool IsAutoSave
+ {
+ get
+ {
+ return Interop.Elementary.elm_entry_autosave_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_entry_autosave_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or Gets entry text paste/drop mode.
+ /// </summary>
+ public CopyAndPasteMode CopyAndPasteMode
+ {
+ get
+ {
+ return (CopyAndPasteMode)Interop.Elementary.elm_entry_cnp_mode_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_entry_cnp_mode_set(RealHandle, (Interop.Elementary.CopyAndPasteMode)value);
+ }
+ }
+
+ /// <summary>
+ /// Gets the geometry of the cursor.
+ /// </summary>
+ public Rect CursorGeometry
+ {
+ get
+ {
+ int x, y, w, h;
+ Interop.Elementary.elm_entry_cursor_geometry_get(RealHandle, out x, out y, out w, out h);
+ return new Rect(x, y, w, h);
+ }
+ }
+
+ /// <summary>
+ /// Gets whether a format node exists at the current cursor position.
+ /// </summary>
+ public bool IsCursorFormat
+ {
+ get
+ {
+ return Interop.Elementary.elm_entry_cursor_is_format_get(RealHandle);
+ }
+ }
+
+ /// <summary>
+ /// Gets if the current cursor position holds a visible format node.
+ /// </summary>
+ public bool IsCursorVisibelFormat
+ {
+ get
+ {
+ return Interop.Elementary.elm_entry_cursor_is_visible_format_get(RealHandle);
+ }
+ }
+
+ /// <summary>
+ /// Sets or Gets the value of input hint.
+ /// </summary>
+ public InputHints InputHint
+ {
+ get
+ {
+ return (InputHints)Interop.Elementary.elm_entry_input_hint_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_entry_input_hint_set(RealHandle, (Interop.Elementary.InputHints)value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the language mode of the input panel.
+ /// </summary>
+ public InputPanelLanguage InputPanelLanguage
+ {
+ get
+ {
+ return (InputPanelLanguage)Interop.Elementary.elm_entry_input_panel_language_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_entry_input_panel_language_set(RealHandle, (Interop.Elementary.InputPanelLanguage)value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the input panel layout variation of the entry.
+ /// </summary>
+ public int InputPanelVariation
+ {
+ get
+ {
+ return Interop.Elementary.elm_entry_input_panel_layout_variation_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_entry_input_panel_layout_variation_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the line wrap type to use on multi-line entries.
+ /// </summary>
+ public WrapType LineWrapType
+ {
+ get
+ {
+ return (WrapType)Interop.Elementary.elm_entry_line_wrap_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_entry_line_wrap_set(RealHandle, (Interop.Elementary.WrapType)value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets whether the entry should allow to use the text prediction.
+ /// </summary>
+ public bool PredictionAllowed
+ {
+ get
+ {
+ return Interop.Elementary.elm_entry_prediction_allow_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_entry_prediction_allow_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets whether the return key on the input panel should be disabled or not.
+ /// </summary>
+ public bool InputPanelReturnKeyDisabled
+ {
+ get
+ {
+ return Interop.Elementary.elm_entry_input_panel_return_key_disabled_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_entry_input_panel_return_key_disabled_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the attribute to show the input panel in case of only an user's explicit Mouse Up event.
+ /// It doesn't request to show the input panel even though it has focus.
+ /// If true, the input panel will be shown in case of only Mouse up event. (Focus event will be ignored.)
+ /// </summary>
+ public bool InputPanelShowByOnDemand
+ {
+ get
+ {
+ return Interop.Elementary.elm_entry_input_panel_show_on_demand_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_entry_input_panel_show_on_demand_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets the file (and implicitly loads it) for the text to display and then edit.
+ /// </summary>
+ /// <param name="file">The path to the file to load and save</param>
+ /// <param name="textFormat">The file format</param>
+ public void SetFile(string file, TextFormat textFormat)
+ {
+ Interop.Elementary.elm_entry_file_set(RealHandle, file, (Interop.Elementary.TextFormat)textFormat);
+ }
+
+ /// <summary>
+ /// Converts a markup (HTML-like) string into UTF-8.
+ /// </summary>
+ /// <param name="markup">The string (in markup) to be converted</param>
+ /// <returns>The converted string (in UTF-8) </returns>
+ public static string ConvertMarkupToUtf8(string markup)
+ {
+ return Interop.Elementary.elm_entry_markup_to_utf8(markup);
+ }
+
+ /// <summary>
+ /// Moves the cursor by one position to the right within the entry.
+ /// </summary>
+ /// <returns></returns>
+ public bool MoveCursorNext()
+ {
+ return Interop.Elementary.elm_entry_cursor_next(RealHandle);
+ }
+
+ /// <summary>
+ /// Moves the cursor one place to the left within the entry.
+ /// </summary>
+ /// <returns>TRUE on success, otherwise FALSE on failure</returns>
+ public bool MoveCursorPrev()
+ {
+ return Interop.Elementary.elm_entry_cursor_prev(RealHandle);
+ }
+
+ /// <summary>
+ /// Moves the cursor one line up within the entry.
+ /// </summary>
+ /// <returns>TRUE on success, otherwise FALSE on failure</returns>
+ public bool MoveCursorUp()
+ {
+ return Interop.Elementary.elm_entry_cursor_up(RealHandle);
+ }
+
+ /// <summary>
+ /// Moves the cursor one line down within the entry.
+ /// </summary>
+ /// <returns>TRUE on success, otherwise FALSE on failure</returns>
+ public bool MoveCursorDown()
+ {
+ return Interop.Elementary.elm_entry_cursor_down(RealHandle);
+ }
+
+ /// <summary>
+ /// Moves the cursor to the beginning of the entry.
+ /// </summary>
+ public void MoveCursorBegin()
+ {
+ Interop.Elementary.elm_entry_cursor_begin_set(RealHandle);
+ }
+
+ /// <summary>
+ /// Moves the cursor to the end of the entry.
+ /// </summary>
+ public void MoveCursorEnd()
+ {
+ Interop.Elementary.elm_entry_cursor_end_set(RealHandle);
+ }
+
+ /// <summary>
+ /// Moves the cursor to the beginning of the current line.
+ /// </summary>
+ public void MoveCursorLineBegin()
+ {
+ Interop.Elementary.elm_entry_cursor_line_begin_set(RealHandle);
+ }
+
+ /// <summary>
+ /// Moves the cursor to the end of the current line.
+ /// </summary>
+ public void MoveCursorLineEnd()
+ {
+ Interop.Elementary.elm_entry_cursor_line_end_set(RealHandle);
+ }
+
+ /// <summary>
+ /// Sets the input panel layout of the entry.
+ /// </summary>
+ /// <param name="layout">The layout type</param>
+ public void SetInputPanelLayout(InputPanelLayout layout)
+ {
+ Interop.Elementary.elm_entry_input_panel_layout_set(RealHandle, (Interop.Elementary.InputPanelLayout)layout);
+ }
+
+ /// <summary>
+ /// Sets the attribute to show the input panel automatically.
+ /// </summary>
+ /// <param name="enabled">If true the input panel appears when the entry is clicked or has focus, otherwise false</param>
+ public void SetInputPanelEnabled(bool enabled)
+ {
+ Interop.Elementary.elm_entry_input_panel_enabled_set(RealHandle, enabled);
+ }
+
+ /// <summary>
+ /// Sets the "return" key type. This type is used to set the string or icon on the "return" key of the input panel.
+ /// </summary>
+ /// <param name="keyType">The type of "return" key on the input panel</param>
+ public void SetInputPanelReturnKeyType(InputPanelReturnKeyType keyType)
+ {
+ Interop.Elementary.elm_entry_input_panel_return_key_type_set(RealHandle, (Interop.Elementary.ReturnKeyType)keyType);
+ }
+
+ /// <summary>
+ /// Hides the input panel (virtual keyboard).
+ /// </summary>
+ /// <remark>
+ /// Note that the input panel is shown or hidden automatically according to the focus state of the entry widget.
+ /// This API can be used in case of manually controlling by using SetInputPanelEnabled(false).
+ /// </remark>
+ public void HideInputPanel()
+ {
+ Interop.Elementary.elm_entry_input_panel_hide(RealHandle);
+ }
+
+ /// <summary>
+ /// Selects all the text within the entry.
+ /// </summary>
+ public void SelectAll()
+ {
+ Interop.Elementary.elm_entry_select_all(RealHandle);
+ }
+
+ /// <summary>
+ /// Drops any existing text selection within the entry.
+ /// </summary>
+ public void SelectNone()
+ {
+ Interop.Elementary.elm_entry_select_none(RealHandle);
+ }
+
+ /// <summary>
+ /// Sets the color of color class for a given widget.
+ /// </summary>
+ /// <param name="part">The name of color class.</param>
+ /// <param name="color">The struct of color</param>
+ public override void SetPartColor(string part, Color color)
+ {
+ IntPtr handle = (part == "bg") ? Handle : RealHandle;
+ Interop.Elementary.elm_object_color_class_color_set(handle, part, color.R * color.A / 255,
+ color.G * color.A / 255,
+ color.B * color.A / 255,
+ color.A);
+ }
+
+ /// <summary>
+ /// Forces calculation of the entry size and text layouting.
+ /// </summary>
+ public void ForceCalculation()
+ {
+ Interop.Elementary.elm_entry_calc_force(RealHandle);
+ }
+
+ /// <summary>
+ /// Gets the string by the cursor at its current position.
+ /// </summary>
+ /// <returns></returns>
+ public string GetCursorContent()
+ {
+ return Interop.Elementary.elm_entry_cursor_content_get(RealHandle);
+ }
+
+ /// <summary>
+ /// Begins a selection within the entry as though the user were holding down the mouse button to make a selection.
+ /// </summary>
+ public void BeginCursorSelection()
+ {
+ Interop.Elementary.elm_entry_cursor_selection_begin(RealHandle);
+ }
+
+ /// <summary>
+ /// Appends the text of the entry.
+ /// </summary>
+ /// <param name="text">The text to be displayed</param>
+ public void AppendText(string text)
+ {
+ Interop.Elementary.elm_entry_entry_append(RealHandle, text);
+ }
+
+ /// <summary>
+ /// Inserts the given text into the entry at the current cursor position.
+ /// </summary>
+ /// <param name="text"></param>
+ public void InsertTextToCursor(string text)
+ {
+ Interop.Elementary.elm_entry_entry_insert(RealHandle, text);
+ }
+
+ /// <summary>
+ /// Ends a selection within the entry as though the user had just released the mouse button while making a selection.
+ /// </summary>
+ public void EndCursorSelection()
+ {
+ Interop.Elementary.elm_entry_cursor_selection_end(RealHandle);
+ }
+
+ /// <summary>
+ /// Writes any changes made to the file that is set by File.
+ /// </summary>
+ public void SaveFile()
+ {
+ Interop.Elementary.elm_entry_file_save(RealHandle);
+ }
+
+ /// <summary>
+ /// Show the input panel (virtual keyboard) based on the input panel property of entry such as layout, autocapital types, and so on.
+ /// </summary>
+ /// <remarks>
+ /// Note that input panel is shown or hidden automatically according to the focus state of entry widget.
+ /// This API can be used in the case of manually controlling by using SetInputPanelEnabled(false).
+ /// </remarks>
+ public void ShowInputPanel()
+ {
+ Interop.Elementary.elm_entry_input_panel_show(RealHandle);
+ }
+
+ /// <summary>
+ /// This appends a custom item provider to the list for that entry.
+ /// </summary>
+ /// <param name="func">This function is used to provide items.</param>
+ public void AppendItemProvider(Func<string, EvasObject> func)
+ {
+ if (func != null)
+ {
+ if (!_itemsProvider.ContainsKey(func))
+ {
+ Interop.Elementary.Elm_Entry_Item_Provider_Cb itemProviderCallback;
+
+ itemProviderCallback = (d, o, t) =>
+ {
+ return func?.Invoke(t);
+ };
+ Interop.Elementary.elm_entry_item_provider_append(RealHandle, itemProviderCallback, IntPtr.Zero);
+ _itemsProvider.Add(func, itemProviderCallback);
+ }
+ }
+ }
+
+ /// <summary>
+ /// This prepends a custom item provider to the list for that entry.
+ /// </summary>
+ /// <param name="func">This function is used to provide items.</param>
+ public void PrependItemProvider(Func<string, EvasObject> func)
+ {
+ if (!_itemsProvider.ContainsKey(func))
+ {
+ Interop.Elementary.Elm_Entry_Item_Provider_Cb itemProviderCallback;
+
+ itemProviderCallback = (d, o, t) =>
+ {
+ return func?.Invoke(t);
+ };
+ Interop.Elementary.elm_entry_item_provider_prepend(RealHandle, itemProviderCallback, IntPtr.Zero);
+ _itemsProvider.Add(func, itemProviderCallback);
+ }
+ }
+
+ /// <summary>
+ /// This removes a custom item provider to the list for that entry.
+ /// </summary>
+ /// <param name="itemProvider">This function is used to provide items.</param>
+ public void RemoveItemProvider(Func<string, EvasObject> func)
+ {
+ if (_itemsProvider.ContainsKey(func))
+ {
+ Interop.Elementary.Elm_Entry_Item_Provider_Cb itemProviderCallback;
+ _itemsProvider.TryGetValue(func, out itemProviderCallback);
+
+ Interop.Elementary.elm_entry_item_provider_remove(RealHandle, itemProviderCallback, IntPtr.Zero);
+ _itemsProvider.Remove(func);
+ }
+ }
+
+ /// <summary>
+ /// Append a markup filter function for text inserted in the entry.
+ /// </summary>
+ /// <param name="filter">This function type is used by entry filters to modify text.</param>
+ public void AppendMarkUpFilter(Func<Entry, string, string> filter)
+ {
+ if (!_textFilters.ContainsKey(filter))
+ {
+ Interop.Elementary.Elm_Entry_Filter_Cb textFilterCallback = (IntPtr d, IntPtr e, ref IntPtr t) =>
+ {
+ var text = Marshal.PtrToStringAnsi(t);
+
+ var updateText = filter(this, text);
+
+ if (updateText != text)
+ {
+ Interop.Libc.Free(t);
+ t = Marshal.StringToHGlobalAnsi(updateText);
+ }
+ };
+ Interop.Elementary.elm_entry_markup_filter_append(RealHandle, textFilterCallback, IntPtr.Zero);
+ _textFilters.Add(filter, textFilterCallback);
+ }
+ }
+
+ /// <summary>
+ /// Prepend a markup filter function for text inserted in the entry.
+ /// </summary>
+ /// <param name="filter">This function type is used by entry filters to modify text.</param>
+ public void PrependMarkUpFilter(Func<Entry, string, string> filter)
+ {
+ if (!_textFilters.ContainsKey(filter))
+ {
+ Interop.Elementary.Elm_Entry_Filter_Cb textFilterCallback = (IntPtr d, IntPtr e, ref IntPtr t) =>
+ {
+ var text = Marshal.PtrToStringAnsi(t);
+
+ var updateText = filter(this, text);
+
+ if (updateText != text)
+ {
+ Interop.Libc.Free(t);
+ t = Marshal.StringToHGlobalAnsi(updateText);
+ }
+ };
+ Interop.Elementary.elm_entry_markup_filter_prepend(RealHandle, textFilterCallback, IntPtr.Zero);
+ _textFilters.Add(filter, textFilterCallback);
+ }
+ }
+
+ /// <summary>
+ /// Remove a markup filter
+ /// </summary>
+ /// <param name="filter">This function type is used by entry filters to modify text.</param>
+ public void RemoveMarkUpFilter(Func<Entry, string, string> filter)
+ {
+ if (_textFilters.ContainsKey(filter))
+ {
+ Interop.Elementary.Elm_Entry_Filter_Cb textFilterCallback;
+ _textFilters.TryGetValue(filter, out textFilterCallback);
+
+ Interop.Elementary.elm_entry_markup_filter_remove(RealHandle, textFilterCallback, IntPtr.Zero);
+ _textFilters.Remove(filter);
+ }
+ }
+
+ /// <summary>
+ /// This executes a "copy" action on the selected text in the entry.
+ /// </summary>
+ public void CopySelection()
+ {
+ Interop.Elementary.elm_entry_selection_copy(RealHandle);
+ }
+
+ /// <summary>
+ /// This executes a "cut" action on the selected text in the entry.
+ /// </summary>
+ public void CutSelection()
+ {
+ Interop.Elementary.elm_entry_selection_cut(RealHandle);
+ }
+
+ /// <summary>
+ /// This executes a "paste" action in the entry.
+ /// </summary>
+ public void PasteSelection()
+ {
+ Interop.Elementary.elm_entry_selection_paste(RealHandle);
+ }
+
+ /// <summary>
+ /// This disabled the entry's selection.
+ /// </summary>
+ /// <param name="disable">If true, the selection are disabled.</param>
+ public void DisableSelection(bool disable)
+ {
+ Interop.Elementary.elm_entry_selection_handler_disabled_set(RealHandle, disable);
+ }
+
+ /// <summary>
+ /// Get any selected text within the entry.
+ /// </summary>
+ /// <returns>Selection's value</returns>
+ public string GetSelection()
+ {
+ return Interop.Elementary.elm_entry_selection_get(RealHandle);
+ }
+
+ /// <summary>
+ /// This selects a region of text within the entry.
+ /// </summary>
+ /// <param name="start">The starting position.</param>
+ /// <param name="end">The end position.</param>
+ public void SetSelectionRegion(int start, int end)
+ {
+ Interop.Elementary.elm_entry_select_region_set(RealHandle, start, end);
+ }
+
+ /// <summary>
+ /// Sets the visibility of the left-side widget of the entry
+ /// </summary>
+ /// <param name="isDisplay">true if the object should be displayed, false if not.</param>
+ public void SetIconVisible(bool isDisplay)
+ {
+ Interop.Elementary.elm_entry_icon_visible_set(RealHandle, isDisplay);
+ }
+
+ /// <summary>
+ /// Set whether the return key on the input panel is disabled automatically when entry has no text.
+ /// </summary>
+ /// <param name="enable">If enabled is true, the return key is automatically disabled when the entry has no text.</param>
+ public void SetInputPanelReturnKeyAutoEnable(bool enable)
+ {
+ Interop.Elementary.elm_entry_input_panel_return_key_autoenabled_set(RealHandle, enable);
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ IntPtr handle = Interop.Elementary.elm_layout_add(parent.Handle);
+ Interop.Elementary.elm_layout_theme_set(handle, "layout", "background", "default");
+
+ RealHandle = Interop.Elementary.elm_entry_add(handle);
+ Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
+
+ return handle;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/EvasCanvas.cs b/src/ElmSharp/ElmSharp/EvasCanvas.cs
new file mode 100644
index 0000000..6f778c6
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/EvasCanvas.cs
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// Low level Evas canvas functions. Sub groups will present more high level ones, though.
+ /// Most of these functions deal with low level Evas actions, like:
+ /// create/destroy raw canvases, not bound to any displaying engine
+ /// tell a canvas i got focused(in a windowing context, for example)
+ /// tell a canvas a region should not be calculated anymore in rendering
+ /// tell a canvas to render its contents, immediately
+ /// Most users will be using Evas by means of the Ecore_Evas wrapper, which deals with all the above mentioned issues automatically for them.Thus, you'll be looking at this section only if you're building low level stuff.
+ /// The groups within present you functions that deal with the canvas directly, too, and not yet with its objects.They are the functions you need to use at a minimum to get a working canvas.
+ /// </summary>
+ public class EvasCanvas
+ {
+ IntPtr _handle = IntPtr.Zero;
+ Dictionary<EventData, Interop.Evas.EvasCallback> _eventDatas = new Dictionary<EventData, Interop.Evas.EvasCallback>();
+
+ internal EvasCanvas(IntPtr evasObject)
+ {
+ _handle = CreateHandle(evasObject);
+ }
+
+ /// <summary>
+ /// Gets or sets the image cache.
+ /// This function returns the image cache size of canvas in bytes.
+ /// </summary>
+ public int ImageCacheSize
+ {
+ get
+ {
+ return Interop.Evas.evas_image_cache_get(_handle);
+ }
+ set
+ {
+ Interop.Evas.evas_image_cache_set(_handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Flush the image cache of the canvas.
+ /// </summary>
+ public void FlushImageCache()
+ {
+ Interop.Evas.evas_image_cache_flush(_handle);
+ }
+
+ /// <summary>
+ /// Add a damage rectangle.
+ /// </summary>
+ /// <param name="x">The rectangle's top left corner's horizontal coordinate.</param>
+ /// <param name="y">The rectangle's top left corner's vertical coordinate.</param>
+ /// <param name="width">The rectangle's width.</param>
+ /// <param name="height">The rectangle's height.</param>
+ public void AddDamageRectangle(int x, int y, int width, int height)
+ {
+ Interop.Evas.evas_damage_rectangle_add(_handle, x, y, width, height);
+ }
+
+ /// <summary>
+ /// Add an "obscured region" to an Evas canvas.
+ /// </summary>
+ /// <param name="x">The rectangle's top left corner's horizontal coordinate.</param>
+ /// <param name="y">The rectangle's top left corner's vertical coordinate.</param>
+ /// <param name="width">The rectangle's width.</param>
+ /// <param name="height">The rectangle's height.</param>
+ public void AddObscuredRectangle(int x, int y, int width, int height)
+ {
+ Interop.Evas.evas_obscured_rectangle_add(_handle, x, y, width, height);
+ }
+
+ /// <summary>
+ /// Remove all "obscured regions" from an Evas canvas.
+ /// </summary>
+ public void ClearObscuredRectangle()
+ {
+ Interop.Evas.evas_obscured_clear(_handle);
+ }
+
+ /// <summary>
+ /// Adds or registers a event to a given canvas event.
+ /// </summary>
+ /// <param name="type">The type of event that triggers</param>
+ /// <param name="action">The action to be called when the event is triggered</param>
+ public void AddEventAction(EvasObjectCallbackType type, Action action)
+ {
+ if (action != null)
+ {
+ var eventData = new EventData(type, action);
+
+ if (!_eventDatas.ContainsKey(eventData))
+ {
+ var evasCallback = new Interop.Evas.EvasCallback((d, o, t) => action());
+ Interop.Evas.evas_event_callback_add(_handle, (Interop.Evas.ObjectCallbackType)type, evasCallback, IntPtr.Zero);
+ _eventDatas.Add(eventData, evasCallback);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Deletes a event to a given canvas event.
+ /// </summary>
+ /// <param name="type">The type of event that triggers</param>
+ /// <param name="action">The action to be called when the event is triggered</param>
+ public void DeleteEventAction(EvasObjectCallbackType type, Action action)
+ {
+ if (action != null)
+ {
+ var eventData = new EventData(type, action);
+ Interop.Evas.EvasCallback evasCallback = null;
+ _eventDatas.TryGetValue(eventData, out evasCallback);
+
+ if (evasCallback != null)
+ {
+ Interop.Evas.evas_event_callback_del(_handle, (Interop.Evas.ObjectCallbackType)type, evasCallback);
+ _eventDatas.Remove(eventData);
+ }
+ }
+ }
+
+ IntPtr CreateHandle(IntPtr evasObject)
+ {
+ return Interop.Evas.evas_object_evas_get(evasObject);
+ }
+
+ class EventData
+ {
+ public EvasObjectCallbackType Type { get; set; }
+ public Action Action { get; set; }
+
+ public EventData(EvasObjectCallbackType type, Action action)
+ {
+ Type = type;
+ Action = action;
+ }
+
+ public override bool Equals(object obj)
+ {
+ EventData e = obj as EventData;
+ if (e == null)
+ {
+ return false;
+ }
+ return (Type == e.Type) && (Action == e.Action);
+ }
+
+ public override int GetHashCode()
+ {
+ int hashCode = Type.GetHashCode();
+ hashCode ^= Action.GetHashCode();
+ return hashCode;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/EvasKeyEventArgs.cs b/src/ElmSharp/ElmSharp/EvasKeyEventArgs.cs
new file mode 100755
index 0000000..cf5ffae
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/EvasKeyEventArgs.cs
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The EvasKeyEventArgs is an EvasKey EventArgs
+ /// </summary>
+ public class EvasKeyEventArgs : EventArgs
+ {
+ /// <summary>
+ /// BackButton name in Platform
+ /// </summary>
+ public const string PlatformBackButtonName = "XF86Back";
+ /// <summary>
+ /// MenuButton name in Platform
+ /// </summary>
+ public const string PlatformMenuButtonName = "XF86Menu";
+ /// <summary>
+ /// HomeButton name in Platform
+ /// </summary>
+ public const string PlatformHomeButtonName = "XF86Home";
+
+ /// <summary>
+ /// Gets the name of Key
+ /// </summary>
+ public string KeyName { get; private set; }
+
+ /// <summary>
+ /// Creates and initializes a new instance of the EvasKeyEventArgs class.
+ /// </summary>
+ /// <param name="data">data info</param>
+ /// <param name="obj"> object </param>
+ /// <param name="info">information </param>
+ /// <returns>EvasKey eventArgs</returns>
+ static public EvasKeyEventArgs Create(IntPtr data, IntPtr obj, IntPtr info)
+ {
+ var evt = Marshal.PtrToStructure<EvasEventKeyDown>(info);
+ return new EvasKeyEventArgs() { KeyName = evt.keyname };
+ }
+
+ /// <summary>
+ /// Event structure for Key Down event callbacks.
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential)]
+ struct EvasEventKeyDown
+ {
+ /// <summary>
+ /// Name string of the key pressed
+ /// </summary>
+ public string keyname;
+ /// <summary>
+ /// Data to be passed to the event
+ /// </summary>
+ public IntPtr data;
+ /// <summary>
+ /// Modifier keys pressed during the event
+ /// </summary>
+ public IntPtr modifiers;
+ /// <summary>
+ /// Locks info
+ /// </summary>
+ public IntPtr locks;
+ /// <summary>
+ /// Logical key: (example, shift+1 == exclamation)
+ /// </summary>
+ public string key;
+ /// <summary>
+ /// UTF8 string if this keystroke has produced a visible string to be ADDED
+ /// </summary>
+ public string str;
+ /// <summary>
+ /// UTF8 string if this keystroke has modified a string in the middle of being composed - this string replaces the previous one
+ /// </summary>
+ public string compose;
+ /// <summary>
+ /// Event_flags
+ /// </summary>
+ public IntPtr event_flags;
+ /// <summary>
+ ///
+ /// </summary>
+ public IntPtr dev;
+ /// <summary>
+ /// Keycode
+ /// </summary>
+ public uint keycode;
+ };
+
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/EvasMap.cs b/src/ElmSharp/ElmSharp/EvasMap.cs
new file mode 100755
index 0000000..b67264e
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/EvasMap.cs
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The EvasMap is an opaque handle to map points.
+ /// </summary>
+ public class EvasMap
+ {
+ IntPtr _evasMap;
+ bool _ownership;
+
+ /// <summary>
+ /// Creates and initializes a new instance of the EvasMap class.
+ /// </summary>
+ /// <param name="count">The number of points in the map</param>
+ public EvasMap(int count)
+ {
+ _evasMap = Interop.Evas.evas_map_new(count);
+ _ownership = true;
+ }
+
+ internal EvasMap(IntPtr handle)
+ {
+ _evasMap = handle;
+ _ownership = false;
+ }
+
+ ~EvasMap()
+ {
+ if (_ownership)
+ {
+ Interop.Evas.evas_map_free(_evasMap);
+ }
+ }
+
+ internal IntPtr Handle
+ {
+ get
+ {
+ return _evasMap;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the flag of the object move synchronization for map rendering.
+ /// </summary>
+ public bool IsMoveSync
+ {
+ get
+ {
+ return Interop.Evas.evas_map_util_object_move_sync_get(_evasMap);
+ }
+ set
+ {
+ Interop.Evas.evas_map_util_object_move_sync_set(_evasMap, value);
+ }
+ }
+
+ /// <summary>
+ /// Populates source and destination map points to exactly match the object.
+ /// </summary>
+ /// <param name="obj">The object to use unmapped geometry to populate map coordinates</param>
+ /// <param name="z">
+ /// The point Z coordinate hint (pre-perspective transform)This value is used for all four points.
+ /// </param>
+ public void PopulatePoints(EvasObject obj, int z)
+ {
+ Interop.Evas.evas_map_util_points_populate_from_object_full(_evasMap, obj, z);
+ }
+
+ /// <summary>
+ /// Populates the source and destination map points to match the given geometry.
+ /// </summary>
+ /// <param name="geometry">The geometry value contains X coordinate,Y coordinate,the width and height to use to calculate second and third points</param>
+ /// <param name="z">The Z coordinate hint (pre-perspective transform) This value is used for all four points.</param>
+ public void PopulatePoints(Rect geometry, int z)
+ {
+ Interop.Evas.evas_map_util_points_populate_from_geometry(_evasMap, geometry.X, geometry.Y, geometry.Width, geometry.Height, z);
+ }
+
+ /// <summary>
+ /// Rotates the map around 3 axes in 3D.
+ /// </summary>
+ /// <param name="dx">The amount of degrees from 0.0 to 360.0 to rotate around X axis</param>
+ /// <param name="dy">The amount of degrees from 0.0 to 360.0 to rotate around Y axis</param>
+ /// <param name="dz">The amount of degrees from 0.0 to 360.0 to rotate around Z axis</param>
+ /// <param name="cx">The rotation's center horizontal position</param>
+ /// <param name="cy">The rotation's center vertical position</param>
+ /// <param name="cz">The rotation's center vertical position</param>
+ public void Rotate3D(double dx, double dy, double dz, int cx, int cy, int cz)
+ {
+ Interop.Evas.evas_map_util_3d_rotate(_evasMap, dx, dy, dz, cx, cy, cz);
+ }
+
+ /// <summary>
+ /// Changes the map point's coordinate.
+ /// </summary>
+ /// <param name="idx">The index of point to change ,this must be smaller than map size.</param>
+ /// <param name="point">3D Point coordinate</param>
+ public void SetPointCoordinate(int idx, Point3D point)
+ {
+ Interop.Evas.evas_map_point_coord_set(_evasMap, idx, point.X, point.Y, point.Z);
+ }
+
+ /// <summary>
+ /// Gets the map point's coordinate.
+ /// </summary>
+ /// <param name="idx">The index of point to change ,this must be smaller than map size.</param>
+ /// <returns>The coordinates of the given point in the map.</returns>
+ public Point3D GetPointCoordinate(int idx)
+ {
+ Point3D point;
+ Interop.Evas.evas_map_point_coord_get(_evasMap, idx, out point.X, out point.Y, out point.Z);
+ return point;
+ }
+
+ /// <summary>
+ /// Changes the map to apply the given zooming.
+ /// </summary>
+ /// <param name="x">The horizontal zoom to use</param>
+ /// <param name="y">The vertical zoom to use</param>
+ /// <param name="cx">The zooming center horizontal position</param>
+ /// <param name="cy">The zooming center vertical position</param>
+ public void Zoom(double x, double y, int cx, int cy)
+ {
+ Interop.Evas.evas_map_util_zoom(_evasMap, x, y, cx, cy);
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/EvasObject.cs b/src/ElmSharp/ElmSharp/EvasObject.cs
new file mode 100644
index 0000000..0a40609
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/EvasObject.cs
@@ -0,0 +1,964 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace ElmSharp
+{
+ public enum TooltipOrientation
+ {
+ None,
+ TopLeft,
+ Top,
+ TopRight,
+ Left,
+ Center,
+ Right,
+ BottomLeft,
+ Bottom,
+ BottomRight,
+ }
+
+ public enum AspectControl
+ {
+ None = 0, /* Preference on scaling unset */
+ Neither = 1, /* Same effect as unset preference on scaling */
+ Horizontal = 2, /* Use all horizontal container space to place an object, using the given aspect */
+ Vertical = 3, /* Use all vertical container space to place an object, using the given aspect */
+ Both = 4 /* Use all horizontal @b and vertical container spaces to place an object (never growing it out of those bounds), using the given aspect */
+ }
+
+ /// <summary>
+ /// The EcasObject is a base class for other widget class
+ /// </summary>
+ public abstract class EvasObject
+ {
+ private IntPtr _realHandle = IntPtr.Zero;
+ private EvasCanvas _evasCanvas;
+
+ private event EventHandler _backButtonPressed;
+
+ private event EventHandler _moreButtonPressed;
+
+ private Interop.Eext.EextEventCallback _backButtonHandler;
+ private Interop.Eext.EextEventCallback _moreButtonHandler;
+
+ public IntPtr Handle { get; protected set; }
+ public EvasObject Parent { get; private set; }
+
+ public IntPtr RealHandle
+ {
+ get
+ {
+ return _realHandle == IntPtr.Zero ? Handle : _realHandle;
+ }
+ protected set
+ {
+ _realHandle = value;
+ }
+ }
+
+ EvasObjectEvent _deleted;
+ EvasObjectEvent<EvasKeyEventArgs> _keyup;
+ EvasObjectEvent<EvasKeyEventArgs> _keydown;
+ EvasObjectEvent _moved;
+ EvasObjectEvent _resized;
+ EventHandler _renderPost;
+ Interop.Evas.EvasCallback _renderPostCallback = null;
+ Interop.Elementary.Elm_Tooltip_Content_Cb _tooltipContentCallback = null;
+
+ GetTooltipContentDelegate _tooltipContentDelegate = null;
+
+ readonly HashSet<IInvalidatable> _eventStore = new HashSet<IInvalidatable>();
+
+ /// <summary>
+ /// Creates and initializes a new instance of the EvasObject class with parent EvasObject class parameter.
+ /// </summary>
+ /// <param name="parent">Parent EvasObject class </param>
+ protected EvasObject(EvasObject parent) : this()
+ {
+ Debug.Assert(parent == null || parent.IsRealized);
+ Realize(parent);
+ }
+
+ /// <summary>
+ /// Creates and initializes a new instance of the EvasObject class.
+ /// </summary>
+ protected EvasObject()
+ {
+ _backButtonHandler = new Interop.Eext.EextEventCallback((d, o, i) => { _backButtonPressed?.Invoke(this, EventArgs.Empty); });
+ _moreButtonHandler = new Interop.Eext.EextEventCallback((d, o, i) => { _moreButtonPressed?.Invoke(this, EventArgs.Empty); });
+
+ OnInstantiated();
+
+ _tooltipContentCallback = (d, o, t) =>
+ {
+ return _tooltipContentDelegate?.Invoke();
+ };
+ }
+
+ // C# Finalizer was called on GC thread
+ // So, We can't access to EFL object
+ // And When Finalizer was called, Field can be already released.
+ //~EvasObject()
+ //{
+ // Unrealize();
+ //}
+
+ /// <summary>
+ /// Deleted will be triggered when widght is deleted
+ /// </summary>
+ public event EventHandler Deleted;
+
+ /// <summary>
+ /// KeyUp will be triggered when key is loose
+ /// </summary>
+ public event EventHandler<EvasKeyEventArgs> KeyUp;
+
+ /// <summary>
+ /// KeyDown will be triggered when key is preesd down
+ /// </summary>
+ public event EventHandler<EvasKeyEventArgs> KeyDown;
+
+ /// <summary>
+ /// BackButtonPressed will be triggered when Back button is pressed
+ /// </summary>
+ public event EventHandler BackButtonPressed
+ {
+ add
+ {
+ if (_backButtonPressed == null)
+ {
+ Interop.Eext.eext_object_event_callback_add(RealHandle, Interop.Eext.EextCallbackType.EEXT_CALLBACK_BACK, _backButtonHandler, IntPtr.Zero);
+ }
+ _backButtonPressed += value;
+ }
+ remove
+ {
+ _backButtonPressed -= value;
+ if (_backButtonPressed == null)
+ {
+ Interop.Eext.eext_object_event_callback_del(RealHandle, Interop.Eext.EextCallbackType.EEXT_CALLBACK_BACK, _backButtonHandler);
+ }
+ }
+ }
+
+ /// <summary>
+ /// MoreButtonPressed will be triggered when More button is pressed
+ /// </summary>
+ public event EventHandler MoreButtonPressed
+ {
+ add
+ {
+ if (_moreButtonPressed == null)
+ {
+ Interop.Eext.eext_object_event_callback_add(RealHandle, Interop.Eext.EextCallbackType.EEXT_CALLBACK_MORE, _moreButtonHandler, IntPtr.Zero);
+ }
+ _moreButtonPressed += value;
+ }
+ remove
+ {
+ _moreButtonPressed -= value;
+ if (_moreButtonPressed == null)
+ {
+ Interop.Eext.eext_object_event_callback_del(RealHandle, Interop.Eext.EextCallbackType.EEXT_CALLBACK_MORE, _moreButtonHandler);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Moved will be triggered when widght is moved
+ /// </summary>
+ public event EventHandler Moved
+ {
+ add { _moved.On += value; }
+ remove { _moved.On -= value; }
+ }
+
+ /// <summary>
+ /// Current widget's size Resized Event Handler
+ /// </summary>
+ public event EventHandler Resized
+ {
+ add { _resized.On += value; }
+ remove { _resized.On -= value; }
+ }
+
+ /// <summary>
+ /// Current widget RenderPost Event Handler
+ /// </summary>
+ public event EventHandler RenderPost
+ {
+ add
+ {
+ _renderPost += value;
+ if (_renderPostCallback == null)
+ {
+ _renderPostCallback = new Interop.Evas.EvasCallback((o, e, d) => _renderPost?.Invoke(this, EventArgs.Empty));
+ Interop.Evas.evas_event_callback_add(Interop.Evas.evas_object_evas_get(RealHandle), Interop.Evas.ObjectCallbackType.RenderPost, _renderPostCallback, IntPtr.Zero);
+ }
+ }
+ remove
+ {
+ _renderPost -= value;
+ if (_renderPost?.GetInvocationList().Length == 0)
+ {
+ Interop.Evas.evas_event_callback_del(Interop.Evas.evas_object_evas_get(RealHandle), Interop.Evas.ObjectCallbackType.RenderPost, _renderPostCallback);
+ _renderPostCallback = null;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Called back when a widget's tooltip is activated and needs content.
+ /// </summary>
+ /// <returns></returns>
+ public delegate EvasObject GetTooltipContentDelegate();
+
+ /// <summary>
+ /// Get widget's status of Realized or not.
+ /// </summary>
+ public bool IsRealized { get { return Handle != IntPtr.Zero; } }
+
+ /// <summary>
+ /// Gets EvasCanvas
+ /// </summary>
+ public EvasCanvas EvasCanvas
+ {
+ get
+ {
+ if (_evasCanvas == null)
+ _evasCanvas = new EvasCanvas(Handle);
+ return _evasCanvas;
+ }
+ }
+
+ /// <summary>
+ /// Gets the current class's Name.
+ /// </summary>
+ public string ClassName
+ {
+ get
+ {
+ return Interop.Eo.eo_class_name_get(Interop.Eo.eo_class_get(RealHandle));
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the horizontal pointer hints for an object's weight.
+ /// </summary>
+ public double WeightX
+ {
+ get
+ {
+ return Interop.Evas.GetWeightX(Handle);
+ }
+ set
+ {
+ Interop.Evas.SetWeightX(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the vertical pointer hints for an object's weight.
+ /// </summary>
+ public double WeightY
+ {
+ get
+ {
+ return Interop.Evas.GetWeightY(Handle);
+ }
+ set
+ {
+ Interop.Evas.SetWeightY(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the horizontal alignment hint of an object's alignment.
+ /// </summary>
+ public virtual double AlignmentX
+ {
+ get
+ {
+ return Interop.Evas.GetAlignX(Handle);
+ }
+ set
+ {
+ Interop.Evas.SetAlignX(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the vertical alignment hint of an object's alignment.
+ /// </summary>
+ public virtual double AlignmentY
+ {
+ get
+ {
+ return Interop.Evas.GetAlignY(Handle);
+ }
+ set
+ {
+ Interop.Evas.SetAlignY(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the Width hints for an object's minimum size.
+ /// </summary>
+ public int MinimumWidth
+ {
+ get
+ {
+ int w, h;
+ Interop.Evas.evas_object_size_hint_min_get(RealHandle, out w, out h);
+ return w;
+ }
+ set
+ {
+ int h = MinimumHeight;
+ Interop.Evas.evas_object_size_hint_min_set(RealHandle, value, h);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the Height hints for an object's minimum size.
+ /// </summary>
+ public int MinimumHeight
+ {
+ get
+ {
+ int w, h;
+ Interop.Evas.evas_object_size_hint_min_get(RealHandle, out w, out h);
+ return h;
+ }
+ set
+ {
+ int w = MinimumWidth;
+ Interop.Evas.evas_object_size_hint_min_set(RealHandle, w, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets the visible state of the given Evas object.
+ /// </summary>
+ public bool IsVisible
+ {
+ get
+ {
+ return Interop.Evas.evas_object_visible_get(Handle);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the position and (rectangular) size of the given Evas object.
+ /// </summary>
+ public Rect Geometry
+ {
+ get
+ {
+ int x, y, w, h;
+ Interop.Evas.evas_object_geometry_get(Handle, out x, out y, out w, out h);
+ Rect rect = new Rect(x, y, w, h);
+ return rect;
+ }
+ set
+ {
+ Interop.Evas.evas_object_geometry_set(Handle, value.X, value.Y, value.Width, value.Height);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the general or main color of the given Evas object.
+ /// </summary>
+ public virtual Color Color
+ {
+ get
+ {
+ int r, g, b, a;
+ Interop.Evas.evas_object_color_get(RealHandle, out r, out g, out b, out a);
+ return Color.FromRgba(r, g, b, a);
+ }
+ set
+ {
+ Interop.Evas.SetPremultipliedColor(RealHandle, value.R, value.G, value.B, value.A);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the map enabled state.
+ /// </summary>
+ public bool IsMapEnabled
+ {
+ get
+ {
+ return Interop.Evas.evas_object_map_enable_get(Handle);
+ }
+ set
+ {
+ Interop.Evas.evas_object_map_enable_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets current object transformation map.
+ /// </summary>
+ public EvasMap EvasMap
+ {
+ get
+ {
+ IntPtr evasMap = Interop.Evas.evas_object_map_get(Handle);
+ return new EvasMap(evasMap);
+ }
+ set
+ {
+ Interop.Evas.evas_object_map_set(Handle, value.Handle);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets whether an object is to repeat events.
+ /// </summary>
+ public bool RepeatEvents
+ {
+ get
+ {
+ return Interop.Evas.evas_object_repeat_events_get(RealHandle);
+ }
+ set
+ {
+ Interop.Evas.evas_object_repeat_events_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets whether events on a smart object's member should get propagated up to its parent.
+ /// </summary>
+ public bool PropagateEvents
+ {
+ get
+ {
+ return Interop.Evas.evas_object_propagate_events_get(RealHandle);
+ }
+ set
+ {
+ Interop.Evas.evas_object_propagate_events_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets whether an object is set to pass (ignore) events.
+ /// </summary>
+ public bool PassEvents
+ {
+ get
+ {
+ return Interop.Evas.evas_object_pass_events_get(RealHandle);
+ }
+ set
+ {
+ Interop.Evas.evas_object_pass_events_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or Gets style for this object tooltip.
+ /// </summary>
+ public string TooltipStyle
+ {
+ get
+ {
+ return Interop.Elementary.elm_object_tooltip_style_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_object_tooltip_style_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the orientation of Tooltip.
+ /// </summary>
+ public TooltipOrientation TooltipOrientation
+ {
+ get
+ {
+ return (TooltipOrientation)Interop.Elementary.elm_object_tooltip_orient_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_object_tooltip_orient_set(RealHandle, (int)value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets size restriction state of an object's tooltip.
+ /// </summary>
+ public bool TooltipWindowMode
+ {
+ get
+ {
+ return Interop.Elementary.elm_object_tooltip_window_mode_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_object_tooltip_window_mode_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets the content to be shown in the tooltip object.
+ /// </summary>
+ public GetTooltipContentDelegate TooltipContentDelegate
+ {
+ get
+ {
+ return _tooltipContentDelegate;
+ }
+ set
+ {
+ _tooltipContentDelegate = value;
+ if (value != null)
+ {
+ Interop.Elementary.elm_object_tooltip_content_cb_set(RealHandle, _tooltipContentCallback, IntPtr.Zero, null);
+ }
+ else
+ {
+ Interop.Elementary.elm_object_tooltip_content_cb_set(RealHandle, null, IntPtr.Zero, null);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the movement freeze by 1
+ /// This gets the movement freeze count by one.
+ /// </summary>
+ public int TooltipMoveFreezeCount
+ {
+ get
+ {
+ return Interop.Elementary.elm_object_tooltip_move_freeze_get(RealHandle);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets whether an Evas object is to freeze (discard) events.
+ /// </summary>
+ public bool AllEventsFrozen
+ {
+ get
+ {
+ return Interop.Evas.evas_object_freeze_events_get(RealHandle);
+ }
+ set
+ {
+ Interop.Evas.evas_object_freeze_events_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the layer of its canvas that the given object will be part of.
+ /// </summary>
+ public virtual int Layer
+ {
+ get
+ {
+ return Interop.Evas.evas_object_layer_get(Handle);
+ }
+ set
+ {
+ Interop.Evas.evas_object_layer_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Clips one object to another.
+ /// </summary>
+ /// <param name="clip">The object to clip object by</param>
+ public void SetClip(EvasObject clip)
+ {
+ Interop.Evas.evas_object_clip_set(Handle, clip);
+ }
+
+ /// <summary>
+ /// Sets the hints for an object's alignment.
+ /// </summary>
+ /// <param name="x">The horizontal alignment hint as double value ranging from 0.0 to 1.0,The default alignment hint value is 0.5 </param>
+ /// <param name="y">The vertical alignment hint as double value ranging from 0.0 to 1.0,The default alignment hint value is 0.5 </param>
+ public void SetAlignment(double x, double y)
+ {
+ Interop.Evas.evas_object_size_hint_align_set(Handle, x, y);
+ }
+
+ /// <summary>
+ /// Sets the hints for an object's weight.
+ /// </summary>
+ /// <param name="x">The non-negative double value to use as horizontal weight hint</param>
+ /// <param name="y">The non-negative double value to use as vertical weight hint</param>
+ public void SetWeight(double x, double y)
+ {
+ Interop.Evas.evas_object_size_hint_weight_set(Handle, x, y);
+ }
+
+ /// <summary>
+ /// Sets the text for an object's tooltip.
+ /// </summary>
+ /// <param name="text">The text value to display inside the tooltip</param>
+ public void SetTooltipText(string text)
+ {
+ Interop.Elementary.elm_object_tooltip_text_set(RealHandle, text);
+ }
+
+ /// <summary>
+ /// Unsets an object's tooltip.
+ /// </summary>
+ public void UnsetTooltip()
+ {
+ Interop.Elementary.elm_object_tooltip_unset(RealHandle);
+ }
+
+ /// <summary>
+ /// This increments the tooltip movement freeze count by one.
+ /// If the count is more than 0, the tooltip position will be fixed.
+ /// </summary>
+ public void PushTooltipMoveFreeze()
+ {
+ Interop.Elementary.elm_object_tooltip_move_freeze_push(RealHandle);
+ }
+
+ /// <summary>
+ /// This decrements the tooltip freeze count by one.
+ /// </summary>
+ public void PopTooltipMoveFreeze()
+ {
+ Interop.Elementary.elm_object_tooltip_move_freeze_pop(RealHandle);
+ }
+
+ /// <summary>
+ /// Force hide tooltip of object.
+ /// </summary>
+ public void HideTooltip()
+ {
+ Interop.Elementary.elm_object_tooltip_hide(RealHandle);
+ }
+
+ /// <summary>
+ /// Force show tooltip of object.
+ /// </summary>
+ public void ShowTooltip()
+ {
+ Interop.Elementary.elm_object_tooltip_show(RealHandle);
+ }
+
+ /// <summary>
+ /// Makes the current object visible.
+ /// </summary>
+ public void Show()
+ {
+ Interop.Evas.evas_object_show(Handle);
+ }
+
+ /// <summary>
+ /// Makes the current object invisible.
+ /// </summary>
+ public void Hide()
+ {
+ Interop.Evas.evas_object_hide(Handle);
+ }
+
+ /// <summary>
+ /// Changes the size of the current object.
+ /// </summary>
+ /// <param name="w">The new width</param>
+ /// <param name="h">The new height</param>
+ public void Resize(int w, int h)
+ {
+ Interop.Evas.evas_object_resize(Handle, w, h);
+ }
+
+ /// <summary>
+ /// Moves the current object to the given location.
+ /// </summary>
+ /// <param name="x">The X position to move the object to.</param>
+ /// <param name="y">The Y position to move the object to.</param>
+ public void Move(int x, int y)
+ {
+ Interop.Evas.evas_object_move(Handle, x, y);
+ }
+
+ /// <summary>
+ /// Lowers obj to the bottom of its layer.
+ /// </summary>
+ public void Lower()
+ {
+ Interop.Evas.evas_object_lower(Handle);
+ }
+
+ /// <summary>
+ /// Define IntPtr operator
+ /// </summary>
+ /// <param name="obj">Parent object</param>
+ public static implicit operator IntPtr(EvasObject obj)
+ {
+ if (obj == null)
+ return IntPtr.Zero;
+ return obj.Handle;
+ }
+
+ /// <summary>
+ /// Requests keyname key events be directed to current obj.
+ /// </summary>
+ /// <param name="keyname">The key to request events for</param>
+ /// <param name="exclusive">Set TRUE to request that the obj is the only object receiving the keyname events,otherwise set FALSE</param>
+ /// <returns>If the call succeeded is true,otherwise is false</returns>
+ public bool KeyGrab(string keyname, bool exclusive)
+ {
+ return Interop.Evas.evas_object_key_grab(Handle, keyname, 0, 0, exclusive);
+ }
+
+ /// <summary>
+ /// Removes the grab on keyname key events.
+ /// </summary>
+ /// <param name="keyname">The key the grab is set for</param>
+ public void KeyUngrab(string keyname)
+ {
+ Interop.Evas.evas_object_key_ungrab(Handle, keyname, 0, 0);
+ }
+
+ /// <summary>
+ /// Mark smart object as changed.
+ /// </summary>
+ public void MarkChanged()
+ {
+ Interop.Evas.evas_object_smart_changed(RealHandle);
+ }
+
+ /// <summary>
+ /// Call the calculate smart function immediately.
+ /// This will force immediate calculations needed for renderization of this object.
+ /// </summary>
+ public void Calculate()
+ {
+ Interop.Evas.evas_object_smart_calculate(RealHandle);
+ }
+
+ /// <summary>
+ /// Sets the hints for an object's aspect ratio.
+ /// </summary>
+ /// <param name="aspect">The policy or type of aspect ratio to apply to object</param>
+ /// <param name="w">The integer to use as aspect width ratio term</param>
+ /// <param name="h">The integer to use as aspect height ratio term</param>
+ public void SetSizeHintAspect(AspectControl aspect, int w, int h)
+ {
+ Interop.Evas.evas_object_size_hint_aspect_set(Handle, (int)aspect, w, h);
+ }
+
+ /// <summary>
+ /// Gets the hints for an object's aspect ratio.
+ /// </summary>
+ /// <param name="aspect">The policy or type of aspect ratio to apply to object</param>
+ /// <param name="w">The integer to use as aspect width ratio term</param>
+ /// <param name="h">The integer to use as aspect height ratio term</param>
+ public void GetSizeHintAspect(out AspectControl aspect, out int w, out int h)
+ {
+ int aspectRatio;
+ Interop.Evas.evas_object_size_hint_aspect_get(Handle, out aspectRatio, out w, out h);
+ aspect = (AspectControl)aspectRatio;
+ }
+
+ /// <summary>
+ /// Stack immediately below anchor.
+ /// </summary>
+ /// <param name="anchor">The object below which to stack.</param>
+ public void StackBelow(EvasObject anchor)
+ {
+ Interop.Evas.evas_object_stack_below(Handle, anchor);
+ }
+
+ /// <summary>
+ /// Stack immediately above anchor.
+ /// </summary>
+ /// <param name="anchor">The object above which to stack.</param>
+ public void StackAbove(EvasObject anchor)
+ {
+ Interop.Evas.evas_object_stack_above(Handle, anchor);
+ }
+
+ /// <summary>
+ /// Raise to the top of its layer.
+ /// </summary>
+ public void RaiseTop()
+ {
+ Interop.Evas.evas_object_raise(Handle);
+ }
+
+ /// <summary>
+ /// Get the geometry of a line number.
+ /// </summary>
+ /// <param name="lineNumber">the line number.</param>
+ /// <param name="x">x coord of the line.</param>
+ /// <param name="y">y coord of the line.</param>
+ /// <param name="w">w coord of the line.</param>
+ /// <param name="h">h coord of the line.</param>
+ /// <returns></returns>
+ public bool GetTextBlockGeometryByLineNumber(int lineNumber, out int x, out int y, out int w, out int h)
+ {
+ return Interop.Evas.evas_object_textblock_line_number_geometry_get(RealHandle, lineNumber, out x, out y, out w, out h);
+ }
+
+ internal IntPtr GetData(string key)
+ {
+ return Interop.Evas.evas_object_data_get(RealHandle, key);
+ }
+
+ internal void SetData(string key, IntPtr data)
+ {
+ Interop.Evas.evas_object_data_set(RealHandle, key, data);
+ }
+
+ internal IntPtr DeleteData(string key)
+ {
+ return Interop.Evas.evas_object_data_del(RealHandle, key);
+ }
+
+ /// <summary>
+ /// The callback of Invalidate Event
+ /// </summary>
+ protected virtual void OnInvalidate()
+ {
+ }
+
+ /// <summary>
+ /// The callback of Instantiated Event
+ /// </summary>
+ protected virtual void OnInstantiated()
+ {
+ }
+
+ /// <summary>
+ /// The callback of Realized Event
+ /// </summary>
+ protected virtual void OnRealized()
+ {
+ }
+
+ /// <summary>
+ /// The callback of Unrealize Event
+ /// </summary>
+ protected virtual void OnUnrealize()
+ {
+ }
+
+ /// <summary>
+ /// Creates a widget handle.
+ /// </summary>
+ /// <param name="parent">Parent EvasObject</param>
+ /// <returns>Handle IntPtr</returns>
+ protected abstract IntPtr CreateHandle(EvasObject parent);
+
+ /// <summary>
+ /// For this object bind Parent object.Init handle and all kinds of EvasObjectEvent.
+ /// </summary>
+ /// <param name="parent">Parent object</param>
+ public void Realize(EvasObject parent)
+ {
+ if (!IsRealized)
+ {
+ Parent = parent;
+ Handle = CreateHandle(parent);
+ Debug.Assert(Handle != IntPtr.Zero);
+
+ (parent as Window)?.AddChild(this);
+
+ OnRealized();
+ _deleted = new EvasObjectEvent(this, EvasObjectCallbackType.Del);
+ _keydown = new EvasObjectEvent<EvasKeyEventArgs>(this, EvasObjectCallbackType.KeyDown, EvasKeyEventArgs.Create);
+ _keyup = new EvasObjectEvent<EvasKeyEventArgs>(this, EvasObjectCallbackType.KeyUp, EvasKeyEventArgs.Create);
+ _moved = new EvasObjectEvent(this, EvasObjectCallbackType.Move);
+ _resized = new EvasObjectEvent(this, EvasObjectCallbackType.Resize);
+
+ _deleted.On += (s, e) => MakeInvalidate();
+ _keydown.On += (s, e) => KeyDown?.Invoke(this, e);
+ _keyup.On += (s, e) => KeyUp?.Invoke(this, e);
+ }
+ }
+
+ /// <summary>
+ /// Removes current object relationship with others.
+ /// </summary>
+ public void Unrealize()
+ {
+ if (IsRealized)
+ {
+ if (_renderPostCallback != null)
+ {
+ Interop.Evas.evas_event_callback_del(Interop.Evas.evas_object_evas_get(Handle), Interop.Evas.ObjectCallbackType.RenderPost, _renderPostCallback);
+ _renderPostCallback = null;
+ }
+
+ OnUnrealize();
+ IntPtr toBeDeleted = Handle;
+ Handle = IntPtr.Zero;
+
+ DisposeEvent();
+
+ (Parent as Window)?.RemoveChild(this);
+
+ Interop.Evas.evas_object_del(toBeDeleted);
+ Parent = null;
+ }
+ }
+
+ private void MakeInvalidate()
+ {
+ Deleted?.Invoke(this, EventArgs.Empty);
+ OnInvalidate();
+ Handle = IntPtr.Zero;
+
+ MakeInvalidateEvent();
+
+ (Parent as Window)?.RemoveChild(this);
+ Parent = null;
+ _deleted = null;
+ }
+
+ private void DisposeEvent()
+ {
+ foreach (var evt in _eventStore)
+ {
+ evt.Dispose();
+ }
+ _eventStore.Clear();
+ }
+
+ private void MakeInvalidateEvent()
+ {
+ foreach (var evt in _eventStore)
+ {
+ evt.MakeInvalidate();
+ }
+ _eventStore.Clear();
+ }
+
+ internal void AddToEventLifeTracker(IInvalidatable item)
+ {
+ _eventStore.Add(item);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/EvasObjectEvent.cs b/src/ElmSharp/ElmSharp/EvasObjectEvent.cs
new file mode 100755
index 0000000..96a3716
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/EvasObjectEvent.cs
@@ -0,0 +1,419 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// IInvalidatable is a interface which can be overrided by its children class.
+ /// Inherits IDisposable
+ /// </summary>
+ public interface IInvalidatable : IDisposable
+ {
+ void MakeInvalidate();
+ }
+
+ /// <summary>
+ /// Enumeration for EvasObjectCallbackType
+ /// </summary>
+ public enum EvasObjectCallbackType
+ {
+ /// <summary>
+ /// Mouse In Event CallbackType.
+ /// </summary>
+ MouseIn,
+ /// <summary>
+ /// Mouse Out Event CallbackType
+ /// </summary>
+ MouseOut,
+ /// <summary>
+ /// Mouse Button Down Event CallbackType
+ /// </summary>
+ MouseDown,
+ /// <summary>
+ /// Mouse Button Up Event CallbackType
+ /// </summary>
+ MouseUp,
+ /// <summary>
+ /// Mouse Move Event CallbackType
+ /// </summary>
+ MouseMove,
+ /// <summary>
+ /// Mouse Wheel Event CallbackType
+ /// </summary>
+ MouseWheel,
+ /// <summary>
+ /// Multi-touch Down Event CallbackType
+ /// </summary>
+ MultiDown,
+ /// <summary>
+ /// Multi-touch Up Event CallbackType
+ /// </summary>
+ MultiUp,
+ /// <summary>
+ /// Multi-touch Move Event CallbackType
+ /// </summary>
+ MultiMove,
+ /// <summary>
+ /// Object Being Freed (Called after Del)
+ /// </summary>
+ Free,
+ /// <summary>
+ /// Key Press Event CallbackType
+ /// </summary>
+ KeyDown,
+ /// <summary>
+ /// Key Release Event CallbackType
+ /// </summary>
+ KeyUp,
+ /// <summary>
+ /// Focus In Event CallbackType
+ /// </summary>
+ FocusIn,
+ /// <summary>
+ /// Focus Out Event CallbackType
+ /// </summary>
+ FocusOut,
+ /// <summary>
+ /// Show Event CallbackType
+ /// </summary>
+ Show,
+ /// <summary>
+ /// Hide Event CallbackType
+ /// </summary>
+ Hide,
+ /// <summary>
+ /// Move Event CallbackType
+ /// </summary>
+ Move,
+ /// <summary>
+ /// Resize Event CallbackType
+ /// </summary>
+ Resize,
+ /// <summary>
+ /// Restack Event CallbackType
+ /// </summary>
+ Restack,
+ /// <summary>
+ /// Object Being Deleted (called before Free)
+ /// </summary>
+ Del,
+ /// <summary>
+ /// Hold Event CallbackType, Informational purpose event to indicate something
+ /// </summary>
+ Hold,
+ /// <summary>
+ /// Size hints changed Event CallbackType
+ /// </summary>
+ ChangedSizeHints,
+ /// <summary>
+ /// Image has been preloaded
+ /// </summary>
+ ImagePreloaded,
+ /// <summary>
+ /// Canvas got focus as a whole
+ /// </summary>
+ CanvasFocusIn,
+ /// <summary>
+ /// Canvas lost focus as a whole
+ /// </summary>
+ CanvasFocusOut,
+ /// <summary>
+ /// Called just before rendering is updated on the canvas target
+ /// </summary>
+ RenderFlushPre,
+ /// <summary>
+ /// Called just after rendering is updated on the canvas target
+ /// </summary>
+ RenderFlushPost,
+ /// <summary>
+ /// Canvas object got focus
+ /// </summary>
+ CanvasObjectFocusIn,
+ /// <summary>
+ /// Canvas object lost focus
+ /// </summary>
+ CanvasObjectFocusOut,
+ /// <summary>
+ /// Image data has been unloaded (by some mechanism in Evas that throw out original image data)
+ /// </summary>
+ ImageUnloaded,
+ /// <summary>
+ /// Called just before rendering starts on the canvas target
+ /// </summary>
+ RenderPre,
+ /// <summary>
+ /// Called just after rendering stops on the canvas target
+ /// </summary>
+ RenderPost,
+ /// <summary>
+ /// Image size is changed
+ /// </summary>
+ ImageResize,
+ /// <summary>
+ /// Devices added, removed or changed on canvas
+ /// </summary>
+ DeviceChanged,
+ /// <summary>
+ /// Axis is changed
+ /// </summary>
+ AxisUpdate,
+ /// <summary>
+ /// Canvas Viewport size is changed
+ /// </summary>
+ CanvasViewportResize
+ }
+
+ /// <summary>
+ /// Event class for EvasObject
+ /// </summary>
+ /// <typeparam name="TEventArgs">Kinds of EventArgs</typeparam>
+ public class EvasObjectEvent<TEventArgs> : IInvalidatable where TEventArgs : EventArgs
+ {
+ /// <summary>
+ /// SmartEventInfoParser delegate of EvasObjectEvent class
+ /// </summary>
+ /// <param name="data">data</param>
+ /// <param name="obj">obj</param>
+ /// <param name="info">info</param>
+ /// <returns> delegate handle</returns>
+ public delegate TEventArgs SmartEventInfoParser(IntPtr data, IntPtr obj, IntPtr info);
+
+ private bool _disposed = false;
+ private EvasObject _sender;
+ private IntPtr _handle;
+ private readonly EvasObjectCallbackType _type;
+ private readonly SmartEventInfoParser _parser;
+ private readonly List<NativeCallback> _nativeCallbacks = new List<NativeCallback>();
+
+ /// <summary>
+ /// Creates and initializes a new instance of the EvasObjectEvent.
+ /// </summary>
+ /// <param name="sender">EvasObject class belong to</param>
+ /// <param name="type">EvasObjectCallbackType</param>
+ /// <param name="parser">SmartEventInfoParser</param>
+ public EvasObjectEvent(EvasObject sender, EvasObjectCallbackType type, SmartEventInfoParser parser) : this(sender, sender.Handle, type, parser)
+ {
+ }
+ /// <summary>
+ /// Creates and initializes a new instance of the EvasObjectEvent.
+ /// </summary>
+ /// <param name="sender">EvasObject class belong to</param>
+ /// <param name="handle">EvasObject class's handle</param>
+ /// <param name="type">EvasObjectCallbackType</param>
+ /// <param name="parser">SmartEventInfoParser</param>
+ [EditorBrowsableAttribute(EditorBrowsableState.Never)]
+ public EvasObjectEvent(EvasObject sender, IntPtr handle, EvasObjectCallbackType type, SmartEventInfoParser parser)
+ {
+ _sender = sender;
+ _handle = handle;
+ _type = type;
+ _parser = parser;
+ sender.AddToEventLifeTracker(this);
+ }
+ /// <summary>
+ /// Creates and initializes a new instance of the EvasObjectEvent.
+ /// </summary>
+ /// <param name="sender">EvasObject class belong with</param>
+ /// <param name="type">SmartEventInfoParser</param>
+ public EvasObjectEvent(EvasObject sender, EvasObjectCallbackType type) : this(sender, type, null)
+ {
+ }
+
+ ~EvasObjectEvent()
+ {
+ Dispose(false);
+ }
+
+ private struct NativeCallback
+ {
+ public Interop.Evas.EventCallback callback;
+ public EventHandler<TEventArgs> eventHandler;
+ }
+
+ /// <summary>
+ /// On Event Handler of EvasObjectEvent
+ /// </summary>
+ public event EventHandler<TEventArgs> On
+ {
+ add
+ {
+ if (_handle == IntPtr.Zero)
+ {
+ return;
+ }
+ EventHandler<TEventArgs> handler = value;
+ var cb = new Interop.Evas.EventCallback((data, evas, obj, info) =>
+ {
+ TEventArgs ea = _parser == null ? (TEventArgs)EventArgs.Empty : _parser(data, obj, info);
+ handler(_sender, ea);
+ });
+ _nativeCallbacks.Add(new NativeCallback { callback = cb, eventHandler = handler });
+ int i = _nativeCallbacks.Count - 1;
+ Interop.Evas.evas_object_event_callback_add(_handle, (Interop.Evas.ObjectCallbackType)_type, _nativeCallbacks[i].callback, IntPtr.Zero);
+ }
+
+ remove
+ {
+ if (_handle == IntPtr.Zero)
+ {
+ return;
+ }
+ EventHandler<TEventArgs> handler = value;
+ var callbacks = _nativeCallbacks.Where(cb => cb.eventHandler == handler);
+ foreach (var cb in callbacks)
+ {
+ Interop.Evas.evas_object_event_callback_del(_handle, (Interop.Evas.ObjectCallbackType)_type, cb.callback);
+ }
+ }
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (disposing)
+ {
+ // Place holder to dispose managed state (managed objects).
+ }
+ if (_handle != IntPtr.Zero)
+ {
+ foreach (var cb in _nativeCallbacks)
+ {
+ Interop.Evas.evas_object_event_callback_del(_handle, (Interop.Evas.ObjectCallbackType)_type, cb.callback);
+ }
+ }
+ _nativeCallbacks.Clear();
+ _disposed = true;
+ }
+ }
+
+ /// <summary>
+ /// Destroy Current Obj
+ /// </summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Make current instance invalidate
+ /// </summary>
+ public void MakeInvalidate()
+ {
+ _sender = null;
+ _handle = IntPtr.Zero;
+ }
+ }
+
+ /// <summary>
+ /// Event class for EvasObject
+ /// </summary>
+ public class EvasObjectEvent : IInvalidatable
+ {
+ private EvasObjectEvent<EventArgs> _evasObjectEvent;
+ private event EventHandler _handlers;
+ private bool _disposed = false;
+
+ /// <summary>
+ /// Creates and initializes a new instance of the EvasObjectEvent.
+ /// </summary>
+ /// <param name="sender">EvasObject class belong to</param>
+ /// <param name="type">EvasObjectCallbackType</param>
+ public EvasObjectEvent(EvasObject sender, EvasObjectCallbackType type) : this(sender, sender.Handle, type)
+ {
+ }
+ /// <summary>
+ /// Creates and initializes a new instance of the EvasObjectEvent.
+ /// </summary>
+ /// <param name="sender">EvasObject class belong to</param>
+ /// <param name="handle">EvasObject class's handle</param>
+ /// <param name="type">EvasObjectCallbackTypes</param>
+ [EditorBrowsableAttribute(EditorBrowsableState.Never)]
+ public EvasObjectEvent(EvasObject sender, IntPtr handle, EvasObjectCallbackType type)
+ {
+ _evasObjectEvent = new EvasObjectEvent<EventArgs>(sender, handle, type, null);
+ }
+
+ ~EvasObjectEvent()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// On Event Handler of EvasObjectEvent
+ /// </summary>
+ public event EventHandler On
+ {
+ add
+ {
+ if (_handlers == null)
+ {
+ _evasObjectEvent.On += SendEvent;
+ }
+ _handlers += value;
+ }
+
+ remove
+ {
+ _handlers -= value;
+ if (_handlers == null)
+ {
+ _evasObjectEvent.On -= SendEvent;
+ }
+ }
+ }
+
+ private void SendEvent(object sender, EventArgs e)
+ {
+ _handlers?.Invoke(sender, e);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (disposing)
+ {
+ _evasObjectEvent.Dispose();
+ }
+ _disposed = true;
+ }
+ }
+
+ /// <summary>
+ /// Destroy Current Obj
+ /// </summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Make current instance invalidate
+ /// </summary>
+ public void MakeInvalidate()
+ {
+ _evasObjectEvent.MakeInvalidate();
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/FlipSelector.cs b/src/ElmSharp/ElmSharp/FlipSelector.cs
new file mode 100755
index 0000000..bffb713
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/FlipSelector.cs
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// A flip selector is a widget to show a set of text items,one at a time.with the same sheet switching style as the clock widget, when one changes the current displaying sheet.
+ /// </summary>
+ public class FlipSelector : Layout
+ {
+ SmartEvent _selected;
+ SmartEvent _overflowed;
+ SmartEvent _underflowed;
+
+ /// <summary>
+ /// Creates and initializes a new instance of the FlipSelector.
+ /// </summary>
+ /// <param name="parent">Parent EvasObject </param>
+ public FlipSelector(EvasObject parent) : base(parent)
+ {
+ _selected = new SmartEvent(this, Handle, "selected");
+ _overflowed = new SmartEvent(this, Handle, "overflowed");
+ _underflowed = new SmartEvent(this, Handle, "underflowed");
+
+ _selected.On += SelectedChanged;
+ _overflowed.On += OverflowedChanged;
+ _underflowed.On += UnderflowedChanged;
+ }
+
+ /// <summary>
+ /// Selected will be triggered when be Selected
+ /// </summary>
+ public event EventHandler Selected;
+ /// <summary>
+ /// Overflowed will be triggered when Overflowed
+ /// </summary>
+ public event EventHandler Overflowed;
+ /// <summary>
+ /// Underflowed will be triggered when be Underflowed
+ /// </summary>
+ public event EventHandler Underflowed;
+
+ /// <summary>
+ /// Sets or gets the interval on time updates for an user mouse button hold on a flip selector widget.
+ /// </summary>
+ public double Interval
+ {
+ get
+ {
+ return Interop.Elementary.elm_flipselector_first_interval_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_flipselector_first_interval_set(Handle, value);
+ }
+ }
+
+
+ /// <summary>
+ /// Gets the currently selected item in a flip selector widget.
+ /// </summary>
+ public FlipSelectorItem SelectedItem
+ {
+ get
+ {
+ IntPtr handle = Interop.Elementary.elm_flipselector_selected_item_get(Handle);
+ return ItemObject.GetItemByHandle(handle) as FlipSelectorItem;
+ }
+ }
+
+ /// <summary>
+ /// Gets the first item in the given flip selector widget's list of items.
+ /// </summary>
+ public FlipSelectorItem FirstItem
+ {
+ get
+ {
+ IntPtr handle = Interop.Elementary.elm_flipselector_first_item_get(Handle);
+ return ItemObject.GetItemByHandle(handle) as FlipSelectorItem;
+ }
+ }
+
+ /// <summary>
+ /// Gets the last item in the given flip selector widget's list of items.
+ /// </summary>
+ public FlipSelectorItem LastItem
+ {
+ get
+ {
+ IntPtr handle = Interop.Elementary.elm_flipselector_last_item_get(Handle);
+ return ItemObject.GetItemByHandle(handle) as FlipSelectorItem;
+ }
+ }
+
+ /// <summary>
+ /// Appends a (text) item to a flip selector widget.
+ /// </summary>
+ /// <param name="text">text value</param>
+ /// <returns>
+ /// A handle to the item added or NULL, on errors
+ /// </returns>
+ /// <remarks>
+ /// The widget's list of labels to show will be appended with the given value. If the user wishes so, a callback function pointer can be passed, which will get called when this same item is selected.
+ /// </remarks>
+ public FlipSelectorItem Append(string text)
+ {
+ FlipSelectorItem item = new FlipSelectorItem(text);
+ item.Handle = Interop.Elementary.elm_flipselector_item_append(Handle, text, null, (IntPtr)item.Id);
+ return item;
+ }
+
+ /// <summary>
+ /// Prepend a (text) item to a flip selector widget.
+ /// </summary>
+ /// <param name="text">Prepend text</param>
+ /// <returns>A handle to the item added or NULL, on errors</returns>
+ /// <remarks>
+ /// The widget's list of labels to show will be prepended with the given value. If the user wishes so, a callback function pointer can be passed, which will get called when this same item is selected.
+ /// </remarks>
+ public FlipSelectorItem Prepend(string text)
+ {
+ FlipSelectorItem item = new FlipSelectorItem(text);
+ item.Handle = Interop.Elementary.elm_flipselector_item_prepend(Handle, text, null, (IntPtr)item.Id);
+ return item;
+ }
+
+ /// <summary>
+ /// To remove the given item.
+ /// </summary>
+ /// <param name="item">FlipSelector's item</param>
+ public void Remove(FlipSelectorItem item)
+ {
+ if (item as FlipSelectorItem != null)
+ item.Delete();
+ }
+
+ /// <summary>
+ /// Programmatically select the next item of a flip selector widget.
+ /// </summary>
+ /// <remarks>
+ /// The selection will be animated. Also, if it reaches the beginning of its list of member items, it will continue with the last one backwards.
+ /// </remarks>
+ public void Next()
+ {
+ Interop.Elementary.elm_flipselector_flip_next(Handle);
+ }
+
+ /// <summary>
+ /// Programmatically select the previous item of a flip selector widget.
+ /// </summary>
+ public void Prev()
+ {
+ Interop.Elementary.elm_flipselector_flip_prev(Handle);
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ return Interop.Elementary.elm_flipselector_add(parent.Handle);
+ }
+
+ void SelectedChanged(object sender, EventArgs e)
+ {
+ SelectedItem?.SendSelected();
+ Selected?.Invoke(this, EventArgs.Empty);
+ }
+
+ void OverflowedChanged(object sender, EventArgs e)
+ {
+ Overflowed?.Invoke(this, e);
+ }
+
+ void UnderflowedChanged(object sender, EventArgs e)
+ {
+ Underflowed?.Invoke(this, e);
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/FlipSelectorItem.cs b/src/ElmSharp/ElmSharp/FlipSelectorItem.cs
new file mode 100755
index 0000000..3210e3b
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/FlipSelectorItem.cs
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// Iterm class of FlipSelector
+ /// </summary>
+ public class FlipSelectorItem : ItemObject
+ {
+ /// <summary>
+ /// Sets or gets the Text of FlipSelectorItem
+ /// </summary>
+ public string Text { get; private set; }
+
+ /// <summary>
+ /// Selected will be triggered when Selected
+ /// </summary>
+ public event EventHandler Selected;
+
+ /// <summary>
+ /// Creates and initializes a new instance of the FlipSelectorItem.
+ /// </summary>
+ /// <param name="text">FlipSelectorItem's text</param>
+ public FlipSelectorItem(string text) : base(IntPtr.Zero)
+ {
+ Text = text;
+ }
+
+ internal void SendSelected()
+ {
+ Selected?.Invoke(this, EventArgs.Empty);
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/FloatingButton.cs b/src/ElmSharp/ElmSharp/FloatingButton.cs
new file mode 100755
index 0000000..5252a1f
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/FloatingButton.cs
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The FloatingButton is a widget that to add floating area for buttons.
+ /// </summary>
+ public class FloatingButton : Layout
+ {
+ /// <summary>
+ /// Creates and initializes a new instance of the FloatingButton class.
+ /// </summary>
+ /// <param name="parent">Created on this parent container..</param>
+ public FloatingButton(EvasObject parent) : base(parent)
+ {
+ }
+
+ /// <summary>
+ /// Sets or gets floatingbutton mode.
+ /// </summary>
+ public FloatingButtonMode Mode
+ {
+ get
+ {
+ return (FloatingButtonMode)Interop.Eext.eext_floatingbutton_mode_get(Handle);
+ }
+ set
+ {
+ Interop.Eext.eext_floatingbutton_mode_set(Handle, (int)value);
+ }
+ }
+
+ /// <summary>
+ /// Gets floatingbutton Position.
+ /// </summary>
+ public FloatingButtonPosition Position
+ {
+ get
+ {
+ return (FloatingButtonPosition)Interop.Eext.eext_floatingbutton_pos_get(Handle);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets movability for a given floatingbutton widget.
+ /// </summary>
+ public bool MovementBlock
+ {
+ get
+ {
+ return Interop.Eext.eext_floatingbutton_movement_block_get(Handle);
+ }
+ set
+ {
+ Interop.Eext.eext_floatingbutton_movement_block_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Get Opacity's value of the given FloatingButton.
+ /// </summary>
+ public override int Opacity
+ {
+ get
+ {
+ return Color.Default.A;
+ }
+
+ set
+ {
+ Console.WriteLine("FloatingButton instance doesn't support to set Opacity.");
+ }
+ }
+
+ /// <summary>
+ /// Set the floatingbutton position with animation or not.
+ /// </summary>
+ /// <param name="position">Button position</param>
+ /// <param name="animated">Animat flag</param>
+ public void SetPosition(FloatingButtonPosition position, bool animated)
+ {
+ if (animated)
+ {
+ Interop.Eext.eext_floatingbutton_pos_bring_in(Handle, (int)position);
+ }
+ else
+ {
+ Interop.Eext.eext_floatingbutton_pos_set(Handle, (int)position);
+ }
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ return Interop.Eext.eext_floatingbutton_add(parent.Handle);
+ }
+ }
+
+ /// <summary>
+ /// Enumeration for FloatingButtonMode
+ /// </summary>
+ public enum FloatingButtonMode
+ {
+ /// <summary>
+ /// Allows all positions
+ /// </summary>
+ All,
+
+ /// <summary>
+ /// Allows LEFT and RIGHT positions only
+ /// </summary>
+ LeftRightOnly,
+ }
+
+ /// <summary>
+ /// Enumeration for FloatingButtonPosition
+ /// </summary>
+ public enum FloatingButtonPosition
+ {
+ /// <summary>
+ /// Hides in the left, but small handler will show only
+ /// </summary>
+ LeftOut,
+
+ /// <summary>
+ /// Shows all of buttons, but lies on the left
+ /// </summary>
+ Left,
+
+ /// <summary>
+ /// Shows all of buttons, but lies on the center
+ /// </summary>
+ Center,
+
+ /// <summary>
+ /// Shows all of buttons, but lies on the right
+ /// </summary>
+ Right,
+
+ /// <summary>
+ /// Hides in the right, but small handler will show only
+ /// </summary>
+ RightOut,
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/GenGrid.cs b/src/ElmSharp/ElmSharp/GenGrid.cs
new file mode 100644
index 0000000..2b1a6ee
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/GenGrid.cs
@@ -0,0 +1,606 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// It inherits System.EventArgs.
+ /// It contains Item which is <see cref="GenGridItem"/> type.
+ /// All events of GenGrid contain GenGridItemEventArgs as a parameter.
+ /// </summary>
+ public class GenGridItemEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Gets or sets GenGrid item.The return type is <see cref="GenGridItem"/>.
+ /// </summary>
+ public GenGridItem Item { get; set; }
+
+ internal static GenGridItemEventArgs CreateFromSmartEvent(IntPtr data, IntPtr obj, IntPtr info)
+ {
+ GenGridItem item = ItemObject.GetItemByHandle(info) as GenGridItem;
+ return new GenGridItemEventArgs() { Item = item };
+ }
+ }
+
+ /// <summary>
+ /// It inherits <see cref="Layout"/>.
+ /// The GenGrid is a widget that aims to position objects in a grid layout while actually creating and rendering only the visible ones.
+ /// It has two direction in which a given GenGrid widget expands while placing its items, horizontal and vertical.
+ /// The GenGrid items are represented through <see cref="GenItemClass"/> definition field details.
+ /// </summary>
+ public class GenGrid : Layout
+ {
+ HashSet<GenGridItem> _children = new HashSet<GenGridItem>();
+
+ SmartEvent<GenGridItemEventArgs> _selected;
+ SmartEvent<GenGridItemEventArgs> _unselected;
+ SmartEvent<GenGridItemEventArgs> _activated;
+ SmartEvent<GenGridItemEventArgs> _pressed;
+ SmartEvent<GenGridItemEventArgs> _released;
+ SmartEvent<GenGridItemEventArgs> _doubleClicked;
+ SmartEvent<GenGridItemEventArgs> _realized;
+ SmartEvent<GenGridItemEventArgs> _unrealized;
+ SmartEvent<GenGridItemEventArgs> _longpressed;
+ SmartEvent _changed;
+
+ /// <summary>
+ /// Creates and initializes a new instance of the GenGrid class.
+ /// </summary>
+ /// <param name="parent">The parent is a given container which will be attached by GenGrid as a child. It's <see cref="EvasObject"/> type.</param>
+ public GenGrid(EvasObject parent) : base(parent)
+ {
+ InitializeSmartEvent();
+ }
+
+ /// <summary>
+ /// ItemSelected is raised when a new gengrid item is selected.
+ /// </summary>
+ public event EventHandler<GenGridItemEventArgs> ItemSelected;
+
+ /// <summary>
+ /// ItemUnselected is raised when the gengrid item is Unselected.
+ /// </summary>
+ public event EventHandler<GenGridItemEventArgs> ItemUnselected;
+
+ /// <summary>
+ /// ItemPressed is raised when a new gengrid item is pressed.
+ /// </summary>
+ public event EventHandler<GenGridItemEventArgs> ItemPressed;
+
+ /// <summary>
+ /// ItemReleased is raised when a new gengrid item is released.
+ /// </summary>
+ public event EventHandler<GenGridItemEventArgs> ItemReleased;
+
+ /// <summary>
+ /// ItemActivated is raised when a new gengrid item is double clicked or pressed (enter|return|spacebar).
+ /// </summary>
+ public event EventHandler<GenGridItemEventArgs> ItemActivated;
+
+ /// <summary>
+ /// ItemDoubleClicked is raised when a new gengrid item is double clicked.
+ /// </summary>
+ public event EventHandler<GenGridItemEventArgs> ItemDoubleClicked;
+
+ /// <summary>
+ /// ItemRealized is raised when a gengrid item is implementing through <see cref="GenItemClass"/>.
+ /// </summary>
+ public event EventHandler<GenGridItemEventArgs> ItemRealized;
+
+ /// <summary>
+ /// ItemUnrealized is raised when the gengrid item is deleted.
+ /// </summary>
+ public event EventHandler<GenGridItemEventArgs> ItemUnrealized;
+
+ /// <summary>
+ /// ItemLongPressed is raised when a gengrid item is pressed for a certain amount of time. By default it's 1 second.
+ /// </summary>
+ public event EventHandler<GenGridItemEventArgs> ItemLongPressed;
+
+ /// <summary>
+ /// Changed is raised when an item is added, removed, resized or moved and when the gengrid is resized or gets "horizontal" property changes.
+ /// </summary>
+ public event EventHandler Changed;
+
+ /// <summary>
+ /// Gets or sets the item's grid alignment along x-axis within a given gengrid widget.
+ /// Accepted values are in the 0.0 to 1.0 range, with the special value -1.0 used to specify "justify" or "fill" by some users.
+ /// By default, value is 0.0, meaning that the gengrid has its items grid placed exactly in the left along x-axis.
+ /// </summary>
+ public double ItemAlignmentX
+ {
+ get
+ {
+ double align;
+ Interop.Elementary.elm_gengrid_align_get(RealHandle, out align, IntPtr.Zero);
+ return align;
+ }
+ set
+ {
+ double aligny = ItemAlignmentY;
+ Interop.Elementary.elm_gengrid_align_set(RealHandle, value, aligny);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the item's grid alignment on y-axis within a given gengrid widget.
+ /// Accepted values are in the 0.0 to 1.0 range, with the special value -1.0 used to specify "justify" or "fill" by some users.
+ /// By default, value is 0.0, meaning that the gengrid has its items grid placed exactly in the top along y-axis.
+ /// </summary>
+ public double ItemAlignmentY
+ {
+ get
+ {
+ double align;
+ Interop.Elementary.elm_gengrid_align_get(RealHandle, IntPtr.Zero, out align);
+ return align;
+ }
+ set
+ {
+ double alignx = ItemAlignmentX;
+ Interop.Elementary.elm_gengrid_align_set(RealHandle, alignx, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the manner in which the items grid is filled within a given gengrid widget.
+ /// It is filled if true, otherwise false.
+ /// </summary>
+ public bool FillItems
+ {
+ get
+ {
+ return Interop.Elementary.elm_gengrid_filled_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_gengrid_filled_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets whether multi-selection is enabled or disabled for a given gengrid widget.
+ /// </summary>
+ /// <remarks>
+ /// Multi-selection is the ability to have more than one item selected, on a given gengrid, simultaneously.
+ /// When it is enabled, a sequence of clicks on different items makes them all selected, progressively.
+ /// A click on an already selected item unselects it. If interacting via the keyboard, multi-selection is enabled while holding the "Shift" key.
+ /// By default, multi-selection is disabled.
+ /// </remarks>
+ public bool MultipleSelection
+ {
+ get
+ {
+ return Interop.Elementary.elm_gengrid_multi_select_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_gengrid_multi_select_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the width for the items of a given gengrid widget.
+ /// </summary>
+ /// <remarks>
+ /// A gengrid, after creation, still has no information on the size to give to each of its cells.
+ /// The default width and height just have one finger wide.
+ /// Use this property to force a custom width for your items, making them as big as you wish.
+ /// </remarks>
+ public int ItemWidth
+ {
+ get
+ {
+ int width;
+ Interop.Elementary.elm_gengrid_item_size_get(RealHandle, out width, IntPtr.Zero);
+ return width;
+ }
+ set
+ {
+ int height = ItemHeight;
+ Interop.Elementary.elm_gengrid_item_size_set(RealHandle, value, height);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the height for the items of a given gengrid widget.
+ /// </summary>
+ /// <remarks>
+ /// A gengrid, after creation, still has no information on the size to give to each of its cells.
+ /// The default width and height just have one finger wide.
+ /// Use this property to force a custom height for your items, making them as big as you wish.
+ /// </remarks>
+ public int ItemHeight
+ {
+ get
+ {
+ int height;
+ Interop.Elementary.elm_gengrid_item_size_get(RealHandle, IntPtr.Zero, out height);
+ return height;
+ }
+ set
+ {
+ int width = ItemWidth;
+ Interop.Elementary.elm_gengrid_item_size_set(RealHandle, width, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the gengrid select mode by <see cref="GenGridSelectionMode"/>.
+ /// </summary>
+ public GenItemSelectionMode SelectionMode
+ {
+ get
+ {
+ return (GenItemSelectionMode)Interop.Elementary.elm_gengrid_select_mode_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_gengrid_select_mode_set(RealHandle, (int)value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the direction for which a given gengrid widget expands while placing its items.
+ /// </summary>
+ /// <remarks>
+ /// If true, items are placed in columns from top to bottom and when the space for a column is filled, another one is started on the right, thus expanding the grid horizontally.
+ /// If false, items are placed in rows from left to right, and when the space for a row is filled, another one is started below, thus expanding the grid vertically.
+ /// </remarks>
+ public bool IsHorizontal
+ {
+ get
+ {
+ return Interop.Elementary.elm_gengrid_horizontal_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_gengrid_horizontal_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets whether the gengrid items should be highlighted when an item is selected.
+ /// </summary>
+ public bool IsHighlight
+ {
+ get
+ {
+ return Interop.Elementary.elm_gengrid_highlight_mode_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_gengrid_highlight_mode_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the value of HorizontalScrollBarVisiblePolicy
+ /// </summary>
+ /// <remarks>
+ /// ScrollBarVisiblePolicy.Auto means the horizontal scrollbar is made visible if it is needed, and otherwise kept hidden.
+ /// ScrollBarVisiblePolicy.Visible turns it on all the time, and ScrollBarVisiblePolicy.Invisible always keeps it off.
+ /// </remarks>
+ public ScrollBarVisiblePolicy HorizontalScrollBarVisiblePolicy
+ {
+ get
+ {
+ int policy;
+ Interop.Elementary.elm_scroller_policy_get(RealHandle, out policy, IntPtr.Zero);
+ return (ScrollBarVisiblePolicy)policy;
+ }
+ set
+ {
+ ScrollBarVisiblePolicy v = VerticalScrollBarVisiblePolicy;
+ Interop.Elementary.elm_scroller_policy_set(RealHandle, (int)value, (int)v);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the value of VerticalScrollBarVisiblePolicy
+ /// </summary>
+ /// <remarks>
+ /// ScrollBarVisiblePolicy.Auto means the vertical scrollbar is made visible if it is needed, and otherwise kept hidden.
+ /// ScrollBarVisiblePolicy.Visible turns it on all the time, and ScrollBarVisiblePolicy.Invisible always keeps it off.
+ /// </remarks>
+ public ScrollBarVisiblePolicy VerticalScrollBarVisiblePolicy
+ {
+ get
+ {
+ int policy;
+ Interop.Elementary.elm_scroller_policy_get(RealHandle, IntPtr.Zero, out policy);
+ return (ScrollBarVisiblePolicy)policy;
+ }
+ set
+ {
+ ScrollBarVisiblePolicy h = HorizontalScrollBarVisiblePolicy;
+ Interop.Elementary.elm_scroller_policy_set(RealHandle, (int)h, (int)value);
+ }
+ }
+
+ /// <summary>
+ /// Gets the first item in a given gengrid widget.
+ /// </summary>
+ public GenGridItem FirstItem
+ {
+ get
+ {
+ IntPtr handle = Interop.Elementary.elm_gengrid_first_item_get(RealHandle);
+ return ItemObject.GetItemByHandle(handle) as GenGridItem;
+ }
+ }
+
+ /// <summary>
+ /// Gets the last item in a given gengrid widget.
+ /// </summary>
+ public GenGridItem LastItem
+ {
+ get
+ {
+ IntPtr handle = Interop.Elementary.elm_gengrid_last_item_get(RealHandle);
+ return ItemObject.GetItemByHandle(handle) as GenGridItem;
+ }
+ }
+
+ /// <summary>
+ /// Gets the items count in a given gengrid widget.
+ /// </summary>
+ public uint ItemCount
+ {
+ get
+ {
+ return Interop.Elementary.elm_gengrid_items_count(RealHandle);
+ }
+ }
+
+ /// <summary>
+ /// Gets the selected item in a given gengrid widget.
+ /// </summary>
+ public GenGridItem SelectedItem
+ {
+ get
+ {
+ IntPtr handle = Interop.Elementary.elm_gengrid_selected_item_get(RealHandle);
+ return ItemObject.GetItemByHandle(handle) as GenGridItem;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets whether a given gengrid widget is or not able have items reordered.
+ /// </summary>
+ public bool ReorderMode
+ {
+ get
+ {
+ return Interop.Elementary.elm_gengrid_reorder_mode_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_gengrid_reorder_mode_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Appends a new item to a given gengrid widget. This adds an item to the end of the gengrid.
+ /// </summary>
+ /// <param name="itemClass">The itemClass defines how to display the data.</param>
+ /// <param name="data">The item data.</param>
+ /// <returns>Return a gengrid item that contains data and itemClass.</returns>
+ /// <seealso cref="GenItemClass"/>
+ /// <seealso cref="GenGridItem"/>
+ public GenGridItem Append(GenItemClass itemClass, object data)
+ {
+ GenGridItem item = new GenGridItem(data, itemClass);
+ IntPtr handle = Interop.Elementary.elm_gengrid_item_append(RealHandle, itemClass.UnmanagedPtr, (IntPtr)item.Id, null, (IntPtr)item.Id);
+ item.Handle = handle;
+ AddInternal(item);
+ return item;
+ }
+
+ /// <summary>
+ /// Prepends a new item to a given gengrid widget. This adds an item to the beginning of the gengrid.
+ /// </summary>
+ /// <param name="itemClass">The itemClass defines how to display the data.</param>
+ /// <param name="data">The item data.</param>
+ /// <returns>Return a gengrid item that contains data and itemClass.</returns>
+ /// <seealso cref="GenItemClass"/>
+ /// <seealso cref="GenGridItem"/>
+ public GenGridItem Prepend(GenItemClass itemClass, object data)
+ {
+ GenGridItem item = new GenGridItem(data, itemClass);
+ IntPtr handle = Interop.Elementary.elm_gengrid_item_prepend(RealHandle, itemClass.UnmanagedPtr, (IntPtr)item.Id, null, (IntPtr)item.Id);
+ item.Handle = handle;
+ AddInternal(item);
+ return item;
+ }
+
+ /// <summary>
+ /// Inserts an item before another in a gengrid widget. This inserts an item before another in the gengrid.
+ /// </summary>
+ /// <param name="itemClass">The itemClass defines how to display the data.</param>
+ /// <param name="data">The item data.</param>
+ /// <param name="before">The item before which to place this new one.</param>
+ /// <returns>Return a gengrid item that contains data and itemClass./></returns>
+ /// <seealso cref="GenItemClass"/>
+ /// <seealso cref="GenGridItem"/>
+ public GenGridItem InsertBefore(GenItemClass itemClass, object data, GenGridItem before)
+ {
+ GenGridItem item = new GenGridItem(data, itemClass);
+ IntPtr handle = Interop.Elementary.elm_gengrid_item_insert_before(RealHandle, itemClass.UnmanagedPtr, (IntPtr)item.Id, before, null, (IntPtr)item.Id);
+ item.Handle = handle;
+ AddInternal(item);
+ return item;
+ }
+
+ /// <summary>
+ /// Inserts an item before another in a gengrid widget. This inserts an item after another in the gengrid.
+ /// </summary>
+ /// <param name="itemClass">The itemClass defines how to display the data.</param>
+ /// <param name="data">The item data.</param>
+ /// <param name="after">The item after which to place this new one.</param>
+ /// <returns>Return a gengrid item that contains data and itemClass.</returns>
+ /// <seealso cref="GenItemClass"/>
+ /// <seealso cref="GenGridItem"/>
+ public GenGridItem InsertAfter(GenItemClass itemClass, object data, GenGridItem after)
+ {
+ GenGridItem item = new GenGridItem(data, itemClass);
+ IntPtr handle = Interop.Elementary.elm_gengrid_item_insert_after(RealHandle, itemClass.UnmanagedPtr, (IntPtr)item.Id, after, null, (IntPtr)item.Id);
+ item.Handle = handle;
+ AddInternal(item);
+ return item;
+ }
+
+ /// <summary>
+ /// Insert an item in a gengrid widget using a user-defined sort function.
+ /// </summary>
+ /// <param name="itemClass">The itemClass defines how to display the data.</param>
+ /// <param name="data">The item data.</param>
+ /// <param name="func">User defined comparison function that defines the sort order based on gengrid item and its data.</param>
+ /// <returns>Return a gengrid item that contains data and itemClass.</returns>
+ public GenGridItem InsertSorted(GenItemClass itemClass, object data, Comparison<object> comparison)
+ {
+ GenGridItem item = new GenGridItem(data, itemClass);
+
+ Interop.Elementary.Eina_Compare_Cb compareCallback = (handle1, handle2) =>
+ {
+ GenGridItem first = (ItemObject.GetItemByHandle(handle1) as GenGridItem) ?? item;
+ GenGridItem second = (ItemObject.GetItemByHandle(handle2) as GenGridItem) ?? item;
+ return comparison(first.Data, second.Data);
+ };
+
+ IntPtr handle = Interop.Elementary.elm_gengrid_item_sorted_insert(RealHandle, itemClass.UnmanagedPtr, (IntPtr)item.Id, compareCallback, null, (IntPtr)item.Id);
+ item.Handle = handle;
+ AddInternal(item);
+ return item;
+ }
+
+ /// <summary>
+ /// Shows a given item to the visible area of a gengrid.
+ /// </summary>
+ /// <param name="item">The gengrid item to display.</param>
+ /// <param name="position">The position of the item in the viewport.</param>
+ /// <param name="animated">The type of how to show the item.</param>
+ /// <remarks>
+ /// If animated is true, the gengrid shows item by scrolling if it's not fully visible.
+ /// If animated is false, the gengrid shows item by jumping if it's not fully visible.
+ /// </remarks>
+ /// <seealso cref="ScrollToPosition"/>
+ public void ScrollTo(GenGridItem item, ScrollToPosition position, bool animated)
+ {
+ if (animated)
+ {
+ Interop.Elementary.elm_gengrid_item_bring_in(item.Handle, (int)position);
+ }
+ else
+ {
+ Interop.Elementary.elm_gengrid_item_show(item.Handle, (int)position);
+ }
+ }
+
+ /// <summary>
+ /// Updates the contents of all the realized items.
+ /// This updates all realized items by calling all the <see cref="GenItemClass"/> again to get the content, text, and states.
+ /// Use this when the original item data has changed and the changes are desired to reflect.
+ /// </summary>
+ /// <remarks>
+ /// <see cref="GenItem.Update()"/> to update just one item.
+ /// </remarks>
+ public void UpdateRealizedItems()
+ {
+ Interop.Elementary.elm_gengrid_realized_items_update(RealHandle);
+ }
+
+ /// <summary>
+ /// Removes all items from a given gengrid widget.
+ /// This removes(and deletes) all items in obj, making it empty.
+ /// </summary>
+ /// <remarks>
+ /// <see cref="ItemObject.Delete()"/> to delete just one item.
+ /// </remarks>
+ public void Clear()
+ {
+ Interop.Elementary.elm_gengrid_clear(RealHandle);
+ }
+
+ /// <summary>
+ /// Get the item that is at the x, y canvas coords.
+ /// </summary>
+ /// <param name="x">The input x coordinate</param>
+ /// <param name="y">The input y coordinate</param>
+ /// <param name="positionX">The position relative to the item returned here.
+ /// -1, 0 or 1, depending if the coordinate is on the left portion of that item(-1), on the middle section(0) or on the right part(1).
+ /// </param>
+ /// <param name="positionY">The position relative to the item returned here
+ /// -1, 0 or 1, depending if the coordinate is on the upper portion of that item (-1), on the middle section (0) or on the lower part (1).
+ /// </param>
+ /// <returns></returns>
+ public GenGridItem GetItemByPosition(int x, int y, out int portionX, out int portionY)
+ {
+ IntPtr handle = Interop.Elementary.elm_gengrid_at_xy_item_get(RealHandle, x, y, out portionX, out portionY);
+ return ItemObject.GetItemByHandle(handle) as GenGridItem;
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ IntPtr handle = Interop.Elementary.elm_layout_add(parent.Handle);
+ Interop.Elementary.elm_layout_theme_set(handle, "layout", "elm_widget", "default");
+
+ RealHandle = Interop.Elementary.elm_gengrid_add(handle);
+ Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
+
+ return handle;
+ }
+
+ void InitializeSmartEvent()
+ {
+ _selected = new SmartEvent<GenGridItemEventArgs>(this, this.RealHandle, "selected", GenGridItemEventArgs.CreateFromSmartEvent);
+ _unselected = new SmartEvent<GenGridItemEventArgs>(this, this.RealHandle, "unselected", GenGridItemEventArgs.CreateFromSmartEvent);
+ _activated = new SmartEvent<GenGridItemEventArgs>(this, this.RealHandle, "activated", GenGridItemEventArgs.CreateFromSmartEvent);
+ _pressed = new SmartEvent<GenGridItemEventArgs>(this, this.RealHandle, "pressed", GenGridItemEventArgs.CreateFromSmartEvent);
+ _released = new SmartEvent<GenGridItemEventArgs>(this, this.RealHandle, "released", GenGridItemEventArgs.CreateFromSmartEvent);
+ _doubleClicked = new SmartEvent<GenGridItemEventArgs>(this, this.RealHandle, "clicked,double", GenGridItemEventArgs.CreateFromSmartEvent);
+ _realized = new SmartEvent<GenGridItemEventArgs>(this, this.RealHandle, "realized", GenGridItemEventArgs.CreateFromSmartEvent);
+ _unrealized = new SmartEvent<GenGridItemEventArgs>(this, this.RealHandle, "unrealized", GenGridItemEventArgs.CreateFromSmartEvent);
+ _longpressed = new SmartEvent<GenGridItemEventArgs>(this, this.RealHandle, "longpressed", GenGridItemEventArgs.CreateFromSmartEvent);
+ _changed = new SmartEvent(this, this.RealHandle, "changed");
+
+ _selected.On += (s, e) => { if (e.Item != null) ItemSelected?.Invoke(this, e); };
+ _unselected.On += (s, e) => { if (e.Item != null) ItemUnselected?.Invoke(this, e); };
+ _activated.On += (s, e) => { if (e.Item != null) ItemActivated?.Invoke(this, e); };
+ _pressed.On += (s, e) => { if (e.Item != null) ItemPressed?.Invoke(this, e); };
+ _released.On += (s, e) => { if (e.Item != null) ItemReleased?.Invoke(this, e); };
+ _doubleClicked.On += (s, e) => { if (e.Item != null) ItemDoubleClicked?.Invoke(this, e); };
+ _realized.On += (s, e) => { if (e.Item != null) ItemRealized?.Invoke(this, e); };
+ _unrealized.On += (s, e) => { if (e.Item != null) ItemUnrealized?.Invoke(this, e); };
+ _longpressed.On += (s, e) => { if (e.Item != null) ItemLongPressed?.Invoke(this, e); };
+ _changed.On += (s, e) => { Changed?.Invoke(this, e); };
+ }
+
+ void AddInternal(GenGridItem item)
+ {
+ _children.Add(item);
+ item.Deleted += Item_Deleted;
+ }
+
+ void Item_Deleted(object sender, EventArgs e)
+ {
+ _children.Remove((GenGridItem)sender);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/GenGridItem.cs b/src/ElmSharp/ElmSharp/GenGridItem.cs
new file mode 100644
index 0000000..66b451f
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/GenGridItem.cs
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.ComponentModel;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// It inherits <see cref="GenItem"/>.
+ /// A instance to the gengrid item added.
+ /// It contains Update() method to update a gengrid item which is given.
+ /// </summary>
+ public class GenGridItem : GenItem
+ {
+ internal GenGridItem(object data, GenItemClass itemClass) : base(data, itemClass)
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets whether a given gengrid item is selected.
+ /// If one gengrid item is selected, any other previously selected items get unselected in favor of this new one.
+ /// </summary>
+ /// <remarks>
+ /// If true, it is selected.
+ /// If false, it is unselected.
+ /// </remarks>
+ public override bool IsSelected
+ {
+ get
+ {
+ return Interop.Elementary.elm_gengrid_item_selected_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_gengrid_item_selected_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the type of mouse pointer/cursor decoration to be shown, when the mouse pointer is over the given gengrid widget item.
+ /// <remarks>
+ /// The cursor's changing area is restricted to the item's area, and not the whole widget's. Note that that item cursors have precedence over widget cursors, so that a mouse over item will always show cursor type.
+ /// </remarks>>
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override string Cursor
+ {
+ get
+ {
+ return Interop.Elementary.elm_gengrid_item_cursor_get(Handle);
+ }
+ set
+ {
+ if (!string.IsNullOrEmpty(value))
+ {
+ Interop.Elementary.elm_gengrid_item_cursor_set(Handle, value);
+ }
+ else
+ {
+ Interop.Elementary.elm_gengrid_item_cursor_unset(Handle);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets custom cursor for gengrid item.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override string CursorStyle
+ {
+ get
+ {
+ return Interop.Elementary.elm_gengrid_item_cursor_style_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_gengrid_item_cursor_style_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets whether to rely on the rendering engine.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override bool IsUseEngineCursor
+ {
+ get
+ {
+ return Interop.Elementary.elm_gengrid_item_cursor_engine_only_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_gengrid_item_cursor_engine_only_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the style of given gengrid item's tooltip.
+ /// </summary>
+ public override string TooltipStyle
+ {
+ get
+ {
+ return Interop.Elementary.elm_gengrid_item_tooltip_style_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_gengrid_item_tooltip_style_set(Handle, value);
+ }
+ }
+
+ public override GenItemSelectionMode SelectionMode
+ {
+ get
+ {
+ return (GenItemSelectionMode)Interop.Elementary.elm_gengrid_item_select_mode_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_gengrid_item_select_mode_set(Handle, (Interop.Elementary.Elm_Object_Select_Mode)value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets gengrid item's row position, relative to the whole gengrid's grid area.
+ /// </summary>
+ public int Row
+ {
+ get
+ {
+ int row, column;
+ Interop.Elementary.elm_gengrid_item_pos_get(Handle, out row, out column);
+ return row;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets gengrid item's column position, relative to the whole gengrid's grid area.
+ /// </summary>
+ public int Column
+ {
+ get
+ {
+ int row, column;
+ Interop.Elementary.elm_gengrid_item_pos_get(Handle, out row, out column);
+ return column;
+ }
+ }
+
+ public override void SetTooltipText(string tooltip)
+ {
+ Interop.Elementary.elm_gengrid_item_tooltip_text_set(Handle, tooltip);
+ }
+
+ public override void UnsetTooltip()
+ {
+ Interop.Elementary.elm_gengrid_item_tooltip_unset(Handle);
+ }
+
+ /// <summary>
+ /// Updates the content of a given gengrid item.
+ /// This updates an item by calling all the genitem class functions again to get the content, text, and states.
+ /// Use this when the original item data has changed and you want the changes to reflect.
+ /// </summary>
+ /// <remarks>
+ /// <see cref="GenGrid.UpdateRealizedItems"/> to update the contents of all the realized items.
+ /// </remarks>
+ public override void Update()
+ {
+ Interop.Elementary.elm_gengrid_item_update(Handle);
+ }
+
+ protected override void UpdateTooltipDelegate()
+ {
+ Interop.Elementary.elm_gengrid_item_tooltip_content_cb_set(Handle,
+ TooltipContentDelegate != null ? _tooltipCb : null,
+ IntPtr.Zero,
+ null);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/GenItem.cs b/src/ElmSharp/ElmSharp/GenItem.cs
new file mode 100644
index 0000000..ac609b0
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/GenItem.cs
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ public enum GenItemSelectionMode
+ {
+ /// <summary>
+ /// Default select mode.
+ /// </summary>
+ Default,
+
+ /// <summary>
+ /// Always select mode.
+ /// </summary>
+ Always,
+
+ /// <summary>
+ /// No select mode.
+ /// </summary>
+ None,
+
+ /// <summary>
+ /// No select mode with no finger size rule.
+ /// </summary>
+ DisplayOnly
+ }
+
+ /// <summary>
+ /// It inherits <see cref="ItemObject"/>.
+ /// A base class for <see cref="GenGridItem"/> and <see cref="GenListItem"/>.
+ /// It contains genitem class and data to display data.
+ /// </summary>
+ public abstract class GenItem : ItemObject
+ {
+ internal Interop.Elementary.Elm_Tooltip_Item_Content_Cb _tooltipCb;
+ GetTooltipContentDelegate _tooltipContentDelegate = null;
+
+ /// <summary>
+ /// The delegate returning the tooltip contents.
+ /// </summary>
+ public delegate EvasObject GetTooltipContentDelegate();
+
+ internal GenItem(object data, GenItemClass itemClass) : base(IntPtr.Zero)
+ {
+ Data = data;
+ ItemClass = itemClass;
+ _tooltipCb = (d, obj, tooltip, item) => { return TooltipContentDelegate(); };
+ }
+
+ /// <summary>
+ /// Gets the item class that defines how to display data. It returns <see cref="GenItemClass"/> type.
+ /// </summary>
+ public GenItemClass ItemClass { get; protected set; }
+
+ /// <summary>
+ /// It's a abstract property. It's implemented by <see cref="GenGridItem.TooltipContent"/> and <see cref="GenListItem.TooltipContent"/>.
+ /// </summary>
+ public GetTooltipContentDelegate TooltipContentDelegate
+ {
+ get
+ {
+ return _tooltipContentDelegate;
+ }
+ set
+ {
+ _tooltipContentDelegate = value;
+ UpdateTooltipDelegate();
+ }
+ }
+
+ public abstract GenItemSelectionMode SelectionMode { get; set; }
+
+ public abstract string Cursor { get; set; }
+ public abstract string CursorStyle { get; set; }
+
+ public abstract bool IsUseEngineCursor { get; set; }
+
+ /// <summary>
+ /// Gets item data that is added through calling <see cref="GenGrid.Append(GenItemClass, object)"/>, <see cref="GenGrid.Prepend(GenItemClass, object)"/> or <see cref="GenGrid.InsertBefore(GenItemClass, object, GenGridItem)"/> methods.
+ /// </summary>
+ public object Data { get; protected set; }
+
+ /// <summary>
+ /// It's a abstract property. It's implemented by <see cref="GenGridItem.IsSelected"/> and <see cref="GenListItem.IsSelected"/>.
+ /// </summary>
+ public abstract bool IsSelected { get; set; }
+
+ /// <summary>
+ /// It's a abstract property. It's implemented by <see cref="GenGridItem.TooltipStyle"/> and <see cref="GenListItem.TooltipStyle"/>.
+ /// </summary>
+ public abstract string TooltipStyle { get; set; }
+
+ public abstract void SetTooltipText(string tooltip);
+ public abstract void UnsetTooltip();
+
+ /// <summary>
+ /// It's a abstract method. It's implemented by <see cref="GenGridItem.Update"/> and <see cref="GenListItem.Update"/>.
+ /// </summary>
+ public abstract void Update();
+
+ /// <summary>
+ /// The override method for delete item class and item data. It's called when the item is deleting.
+ /// </summary>
+ protected override void OnInvalidate()
+ {
+ ItemClass?.SendItemDeleted(Data);
+ Data = null;
+ ItemClass = null;
+ }
+
+ protected abstract void UpdateTooltipDelegate();
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/GenItemClass.cs b/src/ElmSharp/ElmSharp/GenItemClass.cs
new file mode 100644
index 0000000..17fe11a
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/GenItemClass.cs
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// It represents the GenGrid or GenList item class definition field details.
+ /// It has some display styles, such as "default", "full" and "group_index".
+ /// </summary>
+ public class GenItemClass : IDisposable
+ {
+ static Dictionary<IntPtr, EvasObject> s_HandleToEvasObject = new Dictionary<IntPtr, EvasObject>();
+
+ /// <summary>
+ /// The delegate to define <see cref="GetTextHandler"/>.
+ /// </summary>
+ /// <param name="data">The item data.</param>
+ /// <param name="part">The part where the data should be shown.</param>
+ /// <returns>Return string that should be shown.</returns>
+ public delegate string GetTextDelegate(object data, string part);
+
+ /// <summary>
+ /// The delegate to define <see cref="GetContentHandler"/>.
+ /// </summary>
+ /// <param name="data">The item data.</param>
+ /// <param name="part">The part where the data should be shown.</param>
+ /// <returns>Return content that should be shown.</returns>
+ public delegate EvasObject GetContentDelegate(object data, string part);
+
+ /// <summary>
+ /// The delegate to define <see cref="DeleteHandler"/>.
+ /// </summary>
+ /// <param name="data">The item data.</param>
+ public delegate void DeleteDelegate(object data);
+
+ /// <summary>
+ /// The delegate to define <see cref="ReusableContentHandler"/>.
+ /// </summary>
+ /// <param name="data">The item data.</param>
+ /// <param name="part">The part where the data should be shown.</param>
+ /// <param name="old">The content has been added in gengrid.</param>
+ /// <returns>Return content that should be shown.</returns>
+ public delegate EvasObject GetReusableContentDelegate(object data, string part, EvasObject old);
+
+ ItemClass _itemClass;
+ IntPtr _unmanagedPtr = IntPtr.Zero;
+ string _style;
+
+ /// <summary>
+ /// Creates and initializes a new instance of the GenItemClass.
+ /// </summary>
+ /// <param name="style">The item display style.</param>
+ public GenItemClass(string style)
+ {
+ _style = style;
+ IntPtr unmanaged = CreateItemClass();
+
+ _itemClass = Marshal.PtrToStructure<ItemClass>(unmanaged);
+ _itemClass.itemStyle = style;
+ _itemClass.textCallback = GetTextCallback;
+ _itemClass.contentCallback = GetContentCallback;
+ _itemClass.stateCallback = null;
+ _itemClass.delCallback = DelCallback;
+ _itemClass.reusableContentCallback = GetReusableContentCallback;
+
+ ReleaseItemClass(unmanaged);
+ }
+
+ ~GenItemClass()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Gets the item style.
+ /// </summary>
+ public string ItemStyle { get { return _style; } }
+
+ /// <summary>
+ /// Gets or sets the callback that defines how to display item text.
+ /// If get, return <see cref="GetTextDelegate"/>.
+ /// </summary>
+ public GetTextDelegate GetTextHandler { get; set; }
+
+ /// <summary>
+ /// Gets or sets the callback that defines how to display item content.
+ /// If get, return <see cref="GetContentDelegate"/>.
+ /// </summary>
+ public GetContentDelegate GetContentHandler { get; set; }
+
+ /// <summary>
+ /// Gets or sets the callback that defines how to delete item text and content.
+ /// If get, return <see cref="DeleteDelegate"/>.
+ /// </summary>
+ public DeleteDelegate DeleteHandler { get; set; }
+
+ /// <summary>
+ /// Gets or sets the callback that defines how to reuse item content.
+ /// If get, return <see cref="GetReusableContentDelegate"/>.
+ /// </summary>
+ public GetReusableContentDelegate ReusableContentHandler { get; set; }
+
+ internal IntPtr UnmanagedPtr
+ {
+ get
+ {
+ if (_unmanagedPtr == IntPtr.Zero)
+ {
+ _unmanagedPtr = Marshal.AllocHGlobal(Marshal.SizeOf(_itemClass));
+ Marshal.StructureToPtr(_itemClass, _unmanagedPtr, false);
+ }
+ return _unmanagedPtr;
+ }
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_unmanagedPtr != IntPtr.Zero)
+ {
+ Marshal.FreeHGlobal(_unmanagedPtr);
+ _unmanagedPtr = IntPtr.Zero;
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ internal void SendItemDeleted(object data)
+ {
+ // data is user inserted value with GenItem
+ DeleteHandler?.Invoke(data);
+ }
+
+ protected virtual IntPtr CreateItemClass()
+ {
+ return Interop.Elementary.elm_genlist_item_class_new();
+ }
+
+ protected virtual void ReleaseItemClass(IntPtr unmanagedPtr)
+ {
+ Interop.Elementary.elm_genlist_item_class_free(unmanagedPtr);
+ }
+
+ string GetTextCallback(IntPtr data, IntPtr obj, IntPtr part)
+ {
+ GenItem item = ItemObject.GetItemById((int)data) as GenItem;
+ return GetTextHandler?.Invoke(item?.Data, Marshal.PtrToStringAnsi(part));
+ }
+
+ IntPtr GetContentCallback(IntPtr data, IntPtr obj, IntPtr part)
+ {
+ GenItem item = ItemObject.GetItemById((int)data) as GenItem;
+ EvasObject evasObject = GetContentHandler?.Invoke(item?.Data, Marshal.PtrToStringAnsi(part));
+ if (evasObject != null)
+ {
+ s_HandleToEvasObject[evasObject.Handle] = evasObject;
+ evasObject.Deleted += EvasObjectDeleted;
+ }
+ return evasObject;
+ }
+
+ void EvasObjectDeleted(object sender, EventArgs e)
+ {
+ IntPtr handle = (sender as EvasObject).Handle;
+ s_HandleToEvasObject.Remove(handle);
+ }
+
+ IntPtr GetReusableContentCallback(IntPtr data, IntPtr obj, IntPtr part, IntPtr old)
+ {
+ IntPtr reusedHandle = IntPtr.Zero;
+ GenItem item = ItemObject.GetItemById((int)data) as GenItem;
+ if (s_HandleToEvasObject.ContainsKey(old))
+ {
+ reusedHandle = ReusableContentHandler?.Invoke(item?.Data, Marshal.PtrToStringAnsi(part), s_HandleToEvasObject[old]);
+ }
+ return reusedHandle;
+ }
+
+ void DelCallback(IntPtr data, IntPtr obj)
+ {
+ // We can't use this callback
+ // because, when item was deleted
+ // First, ItemObject deleted callback was called
+ // and We need to clean up ItemObject related objects
+ // This callback was called after ItemObject deleted callback was completed.
+ // So, We can't get resource reletated with ItemObject
+ }
+ }
+
+ public class GenGridItemClass : GenItemClass
+ {
+ public GenGridItemClass(string style) : base(style)
+ {
+ }
+
+ protected override IntPtr CreateItemClass()
+ {
+ return Interop.Elementary.elm_gengrid_item_class_new();
+ }
+
+ protected override void ReleaseItemClass(IntPtr unmanagedPtr)
+ {
+ Interop.Elementary.elm_gengrid_item_class_free(unmanagedPtr);
+ }
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal class ItemClass
+ {
+ public delegate string GetTextCallback(IntPtr data, IntPtr obj, IntPtr part);
+
+ public delegate IntPtr GetContentCallback(IntPtr data, IntPtr obj, IntPtr part);
+
+ public delegate int GetStateCallback(IntPtr data, IntPtr obj, IntPtr part);
+
+ public delegate void DelCallback(IntPtr data, IntPtr obj);
+
+ public delegate int FilterCallback(IntPtr data, IntPtr obj, IntPtr key);
+
+ public delegate IntPtr GetReusableContentCallback(IntPtr data, IntPtr obj, IntPtr part, IntPtr old);
+
+ public int version;
+ public uint refCount;
+ public int deleteMe;
+ public string itemStyle;
+ public readonly string decorateItemStyle;
+ public readonly string decorateAllItemStyle;
+ public GetTextCallback textCallback;
+ public GetContentCallback contentCallback;
+ public GetStateCallback stateCallback;
+ public DelCallback delCallback;
+ public FilterCallback filterCallback;
+ public GetReusableContentCallback reusableContentCallback;
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/GenList.cs b/src/ElmSharp/ElmSharp/GenList.cs
new file mode 100644
index 0000000..ff52588
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/GenList.cs
@@ -0,0 +1,762 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// Enumeration for setting genlist item type.
+ /// </summary>
+ public enum GenListItemType
+ {
+ /// <summary>
+ /// if Normal is set then this item is normal item.
+ /// </summary>
+ Normal = 0,
+
+ /// <summary>
+ /// If tree is set then this item is displayed as an item that is able to expand and have child items.
+ /// </summary>
+ Tree = (1 << 0),
+
+ /// <summary>
+ /// if Group is set then this item is group index item that is displayed at the top until the next group comes.
+ /// </summary>
+ Group = (1 << 1),
+ }
+
+ /// <summary>
+ /// Enumeration for setting genlist's resizing behavior, transverse axis scrolling and items cropping.
+ /// </summary>
+ public enum GenListMode
+ {
+ /// <summary>
+ /// The genlist won't set any of its size hints to inform how a possible container should resize it.
+ /// Then, if it's not created as a "resize object", it might end with zeroed dimensions.
+ /// The genlist will respect the container's geometry and, if any of its items won't fit into its transverse axis, one won't be able to scroll it in that direction.
+ /// </summary>
+ Compress = 0,
+
+ /// <summary>
+ /// This is the same as Compress, with the exception that if any of its items won't fit into its transverse axis, one will be able to scroll it in that direction.
+ /// </summary>
+ Scroll,
+
+ /// <summary>
+ /// Sets a minimum size hint on the genlist object, so that containers may respect it (and resize itself to fit the child properly).
+ /// More specifically, a minimum size hint will be set for its transverse axis, so that the largest item in that direction fits well.
+ /// This is naturally bound by the genlist object's maximum size hints, set externally.
+ /// </summary>
+ Limit,
+
+ /// <summary>
+ /// Besides setting a minimum size on the transverse axis, just like on Limit, the genlist will set a minimum size on th longitudinal axis, trying to reserve space to all its children to be visible at a time.
+ /// This is naturally bound by the genlist object's maximum size hints, set externally.
+ /// </summary>
+ Expand
+ }
+
+ /// <summary>
+ /// It inherits System.EventArgs.
+ /// It contains Item which is <see cref="GenListItem"/> type.
+ /// All events of GenList contain GenListItemEventArgs as a parameter.
+ /// </summary>
+ public class GenListItemEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Gets or sets GenList item. The return type is <see cref="GenListItem"/>.
+ /// </summary>
+ public GenListItem Item { get; set; }
+
+ internal static GenListItemEventArgs CreateFromSmartEvent(IntPtr data, IntPtr obj, IntPtr info)
+ {
+ GenListItem item = ItemObject.GetItemByHandle(info) as GenListItem;
+ return new GenListItemEventArgs() { Item = item };
+ }
+ }
+
+ /// <summary>
+ /// Enumeration that defines where to position the item in the genlist.
+ /// </summary>
+ public enum ScrollToPosition
+ {
+ /// <summary>
+ /// Scrolls to nowhere.
+ /// </summary>
+ None = 0,
+
+ /// <summary>
+ /// Scrolls to the nearest viewport.
+ /// </summary>
+ In = (1 << 0),
+
+ /// <summary>
+ /// Scrolls to the top of the viewport.
+ /// </summary>
+ Top = (1 << 1),
+
+ /// <summary>
+ /// Scrolls to the middle of the viewport.
+ /// </summary>
+ Middle = (1 << 2),
+
+ /// <summary>
+ /// Scrolls to the bottom of the viewport.
+ /// </summary>
+ Bottom = (1 << 3)
+ }
+
+ /// <summary>
+ /// It inherits <see cref="Layout"/>.
+ /// The GenList is a widget that aims to have more expansive list than the simple <see cref="List"/> in ElmSharp that could have more flexible items and allow many more entries while still being fast and low on memory usage.
+ /// At the same time it was also made to be able to do tree structures.
+ /// But the price to pay is more complexity when it comes to usage.
+ /// If all you want is a simple list with icons and a single text, use the <see cref="List"/> widget.
+ /// </summary>
+ public class GenList : Layout
+ {
+ HashSet<GenListItem> _children = new HashSet<GenListItem>();
+
+ SmartEvent<GenListItemEventArgs> _selected;
+ SmartEvent<GenListItemEventArgs> _unselected;
+ SmartEvent<GenListItemEventArgs> _activated;
+ SmartEvent<GenListItemEventArgs> _pressed;
+ SmartEvent<GenListItemEventArgs> _released;
+ SmartEvent<GenListItemEventArgs> _doubleClicked;
+ SmartEvent<GenListItemEventArgs> _expanded;
+ SmartEvent<GenListItemEventArgs> _realized;
+ SmartEvent<GenListItemEventArgs> _unrealized;
+ SmartEvent<GenListItemEventArgs> _longpressed;
+ SmartEvent<GenListItemEventArgs> _moved;
+ SmartEvent<GenListItemEventArgs> _movedAfter;
+ SmartEvent<GenListItemEventArgs> _movedBefore;
+ SmartEvent _scrollAnimationStarted;
+ SmartEvent _scrollAnimationStopped;
+ SmartEvent _changed;
+
+ /// <summary>
+ /// Creates and initializes a new instance of the GenList class.
+ /// </summary>
+ /// <param name="parent">The parent is a given container which will be attached by GenList as a child. It's <see cref="EvasObject"/> type.</param>
+ public GenList(EvasObject parent) : base(parent)
+ {
+ ListMode = GenListMode.Compress;
+ InitializeSmartEvent();
+ }
+
+ /// <summary>
+ /// Gets or sets whether the homogeneous mode is enabled.
+ /// </summary>
+ /// <remarks>
+ /// If true, the genlist items have same height and width.
+ /// </remarks>
+ public bool Homogeneous
+ {
+ get
+ {
+ return Interop.Elementary.elm_genlist_homogeneous_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_genlist_homogeneous_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the horizontal stretching mode. This mode used for sizing items horizontally.
+ /// The default value is <see cref="GenListMode.Scroll"/> which means that if items are too wide to fit, the scroller scrolls horizontally.
+ /// If set <see cref="GenListMode.Compress"/> which means that the item width is fixed (restricted to a minimum of) to the list width when calculating its size in order to allow the height to be calculated based on it.
+ /// If set <see cref="GenListMode.Limit"/> which means that items are expanded to the viewport width and limited to that size.
+ /// if set <see cref="GenListMode.Expand"/> which means that genlist try to reserve space to all its items to be visible at a time.
+ /// </summary>
+ /// <remarks>
+ /// Compress makes genlist resize slower as it recalculates every item height again whenever the list width changes.
+ /// The homogeneous mode is so that all items in the genlist are of the same width/height. With Compress, genlist items are initialized fast.
+ /// However, there are no sub-objects in the genlist which can be on the flying resizable (such as TEXTBLOCK).
+ /// If so, then some dynamic resizable objects in the genlist would not be diplayed properly.
+ /// </remarks>
+ public GenListMode ListMode
+ {
+ get
+ {
+ return (GenListMode)Interop.Elementary.elm_genlist_mode_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_genlist_mode_set(RealHandle, (int)value);
+ }
+ }
+
+ /// <summary>
+ /// Gets the first item in the genlist.
+ /// </summary>
+ public GenListItem FirstItem
+ {
+ get
+ {
+ IntPtr handle = Interop.Elementary.elm_genlist_first_item_get(RealHandle);
+ return ItemObject.GetItemByHandle(handle) as GenListItem;
+ }
+ }
+
+ /// <summary>
+ /// Gets the last item in the genlist.
+ /// </summary>
+ public GenListItem LastItem
+ {
+ get
+ {
+ IntPtr handle = Interop.Elementary.elm_genlist_last_item_get(RealHandle);
+ return ItemObject.GetItemByHandle(handle) as GenListItem;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the reorder mode.
+ /// After turning on the reorder mode, longpress on a normal item triggers reordering of the item.
+ /// You can move the item up and down. However, reordering does not work with group items.
+ /// </summary>
+ public bool ReorderMode
+ {
+ get
+ {
+ return Interop.Elementary.elm_genlist_reorder_mode_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_genlist_reorder_mode_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or set the maximum number of items within an item block.
+ /// </summary>
+ public int BlockCount
+ {
+ get
+ {
+ return Interop.Elementary.elm_genlist_block_count_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_genlist_block_count_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets whether the genlist items should be highlighted when an item is selected.
+ /// </summary>
+ public bool IsHighlight
+ {
+ get
+ {
+ return Interop.Elementary.elm_genlist_highlight_mode_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_genlist_highlight_mode_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets the depth of expanded item.
+ /// </summary>
+ public int ExpandedItemDepth
+ {
+ get
+ {
+ return Interop.Elementary.elm_genlist_item_expanded_depth_get(RealHandle);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the timeout in seconds for the longpress event.
+ /// </summary>
+ public double LongPressTimeout
+ {
+ get
+ {
+ return Interop.Elementary.elm_genlist_longpress_timeout_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_genlist_longpress_timeout_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets whether enable multi-selection in the genlist.
+ /// </summary>
+ public bool IsMultiSelection
+ {
+ get
+ {
+ return Interop.Elementary.elm_genlist_multi_select_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_genlist_multi_select_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets the selected item in a given genlist widget.
+ /// </summary>
+ public GenListItem SelectedItem
+ {
+ get
+ {
+ IntPtr handle = Interop.Elementary.elm_genlist_selected_item_get(RealHandle);
+ return ItemObject.GetItemByHandle(handle) as GenListItem;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the genlist select mode by <see cref="GenItemSelectionMode"/>.
+ /// </summary>
+ public GenItemSelectionMode SelectionMode
+ {
+ get
+ {
+ return (GenItemSelectionMode)Interop.Elementary.elm_genlist_select_mode_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_genlist_select_mode_set(RealHandle, (int)value);
+ }
+ }
+
+ /// <summary>
+ /// ItemSelected is raised when a new genlist item is selected.
+ /// </summary>
+ public event EventHandler<GenListItemEventArgs> ItemSelected;
+
+ /// <summary>
+ /// ItemUnselected is raised when the genlist item is Unselected.
+ /// </summary>
+ public event EventHandler<GenListItemEventArgs> ItemUnselected;
+
+ /// <summary>
+ /// ItemPressed is raised when a new genlist item is pressed.
+ /// </summary>
+ public event EventHandler<GenListItemEventArgs> ItemPressed;
+
+ /// <summary>
+ /// ItemReleased is raised when a new genlist item is released.
+ /// </summary>
+ public event EventHandler<GenListItemEventArgs> ItemReleased;
+
+ /// <summary>
+ /// ItemActivated is raised when a new genlist item is double clicked or pressed (enter|return|spacebar).
+ /// </summary>
+ public event EventHandler<GenListItemEventArgs> ItemActivated;
+
+ /// <summary>
+ /// ItemDoubleClicked is raised when a new genlist item is double clicked.
+ /// </summary>
+ public event EventHandler<GenListItemEventArgs> ItemDoubleClicked;
+
+ /// <summary>
+ /// ItemExpanded is raised when a new genlist item is indicated to expand.
+ /// </summary>
+ public event EventHandler<GenListItemEventArgs> ItemExpanded;
+
+ /// <summary>
+ /// ItemRealized is raised when a new genlist item is created as a real object.
+ /// </summary>
+ public event EventHandler<GenListItemEventArgs> ItemRealized;
+
+ /// <summary>
+ /// ItemUnrealized is raised when a new genlist item is unrealized.
+ /// After calling unrealize, the item's content objects are deleted and the item object itself is deleted or is put into a floating cache.
+ /// </summary>
+ public event EventHandler<GenListItemEventArgs> ItemUnrealized;
+
+ /// <summary>
+ /// ItemLongPressed is raised when a genlist item is pressed for a certain amount of time. By default it's 1 second.
+ /// </summary>
+ public event EventHandler<GenListItemEventArgs> ItemLongPressed;
+
+ /// <summary>
+ /// ItemMoved is raised when a genlist item is moved in the reorder mode.
+ /// </summary>
+ public event EventHandler<GenListItemEventArgs> ItemMoved;
+
+ /// <summary>
+ /// ItemMovedAfter is raised when a genlist item is moved after another item in the reorder mode.
+ /// To get the relative previous item, use <see cref="GenListItem.Previous"/>.
+ /// </summary>
+ public event EventHandler<GenListItemEventArgs> ItemMovedAfter;
+
+ /// <summary>
+ /// ItemMovedBefore is raised when a genlist item is moved before another item in the reorder mode.
+ /// To get the relative next item, use <see cref="GenListItem.Next"/>.
+ /// </summary>
+ public event EventHandler<GenListItemEventArgs> ItemMovedBefore;
+
+ /// <summary>
+ /// Changed is raised when genlist is changed.
+ /// </summary>
+ public event EventHandler Changed
+ {
+ add { _changed.On += value; }
+ remove { _changed.On -= value; }
+ }
+
+ /// <summary>
+ /// ScrollAnimationStarted is raised when scrolling animation has started.
+ /// </summary>
+ public event EventHandler ScrollAnimationStarted
+ {
+ add { _scrollAnimationStarted.On += value; }
+ remove { _scrollAnimationStarted.On -= value; }
+ }
+
+ /// <summary>
+ /// ScrollAnimationStopped is raised when scrolling animation has stopped.
+ /// </summary>
+ public event EventHandler ScrollAnimationStopped
+ {
+ add { _scrollAnimationStopped.On += value; }
+ remove { _scrollAnimationStopped.On -= value; }
+ }
+
+ /// <summary>
+ /// Appends a new item to the end of a given genlist widget.
+ /// </summary>
+ /// <param name="itemClass">The itemClass defines how to display the data.</param>
+ /// <param name="data">The item data.</param>
+ /// <returns>Return a new added genlist item that contains data and itemClass.</returns>
+ /// <seealso cref="GenItemClass"/>
+ /// <seealso cref="GenListItem"/>
+ public GenListItem Append(GenItemClass itemClass, object data)
+ {
+ return Append(itemClass, data, GenListItemType.Normal);
+ }
+
+ /// <summary>
+ /// Appends a new item with <see cref="GenListItemType"/> to the end of a given genlist widget.
+ /// </summary>
+ /// <param name="itemClass">The itemClass defines how to display the data.</param>
+ /// <param name="data">The item data.</param>
+ /// <param name="type">The genlist item type.</param>
+ /// <returns>Return a new added genlist item that contains data and itemClass.</returns>
+ public GenListItem Append(GenItemClass itemClass, object data, GenListItemType type)
+ {
+ return Append(itemClass, data, type, null);
+ }
+
+ /// <summary>
+ /// Appends a new item with <see cref="GenListItemType"/> to the end of a given genlist widget or the end of the children list if the parent is given.
+ /// </summary>
+ /// <param name="itemClass">The itemClass defines how to display the data.</param>
+ /// <param name="data">The item data.</param>
+ /// <param name="type">The genlist item type.</param>
+ /// <param name="parent">The parent item, otherwise null if there is no parent item.</param>
+ /// <returns>Return a new added genlist item that contains data and itemClass.</returns>
+ public GenListItem Append(GenItemClass itemClass, object data, GenListItemType type, GenListItem parent)
+ {
+ GenListItem item = new GenListItem(data, itemClass);
+ IntPtr handle = Interop.Elementary.elm_genlist_item_append(RealHandle, itemClass.UnmanagedPtr, (IntPtr)item.Id, parent, (int)type, null, (IntPtr)item.Id);
+ item.Handle = handle;
+ AddInternal(item);
+ return item;
+ }
+
+ /// <summary>
+ /// Prepends a new item to the beginning of a given genlist widget.
+ /// </summary>
+ /// <param name="itemClass">The itemClass defines how to display the data.</param>
+ /// <param name="data">The item data.</param>
+ /// <returns>Return a new added genlist item that contains data and itemClass.</returns>
+ public GenListItem Prepend(GenItemClass itemClass, object data)
+ {
+ return Prepend(itemClass, data, GenListItemType.Normal);
+ }
+
+ /// <summary>
+ /// Prepends a new item with <see cref="GenListItemType"/> to the beginning of a given genlist widget.
+ /// </summary>
+ /// <param name="itemClass">The itemClass defines how to display the data.</param>
+ /// <param name="data">The item data.</param>
+ /// <param name="type">The genlist item type.</param>
+ /// <param name="parent">The parent item, otherwise null if there is no parent item.</param>
+ /// <returns>Return a new added genlist item that contains data and itemClass.</returns>
+ public GenListItem Prepend(GenItemClass itemClass, object data, GenListItemType type)
+ {
+ return Prepend(itemClass, data, type, null);
+ }
+
+ /// <summary>
+ /// Prepends a new item with <see cref="GenListItemType"/> to the beginning of a given genlist widget or the beginning of the children list if the parent is given.
+ /// </summary>
+ /// <param name="itemClass">The itemClass defines how to display the data.</param>
+ /// <param name="data">The item data.</param>
+ /// <param name="type">The genlist item type.</param>
+ /// <param name="parent">The parent item, otherwise null if there is no parent item.</param>
+ /// <returns>Return a new added genlist item that contains data and itemClass.</returns>
+ public GenListItem Prepend(GenItemClass itemClass, object data, GenListItemType type, GenListItem parent)
+ {
+ GenListItem item = new GenListItem(data, itemClass);
+ IntPtr handle = Interop.Elementary.elm_genlist_item_prepend(RealHandle, itemClass.UnmanagedPtr, (IntPtr)item.Id, parent, (int)type, null, (IntPtr)item.Id);
+ item.Handle = handle;
+ AddInternal(item);
+ return item;
+ }
+
+ /// <summary>
+ /// Inserts an item before another item in a genlist widget.
+ /// It is the same tree level or group as the item before which it is inserted.????
+ /// </summary>
+ /// <param name="itemClass">The itemClass defines how to display the data.</param>
+ /// <param name="data">The item data.</param>
+ /// <param name="before">The item before which to place this new one.</param>
+ /// <returns>Return a new added genlist item that contains data and itemClass.</returns>
+ public GenListItem InsertBefore(GenItemClass itemClass, object data, GenListItem before)
+ {
+ return InsertBefore(itemClass, data, before, GenListItemType.Normal);
+ }
+
+ /// <summary>
+ /// Inserts an item with <see cref="GenListItemType"/> before another item in a genlist widget.
+ /// It is the same tree level or group as the item before which it is inserted.????
+ /// </summary>
+ /// <param name="itemClass">The itemClass defines how to display the data.</param>
+ /// <param name="data">The item data.</param>
+ /// <param name="before">The item before which to place this new one.</param>
+ /// <param name="type">The genlist item type.</param>
+ /// <returns>Return a new added genlist item that contains data and itemClass.</returns>
+ public GenListItem InsertBefore(GenItemClass itemClass, object data, GenListItem before, GenListItemType type)
+ {
+ return InsertBefore(itemClass, data, before, type, null);
+ }
+
+ /// <summary>
+ /// Inserts an item with <see cref="GenListItemType"/> before another item under a parent in a genlist widget.
+ /// </summary>
+ /// <param name="itemClass">The itemClass defines how to display the data.</param>
+ /// <param name="data">The item data.</param>
+ /// <param name="before">The item before which to place this new one.</param>
+ /// <param name="type">The genlist item type.</param>
+ /// <param name="parent">The parent item, otherwise null if there is no parent item.</param>
+ /// <returns>Return a new added genlist item that contains data and itemClass.</returns>
+ public GenListItem InsertBefore(GenItemClass itemClass, object data, GenListItem before, GenListItemType type, GenListItem parent)
+ {
+ GenListItem item = new GenListItem(data, itemClass);
+ // insert before the `before` list item
+ IntPtr handle = Interop.Elementary.elm_genlist_item_insert_before(
+ RealHandle, // genlist handle
+ itemClass.UnmanagedPtr, // item class
+ (IntPtr)item.Id, // data
+ parent, // parent
+ before, // before
+ (int)type, // item type
+ null, // select callback
+ (IntPtr)item.Id); // callback data
+ item.Handle = handle;
+ AddInternal(item);
+ return item;
+ }
+
+ /// <summary>
+ /// Inserts an item with <see cref="GenListItemType"/> after another item under a parent in a genlist widget.
+ /// </summary>
+ /// <param name="itemClass">The itemClass defines how to display the data.</param>
+ /// <param name="data">The item data.</param>
+ /// <param name="before">The item after which to place this new one.</param>
+ /// <param name="type">The genlist item type.</param>
+ /// <param name="parent">The parent item, otherwise null if there is no parent item.</param>
+ /// <returns>Return a new added genlist item that contains data and itemClass.</returns>
+ public GenListItem InsertAfter(GenItemClass itemClass, object data, GenListItem after, GenListItemType type, GenListItem parent)
+ {
+ GenListItem item = new GenListItem(data, itemClass);
+ // insert before the `before` list item
+ IntPtr handle = Interop.Elementary.elm_genlist_item_insert_before(
+ RealHandle, // genlist handle
+ itemClass.UnmanagedPtr, // item class
+ (IntPtr)item.Id, // data
+ parent, // parent
+ after, // after
+ (int)type, // item type
+ null, // select callback
+ (IntPtr)item.Id); // callback data
+ item.Handle = handle;
+ AddInternal(item);
+ return item;
+ }
+
+ /// <summary>
+ /// Insert an item in a genlist widget using a user-defined sort function.
+ /// </summary>
+ /// <param name="itemClass">The itemClass defines how to display the data.</param>
+ /// <param name="data">The item data.</param>
+ /// <param name="func">User defined comparison function that defines the sort order based on genlist item and its data.</param>
+ /// <param name="type">The genlist item type.</param>
+ /// <param name="parent">The parent item, otherwise null if there is no parent item.</param>
+ /// <returns>Return a genlist item that contains data and itemClass.</returns>
+ public GenListItem InsertSorted(GenItemClass itemClass, object data, Comparison<object> comparison, GenListItemType type, GenListItem parent)
+ {
+ GenListItem item = new GenListItem(data, itemClass);
+
+ Interop.Elementary.Eina_Compare_Cb compareCallback = (handle1, handle2) =>
+ {
+ GenListItem first = (ItemObject.GetItemByHandle(handle1) as GenListItem) ?? item;
+ GenListItem second = (ItemObject.GetItemByHandle(handle2) as GenListItem) ?? item;
+ return comparison(first.Data, second.Data);
+ };
+
+ IntPtr handle = Interop.Elementary.elm_genlist_item_sorted_insert(
+ RealHandle, // genlist handle
+ itemClass.UnmanagedPtr, // item clas
+ (IntPtr)item.Id, // data
+ parent, // parent
+ (int)type, // item type
+ compareCallback, // compare callback
+ null, //select callback
+ (IntPtr)item.Id); // callback data
+ item.Handle = handle;
+ AddInternal(item);
+ return item;
+ }
+
+ /// <summary>
+ /// Shows the given item with position type in a genlist.
+ /// When animated is true, genlist will jump to the given item and display it (by animatedly scrolling), if it is not fully visible. This may use animation and may take some time.
+ /// When animated is false, genlist will jump to the given item and display it (by jumping to that position), if it is not fully visible.
+ /// </summary>
+ /// <param name="item">The item to display.</param>
+ /// <param name="position">The position to show the given item to <see cref="ScrollToPosition"/>.</param>
+ /// <param name="animated">The animated indicates how to display the item, by scrolling or by jumping.</param>
+ public void ScrollTo(GenListItem item, ScrollToPosition position, bool animated)
+ {
+ if (animated)
+ {
+ Interop.Elementary.elm_genlist_item_bring_in(item.Handle, (Interop.Elementary.Elm_Genlist_Item_Scrollto_Type)position);
+ }
+ else
+ {
+ Interop.Elementary.elm_genlist_item_show(item.Handle, (Interop.Elementary.Elm_Genlist_Item_Scrollto_Type)position);
+ }
+ }
+
+ /// <summary>
+ /// Updates the content of all the realized items.
+ /// This updates all the realized items by calling all the <see cref="GenItemClass"/> again to get the content, text and states.
+ /// Use this when the original item data has changed and the changes are desired to reflect.
+ /// To update just one item, use <see cref="GenListItem.Update"/>.
+ /// </summary>
+ /// <seealso cref="GenListItem.Update"/>
+ public void UpdateRealizedItems()
+ {
+ Interop.Elementary.elm_genlist_realized_items_update(RealHandle);
+ }
+
+ /// <summary>
+ /// Removes all items from a given genlist widget.
+ /// This removes (and deletes) all items in obj, making it empty.
+ /// To delete just one item, use <see cref="ItemObject.Delete"/>.
+ /// </summary>
+ /// <seealso cref="ItemObject.Delete"/>
+ public void Clear()
+ {
+ Interop.Elementary.elm_genlist_clear(RealHandle);
+ }
+
+ /// <summary>
+ /// Get the item that is at the x, y canvas coords.
+ /// </summary>
+ /// <param name="x">The input x coordinate</param>
+ /// <param name="y">The input y coordinate</param>
+ /// <param name="pos">The position relative to the item returned here
+ /// -1, 0, or 1, depending on whether the coordinate is on the upper portion of that item (-1), in the middle section (0), or on the lower part (1).
+ /// </param>
+ /// <returns></returns>
+ public GenListItem GetItemByPosition(int x, int y, out int pos)
+ {
+ IntPtr handle = Interop.Elementary.elm_genlist_at_xy_item_get(RealHandle, x, y, out pos);
+ return ItemObject.GetItemByHandle(handle) as GenListItem;
+ }
+
+ /// <summary>
+ /// Gets the nth item in a given genlist widget, placed at position nth, in its internal items list.
+ /// </summary>
+ /// <param name="index">The number of the item to grab (0 being the first)</param>
+ /// <returns></returns>
+ public GenListItem GetItemByIndex(int index)
+ {
+ IntPtr handle = Interop.Elementary.elm_genlist_nth_item_get(RealHandle, index);
+ return ItemObject.GetItemByHandle(handle) as GenListItem;
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ IntPtr handle = Interop.Elementary.elm_layout_add(parent.Handle);
+ Interop.Elementary.elm_layout_theme_set(handle, "layout", "elm_widget", "default");
+
+ RealHandle = Interop.Elementary.elm_genlist_add(handle);
+ Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
+
+ return handle;
+ }
+
+ void InitializeSmartEvent()
+ {
+ _selected = new SmartEvent<GenListItemEventArgs>(this, this.RealHandle, "selected", GenListItemEventArgs.CreateFromSmartEvent);
+ _unselected = new SmartEvent<GenListItemEventArgs>(this, this.RealHandle, "unselected", GenListItemEventArgs.CreateFromSmartEvent);
+ _activated = new SmartEvent<GenListItemEventArgs>(this, this.RealHandle, "activated", GenListItemEventArgs.CreateFromSmartEvent);
+ _pressed = new SmartEvent<GenListItemEventArgs>(this, this.RealHandle, "pressed", GenListItemEventArgs.CreateFromSmartEvent);
+ _released = new SmartEvent<GenListItemEventArgs>(this, this.RealHandle, "released", GenListItemEventArgs.CreateFromSmartEvent);
+ _doubleClicked = new SmartEvent<GenListItemEventArgs>(this, this.RealHandle, "clicked,double", GenListItemEventArgs.CreateFromSmartEvent);
+ _expanded = new SmartEvent<GenListItemEventArgs>(this, this.RealHandle, "expanded", GenListItemEventArgs.CreateFromSmartEvent);
+ _realized = new SmartEvent<GenListItemEventArgs>(this, this.RealHandle, "realized", GenListItemEventArgs.CreateFromSmartEvent);
+ _unrealized = new SmartEvent<GenListItemEventArgs>(this, this.RealHandle, "unrealized", GenListItemEventArgs.CreateFromSmartEvent);
+ _longpressed = new SmartEvent<GenListItemEventArgs>(this, this.RealHandle, "longpressed", GenListItemEventArgs.CreateFromSmartEvent);
+ _moved = new SmartEvent<GenListItemEventArgs>(this, this.RealHandle, "moved", GenListItemEventArgs.CreateFromSmartEvent);
+ _movedAfter = new SmartEvent<GenListItemEventArgs>(this, this.RealHandle, "moved,after", GenListItemEventArgs.CreateFromSmartEvent);
+ _movedBefore = new SmartEvent<GenListItemEventArgs>(this, this.RealHandle, "moved,before", GenListItemEventArgs.CreateFromSmartEvent);
+ _scrollAnimationStarted = new SmartEvent(this, this.RealHandle, "scroll,anim,start");
+ _scrollAnimationStopped = new SmartEvent(this, this.RealHandle, "scroll,anim,stop");
+ _changed = new SmartEvent(this, this.RealHandle, "changed");
+
+ _selected.On += (s, e) => { if (e.Item != null) ItemSelected?.Invoke(this, e); };
+ _unselected.On += (s, e) => { if (e.Item != null) ItemUnselected?.Invoke(this, e); };
+ _activated.On += (s, e) => { if (e.Item != null) ItemActivated?.Invoke(this, e); };
+ _pressed.On += (s, e) => { if (e.Item != null) ItemPressed?.Invoke(this, e); };
+ _released.On += (s, e) => { if (e.Item != null) ItemReleased?.Invoke(this, e); };
+ _doubleClicked.On += (s, e) => { if (e.Item != null) ItemDoubleClicked?.Invoke(this, e); };
+ _expanded.On += (s, e) => { if (e.Item != null) ItemExpanded?.Invoke(this, e); };
+ _realized.On += (s, e) => { if (e.Item != null) ItemRealized?.Invoke(this, e); };
+ _unrealized.On += (s, e) => { if (e.Item != null) ItemUnrealized?.Invoke(this, e); };
+ _longpressed.On += (s, e) => { if (e.Item != null) ItemLongPressed?.Invoke(this, e); };
+ _moved.On += (s, e) => { if (e.Item != null) ItemMoved?.Invoke(this, e); };
+ _movedAfter.On += (s, e) => { if (e.Item != null) ItemMovedAfter?.Invoke(this, e); };
+ _movedBefore.On += (s, e) => { if (e.Item != null) ItemMovedBefore?.Invoke(this, e); };
+ }
+
+ void AddInternal(GenListItem item)
+ {
+ _children.Add(item);
+ item.Deleted += Item_Deleted;
+ }
+
+ void Item_Deleted(object sender, EventArgs e)
+ {
+ _children.Remove((GenListItem)sender);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/GenListItem.cs b/src/ElmSharp/ElmSharp/GenListItem.cs
new file mode 100644
index 0000000..f019a25
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/GenListItem.cs
@@ -0,0 +1,320 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.ComponentModel;
+
+namespace ElmSharp
+{
+
+ /// <summary>
+ /// The type of item's part type.
+ /// </summary>
+ [Flags]
+ public enum GenListItemFieldType
+ {
+ /// <summary>
+ /// All item's parts.
+ /// </summary>
+ All = 0,
+
+ /// <summary>
+ /// The text part type.
+ /// </summary>
+ Text = (1 << 0),
+
+ /// <summary>
+ /// The Content part type.
+ /// </summary>
+ Content = (1 << 1),
+
+ /// <summary>
+ /// The state of part.
+ /// </summary>
+ State = (1 << 2),
+
+ /// <summary>
+ /// No part type.
+ /// </summary>
+ None = (1 << 3)
+ };
+
+ /// <summary>
+ /// It inherits <see cref="GenItem"/>.
+ /// A instance to the genlist item added.
+ /// It contains Update() method to update a genlist item which is given.
+ /// </summary>
+ public class GenListItem : GenItem
+ {
+ internal GenListItem(object data, GenItemClass itemClass) : base(data, itemClass)
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets whether a given genlist item is selected.
+ /// </summary>
+ public override bool IsSelected
+ {
+ get
+ {
+ return Interop.Elementary.elm_genlist_item_selected_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_genlist_item_selected_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets whether a given genlist item is expanded.
+ /// </summary>
+ public bool IsExpanded
+ {
+ get
+ {
+ return Interop.Elementary.elm_genlist_item_expanded_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_genlist_item_expanded_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Updates the content of an item.
+ /// This updates an item by calling all the <see cref="GenItemClass"/> again to get the content, text, and states.
+ /// Use this when the original item data has changed and the changes are desired to reflect.
+ /// To update already realized items, use <see cref="GenList.UpdateRealizedItems"/>.
+ /// </summary>
+ /// <seealso cref="GenList.UpdateRealizedItems"/>
+ public override void Update()
+ {
+ Interop.Elementary.elm_genlist_item_update(Handle);
+ }
+
+ /// <summary>
+ /// Updates the part of an item.
+ /// This updates an item's part by calling item's fetching functions again to get the contents, texts and states.
+ /// Use this when the original item data has changed and the changes are desired to be reflected.
+ /// To update an item's all property, use <see cref="GenList.UpdateRealizedItems"/>.
+ /// </summary>
+ /// <param name="part">The part could be "elm.text", "elm.swalllow.icon", "elm.swallow.end", "elm.swallow.content" and so on. It is also used for globbing to match '*', '?', and '.'. It can be used at updating multi fields.</param>
+ /// <param name="type">The type of item's part type.</param>
+ /// <seealso cref="GenList.UpdateRealizedItems"/>
+ public void UpdateField(string part, GenListItemFieldType type)
+ {
+ Interop.Elementary.elm_genlist_item_fields_update(Handle, part, (uint)type);
+ }
+
+ /// <summary>
+ /// Demote an item to the end of the list.
+ /// </summary>
+ /// <param name="item">The genlistitem object</param>
+ public void DemoteItem()
+ {
+ Interop.Elementary.elm_genlist_item_demote(Handle);
+ }
+
+ /// <summary>
+ /// Gets or sets the genlist item's select mode.
+ /// </summary>
+ public override GenItemSelectionMode SelectionMode
+ {
+ get
+ {
+ return (GenItemSelectionMode)Interop.Elementary.elm_genlist_item_select_mode_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_genlist_item_select_mode_set(Handle, (Interop.Elementary.Elm_Object_Select_Mode)value);
+ }
+ }
+
+ /// <summary>
+ /// Gets the next item in a genlist widget's internal list of items.
+ /// </summary>
+ /// <seealso cref="Previous"/>
+ public GenListItem Next
+ {
+ get
+ {
+ IntPtr next = Interop.Elementary.elm_genlist_item_next_get(Handle);
+ if (next == IntPtr.Zero)
+ return null;
+ else
+ return GetItemByHandle(next) as GenListItem;
+ }
+ }
+
+ /// <summary>
+ /// Get the previous item in a genlist widget's internal list of items.
+ /// </summary>
+ /// <seealso cref="Next"/>
+ public GenListItem Previous
+ {
+ get
+ {
+ IntPtr prev = Interop.Elementary.elm_genlist_item_prev_get(Handle);
+ if (prev == IntPtr.Zero)
+ return null;
+ else
+ return GetItemByHandle(prev) as GenListItem;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the type of mouse pointer/cursor decoration to be shown, when the mouse pointer is over the given genlist widget item.
+ /// <remarks>
+ /// The cursor's changing area is restricted to the item's area, and not the whole widget's. Note that that item cursors have precedence over widget cursors, so that a mouse over item will always show cursor type.
+ /// </remarks>>
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override string Cursor
+ {
+ get
+ {
+ return Interop.Elementary.elm_genlist_item_cursor_get(Handle);
+ }
+ set
+ {
+ if (!string.IsNullOrEmpty(value))
+ {
+ Interop.Elementary.elm_genlist_item_cursor_set(Handle, value);
+ }
+ else
+ {
+ Interop.Elementary.elm_genlist_item_cursor_unset(Handle);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets custom cursor for genlist item.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override string CursorStyle
+ {
+ get
+ {
+ return Interop.Elementary.elm_genlist_item_cursor_style_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_genlist_item_cursor_style_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets whether to rely on the rendering engine.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override bool IsUseEngineCursor
+ {
+ get
+ {
+ return Interop.Elementary.elm_genlist_item_cursor_engine_only_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_genlist_item_cursor_engine_only_set(Handle, value);
+ }
+ }
+
+ public override void SetTooltipText(string tooltip)
+ {
+ Interop.Elementary.elm_genlist_item_tooltip_text_set(Handle, tooltip);
+ }
+
+ public override void UnsetTooltip()
+ {
+ Interop.Elementary.elm_genlist_item_tooltip_unset(Handle);
+ }
+
+ /// <summary>
+ /// Gets or sets the style of given genlist item's tooltip.
+ /// </summary>
+ public override string TooltipStyle
+ {
+ get
+ {
+ return Interop.Elementary.elm_genlist_item_tooltip_style_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_genlist_item_tooltip_style_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets whether disable size restrictions on an object's tooltip.
+ /// </summary>
+ public bool IsTooltipWindowMode
+ {
+ get
+ {
+ return Interop.Elementary.elm_genlist_item_tooltip_window_mode_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_genlist_item_tooltip_window_mode_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets the index of the item. It is only valid once displayed.
+ /// </summary>
+ public int Index
+ {
+ get
+ {
+ return Interop.Elementary.elm_genlist_item_index_get(Handle);
+ }
+ }
+
+ /// <summary>
+ /// Remove all sub-items (children) of the given item.
+ /// </summary>
+ /// <remark>
+ /// This removes all items that are children (and their descendants) of the given item it.
+ /// </remark>
+ public void ClearSubitems()
+ {
+ Interop.Elementary.elm_genlist_item_subitems_clear(Handle);
+ }
+
+ /// <summary>
+ /// Update the item class of an item.
+ /// This sets another class of the item, changing the way that it is displayed. After changing the item class, <see cref="Update"/> is called on the item.
+ /// </summary>
+ /// <param name="itemClass">The item class for the item.</param>
+ /// <param name="data">The data for the item.</param>
+ public void UpdateItemClass(GenItemClass itemClass, object data)
+ {
+ Data = data;
+ ItemClass = itemClass;
+ Interop.Elementary.elm_genlist_item_item_class_update((IntPtr)Handle, itemClass.UnmanagedPtr);
+ }
+
+ protected override void UpdateTooltipDelegate()
+ {
+ Interop.Elementary.elm_genlist_item_tooltip_content_cb_set(Handle,
+ TooltipContentDelegate != null ? _tooltipCb : null,
+ IntPtr.Zero,
+ null);
+ }
+
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/GestureLayer.cs b/src/ElmSharp/ElmSharp/GestureLayer.cs
new file mode 100755
index 0000000..9bf1553
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/GestureLayer.cs
@@ -0,0 +1,807 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The GestureLayer is used to detect gestures.
+ /// Inherits EvasObject
+ /// </summary>
+ public class GestureLayer : EvasObject
+ {
+ private readonly Interop.Elementary.GestureEventCallback _gestureCallback;
+
+ // Important: don't remove items from _handlers list
+ // The list can grow up to (number of GestureType) * (number of GestureState)
+ // but all gestures share the callback and you don't want to desynchronize mapping
+ private readonly List<NativeCallback> _handlers = new List<NativeCallback>();
+
+ /// <summary>
+ /// Creates and initializes a new instance of GestureLayer class.
+ /// </summary>
+ /// <param name="parent">The parent is a given container which will be attached by GestureLayer as a child. It's <see cref="EvasObject"/> type.</param>
+ public GestureLayer(EvasObject parent) : base(parent)
+ {
+ _gestureCallback = new Interop.Elementary.GestureEventCallback(GestureCallbackHandler);
+ }
+
+ /// <summary>
+ /// Enumeration for supported gesture types.
+ /// </summary>
+ public enum GestureType
+ {
+ /// <summary>
+ /// N fingers single taps
+ /// </summary>
+ Tap = 1,
+ /// <summary>
+ /// N fingers single long-taps
+ /// </summary>
+ LongTap,
+ /// <summary>
+ /// N fingers double-single taps
+ /// </summary>
+ DoubleTap,
+ /// <summary>
+ /// N fingers triple-single taps
+ /// </summary>
+ TripleTap,
+ /// <summary>
+ /// Reports momentum in the direction of move
+ /// </summary>
+ Momentum,
+ /// <summary>
+ /// N fingers line gesture
+ /// </summary>
+ Line,
+ /// <summary>
+ /// N fingers flick gesture
+ /// </summary>
+ Flick,
+ /// <summary>
+ /// Zoom
+ /// </summary>
+ Zoom,
+ /// <summary>
+ /// Rotate
+ /// </summary>
+ Rotate,
+ }
+
+ /// <summary>
+ /// Enumeration for gesture states.
+ /// </summary>
+ public enum GestureState
+ {
+ /// <summary>
+ /// Gesture not started
+ /// </summary>
+ Undefined = -1,
+ /// <summary>
+ /// Gesture started
+ /// </summary>
+ Start,
+ /// <summary>
+ /// Gesture is ongoing
+ /// </summary>
+ Move,
+ /// <summary>
+ /// Gesture completed
+ /// </summary>
+ End,
+ /// <summary>
+ /// Ongoing gesture is aborted
+ /// </summary>
+ Abort,
+ }
+
+ #region Properties
+ /// <summary>
+ /// Sets or gets the repeat-events setting.
+ /// </summary>
+ public bool HoldEvents
+ {
+ get
+ {
+ return Interop.Elementary.elm_gesture_layer_hold_events_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_gesture_layer_hold_events_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the gesture layer continues enable of an object
+ /// </summary>
+ public bool Continues
+ {
+ get
+ {
+ return Interop.Elementary.elm_gesture_layer_continues_enable_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_gesture_layer_continues_enable_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the gesture layer finger-size for taps.
+ /// </summary>
+ public int TapFingerSize
+ {
+ get
+ {
+ return Interop.Elementary.elm_gesture_layer_tap_finger_size_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_gesture_layer_tap_finger_size_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the gesture layer long tap start timeout of an object
+ /// </summary>
+ public double LongTapTimeout
+ {
+ get
+ {
+ return Interop.Elementary.elm_gesture_layer_long_tap_start_timeout_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_gesture_layer_long_tap_start_timeout_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the gesture layer double tap timeout of an object
+ /// </summary>
+ public double DoubleTapTimeout
+ {
+ get
+ {
+ return Interop.Elementary.elm_gesture_layer_double_tap_timeout_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_gesture_layer_double_tap_timeout_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the gesture layer flick time limit (in ms) of an object
+ /// </summary>
+ public int FlickTimeLimit
+ {
+ get
+ {
+ return (int)Interop.Elementary.elm_gesture_layer_flick_time_limit_ms_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_gesture_layer_flick_time_limit_ms_set(Handle, (UInt32)value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the gesture layer line min length of an object
+ /// </summary>
+ public int MinimumLineLength
+ {
+ get
+ {
+ return Interop.Elementary.elm_gesture_layer_line_min_length_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_gesture_layer_line_min_length_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the gesture layer line angular tolerance of an object
+ /// </summary>
+ public double LineAngularTolerance
+ {
+ get
+ {
+ return Interop.Elementary.elm_gesture_layer_line_angular_tolerance_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_gesture_layer_line_angular_tolerance_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the gesture layer line distance tolerance of an object
+ /// </summary>
+ public int LineDistanceTolerance
+ {
+ get
+ {
+ return Interop.Elementary.elm_gesture_layer_line_distance_tolerance_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_gesture_layer_line_distance_tolerance_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets step-value for rotate action.
+ /// </summary>
+ public double RotateStep
+ {
+ get
+ {
+ return Interop.Elementary.elm_gesture_layer_rotate_step_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_gesture_layer_rotate_step_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the gesture layer rotate angular tolerance of an object
+ /// </summary>
+ public double RotateAngularTolerance
+ {
+ get
+ {
+ return Interop.Elementary.elm_gesture_layer_rotate_angular_tolerance_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_gesture_layer_rotate_angular_tolerance_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets control step value for zoom action.
+ /// </summary>
+ public double ZoomStep
+ {
+ get
+ {
+ return Interop.Elementary.elm_gesture_layer_zoom_step_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_gesture_layer_zoom_step_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the gesture layer zoom distance tolerance of an object
+ /// </summary>
+ public int ZoomDistanceTolerance
+ {
+ get
+ {
+ return Interop.Elementary.elm_gesture_layer_zoom_distance_tolerance_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_gesture_layer_zoom_distance_tolerance_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the gesture layer zoom finger factor of an object
+ /// </summary>
+ public double ZoomFingerFactor
+ {
+ get
+ {
+ return Interop.Elementary.elm_gesture_layer_zoom_finger_factor_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_gesture_layer_zoom_finger_factor_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the gesture layer zoom wheel factor of an object
+ /// </summary>
+ public double ZoomWheelFactor
+ {
+ get
+ {
+ return Interop.Elementary.elm_gesture_layer_zoom_wheel_factor_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_gesture_layer_zoom_wheel_factor_set(Handle, value);
+ }
+ }
+ #endregion Properties
+
+ /// <summary>
+ /// Attach a gesture layer widget to an Evas object (setting the widget's target).
+ /// A gesture layer's target may be any Evas object. This object will be used to listen to mouse and key events.
+ /// </summary>
+ /// <param name="target">The object to attach.</param>
+ public void Attach(EvasObject target)
+ {
+ Interop.Elementary.elm_gesture_layer_attach(Handle, target.Handle);
+ }
+
+ /// <summary>
+ /// Set the gesture state change callback.
+ /// When all callbacks for the gesture are set to null, it means this gesture is disabled.
+ /// </summary>
+ /// <param name="type">The gesture you want to track state of.</param>
+ /// <param name="state">The event the callback tracks (START, MOVE, END, ABORT).</param>
+ /// <param name="action">The callback itself.</param>
+ public void SetGestureCallback(GestureType type, GestureState state, Action<object> action)
+ {
+ lock (_handlers)
+ {
+ bool found = false;
+ int i = 0;
+ // if this (type, state) already exists in _handlers, we will reuse it
+ foreach (var handler in _handlers)
+ {
+ if (handler.Type == type && handler.State == state)
+ {
+ found = true;
+ break;
+ }
+ i++;
+ }
+ if (found)
+ {
+ // if we are changing null -> not-null, or not-null -> null, then inform the EFL
+ if (_handlers[i].Action == null ^ action == null)
+ Interop.Elementary.elm_gesture_layer_cb_set(Handle, type, state, action == null ? null : _gestureCallback, new IntPtr(i));
+ // overwrite previous action
+ _handlers[i].Action = action;
+ }
+ else
+ {
+ if (action == null)
+ {
+ // ignore unsetting a handler for event which was not registered yet?
+ return;
+ }
+ // (type, state) was not found, so we are adding a new entry and registering the callback
+ _handlers.Add(new NativeCallback(type, state, action));
+ // callback is always the same, the event is recognised by the index in _handler list (the index is passed as data)
+ Interop.Elementary.elm_gesture_layer_cb_set(Handle, type, state, _gestureCallback, new IntPtr(i));
+ }
+ }
+ }
+
+ /// <summary>
+ /// clear the gesture state change callback.
+ /// </summary>
+ public void ClearCallbacks()
+ {
+ lock (_handlers)
+ {
+ int i = 0;
+ foreach (var handler in _handlers)
+ {
+ if (handler.Action != null)
+ {
+ Interop.Elementary.elm_gesture_layer_cb_set(Handle, handler.Type, handler.State, null, new IntPtr(i));
+ handler.Action = null;
+ }
+ i++;
+ }
+ }
+ }
+
+ #region Typed callback setting methods
+ // Following methods have been added for convenience, so the user will not have to convert Info structures himself
+ /// <summary>
+ /// Set the tap callback.
+ /// </summary>
+ /// <param name="type">The gesture you want to track state of.</param>
+ /// <param name="state">The event the callback tracks (START, MOVE, END, ABORT).</param>
+ /// <param name="action">The callback itself.</param>
+ public void SetTapCallback(GestureType type, GestureState state, Action<TapData> action)
+ {
+ SetCallback(type, state, action);
+ }
+
+ /// <summary>
+ /// Set the gesture state change callback with Momentum Gesture Type
+ /// </summary>
+ /// <param name="state">The event the callback tracks (START, MOVE, END, ABORT).</param>
+ /// <param name="action">The callback itself.</param>
+ public void SetMomentumCallback(GestureState state, Action<MomentumData> action)
+ {
+ SetCallback(GestureType.Momentum, state, action);
+ }
+
+ /// <summary>
+ /// Set the gesture state change callback with Line Gesture Type
+ /// </summary>
+ /// <param name="state">The event the callback tracks (START, MOVE, END, ABORT).</param>
+ /// <param name="action">The callback itself.</param>
+ public void SetLineCallback(GestureState state, Action<LineData> action)
+ {
+ SetCallback(GestureType.Line, state, action);
+ }
+
+ /// <summary>
+ /// Set the gesture state change callback with Flick Gesture Type
+ /// </summary>
+ /// <param name="state">The event the callback tracks (START, MOVE, END, ABORT).</param>
+ /// <param name="action">The callback itself.</param>
+ public void SetFlickCallback(GestureState state, Action<LineData> action)
+ {
+ SetCallback(GestureType.Flick, state, action);
+ }
+
+ /// <summary>
+ /// Set the gesture state change callback with Zoom Gesture Type
+ /// </summary>
+ /// <param name="state">The event the callback tracks (START, MOVE, END, ABORT).</param>
+ /// <param name="action">The callback itself.</param>
+ public void SetZoomCallback(GestureState state, Action<ZoomData> action)
+ {
+ SetCallback(GestureType.Zoom, state, action);
+ }
+
+ /// <summary>
+ /// Set the gesture state change callback with Rotate Gesture Type
+ /// </summary>
+ /// <param name="state">The event the callback tracks (START, MOVE, END, ABORT).</param>
+ /// <param name="action">The callback itself.</param>
+ public void SetRotateCallback(GestureState state, Action<RotateData> action)
+ {
+ SetCallback(GestureType.Rotate, state, action);
+ }
+ #endregion Typed callback setting methods
+
+ /// <summary>
+ /// Call this function to construct a new gesture-layer object.
+ /// </summary>
+ /// <param name="parent">The gesture layer's parent widget.</param>
+ /// <returns></returns>
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ return Interop.Elementary.elm_gesture_layer_add(parent);
+ }
+
+ /// <summary>
+ /// clear the gesture state change callback.
+ /// </summary>
+ protected override void OnUnrealize()
+ {
+ ClearCallbacks();
+ base.OnUnrealize();
+ }
+
+ private void SetCallback<T>(GestureType type, GestureState state, Action<T> action)
+ {
+ if (action == null)
+ SetGestureCallback(type, state, null);
+ else
+ SetGestureCallback(type, state, new Action<object>((info) => action((T)info)));
+ }
+
+ private void GestureCallbackHandler(IntPtr data, IntPtr event_info)
+ {
+ // so EFL called our callback, lets use data to find the right Action to call
+ var handlerIndex = (int)data;
+ // thanks to the fact that we never remove item from _handlers, we don't need a lock here
+ if (handlerIndex < 0 || handlerIndex >= _handlers.Count)
+ return;
+ Action<object> action = _handlers[handlerIndex].Action;
+ if (action == null)
+ return;
+ // the interpretation of the event_info struct pointer depends on the GestureType
+ switch (_handlers[handlerIndex].Type)
+ {
+ case GestureType.Tap:
+ case GestureType.LongTap:
+ case GestureType.DoubleTap:
+ case GestureType.TripleTap:
+ action(Marshal.PtrToStructure<TapData>(event_info));
+ break;
+ case GestureType.Momentum:
+ action(Marshal.PtrToStructure<MomentumData>(event_info));
+ break;
+ case GestureType.Line:
+ case GestureType.Flick:
+ action(Marshal.PtrToStructure<LineData>(event_info));
+ break;
+ case GestureType.Zoom:
+ action(Marshal.PtrToStructure<ZoomData>(event_info));
+ break;
+ case GestureType.Rotate:
+ action(Marshal.PtrToStructure<RotateData>(event_info));
+ break;
+ }
+ }
+
+ #region Info structures
+ /// <summary>
+ /// The struct of TapData
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential)]
+ public struct TapData
+ {
+ /// <summary>
+ /// The x coordinate of the center point.
+ /// </summary>
+ public Int32 X;
+
+ /// <summary>
+ /// The y coordinate of the center point.
+ /// </summary>
+ public Int32 Y;
+
+#pragma warning disable 3003
+ /// <summary>
+ /// The number of fingers tapped.
+ /// </summary>
+ public UInt32 FingersCount;
+
+ /// <summary>
+ /// The timestamp.
+ /// </summary>
+ public UInt32 Timestamp;
+#pragma warning restore 3003
+ }
+
+ /// <summary>
+ /// The struct of MomentumData
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential)]
+ public struct MomentumData
+ {
+ /// <summary>
+ /// Final-swipe direction starting point on X.
+ /// </summary>
+ public Int32 X1;
+
+ /// <summary>
+ /// Final-swipe direction starting point on Y.
+ /// </summary>
+ public Int32 Y1;
+
+ /// <summary>
+ /// Final-swipe direction ending point on X.
+ /// </summary>
+ public Int32 X2;
+
+ /// <summary>
+ /// Final-swipe direction ending point on Y
+ /// </summary>
+ public Int32 Y2;
+
+#pragma warning disable 3003
+ /// <summary>
+ /// Timestamp of start of final x-swipe.
+ /// </summary>
+ public UInt32 HorizontalSwipeTimestamp;
+
+ /// <summary>
+ /// Timestamp of start of final y-swipe.
+ /// </summary>
+ public UInt32 VerticalSwipeTimestamp;
+
+ /// <summary>
+ /// Momentum on X.
+ /// </summary>
+ public Int32 HorizontalMomentum;
+
+ /// <summary>
+ /// Momentum on Y.
+ /// </summary>
+ public Int32 VerticalMomentum;
+
+ /// <summary>
+ /// Number of fingers.
+ /// </summary>
+ public UInt32 FingersCount;
+#pragma warning restore 3003
+ }
+
+ /// <summary>
+ /// The struct of LineData
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential)]
+ public struct LineData
+ {
+ /// <summary>
+ /// Final-swipe direction starting point on X.
+ /// </summary>
+ public Int32 X1;
+
+ /// <summary>
+ /// Final-swipe direction starting point on Y.
+ /// </summary>
+ public Int32 Y1;
+
+ /// <summary>
+ /// Final-swipe direction ending point on X.
+ /// </summary>
+ public Int32 X2;
+
+ /// <summary>
+ /// Final-swipe direction ending point on Y
+ /// </summary>
+ public Int32 Y2;
+
+#pragma warning disable 3003
+ /// <summary>
+ /// Timestamp of start of final x-swipe.
+ /// </summary>
+ public UInt32 HorizontalSwipeTimestamp;
+
+ /// <summary>
+ /// Timestamp of start of final y-swipe.
+ /// </summary>
+ public UInt32 VerticalSwipeTimestamp;
+
+ /// <summary>
+ /// Momentum on X.
+ /// </summary>
+ public Int32 HorizontalMomentum;
+
+ /// <summary>
+ /// Momentum on Y.
+ /// </summary>
+ public Int32 VerticalMomentum;
+
+ /// <summary>
+ /// Number of fingers.
+ /// </summary>
+ public UInt32 FingersCount;
+#pragma warning restore 3003
+
+ /// <summary>
+ /// Angle (direction) of lines.
+ /// </summary>
+ public double Angle;
+ }
+
+ /// <summary>
+ /// The struct of ZoomData
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential)]
+ public struct ZoomData
+ {
+ /// <summary>
+ /// The x coordinate of zoom center point reported to user.
+ /// </summary>
+ public Int32 X;
+
+ /// <summary>
+ /// The y coordinate of zoom center point reported to user.
+ /// </summary>
+ public Int32 Y;
+
+ /// <summary>
+ /// The radius (distance) between fingers reported to user.
+ /// </summary>
+ public Int32 Radius;
+
+ /// <summary>
+ /// The zoom value. 1.0 means no zoom.
+ /// </summary>
+ public double Zoom;
+
+ /// <summary>
+ /// Zoom momentum: zoom growth per second (NOT YET SUPPORTED).
+ /// </summary>
+ private double Momentum;
+ }
+
+ /// <summary>
+ /// The struct of RotateData
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential)]
+ public struct RotateData
+ {
+ /// <summary>
+ /// The x coordinate of rotation center point reported to user.
+ /// </summary>
+ public Int32 X;
+
+ /// <summary>
+ /// The y coordinate of rotation center point reported to user.
+ /// </summary>
+ public Int32 Y;
+
+ /// <summary>
+ /// The radius (distance) between fingers reported to user.
+ /// </summary>
+ public Int32 Radius;
+
+ /// <summary>
+ /// The start-angle.
+ /// </summary>
+ public double BaseAngle;
+
+ /// <summary>
+ /// The rotation value. 0.0 means no rotation.
+ /// </summary>
+ public double Angle;
+
+ /// <summary>
+ /// Rotation momentum: rotation done per second (NOT YET SUPPORTED).
+ /// </summary>
+ private double Momentum;
+ }
+
+ #endregion Info structures
+ /// <summary>
+ /// Config is a static class, it provides gestureLayer's timeout information.
+ /// </summary>
+ public static class Config
+ {
+ /// <summary>
+ /// Sets or gets the duration for occurring long tap event of gesture layer.
+ /// </summary>
+ public static double DefaultLongTapTimeout
+ {
+ get
+ {
+ return Interop.Elementary.elm_config_glayer_long_tap_start_timeout_get();
+ }
+ set
+ {
+ Interop.Elementary.elm_config_glayer_long_tap_start_timeout_set(value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the duration for occurring double tap event of gesture layer.
+ /// </summary>
+ public static double DefaultDoubleTapTimeout
+ {
+ get
+ {
+ return Interop.Elementary.elm_config_glayer_double_tap_timeout_get();
+ }
+ set
+ {
+ Interop.Elementary.elm_config_glayer_double_tap_timeout_set(value);
+ }
+ }
+ }
+
+ private class NativeCallback
+ {
+ public readonly GestureType Type;
+ public readonly GestureState State;
+ public Action<object> Action;
+
+ public NativeCallback(GestureType type, GestureState state, Action<object> action)
+ {
+ Type = type;
+ State = state;
+ Action = action;
+ }
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/Hoversel.cs b/src/ElmSharp/ElmSharp/Hoversel.cs
new file mode 100644
index 0000000..6adca62
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Hoversel.cs
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The HoverselItemEventArgs is an HoverselItem's EventArgs
+ /// </summary>
+ public class HoverselItemEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Hoversel's Item
+ /// </summary>
+ public HoverselItem Item { get; set; }
+
+ internal static HoverselItemEventArgs CreateFromSmartEvent(IntPtr data, IntPtr obj, IntPtr info)
+ {
+ HoverselItem item = ItemObject.GetItemByHandle(info) as HoverselItem;
+ return new HoverselItemEventArgs() { Item = item };
+ }
+ }
+
+ /// <summary>
+ /// The hoversel is a button that pops up a list of items.
+ /// </summary>
+ public class Hoversel : Layout
+ {
+ SmartEvent _clicked;
+ SmartEvent _expanded;
+ SmartEvent _dismissed;
+ SmartEvent<HoverselItemEventArgs> _selected;
+ Interop.Evas.SmartCallback _onItemSelected;
+
+ /// <summary>
+ /// Creates and initializes a new instance of the Hoversel class.
+ /// </summary>
+ /// <param name="parent">The parent is a given container which will be attached by Hoversel as a child. It's <see cref="EvasObject"/> type.</param>
+ public Hoversel(EvasObject parent) : base(parent)
+ {
+ _clicked = new SmartEvent(this, "clicked");
+ _clicked.On += (sender, e) =>
+ {
+ Clicked?.Invoke(this, EventArgs.Empty);
+ };
+ _expanded = new SmartEvent(this, "expanded");
+ _expanded.On += (sender, e) =>
+ {
+ Expanded?.Invoke(this, EventArgs.Empty);
+ };
+ _dismissed = new SmartEvent(this, "dismissed");
+ _dismissed.On += (sender, e) =>
+ {
+ Dismissed?.Invoke(this, EventArgs.Empty);
+ };
+ _selected = new SmartEvent<HoverselItemEventArgs>(this, RealHandle, "selected", HoverselItemEventArgs.CreateFromSmartEvent);
+ _selected.On += (s, e) =>
+ {
+ if (e.Item != null) ItemSelected?.Invoke(this, e);
+ };
+ _onItemSelected = (data, obj, info) =>
+ {
+ HoverselItem item = ItemObject.GetItemById((int)data) as HoverselItem;
+ item?.SendItemSelected();
+ };
+ }
+
+ /// <summary>
+ /// Clicked will be triggered when Hoversel is clicked
+ /// </summary>
+ public event EventHandler Clicked;
+
+ /// <summary>
+ /// Expanded will be triggered when Hoversel is activated by clicking the hoversel or by a function
+ /// </summary>
+ public event EventHandler Expanded;
+
+ /// <summary>
+ /// Dismissed will be triggered when Hoversel Dismissed
+ /// </summary>
+ public event EventHandler Dismissed;
+
+ /// <summary>
+ /// ItemSelected will be triggered when Hoversel's Item Selected
+ /// </summary>
+ public event EventHandler<HoverselItemEventArgs> ItemSelected;
+
+ /// <summary>
+ /// Gets or sets the status to control whether the hoversel should expand horizontally.
+ /// </summary>
+ public bool IsHorizontal
+ {
+ get
+ {
+ return Interop.Elementary.elm_hoversel_horizontal_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_hoversel_horizontal_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the hover parent.
+ /// </summary>
+ public IntPtr HoverParent
+ {
+ get
+ {
+ return Interop.Elementary.elm_hoversel_hover_parent_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_hoversel_hover_parent_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets the flag of whether the hoversel is expanded.
+ /// </summary>
+ public bool IsExpanded
+ {
+ get
+ {
+ return Interop.Elementary.elm_hoversel_expanded_get(RealHandle);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the status of whether update icon and text of hoversel same to those of selected item automatically.
+ /// </summary>
+ public bool AutoUpdate
+ {
+ get
+ {
+ return Interop.Elementary.elm_hoversel_auto_update_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_hoversel_auto_update_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// This triggers the hoversel popup from code, the same as if the user had clicked the button.
+ /// </summary>
+ public void HoverBegin()
+ {
+ Interop.Elementary.elm_hoversel_hover_begin(RealHandle);
+ }
+
+ /// <summary>
+ /// This dismisses the hoversel popup as if the user had clicked outside the hover.
+ /// </summary>
+ public void HoverEnd()
+ {
+ Interop.Elementary.elm_hoversel_hover_end(RealHandle);
+ }
+
+ /// <summary>
+ /// This will remove all the children items from the hoversel.
+ /// </summary>
+ public void Clear()
+ {
+ Interop.Elementary.elm_hoversel_clear(RealHandle);
+ }
+
+ /// <summary>
+ /// Add an item to the hoversel button.
+ /// This adds an item to the hoversel to show when it is clicked.
+ /// </summary>
+ /// <param name="label">Item's label</param>
+ /// <returns>A handle to the added item.</returns>
+ public HoverselItem AddItem(string label)
+ {
+ HoverselItem item = new HoverselItem();
+ item.Label = label;
+ item.Handle = Interop.Elementary.elm_hoversel_item_add(RealHandle, label, null, 0, _onItemSelected, (IntPtr)item.Id);
+ return item;
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ IntPtr handle = Interop.Elementary.elm_layout_add(parent.Handle);
+ Interop.Elementary.elm_layout_theme_set(handle, "layout", "background", "default");
+
+ RealHandle = Interop.Elementary.elm_hoversel_add(handle);
+ Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
+
+ return handle;
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/HoverselItem.cs b/src/ElmSharp/ElmSharp/HoverselItem.cs
new file mode 100755
index 0000000..ebdaece
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/HoverselItem.cs
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The HoverselItem is the Item of Hoversel
+ /// </summary>
+ public class HoverselItem : ItemObject
+ {
+ internal HoverselItem() : base(IntPtr.Zero)
+ {
+ }
+
+ /// <summary>
+ /// HoverselItem's label
+ /// </summary>
+ public string Label { get; internal set; }
+
+ /// <summary>
+ /// ItemSelected will be triggered when HoverselItem Selected
+ /// </summary>
+ public event EventHandler ItemSelected;
+
+ internal void SendItemSelected()
+ {
+ ItemSelected?.Invoke(this, EventArgs.Empty);
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/IAccessibleObject.cs b/src/ElmSharp/ElmSharp/IAccessibleObject.cs
new file mode 100755
index 0000000..f1488ff
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/IAccessibleObject.cs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace ElmSharp.Accessible
+{
+ /// <summary>
+ /// IAccessibleObject is a interface which defines properties and methods of accessible object.
+ /// </summary>
+ public interface IAccessibleObject
+ {
+ ReadingInfoType ReadingInfoType { get; set; }
+ AccessRole Role { get; set; }
+ bool CanHighlight { get; set; }
+ string TranslationDomain { get; set; }
+ string Name { get; set; }
+ string Description { get; set; }
+ AccessibleInfoProvider NameProvider { get; set; }
+ AccessibleInfoProvider DescriptionProvider { get; set; }
+ void AppendRelation(IAccessibleRelation relation);
+ void RemoveRelation(IAccessibleRelation relation);
+ void Highlight();
+ void Unhighlight();
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/Icon.cs b/src/ElmSharp/ElmSharp/Icon.cs
new file mode 100755
index 0000000..3ebff8f
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Icon.cs
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// Enumeration for the icon lookup order. Should look for icons in the theme, FDO paths, or both.
+ /// </summary>
+ public enum IconLookupOrder
+ {
+ /// <summary>
+ /// Icon look up order: freedesktop, theme
+ /// </summary>
+ FreeDesktopFirst = 0,
+ /// <summary>
+ /// Icon look up order: theme, freedesktop
+ /// </summary>
+ ThemeFirst,
+ /// <summary>
+ /// Icon look up order: freedesktop
+ /// </summary>
+ FreeDesktopOnly,
+ /// <summary>
+ /// Icon look up order: theme
+ /// </summary>
+ ThemeOnly
+ }
+
+ /// <summary>
+ /// The Icon is a widget that displays standard icon images ("delete", "edit", "arrows", etc.)
+ /// or images coming from a custom file (PNG, JPG, EDJE, etc.), on icon context.
+ /// Inherits Image
+ /// </summary>
+ public class Icon : Image
+ {
+ /// <summary>
+ /// Creates and initializes a new instance of Icon class.
+ /// </summary>
+ /// <param name="parent">The parent is a given container which will be attached by Icon as a child. It's <see cref="EvasObject"/> type.</param>
+ public Icon(EvasObject parent) : base(parent)
+ {
+ }
+
+ /// <summary>
+ /// Sets or gets the standard icon name of a given Icon widget.
+ /// </summary>
+ public string StandardIconName
+ {
+ get
+ {
+ return Interop.Elementary.elm_icon_standard_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_icon_standard_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the icon lookup order of a given Icon widget.
+ /// </summary>
+ public IconLookupOrder IconLookupOrder
+ {
+ get
+ {
+ return (IconLookupOrder)Interop.Elementary.elm_icon_order_lookup_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_icon_order_lookup_set(RealHandle, (int)value);
+ }
+ }
+
+ /// <summary>
+ /// Sets the file that is used, but uses a generated thumbnail.
+ /// </summary>
+ /// <param name="file">The path to the file that is used as an icon image</param>
+ /// <param name="group">The group that the icon belongs to</param>
+ public void SetThumb(string file, string group)
+ {
+ Interop.Elementary.elm_icon_thumb_set(RealHandle, file, group);
+ }
+
+ /// <summary>
+ /// Adds a new icon object to the parent.
+ /// </summary>
+ /// <param name="parent">EvasObject</param>
+ /// <returns>The new object, otherwise NULL if it cannot be created</returns>
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ IntPtr handle = Interop.Elementary.elm_layout_add(parent.Handle);
+ Interop.Elementary.elm_layout_theme_set(handle, "layout", "background", "default");
+
+ RealHandle = Interop.Elementary.elm_icon_add(handle);
+ Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
+
+ return handle;
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/Image.cs b/src/ElmSharp/ElmSharp/Image.cs
new file mode 100644
index 0000000..743cb42
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Image.cs
@@ -0,0 +1,688 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.IO;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The Image is a widget that allows one to load and display an image file on it,
+ /// be it from a disk file or from a memory region.
+ /// Inherits Widget
+ /// </summary>
+ public class Image : Widget
+ {
+ bool _canScaleUp = true;
+ bool _canScaleDown = true;
+ SmartEvent _clicked;
+ Color _color = Color.Default;
+
+ /// <summary>
+ /// Creates and initializes a new instance of Image class.
+ /// </summary>
+ /// <param name="parent">The parent is a given container which will be attached by Image as a child. It's <see cref="EvasObject"/> type.</param>
+ public Image(EvasObject parent) : base(parent)
+ {
+ _clicked = new SmartEvent(this, "clicked");
+ _clicked.On += (s, e) => Clicked?.Invoke(this, EventArgs.Empty);
+ }
+
+ /// <summary>
+ /// Clicked will be triggered when the image is clicked.
+ /// </summary>
+ public event EventHandler Clicked;
+
+ /// <summary>
+ /// LoadingCompleted will be triggered when the image is loaded completely.
+ /// </summary>
+ public event EventHandler LoadingCompleted;
+
+ /// <summary>
+ /// Clicked will be triggered when the image is fail to load.
+ /// </summary>
+ public event EventHandler LoadingFailed;
+
+ /// <summary>
+ /// Gets the file that is used as an image.
+ /// </summary>
+ public string File
+ {
+ get
+ {
+ return Interop.Elementary.elm_image_file_get(RealHandle);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the smooth effect for an image.
+ /// </summary>
+ public bool IsSmooth
+ {
+ get
+ {
+ return Interop.Elementary.elm_image_smooth_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_image_smooth_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets whether scaling is disabled on the object.
+ /// </summary>
+ public bool IsScaling
+ {
+ get
+ {
+ return !Interop.Elementary.elm_image_no_scale_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_image_no_scale_set(RealHandle, !value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets whether the object is down resizeable.
+ /// </summary>
+ public bool CanScaleDown
+ {
+ get
+ {
+ return _canScaleDown;
+ }
+ set
+ {
+ _canScaleDown = value;
+ Interop.Elementary.elm_image_resizable_set(RealHandle, _canScaleUp, _canScaleDown);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets whether the object is up resizeable.
+ /// </summary>
+ public bool CanScaleUp
+ {
+ get
+ {
+ return _canScaleUp;
+ }
+ set
+ {
+ _canScaleUp = value;
+ Interop.Elementary.elm_image_resizable_set(RealHandle, _canScaleUp, _canScaleDown);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets whether the image fills the entire object area, when keeping the aspect ratio.
+ /// </summary>
+ public bool CanFillOutside
+ {
+ get
+ {
+ return Interop.Elementary.elm_image_fill_outside_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_image_fill_outside_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the prescale size for the image.
+ /// </summary>
+ public int PrescaleSize
+ {
+ get
+ {
+ return Interop.Elementary.elm_image_prescale_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_image_prescale_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets whether the original aspect ratio of the image should be kept on resize.
+ /// </summary>
+ public bool IsFixedAspect
+ {
+ get
+ {
+ return Interop.Elementary.elm_image_aspect_fixed_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_image_aspect_fixed_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets whether an image object (which supports animation) is to animate itself.
+ /// </summary>
+ public bool IsAnimated
+ {
+ get
+ {
+ return Interop.Elementary.elm_image_animated_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_image_animated_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets whether an image object supports animation.
+ /// </summary>
+ public bool IsAnimatedAvailable
+ {
+ get
+ {
+ return Interop.Elementary.elm_image_animated_available_get(RealHandle);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets whether an image object is under animation.
+ /// </summary>
+ /// <remarks>
+ /// An image object, even if it supports animation, will be displayed by default without animation.
+ /// To actually start playing any image object's animation, <see cref="IsAnimated"/> should be TRUE before setting this property true.
+ /// </remarks>
+ public bool IsAnimationPlaying
+ {
+ get
+ {
+ return Interop.Elementary.elm_image_animated_play_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_image_animated_play_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets whether the image is 'editable'.
+ /// </summary>
+ public bool IsEditable
+ {
+ get
+ {
+ return Interop.Elementary.elm_image_editable_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_image_editable_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets the current size of the image.
+ /// </summary>
+ public Size ObjectSize
+ {
+ get
+ {
+ Interop.Elementary.elm_image_object_size_get(RealHandle, out int w, out int h);
+ return new Size(w, h);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets whether alpha channel data is being used on the given image object.
+ /// </summary>
+ public bool IsOpaque
+ {
+ get
+ {
+ IntPtr evasObj = Interop.Elementary.elm_image_object_get(RealHandle);
+ if (evasObj != IntPtr.Zero)
+ {
+ return !Interop.Evas.evas_object_image_alpha_get(evasObj);
+ }
+ return false;
+ }
+ set
+ {
+ IntPtr evasObj = Interop.Elementary.elm_image_object_get(RealHandle);
+ if (evasObj != IntPtr.Zero)
+ {
+ Interop.Evas.evas_object_image_alpha_set(evasObj, !value);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the image orientation.
+ /// </summary>
+ public ImageOrientation Orientation
+ {
+ get
+ {
+ return (ImageOrientation)Interop.Elementary.elm_image_orient_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_image_orient_set(RealHandle, (int)value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the image color
+ /// </summary>
+ public override Color Color
+ {
+ get
+ {
+ return _color;
+ }
+ set
+ {
+ IntPtr evasObj = Interop.Elementary.elm_image_object_get(RealHandle);
+ if (evasObj != IntPtr.Zero)
+ {
+ if (value.IsDefault)
+ {
+ // Currently, we assume the Image.Color property as a blending color (actually, multiply blending).
+ // Thus we are using Color.White (255,255,255,255) as a default color to ensure original image color. (255/255 * original = original)
+ Interop.Evas.evas_object_color_set(evasObj, 255, 255, 255, 255);
+ }
+ else
+ {
+ Interop.Evas.SetPremultipliedColor(evasObj, value.R, value.G, value.B, value.A);
+ }
+ }
+ _color = value;
+ }
+ }
+
+ /// <summary>
+ /// Sets the background color
+ /// </summary>
+ public override Color BackgroundColor
+ {
+ set
+ {
+ if (value.IsDefault)
+ {
+ SetPartColor("bg", Color.Transparent);
+ }
+ else
+ {
+ SetPartColor("bg", value);
+ }
+ _backgroundColor = value;
+ }
+ }
+
+ /// <summary>
+ /// Sets the dimensions for an image object's border, a region which is not scaled together with its center ever.
+ /// </summary>
+ /// <param name="left">The border's left width</param>
+ /// <param name="right">The border's right width</param>
+ /// <param name="top">The border's top width</param>
+ /// <param name="bottom">The border's bottom width</param>
+ public void SetBorder(int left, int right, int top, int bottom)
+ {
+ IntPtr evasObj = Interop.Elementary.elm_image_object_get(RealHandle);
+ Interop.Evas.evas_object_image_border_set(evasObj, left, right, top, bottom);
+ }
+
+ /// <summary>
+ /// Sets or gets if the center part of the given image object (not the border) should be drawn.
+ /// </summary>
+ /// <remarks>
+ /// When rendering, the image may be scaled to fit the size of the image object.
+ /// This function sets if the center part of the scaled image is to be drawn or left completely blank, or forced to be solid.
+ /// Very useful for frames and decorations.
+ /// </remarks>
+ public ImageBorderFillMode BorderCenterFillMode
+ {
+ get
+ {
+ IntPtr evasObj = Interop.Elementary.elm_image_object_get(RealHandle);
+ return (ImageBorderFillMode)Interop.Evas.evas_object_image_border_center_fill_get(evasObj);
+ }
+ set
+ {
+ IntPtr evasObj = Interop.Elementary.elm_image_object_get(RealHandle);
+ Interop.Evas.evas_object_image_border_center_fill_set(evasObj, (int)value);
+ }
+ }
+
+ /// <summary>
+ /// Sets the file that is used as the image's source.
+ /// </summary>
+ /// <param name="file">The path to the file that is used as an image source</param>
+ /// <returns>(true = success, false = error)</returns>
+ public bool Load(string file)
+ {
+ if (file == null)
+ throw new ArgumentNullException("file");
+
+ Interop.Elementary.elm_image_async_open_set(RealHandle, false);
+ Interop.Elementary.elm_image_preload_disabled_set(RealHandle, true);
+ return Interop.Elementary.elm_image_file_set(RealHandle, file, null);
+ }
+
+ /// <summary>
+ /// Sets the uri that is used as the image's source.
+ /// </summary>
+ /// <param name="uri">The uri to the file that is used as an image source</param>
+ /// <returns>(true = success, false = error)</returns>
+ public bool Load(Uri uri)
+ {
+ if (uri == null)
+ throw new ArgumentNullException("uri");
+
+ return Load(uri.IsFile ? uri.LocalPath : uri.AbsoluteUri);
+ }
+
+ /// <summary>
+ /// Sets a location in the memory to be used as an image object's source bitmap.
+ /// </summary>
+ /// <remarks>
+ /// This function is handy when the contents of an image file are mapped into the memory, for example.
+ /// The format string should be something like "png", "jpg", "tga", "tiff", "bmp" etc, when provided (null, on the contrary).
+ /// This improves the loader performance as it tries the "correct" loader first, before trying a range of other possible loaders until one succeeds.
+ /// </remarks>
+ /// <param name="img">The binary data that is used as an image source</param>
+ /// <param name="size">The size of the binary data blob img</param>
+ /// <returns>(true = success, false = error)</returns>
+ [Obsolete("This method will be removed. Use Load(Stream stream) instead.")]
+ public unsafe bool Load(byte* img, long size)
+ {
+ if (img == null)
+ throw new ArgumentNullException("img");
+
+ Interop.Elementary.elm_image_async_open_set(RealHandle, false);
+ Interop.Elementary.elm_image_preload_disabled_set(RealHandle, true);
+ return Interop.Elementary.elm_image_memfile_set(RealHandle, img, size, IntPtr.Zero, IntPtr.Zero);
+ }
+
+ /// <summary>
+ /// Sets the stream that is used as the image's source.
+ /// </summary>
+ /// <param name="stream">The stream that is used as an image source</param>
+ /// <returns>(true = success, false = error)</returns>
+ public bool Load(Stream stream)
+ {
+ if (stream == null)
+ throw new ArgumentNullException("stream");
+
+ Interop.Elementary.elm_image_async_open_set(RealHandle, false);
+ Interop.Elementary.elm_image_preload_disabled_set(RealHandle, true);
+ MemoryStream memstream = new MemoryStream();
+ stream.CopyTo(memstream);
+ unsafe
+ {
+ byte[] dataArr = memstream.ToArray();
+ fixed (byte* data = &dataArr[0])
+ {
+ return Interop.Elementary.elm_image_memfile_set(RealHandle, data, dataArr.Length, IntPtr.Zero, IntPtr.Zero);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Sets the file that is used as the image's source with async.
+ /// </summary>
+ /// <param name="file">The path to the file that is used as an image source</param>
+ /// <param name="cancellationToken">cancellation token</param>
+ /// <returns>(true = success, false = error)</returns>
+ public Task<bool> LoadAsync(string file, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ if (file == null)
+ throw new ArgumentNullException("file");
+
+ Interop.Elementary.elm_image_async_open_set(RealHandle, true);
+ Interop.Elementary.elm_image_preload_disabled_set(RealHandle, false);
+
+ var tcs = new TaskCompletionSource<bool>();
+
+ cancellationToken.Register(() =>
+ {
+ if (tcs != null && !tcs.Task.IsCompleted)
+ {
+ tcs.SetCanceled();
+ }
+ });
+
+ SmartEvent loadReady = new SmartEvent(this, RealHandle, "load,ready");
+ loadReady.On += (s, e) =>
+ {
+ loadReady.Dispose();
+ LoadingCompleted?.Invoke(this, EventArgs.Empty);
+ if (tcs != null && !tcs.Task.IsCompleted)
+ {
+ tcs.SetResult(true);
+ }
+ };
+
+ SmartEvent loadError = new SmartEvent(this, RealHandle, "load,error");
+ loadError.On += (s, e) =>
+ {
+ loadError.Dispose();
+ LoadingFailed?.Invoke(this, EventArgs.Empty);
+ if (tcs != null && !tcs.Task.IsCompleted)
+ {
+ tcs.SetResult(false);
+ }
+ };
+
+ bool ret = Interop.Elementary.elm_image_file_set(RealHandle, file, null);
+ if (!ret)
+ {
+ throw new InvalidOperationException("Failed to set file to Image");
+ }
+
+ return tcs.Task;
+ }
+
+ /// <summary>
+ /// Sets the uri that is used as the image's source with async.
+ /// </summary>
+ /// <param name="uri">The uri to the file that is used as an image source</param>
+ /// <param name="cancellationToken">cancellation token</param>
+ /// <returns>(true = success, false = error)</returns>
+ public Task<bool> LoadAsync(Uri uri, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ if (uri == null)
+ throw new ArgumentNullException("uri");
+
+ return LoadAsync(uri.IsFile ? uri.LocalPath : uri.AbsoluteUri, cancellationToken);
+ }
+
+ /// <summary>
+ /// Sets the stream that is used as the image's source with async.
+ /// </summary>
+ /// <param name="stream">The stream that is used as an image source</param>
+ /// <param name="cancellationToken">cancellation token</param>
+ /// <returns>(true = success, false = error)</returns>
+ public async Task<bool> LoadAsync(Stream stream, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ if (stream == null)
+ throw new ArgumentNullException("stream");
+
+ Interop.Elementary.elm_image_async_open_set(RealHandle, true);
+ Interop.Elementary.elm_image_preload_disabled_set(RealHandle, false);
+
+ var tcs = new TaskCompletionSource<bool>();
+
+ cancellationToken.Register(() =>
+ {
+ if (tcs != null && !tcs.Task.IsCompleted)
+ {
+ tcs.SetCanceled();
+ }
+ });
+
+ SmartEvent loadReady = new SmartEvent(this, RealHandle, "load,ready");
+ loadReady.On += (s, e) =>
+ {
+ loadReady.Dispose();
+ LoadingCompleted?.Invoke(this, EventArgs.Empty);
+ if (tcs != null && !tcs.Task.IsCompleted)
+ {
+ tcs.SetResult(true);
+ }
+ };
+
+ SmartEvent loadError = new SmartEvent(this, RealHandle, "load,error");
+ loadError.On += (s, e) =>
+ {
+ loadError.Dispose();
+ LoadingFailed?.Invoke(this, EventArgs.Empty);
+ if (tcs != null && !tcs.Task.IsCompleted)
+ {
+ tcs.SetResult(false);
+ }
+ };
+
+ MemoryStream memstream = new MemoryStream();
+ await stream.CopyToAsync(memstream);
+
+ unsafe
+ {
+ byte[] dataArr = memstream.ToArray();
+ fixed (byte* data = &dataArr[0])
+ {
+ bool ret = Interop.Elementary.elm_image_memfile_set(RealHandle, data, dataArr.Length, IntPtr.Zero, IntPtr.Zero);
+ if (!ret)
+ {
+ return false;
+ }
+ }
+ }
+
+ return await tcs.Task;
+ }
+
+ /// <summary>
+ /// Sets the color of color class for a given widget.
+ /// </summary>
+ /// <param name="part">The name of color class.</param>
+ /// <param name="color">The struct of color</param>
+ public override void SetPartColor(string part, Color color)
+ {
+ Interop.Elementary.elm_object_color_class_color_set(Handle, part, color.R * color.A / 255,
+ color.G * color.A / 255,
+ color.B * color.A / 255,
+ color.A);
+ }
+
+ /// <summary>
+ /// Gets the color of color class for a given widget.
+ /// </summary>
+ /// <param name="part">The name of color class.</param>
+ /// <returns>color object</returns>
+ public override Color GetPartColor(string part)
+ {
+ Interop.Elementary.elm_object_color_class_color_get(Handle, part, out int r, out int g, out int b, out int a);
+ return new Color((int)(r / (a / 255.0)), (int)(g / (a / 255.0)), (int)(b / (a / 255.0)), a);
+ }
+
+ /// <summary>
+ /// Sets the content at a part of a given container widget.
+ /// </summary>
+ /// <param name="parent">The parent is a given container which will be attached by Image as a child. It's <see cref="EvasObject"/> type.</param>
+ /// <returns>The new object, otherwise null if it cannot be created</returns>
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ IntPtr handle = Interop.Elementary.elm_layout_add(parent);
+ Interop.Elementary.elm_layout_theme_set(handle, "layout", "background", "default");
+
+ RealHandle = Interop.Elementary.elm_image_add(handle);
+ Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
+
+ return handle;
+ }
+ }
+
+ /// <summary>
+ /// Enumeration for the fill mode of image border
+ /// </summary>
+ public enum ImageBorderFillMode
+ {
+ /// <summary>
+ /// None mode of image border
+ /// </summary>
+ None,
+
+ /// <summary>
+ /// Default mode of image border
+ /// </summary>
+ Default,
+
+ /// <summary>
+ /// Solid mode of image border
+ /// </summary>
+ Solid,
+ }
+
+ /// <summary>
+ /// Enumeration for the possible orientation options
+ /// </summary>
+ public enum ImageOrientation : int
+ {
+ /// <summary>
+ /// No orientation change
+ /// </summary>
+ None = 0,
+
+ /// <summary>
+ /// Rotate 90 degrees clockwise
+ /// </summary>
+ Rotate90,
+
+ /// <summary>
+ /// Rotate 180 degrees clockwise
+ /// </summary>
+ Rotate180,
+
+ /// <summary>
+ /// Rotate 90 degrees counter-clockwise (i.e. 270 degrees clockwise)
+ /// </summary>
+ Rotate270,
+
+ /// <summary>
+ /// Flip image horizontally
+ /// </summary>
+ FlipHorizontal,
+
+ /// <summary>
+ /// Flip image vertically
+ /// </summary>
+ FlipVertical,
+
+ /// <summary>
+ /// Flip the image along the y = (width - x) line (bottom-left to top-right)
+ /// </summary>
+ FlipTranspose,
+
+ /// <summary>
+ /// Flip the image along the y = x line (top-left to bottom-right)
+ /// </summary>
+ FlipTransverse
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/Index.cs b/src/ElmSharp/ElmSharp/Index.cs
new file mode 100755
index 0000000..f73ec7a
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Index.cs
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// An index widget gives you an index for fast access to whichever group of other UI items one might have.
+ /// Inherits Layout
+ /// </summary>
+ public class Index : Layout
+ {
+ HashSet<IndexItem> _children = new HashSet<IndexItem>();
+ SmartEvent _delayedChanged;
+
+ /// <summary>
+ /// Creates and initializes a new instance of Index class.
+ /// </summary>
+ /// <param name="parent">The parent is a given container which will be attached by Index as a child. It's <see cref="EvasObject"/> type.</param>
+ public Index(EvasObject parent) : base(parent)
+ {
+ _delayedChanged = new SmartEvent(this, this.RealHandle, "delay,changed");
+ _delayedChanged.On += _delayedChanged_On;
+ }
+
+ /// <summary>
+ /// Changed will be triggered when the selected index item is changed.
+ /// </summary>
+ public event EventHandler Changed;
+
+ /// <summary>
+ /// Sets or gets the auto hiding feature is enabled or not for a given index widget.
+ /// </summary>
+ public bool AutoHide
+ {
+ get
+ {
+ return !Interop.Elementary.elm_index_autohide_disabled_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_index_autohide_disabled_set(RealHandle, !value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets a value whether horizontal mode is enabled or not.
+ /// </summary>
+ public bool IsHorizontal
+ {
+ get
+ {
+ return Interop.Elementary.elm_index_horizontal_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_index_horizontal_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the value of indicator's disabled status.
+ /// </summary>
+ public bool IndicatorVisible
+ {
+ get
+ {
+ return !Interop.Elementary.elm_index_indicator_disabled_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_index_indicator_disabled_set(RealHandle, !value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the omit feature is enabled or not for a given index widget.
+ /// </summary>
+ public bool OmitEnabled
+ {
+ get
+ {
+ return Interop.Elementary.elm_index_omit_enabled_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_index_omit_enabled_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Set a delay change time for index object.
+ /// delay time is 0.2 sec by default.
+ /// </summary>
+ public double Delay
+ {
+ get
+ {
+ return Interop.Elementary.elm_index_delay_change_time_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_index_delay_change_time_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the items level for a given index widget.
+ /// </summary>
+ public int Level
+ {
+ get
+ {
+ return Interop.Elementary.elm_index_item_level_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_index_item_level_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Control standard_priority group of index.
+ /// Priority group will be shown as many items as it can, and other group will be shown one character only.
+ /// </summary>
+ public int Priority
+ {
+ get
+ {
+ return Interop.Elementary.elm_index_standard_priority_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_index_standard_priority_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets the last selected item, for a given index widget.
+ /// </summary>
+ public IndexItem SelectedItem
+ {
+ get
+ {
+ IntPtr handle = Interop.Elementary.elm_index_selected_item_get(RealHandle, 0);
+ return ItemObject.GetItemByHandle(handle) as IndexItem;
+ }
+ }
+
+ /// <summary>
+ /// Append a new item on a given index widget.
+ /// </summary>
+ /// <param name="label">the label which the item should be indexed</param>
+ /// <returns>A object to the IndexItem added or null, on errors</returns>
+ public IndexItem Append(string label)
+ {
+ IndexItem item = new IndexItem(label);
+ item.Handle = Interop.Elementary.elm_index_item_append(RealHandle, label, null, (IntPtr)item.Id);
+ return item;
+ }
+
+ /// <summary>
+ /// Prepend a new item on a given index widget.
+ /// </summary>
+ /// <param name="label">the label which the item should be indexed</param>
+ /// <returns>A handle to the item added or NULL, on errors</returns>
+ public IndexItem Prepend(string label)
+ {
+ IndexItem item = new IndexItem(label);
+ item.Handle = Interop.Elementary.elm_index_item_prepend(RealHandle, label, null, (IntPtr)item.Id);
+ return item;
+ }
+
+ /// <summary>
+ /// Insert a new item into the index object before item before.
+ /// </summary>
+ /// <param name="label">the label which the item should be indexed</param>
+ /// <param name="before">The index item to insert after.</param>
+ /// <returns>A object to the IndexItem added or null, on errors</returns>
+ public IndexItem InsertBefore(string label, IndexItem before)
+ {
+ IndexItem item = new IndexItem(label);
+ item.Handle = Interop.Elementary.elm_index_item_insert_before(RealHandle, before, label, null, (IntPtr)item.Id);
+ return item;
+ }
+
+ /// <summary>
+ /// Insert a new item into the index object after item after.
+ /// </summary>
+ /// <param name="label">the label which the item should be indexed</param>
+ /// <param name="after">The index item to insert after.</param>
+ /// <returns>A object to the IndexItem added or null, on errors</returns>
+ public IndexItem InsertAfter(string label, IndexItem after)
+ {
+ IndexItem item = new IndexItem(label);
+ item.Handle = Interop.Elementary.elm_index_item_insert_after(RealHandle, after, label, null, (IntPtr)item.Id);
+ return item;
+ }
+
+ /// <summary>
+ /// Flush the changes made to the index items so they work correctly.
+ /// </summary>
+ /// <param name="level">The index level (one of 0 or 1) where changes were made</param>
+ public void Update(int level)
+ {
+ Interop.Elementary.elm_index_level_go(RealHandle, level);
+ }
+
+ /// <summary>
+ /// Removes all items from a given index widget.
+ /// </summary>
+ public void Clear()
+ {
+ Interop.Elementary.elm_index_item_clear(RealHandle);
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ IntPtr handle = Interop.Elementary.elm_layout_add(parent.Handle);
+ Interop.Elementary.elm_layout_theme_set(handle, "layout", "elm_widget", "default");
+
+ RealHandle = Interop.Elementary.elm_index_add(handle);
+ Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
+
+ return handle;
+ }
+
+ void _delayedChanged_On(object sender, EventArgs e)
+ {
+ SelectedItem?.SendSelected();
+ Changed?.Invoke(this, e);
+ }
+
+ void AddInternal(IndexItem item)
+ {
+ _children.Add(item);
+ item.Deleted += Item_Deleted;
+ }
+
+ void Item_Deleted(object sender, EventArgs e)
+ {
+ _children.Remove((IndexItem)sender);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/IndexItem.cs b/src/ElmSharp/ElmSharp/IndexItem.cs
new file mode 100755
index 0000000..67dcfd4
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/IndexItem.cs
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+namespace ElmSharp
+{
+ /// <summary>
+ /// The IndexItem is used to manage index item
+ /// Inherits ItemObject
+ /// </summary>
+ public class IndexItem : ItemObject
+ {
+ /// <summary>
+ /// Creates and initializes a new instance of IndexItem class.
+ /// </summary>
+ /// <param name="text">the text is set to the Text. It's 'string' type.</param>
+ public IndexItem(string text) : base(IntPtr.Zero)
+ {
+ Text = text;
+ }
+
+ /// <summary>
+ /// Selected will be triggered when the index item is selected
+ /// </summary>
+ public event EventHandler Selected;
+
+ /// <summary>
+ /// Gets the text
+ /// </summary>
+ public string Text { get; private set; }
+
+ /// <summary>
+ /// Sets the selected state of an item.
+ /// </summary>
+ /// <param name="selected">The selected state</param>
+ public void Select(bool selected)
+ {
+ Interop.Elementary.elm_index_item_selected_set(Handle, selected);
+ }
+ internal void SendSelected()
+ {
+ Selected?.Invoke(this, EventArgs.Empty);
+ }
+
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/ItemObject.cs b/src/ElmSharp/ElmSharp/ItemObject.cs
new file mode 100644
index 0000000..f009396
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/ItemObject.cs
@@ -0,0 +1,366 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The ItemObject is used to manage item object
+ /// </summary>
+ public class ItemObject
+ {
+ private static Dictionary<int, ItemObject> s_IdToItemTable = new Dictionary<int, ItemObject>();
+ private static Dictionary<IntPtr, ItemObject> s_HandleToItemTable = new Dictionary<IntPtr, ItemObject>();
+ private static int s_globalId = 0;
+
+ readonly Dictionary<string, EvasObject> _partContents = new Dictionary<string, EvasObject>();
+ Interop.Evas.SmartCallback _deleteCallback;
+ IntPtr _handle = IntPtr.Zero;
+ Dictionary<SignalData, Interop.Elementary.Elm_Object_Item_Signal_Cb> _signalDatas = new Dictionary<SignalData, Interop.Elementary.Elm_Object_Item_Signal_Cb>();
+ EvasObject _trackObject = null;
+
+ /// <summary>
+ /// Creates and initializes a new instance of ItemObject class.
+ /// </summary>
+ /// <param name="handle">IntPtr</param>
+ protected ItemObject(IntPtr handle)
+ {
+ _deleteCallback = DeleteCallbackHandler;
+ Id = GetNextId();
+ s_IdToItemTable[Id] = this;
+ Handle = handle;
+ }
+
+ // C# Finalizer was called on GC thread
+ // So, We can't access to EFL object
+ // And When Finalizer was called, Field can be already released.
+ //~ItemObject()
+ //{
+ // if (Handle != IntPtr.Zero)
+ // Interop.Elementary.elm_object_item_del(Handle);
+ //}
+
+ /// <summary>
+ /// Gets the id of item object
+ /// </summary>
+ public int Id { get; private set; }
+
+ /// <summary>
+ /// Sets or gets whether the item object is enabled
+ /// </summary>
+ public bool IsEnabled
+ {
+ get { return !Interop.Elementary.elm_object_item_disabled_get(Handle); }
+ set { Interop.Elementary.elm_object_item_disabled_set(Handle, !value); }
+ }
+
+ /// <summary>
+ /// Gets track object of the item.
+ /// </summary>
+ public EvasObject TrackObject
+ {
+ get
+ {
+ if (_trackObject == null)
+ _trackObject = new ItemEvasObject(Handle);
+ return _trackObject;
+ }
+ }
+
+ internal IntPtr Handle
+ {
+ get
+ {
+ return _handle;
+ }
+ set
+ {
+ if (_handle == value)
+ return;
+
+ if (_handle != IntPtr.Zero)
+ {
+ UnsetDeleteCallback();
+ }
+ _handle = value;
+ SetDeleteCallback();
+ s_HandleToItemTable[Handle] = this;
+ }
+ }
+
+ /// <summary>
+ /// Deleted will be triggered when the item object is deleted
+ /// </summary>
+ public event EventHandler Deleted;
+
+ /// <summary>
+ /// Delete the item object
+ /// </summary>
+ public void Delete()
+ {
+ Interop.Elementary.elm_object_item_del(Handle);
+ _handle = IntPtr.Zero;
+ }
+
+ /// <summary>
+ /// Set a content of an object item and delete old content
+ /// </summary>
+ /// <param name="part">The content part name (null for the default content)</param>
+ /// <param name="content">The content of the object item</param>
+ public void SetPartContent(string part, EvasObject content)
+ {
+ SetPartContent(part, content, false);
+ }
+
+ /// <summary>
+ /// Set a content of an object item
+ /// </summary>
+ /// <param name="part">The content part name (null for the default content)</param>
+ /// <param name="content">The content of the object item</param>
+ /// <param name="preserveOldContent">judge whether delete old content</param>
+ public void SetPartContent(string part, EvasObject content, bool preserveOldContent)
+ {
+ IntPtr oldContent = Interop.Elementary.elm_object_item_part_content_unset(Handle, part);
+ if (oldContent != IntPtr.Zero && !preserveOldContent)
+ {
+ Interop.Evas.evas_object_del(oldContent);
+ }
+ Interop.Elementary.elm_object_item_part_content_set(Handle, part, content);
+ _partContents[part ?? "__default__"] = content;
+ }
+
+ /// <summary>
+ /// Set a label of an object item
+ /// </summary>
+ /// <param name="part">The text part name (null for the default label)</param>
+ /// <param name="text">Text of the label</param>
+ public void SetPartText(string part, string text)
+ {
+ Interop.Elementary.elm_object_item_part_text_set(Handle, part, text);
+ }
+
+ /// <summary>
+ /// Gets a label of an object item
+ /// </summary>
+ /// <param name="part">The text part name (null for the default label)</param>
+ /// <returns></returns>
+ public string GetPartText(string part)
+ {
+ return Interop.Elementary.elm_object_item_part_text_get(Handle, part);
+ }
+
+ /// <summary>
+ /// Sets color of an object item
+ /// </summary>
+ /// <param name="part">The text part name (null for the default label)</param>
+ /// <param name="color">the color</param>
+ public void SetPartColor(string part, Color color)
+ {
+ Interop.Elementary.elm_object_item_color_class_color_set(Handle, part, color.R * color.A / 255,
+ color.G * color.A / 255,
+ color.B * color.A / 255,
+ color.A);
+ }
+
+ /// <summary>
+ /// Gets color of an object item
+ /// </summary>
+ /// <param name="part">The text part name (null for the default label)</param>
+ /// <returns>the color of object item</returns>
+ public Color GetPartColor(string part)
+ {
+ int r, g, b, a;
+ Interop.Elementary.elm_object_item_color_class_color_get(Handle, part, out r, out g, out b, out a);
+ return new Color((int)(r / (a / 255.0)), (int)(g / (a / 255.0)), (int)(b / (a / 255.0)), a);
+ }
+
+ /// <summary>
+ /// Deletes color of an object item
+ /// </summary>
+ /// <param name="part">The text part name</param>
+ public void DeletePartColor(string part)
+ {
+ Interop.Elementary.elm_object_item_color_class_del(Handle, part);
+ }
+
+ /// <summary>
+ /// Add a function for a signal emitted by object item edje.
+ /// </summary>
+ /// <param name="emission">The signal's name.</param>
+ /// <param name="source">The signal's source.</param>
+ /// <param name="func">The function to be executed when the signal is emitted.</param>
+ public void AddSignalHandler(string emission, string source, Func<string, string, bool> func)
+ {
+ if (emission != null && source != null && func != null)
+ {
+ var signalData = new SignalData(emission, source, func);
+ if (!_signalDatas.ContainsKey(signalData))
+ {
+ var signalCallback = new Interop.Elementary.Elm_Object_Item_Signal_Cb((d, o, e, s) =>
+ {
+ return func(e, s);
+ });
+ Interop.Elementary.elm_object_item_signal_callback_add(Handle, emission, source, signalCallback, IntPtr.Zero);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Remove a signal-triggered function from a object item edje object.
+ /// </summary>
+ /// <param name="emission">The signal's name.</param>
+ /// <param name="source">The signal's source.</param>
+ /// <param name="func">The function to be executed when the signal is emitted.</param>
+ public void RemoveSignalHandler(string emission, string source, Func<string, string, bool> func)
+ {
+ if (emission != null && source != null && func != null)
+ {
+ var signalData = new SignalData(emission, source, func);
+
+ Interop.Elementary.Elm_Object_Item_Signal_Cb signalCallback = null;
+ _signalDatas.TryGetValue(signalData, out signalCallback);
+
+ if (signalCallback != null)
+ {
+ Interop.Elementary.elm_object_item_signal_callback_del(Handle, emission, source, signalCallback);
+ _signalDatas.Remove(signalData);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Send a signal to the edje object of the widget item.
+ /// </summary>
+ /// <param name="emission">The signal's name.</param>
+ /// <param name="source">The signal's source.</param>
+ public void EmitSignal(string emission, string source)
+ {
+ Interop.Elementary.elm_object_item_signal_emit(Handle, emission, source);
+ }
+
+ /// <summary>
+ /// Gets the handle of object item
+ /// </summary>
+ /// <param name="obj">ItemObject</param>
+ public static implicit operator IntPtr(ItemObject obj)
+ {
+ if (obj == null)
+ return IntPtr.Zero;
+ return obj.Handle;
+ }
+
+ /// <summary>
+ /// OnInvalidate of object item
+ /// </summary>
+ protected virtual void OnInvalidate() { }
+
+ internal static ItemObject GetItemById(int id)
+ {
+ ItemObject value;
+ s_IdToItemTable.TryGetValue(id, out value);
+ return value;
+ }
+
+ internal static ItemObject GetItemByHandle(IntPtr handle)
+ {
+ ItemObject value;
+ s_HandleToItemTable.TryGetValue(handle, out value);
+ return value;
+ }
+
+ void DeleteCallbackHandler(IntPtr data, IntPtr obj, IntPtr info)
+ {
+ Deleted?.Invoke(this, EventArgs.Empty);
+ OnInvalidate();
+ if (s_IdToItemTable.ContainsKey(Id))
+ {
+ s_IdToItemTable.Remove(Id);
+ }
+ if (s_HandleToItemTable.ContainsKey(_handle))
+ {
+ s_HandleToItemTable.Remove(_handle);
+ }
+ _partContents.Clear();
+ _handle = IntPtr.Zero;
+ }
+
+ void UnsetDeleteCallback()
+ {
+ Interop.Elementary.elm_object_item_del_cb_set(Handle, null);
+ }
+
+ void SetDeleteCallback()
+ {
+ if (Handle != IntPtr.Zero)
+ Interop.Elementary.elm_object_item_del_cb_set(Handle, _deleteCallback);
+ }
+
+ static int GetNextId()
+ {
+ return s_globalId++;
+ }
+
+ class SignalData
+ {
+ public string Emission { get; set; }
+ public string Source { get; set; }
+ public Func<string, string, bool> Func { get; set; }
+
+ public SignalData(string emission, string source, Func<string, string, bool> func)
+ {
+ Emission = emission;
+ Source = source;
+ Func = func;
+ }
+
+ public override bool Equals(object obj)
+ {
+ SignalData s = obj as SignalData;
+ if (s == null)
+ {
+ return false;
+ }
+ return (Emission == s.Emission) && (Source == s.Source) && (Func == s.Func);
+ }
+
+ public override int GetHashCode()
+ {
+ int hashCode = Emission.GetHashCode();
+ hashCode ^= Source.GetHashCode();
+ hashCode ^= Func.GetHashCode();
+ return hashCode;
+ }
+ }
+
+ class ItemEvasObject : EvasObject
+ {
+ IntPtr _parent = IntPtr.Zero;
+
+ public ItemEvasObject(IntPtr parent) : base()
+ {
+ _parent = parent;
+ Realize(null);
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ return Interop.Elementary.elm_object_item_track(_parent);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/ItemObjectExtension.cs b/src/ElmSharp/ElmSharp/ItemObjectExtension.cs
new file mode 100755
index 0000000..ef8b609
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/ItemObjectExtension.cs
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The ItemObjectExtension is used to manage item object extension
+ /// </summary>
+ public static class ItemObjectExtension
+ {
+ /// <summary>
+ /// Grab high light of item object
+ /// </summary>
+ /// <param name="obj">the item object which is grabbed high light</param>
+ public static void GrabHighlight(this ItemObject obj)
+ {
+ Interop.Elementary.elm_atspi_component_highlight_grab(obj.Handle);
+ }
+
+ /// <summary>
+ /// Clear high light of item object
+ /// </summary>
+ /// <param name="obj">the item object which is cleared high light</param>
+ public static void ClearHighlight(this ItemObject obj)
+ {
+ Interop.Elementary.elm_atspi_component_highlight_clear(obj.Handle);
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/Label.cs b/src/ElmSharp/ElmSharp/Label.cs
new file mode 100755
index 0000000..3a0b012
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Label.cs
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+namespace ElmSharp
+{
+ /// <summary>
+ /// Label is a widget to display text, with simple html-like markup.
+ /// Inherits Layout
+ /// </summary>
+ public class Label : Layout
+ {
+ SmartEvent _slideCompleted;
+
+ /// <summary>
+ /// Creates and initializes a new instance of Label class.
+ /// </summary>
+ /// <param name="parent">The parent is a given container which will be attached by Label as a child. It's <see cref="EvasObject"/> type.</param>
+ public Label(EvasObject parent) : base(parent)
+ {
+ _slideCompleted = new SmartEvent(this, this.RealHandle, "slide,end");
+ _slideCompleted.On += (s, e) =>
+ {
+ SlideCompleted?.Invoke(this, EventArgs.Empty);
+ };
+ }
+
+ /// <summary>
+ /// SlideCompleted will be triggered when the slide is completed.
+ /// </summary>
+ public event EventHandler SlideCompleted;
+
+ /// <summary>
+ /// Sets or gets wrap width of the label.
+ /// </summary>
+ public int LineWrapWidth
+ {
+ get
+ {
+ return Interop.Elementary.elm_label_wrap_width_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_label_wrap_width_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the wrapping behavior of the label.
+ /// </summary>
+ public WrapType LineWrapType
+ {
+ get
+ {
+ return (WrapType)Interop.Elementary.elm_label_line_wrap_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_label_line_wrap_set(RealHandle, (int)value);
+ if (value != WrapType.None)
+ {
+ Interop.Evas.evas_object_size_hint_min_get(RealHandle, IntPtr.Zero, out int h);
+ Interop.Evas.evas_object_size_hint_min_set(RealHandle, 0, h);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the slide mode of the label widget.
+ /// </summary>
+ public LabelSlideMode SlideMode
+ {
+ get
+ {
+ return (LabelSlideMode)Interop.Elementary.elm_label_slide_mode_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_label_slide_mode_set(RealHandle, (int)value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the slide duration of the label.
+ /// </summary>
+ public double SlideDuration
+ {
+ get
+ {
+ return Interop.Elementary.elm_label_slide_duration_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_label_slide_duration_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the slide Speed of the label.
+ /// </summary>
+ /// <remarks>
+ /// The speed of the slide animation in px per seconds.
+ /// If you set the duration of the slide using elm_label_slide_duration_set() you cannot get the correct speed using this function until the label is actually rendered and resized.
+ /// </remarks>
+ /// <seealso cref="SlideDuration"/>
+ public double SlideSpeed
+ {
+ get
+ {
+ return Interop.Elementary.elm_label_slide_speed_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_label_slide_speed_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the ellipsis behavior of the label.
+ /// </summary>
+ public bool IsEllipsis
+ {
+ get
+ {
+ return Interop.Elementary.elm_label_ellipsis_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_label_ellipsis_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the style of the label text.
+ /// </summary>
+ /// <remarks>
+ /// APIs, elm_label_text_style_user_peek/pop/push, are internal APIs only in Tizen. Avalilable since Tizen_4.0.
+ /// </remarks>
+ ///
+ public string TextStyle
+ {
+ get
+ {
+ return Interop.Elementary.elm_label_text_style_user_peek(RealHandle);
+ }
+ set
+ {
+ if (string.IsNullOrEmpty(value))
+ {
+ Interop.Elementary.elm_label_text_style_user_pop(RealHandle);
+ }
+ else
+ {
+ Interop.Elementary.elm_label_text_style_user_push(RealHandle, value);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Start slide effect.
+ /// </summary>
+ public void PlaySlide()
+ {
+ Interop.Elementary.elm_label_slide_go(RealHandle);
+ }
+
+ /// <summary>
+ /// Sets the content at a part of a given container widget.
+ /// </summary>
+ /// <param name="parent">EvasObject</param>
+ /// <returns>The new object, otherwise null if it cannot be created</returns>
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ IntPtr handle = Interop.Elementary.elm_layout_add(parent.Handle);
+ Interop.Elementary.elm_layout_theme_set(handle, "layout", "elm_widget", "default");
+
+ RealHandle = Interop.Elementary.elm_label_add(handle);
+ Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
+
+ return handle;
+ }
+ }
+
+ /// <summary>
+ /// Enumeration for slide mode of a label widget
+ /// </summary>
+ public enum LabelSlideMode
+ {
+ /// <summary>
+ /// no slide effect
+ /// </summary>
+ None = 0,
+ /// <summary>
+ /// slide only if the label area is bigger than the text width length
+ /// </summary>
+ Auto,
+ /// <summary>
+ /// slide always
+ /// </summary>
+ Always
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/Layout.cs b/src/ElmSharp/ElmSharp/Layout.cs
new file mode 100644
index 0000000..9a45bbe
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Layout.cs
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// This is a container widget that takes a standard Edje design file and wraps it very thinly in a widget.
+ /// Inherits Widget
+ /// </summary>
+ public class Layout : Container
+ {
+ SmartEvent _languageChanged;
+ SmartEvent _themeChanged;
+
+ IntPtr _edjeHandle;
+
+ /// <summary>
+ /// Creates and initializes a new instance of Layout class.
+ /// </summary>
+ /// <param name="parent">The parent is a given container which will be attached by Layout as a child. It's <see cref="EvasObject"/> type.</param>
+ public Layout(EvasObject parent) : base(parent)
+ {
+ _languageChanged = new SmartEvent(this, this.RealHandle, "language,changed");
+ _languageChanged.On += (s, e) =>
+ {
+ LanguageChanged?.Invoke(this, EventArgs.Empty);
+ };
+
+ _themeChanged = new SmartEvent(this, this.RealHandle, "theme,changed");
+ _themeChanged.On += (s, e) =>
+ {
+ ThemeChanged?.Invoke(this, EventArgs.Empty);
+ };
+ }
+
+ /// <summary>
+ /// LanguageChanged will be triggered when the program's language is changed.
+ /// </summary>
+ public event EventHandler LanguageChanged;
+
+ /// <summary>
+ /// ThemeChanged will be triggered when the theme is changed.
+ /// </summary>
+ public event EventHandler ThemeChanged;
+
+ /// <summary>
+ /// Gets the edje layout.
+ /// </summary>
+ public EdjeObject EdjeObject
+ {
+ get
+ {
+ if (_edjeHandle == IntPtr.Zero)
+ _edjeHandle = Interop.Elementary.elm_layout_edje_get(RealHandle);
+ return new EdjeObject(_edjeHandle);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets accessibility state of texblock(text) parts in the layout object.
+ /// </summary>
+ public bool TextBlockAccessibility
+ {
+ get
+ {
+ return Interop.Elementary.elm_layout_edje_object_can_access_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_layout_edje_object_can_access_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Freezes the Elementary layout object.
+ /// This function puts all changes on hold.
+ /// Successive freezes will nest, requiring an equal number of thaws.
+ /// </summary>
+ /// <returns>The frozen state or 0 if the object is not frozen or on error.</returns>
+ public int Freeze()
+ {
+ return Interop.Elementary.elm_layout_freeze(RealHandle);
+ }
+
+ /// <summary>
+ /// Thaws the Elementary object.
+ /// If sucessives freezes were done, an equal number of thaws will be required.
+ /// </summary>
+ /// <returns>The frozen state or 0 if the object is not frozen or on error.</returns>
+ public int Thaw()
+ {
+ return Interop.Elementary.elm_layout_thaw(RealHandle);
+ }
+
+ /// <summary>
+ /// Eval sizing.
+ /// Manually forces a sizing re-evaluation.
+ /// This is useful when the minimum size required by the edje theme of this layout has changed.
+ /// The change on the minimum size required by the edje theme is not immediately reported to the elementary layout, so one needs to call this function in order to tell the widget (layout) that it needs to reevaluate its own size.
+ /// The minimum size of the theme is calculated based on minimum size of parts, the size of elements inside containers like box and table, etc.
+ /// All of this can change due to state changes, and that's when this function should be called.
+ /// </summary>
+ public void Resizing()
+ {
+ Interop.Elementary.elm_layout_sizing_eval(RealHandle);
+ }
+
+ /// <summary>
+ /// Request sizing reevaluation, restricted to current width and/or height.
+ /// Useful mostly when there are TEXTBLOCK parts defining the height of the object and nothing else restricting it to a minimum width.Calling this function will restrict the minimum size in the Edje calculation to whatever size it the layout has at the moment.
+ /// </summary>
+ /// <param name="width">Restrict minimum size ot the current width.</param>
+ /// <param name="height">Restrict minimum size ot the current height.</param>
+ public void Resizing(bool width, bool height)
+ {
+ Interop.Elementary.elm_layout_sizing_restricted_eval(RealHandle, width, height);
+ }
+
+ /// <summary>
+ /// Get the edje data from the given layout.
+ /// This function fetches data specified inside the edje theme of this layout.
+ /// This function return NULL if data is not found.
+ /// </summary>
+ /// <param name="key">The data key</param>
+ /// <returns>The data</returns>
+ public string GetEdjeData(string key)
+ {
+ return Interop.Elementary.elm_layout_data_get(RealHandle, key);
+ }
+
+ /// <summary>
+ /// Gets the text set in the given part.
+ /// </summary>
+ /// <param name="part">The TEXT part to retrieve the text off.</param>
+ /// <returns></returns>
+ public override string GetPartText(string part)
+ {
+ return Interop.Elementary.elm_layout_text_get(RealHandle, part);
+ }
+
+ /// <summary>
+ /// Sets the text set in the given part.
+ /// </summary>
+ /// <param name="part">The TEXT part to retrieve the text off.</param>
+ /// <param name="text">The text to set.</param>
+ /// <returns></returns>
+ public override bool SetPartText(string part, string text)
+ {
+ return Interop.Elementary.elm_layout_text_set(RealHandle, part, text);
+ }
+
+ /// <summary>
+ /// Append child to layout box part.
+ /// Once the object is appended, it will become child of the layout.
+ /// Its lifetime will be bound to the layout, whenever the layout dies the child will be deleted automatically.
+ /// </summary>
+ /// <param name="part">The part</param>
+ /// <param name="child">The Object to append</param>
+ /// <returns>Sucess is true</returns>
+ public bool BoxAppend(string part, EvasObject child)
+ {
+ AddChild(child);
+ return Interop.Elementary.elm_layout_box_append(RealHandle, part, child.Handle);
+ }
+
+ /// <summary>
+ /// Prepend child to layout box part.
+ /// Once the object is prepended, it will become child of the layout.
+ /// Its lifetime will be bound to the layout, whenever the layout dies the child will be deleted automatically.
+ /// </summary>
+ /// <param name="part">The part</param>
+ /// <param name="child">The Object to prepend</param>
+ /// <returns>Sucess is true</returns>
+ public bool BoxPrepend(string part, EvasObject child)
+ {
+ AddChild(child);
+ return Interop.Elementary.elm_layout_box_prepend(RealHandle, part, child.Handle);
+ }
+
+ /// <summary>
+ /// Remove a child of the given part box.
+ /// The object will be removed from the box part and its lifetime will not be handled by the layout anymore.
+ /// </summary>
+ /// <param name="part">The part</param>
+ /// <param name="child">The Object to remove</param>
+ /// <returns>Sucess is true</returns>
+ public bool BoxRemove(string part, EvasObject child)
+ {
+ RemoveChild(child);
+ return Interop.Elementary.elm_layout_box_remove(RealHandle, part, child.Handle) != null;
+ }
+
+ /// <summary>
+ /// Remove all children of the given part box.
+ /// The objects will be removed from the box part and their lifetime will not be handled by the layout anymore.
+ /// </summary>
+ /// <param name="part">The part</param>
+ /// <param name="clear">If true, then all objects will be deleted as well, otherwise they will just be removed and will be dangling on the canvas.</param>
+ /// <returns>Sucess is true</returns>
+ public bool BoxRemoveAll(string part, bool clear)
+ {
+ ClearChildren();
+ return Interop.Elementary.elm_layout_box_remove_all(RealHandle, part, clear);
+ }
+
+ /// <summary>
+ /// Insert child to layout box part at a given position.
+ /// Once the object is inserted, it will become child of the layout.
+ /// Its lifetime will be bound to the layout, whenever the layout dies the child will be deleted automatically.
+ /// </summary>
+ /// <param name="part">The part</param>
+ /// <param name="child">The child object to insert into box.</param>
+ /// <param name="position">The numeric position >=0 to insert the child.</param>
+ /// <returns>Sucess is true</returns>
+ public bool BoxInsertAt(string part, EvasObject child, uint position)
+ {
+ AddChild(child);
+ return Interop.Elementary.elm_layout_box_insert_at(RealHandle, part, child.Handle, position);
+ }
+
+ /// <summary>
+ /// Insert child to layout box part before a reference object.
+ /// Once the object is inserted, it will become child of the layout.
+ /// Its lifetime will be bound to the layout, whenever the layout dies the child will be deleted automatically.
+ /// </summary>
+ /// <param name="part"></param>
+ /// <param name="child">The child object to insert into box.</param>
+ /// <param name="reference">Another reference object to insert before in box.</param>
+ /// <returns>Sucess is true</returns>
+ public bool BoxInsertBefore(string part, EvasObject child, EvasObject reference)
+ {
+ AddChild(child);
+ return Interop.Elementary.elm_layout_box_insert_before(RealHandle, part, child.Handle, reference.Handle);
+ }
+
+ /// <summary>
+ /// Sets the layout content.
+ /// </summary>
+ /// <param name="part">The swallow part name in the edje file</param>
+ /// <param name="content">The child that will be added in this layout object.</param>
+ /// <returns>TRUE on success, FALSE otherwise</returns>
+ public override bool SetPartContent(string part, EvasObject content)
+ {
+ return SetPartContent(part, content, false);
+ }
+
+ /// <summary>
+ /// Sets the layout content.
+ /// </summary>
+ /// <param name="part">The name of particular part</param>
+ /// <param name="content">The content</param>
+ /// <param name="preserveOldContent">true, preserve old content will be unset. false, preserve old content will not be unset.</param>
+ /// <returns>TRUE on success, FALSE otherwise</returns>
+ public override bool SetPartContent(string part, EvasObject content, bool preserveOldContent)
+ {
+ if (preserveOldContent)
+ {
+ Interop.Elementary.elm_layout_content_unset(RealHandle, part);
+ }
+ UpdatePartContents(content, part);
+ return Interop.Elementary.elm_layout_content_set(RealHandle, part, content);
+ }
+
+ /// <summary>
+ /// Sets the edje group from the elementary theme that is used as a layout.
+ /// </summary>
+ /// <param name="klass">The class of the group</param>
+ /// <param name="group">The group</param>
+ /// <param name="style">The style to use</param>
+ public void SetTheme(string klass, string group, string style)
+ {
+ Interop.Elementary.elm_layout_theme_set(RealHandle, klass, group, style);
+ }
+
+ /// <summary>
+ /// Sets the file that is used as a layout.
+ /// </summary>
+ /// <param name="file">The path to the file (edj) that is used as a layout</param>
+ /// <param name="group">The group that the layout belongs to in the edje file</param>
+ public void SetFile(string file, string group)
+ {
+ Interop.Elementary.elm_layout_file_set(RealHandle, file, group);
+ }
+
+ /// <summary>
+ /// Sets the back ground color of layout
+ /// </summary>
+ public override Color BackgroundColor
+ {
+ set
+ {
+ if (value.IsDefault)
+ {
+ string part = ClassName.ToLower().Replace("elm_", "") + "/" + "bg";
+ EdjeObject.DeleteColorClass(part);
+ }
+ else
+ {
+ SetPartColor("bg", value);
+ }
+ _backgroundColor = value;
+ }
+ }
+
+ /// <summary>
+ /// Sets the vertical text alignment of layout's text part
+ /// </summary>
+ /// <remarks>
+ /// API, elm_layout_text_valign_set, is an internal API only in Tizen. Avalilable since Tizen_4.0.
+ /// </remarks>
+ public virtual void SetVerticalTextAlignment(string part, double valign)
+ {
+ Interop.Elementary.elm_layout_text_valign_set(RealHandle, part, valign);
+ }
+
+ /// <summary>
+ /// Gets the vertical text alignment of layout's text part
+ /// </summary>
+ /// <remarks>
+ /// API, elm_layout_text_valign_get, is internal API only in Tizen. Avalilable since Tizen_4.0.
+ /// </remarks>
+ public virtual double GetVerticalTextAlignment(string part)
+ {
+ return Interop.Elementary.elm_layout_text_valign_get(RealHandle, part);
+ }
+
+ /// <summary>
+ /// Sets the content at a part of a given container widget.
+ /// </summary>
+ /// <param name="parent">The parent is a given container which will be attached by Layout as a child. It's <see cref="EvasObject"/> type.</param>
+ /// <returns>The new object, otherwise null if it cannot be created</returns>
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ return Interop.Elementary.elm_layout_add(parent.Handle);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/List.cs b/src/ElmSharp/ElmSharp/List.cs
new file mode 100755
index 0000000..9a14f93
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/List.cs
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// Enumeration for setting list's resizing behavior, transverse axis scrolling and items cropping.
+ /// </summary>
+ public enum ListMode
+ {
+ /// <summary>
+ /// The list won't set any of its size hints to inform how a possible container should resize it.
+ /// Then, if it's not created as a "resize object", it might end with zeroed dimensions.
+ /// The list will respect the container's geometry and, if any of its items won't fit into its transverse axis, one won't be able to scroll it in that direction.
+ /// </summary>
+ Compress = 0,
+ /// <summary>
+ /// This is the same as Compress, with the exception that if any of its items won't fit into its transverse axis, one will be able to scroll it in that direction.
+ /// </summary>
+ Scroll,
+ /// <summary>
+ /// Sets a minimum size hint on the genlist object, so that containers may respect it (and resize itself to fit the child properly).
+ /// More specifically, a minimum size hint will be set for its transverse axis, so that the largest item in that direction fits well.
+ /// This is naturally bound by the list object's maximum size hints, set externally.
+ /// </summary>
+ Limit,
+ /// <summary>
+ /// Besides setting a minimum size on the transverse axis, just like on Limit, the list will set a minimum size on th longitudinal axis, trying to reserve space to all its children to be visible at a time.
+ /// This is naturally bound by the list object's maximum size hints, set externally.
+ /// </summary>
+ Expand
+ }
+
+ /// <summary>
+ /// It inherits System.EventArgs.
+ /// It contains Item which is <see cref="ListItem"/> type.
+ /// All events of List contain ListItemEventArgs as a parameter.
+ /// </summary>
+ public class ListItemEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Gets or sets List item. The return type is <see cref="ListItem"/>.
+ /// </summary>
+ public ListItem Item { get; set; }
+
+ internal static ListItemEventArgs CreateFromSmartEvent(IntPtr data, IntPtr obj, IntPtr info)
+ {
+ ListItem item = ItemObject.GetItemByHandle(info) as ListItem;
+ return new ListItemEventArgs() { Item = item };
+ }
+ }
+
+ /// <summary>
+ /// It inherits <see cref="Layout"/>.
+ /// The List is a widget that aims to display simple list item which has 2 icons and 1 text, and can be selected.
+ /// For more robust lists, <see cref="GenList"/> should probably be used.
+ /// </summary>
+ /// <seealso cref="GenList"/>
+ /// <seealso cref="GenGrid"/>
+ public class List : Layout
+ {
+ HashSet<ListItem> _children = new HashSet<ListItem>();
+ SmartEvent<ListItemEventArgs> _selected;
+ SmartEvent<ListItemEventArgs> _unselected;
+ SmartEvent<ListItemEventArgs> _doubleClicked;
+ SmartEvent<ListItemEventArgs> _longpressed;
+ SmartEvent<ListItemEventArgs> _activated;
+
+ /// <summary>
+ /// Creates and initializes a new instance of the List class.
+ /// </summary>
+ /// <param name="parent">The parent is a given container which will be attached by List as a child. It's <see cref="EvasObject"/> type.</param>
+ public List(EvasObject parent) : base(parent)
+ {
+ _selected = new SmartEvent<ListItemEventArgs>(this, this.RealHandle, "selected", ListItemEventArgs.CreateFromSmartEvent);
+ _unselected = new SmartEvent<ListItemEventArgs>(this, this.RealHandle, "unselected", ListItemEventArgs.CreateFromSmartEvent);
+ _doubleClicked = new SmartEvent<ListItemEventArgs>(this, this.RealHandle, "clicked,double", ListItemEventArgs.CreateFromSmartEvent);
+ _longpressed = new SmartEvent<ListItemEventArgs>(this, this.RealHandle, "longpressed", ListItemEventArgs.CreateFromSmartEvent);
+ _activated = new SmartEvent<ListItemEventArgs>(this, this.RealHandle, "activated", ListItemEventArgs.CreateFromSmartEvent);
+ _selected.On += (s, e) => { ItemSelected?.Invoke(this, e); };
+ _unselected.On += (s, e) => { ItemUnselected?.Invoke(this, e); };
+ _doubleClicked.On += (s, e) => { ItemDoubleClicked?.Invoke(this, e); };
+ _longpressed.On += (s, e) => { ItemLongPressed?.Invoke(this, e); };
+ _activated.On += (s, e) => { ItemActivated?.Invoke(this, e); };
+ }
+
+ /// <summary>
+ /// Gets or sets which mode to use for the list.
+ /// </summary>
+ public ListMode Mode
+ {
+ get
+ {
+ return (ListMode)Interop.Elementary.elm_list_mode_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_list_mode_set(RealHandle, (Interop.Elementary.Elm_List_Mode)value);
+ }
+ }
+
+ /// <summary>
+ /// Gets the selected item.
+ /// </summary>
+ public ListItem SelectedItem
+ {
+ get
+ {
+ IntPtr item = Interop.Elementary.elm_list_selected_item_get(RealHandle);
+ return ItemObject.GetItemByHandle(item) as ListItem;
+ }
+ }
+
+ /// <summary>
+ /// ItemSelected is raised when a new list item is selected.
+ /// </summary>
+ public event EventHandler<ListItemEventArgs> ItemSelected;
+
+ /// <summary>
+ /// ItemUnselected is raised when the list item is Unselected.
+ /// </summary>
+ public event EventHandler<ListItemEventArgs> ItemUnselected;
+
+ /// <summary>
+ /// ItemDoubleClicked is raised when a new list item is double clicked.
+ /// </summary>
+ public event EventHandler<ListItemEventArgs> ItemDoubleClicked;
+
+ /// <summary>
+ /// ItemLongPressed is raised when a list item is pressed for a certain amount of time. By default it's 1 second.
+ /// </summary>
+ public event EventHandler<ListItemEventArgs> ItemLongPressed;
+
+ /// <summary>
+ /// ItemActivated is raised when a new list item is double clicked or pressed (enter|return|spacebar).
+ /// </summary>
+ public event EventHandler<ListItemEventArgs> ItemActivated;
+
+ /// <summary>
+ /// Starts the list.
+ /// Call before running <see cref="EvasObject.Show"/> on the list object.
+ /// If not called, it won't display the list properly.
+ /// </summary>
+ public void Update()
+ {
+ Interop.Elementary.elm_list_go(RealHandle);
+ }
+
+ /// <summary>
+ /// Appends a new item with a text to the end of a given list widget.
+ /// </summary>
+ /// <param name="label">The text for the item.</param>
+ /// <returns>Return a new added list item that contains a text.</returns>
+ /// <seealso cref="ListItem"/>
+ public ListItem Append(string label)
+ {
+ return Append(label, null, null);
+ }
+
+ /// <summary>
+ /// Appends a new item with a text and 2 icons to the end of a given list widget.
+ /// </summary>
+ /// <param name="label">The text for the item.</param>
+ /// <param name="leftIcon">The left icon for the item.</param>
+ /// <param name="rightIcon">The right icon for the item.</param>
+ /// <returns>Return a new added list item that contains a text and 2 icons.</returns>
+ /// <seealso cref="ListItem"/>
+ public ListItem Append(string label, EvasObject leftIcon, EvasObject rightIcon)
+ {
+ ListItem item = new ListItem(label, leftIcon, rightIcon);
+ item.Handle = Interop.Elementary.elm_list_item_append(RealHandle, label, leftIcon, rightIcon, null, (IntPtr)item.Id);
+ AddInternal(item);
+ return item;
+ }
+
+ /// <summary>
+ /// Prepends a new item with a text to the beginning of a given list widget.
+ /// </summary>
+ /// <param name="label">The text for the item.</param>
+ /// <returns>Return a new added list item that contains a text.</returns>
+ public ListItem Prepend(string label)
+ {
+ return Prepend(label, null, null);
+ }
+
+ /// <summary>
+ /// Prepends a new item with a text and 2 icons to the beginning of a given list widget.
+ /// </summary>
+ /// <param name="label">The text for the item.</param>
+ /// <param name="leftIcon">The left icon for the item.</param>
+ /// <param name="rigthIcon">The right icon for the item.</param>
+ /// <returns>Return a new added list item that contains a text and 2 icons.</returns>
+ public ListItem Prepend(string label, EvasObject leftIcon, EvasObject rigthIcon)
+ {
+ ListItem item = new ListItem(label, leftIcon, rigthIcon);
+ item.Handle = Interop.Elementary.elm_list_item_prepend(RealHandle, label, leftIcon, rigthIcon, null, (IntPtr)item.Id);
+ AddInternal(item);
+ return item;
+ }
+
+ /// <summary>
+ /// Removes all items from a given list widget.
+ /// To delete just one item, use <see cref="ItemObject.Delete"/>.
+ /// </summary>
+ public void Clear()
+ {
+ Interop.Elementary.elm_list_clear(RealHandle);
+ foreach (var item in _children)
+ {
+ item.Deleted -= Item_Deleted;
+ }
+ _children.Clear();
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ IntPtr handle = Interop.Elementary.elm_layout_add(parent.Handle);
+ Interop.Elementary.elm_layout_theme_set(handle, "layout", "elm_widget", "default");
+
+ RealHandle = Interop.Elementary.elm_list_add(handle);
+ Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
+
+ return handle;
+ }
+
+ void AddInternal(ListItem item)
+ {
+ _children.Add(item);
+ item.Deleted += Item_Deleted;
+ }
+
+ void Item_Deleted(object sender, EventArgs e)
+ {
+ _children.Remove((ListItem)sender);
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/ListItem.cs b/src/ElmSharp/ElmSharp/ListItem.cs
new file mode 100644
index 0000000..09354b1
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/ListItem.cs
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// It inherits <see cref="ItemObject"/>.
+ /// A instance to the list item added.
+ /// It contains Text, LeftIcon and RightIcon properties to show a list item which is given.
+ /// </summary>
+ public class ListItem : ItemObject
+ {
+ internal ListItem(string text, EvasObject leftIcon, EvasObject rightIcon) : base(IntPtr.Zero)
+ {
+ Text = text;
+ LeftIcon = leftIcon;
+ RightIcon = rightIcon;
+ }
+
+ /// <summary>
+ /// Gets the text for the list item.
+ /// </summary>
+ public string Text { get; internal set; }
+
+ /// <summary>
+ /// Gets the left icon for the list item.
+ /// </summary>
+ public EvasObject LeftIcon { get; internal set; }
+
+ /// <summary>
+ /// Gets the right icon for the list item.
+ /// </summary>
+ public EvasObject RightIcon { get; internal set; }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/MultiButtonEntry.cs b/src/ElmSharp/ElmSharp/MultiButtonEntry.cs
new file mode 100755
index 0000000..21d9a54
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/MultiButtonEntry.cs
@@ -0,0 +1,407 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// It inherits <see cref="Layout"/>.
+ /// The MultiButtonEntry is a widget letting an user enter text and each chunk of text managed as a set of buttons.
+ /// Each text button is inserted by pressing the "return" key. If there is no space in the current row, a new button is added to the next row.
+ /// When a text button is pressed, it will become focused. Backspace removes the focus. When the multi-button entry loses focus, items longer than one line are shrunk to one line.
+ /// The typical use case of multi-button entry is composing emails/messages to a group of addresses, each of which is an item that can be clicked for further actions.
+ /// </summary>
+ public class MultiButtonEntry : Layout
+ {
+ HashSet<MultiButtonEntryItem> _children = new HashSet<MultiButtonEntryItem>();
+ List<Func<string, bool>> _filters = new List<Func<string, bool>>();
+ Func<int, string> _formatFunc = null;
+ Entry _entry = null;
+
+ Interop.Elementary.MultiButtonEntryItemFilterCallback _filterCallback;
+ Interop.Elementary.MultiButtonEntryFormatCallback _formatCallback;
+
+ SmartEvent _clicked;
+ SmartEvent _expanded;
+ SmartEvent _contracted;
+ SmartEvent _expandedStateChanged;
+ SmartEvent<MultiButtonEntryItemEventArgs> _itemSelected;
+ SmartEvent<MultiButtonEntryItemEventArgs> _itemClicked;
+ SmartEvent<MultiButtonEntryItemEventArgs> _itemLongPressed;
+ SmartEvent<MultiButtonEntryItemEventArgs> _itemAdded;
+
+ /// <summary>
+ /// Creates and initializes a new instance of the MultiButtonEntry class.
+ /// </summary>
+ /// <param name="parent">The parent is a given container which will be attached by MultiButtonEntry as a child. It's <see cref="EvasObject"/> type.</param>
+ public MultiButtonEntry(EvasObject parent) : base(parent)
+ {
+ _clicked = new SmartEvent(this, "clicked");
+ _expanded = new SmartEvent(this, "expanded");
+ _contracted = new SmartEvent(this, "contracted");
+ _expandedStateChanged = new SmartEvent(this, "expand,state,changed");
+
+ _itemSelected = new SmartEvent<MultiButtonEntryItemEventArgs>(this, "item,selected", MultiButtonEntryItemEventArgs.CreateFromSmartEvent);
+ _itemClicked = new SmartEvent<MultiButtonEntryItemEventArgs>(this, "item,clicked", MultiButtonEntryItemEventArgs.CreateFromSmartEvent);
+ _itemLongPressed = new SmartEvent<MultiButtonEntryItemEventArgs>(this, "item,longpressed", MultiButtonEntryItemEventArgs.CreateFromSmartEvent);
+ _itemAdded = new SmartEvent<MultiButtonEntryItemEventArgs>(this, "item,added", MultiButtonEntryItemEventArgs.CreateAndAddFromSmartEvent);
+
+ _filterCallback = new Interop.Elementary.MultiButtonEntryItemFilterCallback(FilterCallbackHandler);
+ _formatCallback = new Interop.Elementary.MultiButtonEntryFormatCallback(FormatCallbackHandler);
+
+ _clicked.On += (sender, e) => Clicked?.Invoke(this, EventArgs.Empty);
+ _expanded.On += (sender, e) => Expanded?.Invoke(this, EventArgs.Empty);
+ _contracted.On += (sender, e) => Contracted?.Invoke(this, EventArgs.Empty);
+ _expandedStateChanged.On += (sender, e) => ExpandedStateChanged?.Invoke(this, EventArgs.Empty);
+
+ _itemSelected.On += (sender, e) => { ItemSelected?.Invoke(this, e); };
+ _itemClicked.On += (sender, e) => { ItemClicked?.Invoke(this, e); };
+ _itemLongPressed.On += (sender, e) => { ItemLongPressed?.Invoke(this, e); };
+ _itemAdded.On += OnItemAdded;
+ }
+
+ /// <summary>
+ /// Clicked is raised when a MultiButtonEntry is clicked.
+ /// </summary>
+ public event EventHandler Clicked;
+
+ /// <summary>
+ /// Expanded is raised when a MultiButtonEntry is expanded.
+ /// </summary>
+ public event EventHandler Expanded;
+
+ /// <summary>
+ /// Contracted is raised when a MultiButtonEntry is contracted.
+ /// </summary>
+ public event EventHandler Contracted;
+
+ /// <summary>
+ /// ExpandedStateChanged is raised when shrink mode state of MultiButtonEntry is changed.
+ /// </summary>
+ public event EventHandler ExpandedStateChanged;
+
+ /// <summary>
+ /// ItemSelected is raised when an item is selected by api, user interaction, and etc.
+ /// This is also raised when a user press back space while cursor is on the first field of entry.
+ /// </summary>
+ public event EventHandler<MultiButtonEntryItemEventArgs> ItemSelected;
+
+ /// <summary>
+ /// ItemClicked is raised when an item is clicked by user interaction.
+ /// </summary>
+ public event EventHandler<MultiButtonEntryItemEventArgs> ItemClicked;
+
+ /// <summary>
+ /// ItemLongPressed is raised when MultiButtonEntry item is pressed for a long time.
+ /// </summary>
+ public event EventHandler<MultiButtonEntryItemEventArgs> ItemLongPressed;
+
+ /// <summary>
+ /// ItemAdded is raised when a new MultiButtonEntry item is added.
+ /// </summary>
+ public event EventHandler<MultiButtonEntryItemEventArgs> ItemAdded;
+
+ /// <summary>
+ /// ItemDeleted is raised when a MultiButtonEntry item is deleted.
+ /// </summary>
+ public event EventHandler<MultiButtonEntryItemEventArgs> ItemDeleted;
+
+ /// <summary>
+ /// Gets the selected item in the multibuttonentry.
+ /// </summary>
+ public MultiButtonEntryItem SelectedItem
+ {
+ get
+ {
+ IntPtr handle = Interop.Elementary.elm_multibuttonentry_selected_item_get(RealHandle);
+ return ItemObject.GetItemByHandle(handle) as MultiButtonEntryItem;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets whether the multibuttonentry is editable or not.
+ /// </summary>
+ public bool IsEditable
+ {
+ get
+ {
+ return Interop.Elementary.elm_multibuttonentry_editable_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_multibuttonentry_editable_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the multibuttonentry to expanded state.
+ /// If true, expanded state.
+ /// If false, single line state.
+ /// </summary>
+ public bool IsExpanded
+ {
+ get
+ {
+ return Interop.Elementary.elm_multibuttonentry_expanded_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_multibuttonentry_expanded_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets the first item in the multibuttonentry.
+ /// </summary>
+ public MultiButtonEntryItem FirstItem
+ {
+ get
+ {
+ IntPtr handle = Interop.Elementary.elm_multibuttonentry_first_item_get(RealHandle);
+ return ItemObject.GetItemByHandle(handle) as MultiButtonEntryItem;
+ }
+ }
+
+ /// <summary>
+ /// Gets the last item in the multibuttonentry.
+ /// </summary>
+ public MultiButtonEntryItem LastItem
+ {
+ get
+ {
+ IntPtr handle = Interop.Elementary.elm_multibuttonentry_last_item_get(RealHandle);
+ return ItemObject.GetItemByHandle(handle) as MultiButtonEntryItem;
+ }
+ }
+
+ /// <summary>
+ /// Gets the entry object int the multibuttonentry.
+ /// </summary>
+ public Entry Entry
+ {
+ get
+ {
+ if (_entry == null)
+ {
+ _entry = new EntryInner(this);
+ }
+
+ return _entry;
+ }
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ return Interop.Elementary.elm_multibuttonentry_add(parent.Handle);
+ }
+
+ /// <summary>
+ /// Append a new item to the multibuttonentry.
+ /// </summary>
+ /// <param name="label">The label of new item.</param>
+ /// <returns>A MultiButtonEntryItem to the item added.</returns>
+ public MultiButtonEntryItem Append(string label)
+ {
+ var handle = Interop.Elementary.elm_multibuttonentry_item_append(RealHandle, label, null, IntPtr.Zero);
+ MultiButtonEntryItem item = ItemObject.GetItemByHandle(handle) as MultiButtonEntryItem;
+ return item;
+ }
+
+ /// <summary>
+ /// Prepend a new item to the multibuttonentry.
+ /// </summary>
+ /// <param name="label">The label of new item.</param>
+ /// <returns>A MultiButtonEntryItem to the item added.</returns>
+ public MultiButtonEntryItem Prepend(string label)
+ {
+ var handle = Interop.Elementary.elm_multibuttonentry_item_prepend(RealHandle, label, null, IntPtr.Zero);
+ MultiButtonEntryItem item = ItemObject.GetItemByHandle(handle) as MultiButtonEntryItem;
+ return item;
+ }
+
+ /// <summary>
+ /// Add a new item to the multibuttonentry before the indicated object reference.
+ /// </summary>
+ /// <param name="before">The item before which to add it.</param>
+ /// <param name="label">The label of new item.</param>
+ /// <returns>A MultiButtonEntryItem to the item added.</returns>
+ public MultiButtonEntryItem InsertBefore(MultiButtonEntryItem before, string label)
+ {
+ var handle = Interop.Elementary.elm_multibuttonentry_item_insert_before(RealHandle, before.Handle, label, null, IntPtr.Zero);
+ MultiButtonEntryItem item = ItemObject.GetItemByHandle(handle) as MultiButtonEntryItem;
+ return item;
+ }
+
+ /// <summary>
+ /// Add a new item to the multibuttonentry after the indicated object.
+ /// </summary>
+ /// <param name="after">The item after which to add it.</param>
+ /// <param name="label">The label of new item.</param>
+ /// <returns>A MultiButtonEntryItem to the item added.</returns>
+ public MultiButtonEntryItem InsertAfter(MultiButtonEntryItem after, string label)
+ {
+ var handle = Interop.Elementary.elm_multibuttonentry_item_insert_after(RealHandle, after.Handle, label, null, IntPtr.Zero);
+ MultiButtonEntryItem item = ItemObject.GetItemByHandle(handle) as MultiButtonEntryItem;
+ return item;
+ }
+
+ /// <summary>
+ /// Remove all items in the multibuttonentry.
+ /// </summary>
+ public void Clear()
+ {
+ Interop.Elementary.elm_multibuttonentry_clear(RealHandle);
+ foreach (var item in _children)
+ {
+ item.Deleted -= Item_Deleted;
+ }
+ _children.Clear();
+ }
+
+ /// <summary>
+ /// Append an item filter function for text inserted in the Multibuttonentry.
+ /// </summary>
+ /// <param name="func">The function to use as item filter.</param>
+ public void AppendFilter(Func<string, bool> func)
+ {
+ _filters.Add(func);
+ if (_filters.Count == 1)
+ {
+ Interop.Elementary.elm_multibuttonentry_item_filter_append(RealHandle, _filterCallback, IntPtr.Zero);
+ }
+ }
+
+ /// <summary>
+ /// Prepend a filter function for text inserted in the Multibuttonentry.
+ /// </summary>
+ /// <param name="func">The function to use as text filter.</param>
+ public void PrependFilter(Func<string, bool> func)
+ {
+ _filters.Insert(0, func);
+ if (_filters.Count == 1)
+ {
+ Interop.Elementary.elm_multibuttonentry_item_filter_prepend(RealHandle, _filterCallback, IntPtr.Zero);
+ }
+ }
+
+ /// <summary>
+ /// Remove a filter from the list.
+ /// </summary>
+ /// <param name="func">The filter function to remove.</param>
+ public void RemoveFilter(Func<string, bool> func)
+ {
+ _filters.Remove(func);
+ if (_filters.Count == 0)
+ {
+ Interop.Elementary.elm_multibuttonentry_item_filter_remove(RealHandle, _filterCallback, IntPtr.Zero);
+ }
+ }
+
+ /// <summary>
+ /// Set a function to format the string that will be used to display the hidden items counter.
+ /// If func is NULL, the default format will be used, which is "+ 'the hidden items counter'".
+ /// </summary>
+ /// <param name="func">The function to return string to show</param>
+ public void SetFormatCallback(Func<int, string> func)
+ {
+ if (func == null)
+ {
+ Interop.Elementary.elm_multibuttonentry_format_function_set(RealHandle, null, IntPtr.Zero);
+ }
+ else
+ {
+ _formatFunc = func;
+ Interop.Elementary.elm_multibuttonentry_format_function_set(RealHandle, _formatCallback, IntPtr.Zero);
+ }
+ }
+
+ string FormatCallbackHandler(int count, IntPtr data)
+ {
+ return _formatFunc(count);
+ }
+
+ void Item_Deleted(object sender, EventArgs e)
+ {
+ var removed = sender as MultiButtonEntryItem;
+ _children.Remove(removed);
+
+ // "item,deleted" event will be called after removing the item from ItemObject has been done.
+ // ItemObject will no longer have the item instance that is deleted after this.
+ // So, ItemDelete event with the removed item should be triggered here.
+ ItemDeleted?.Invoke(this, new MultiButtonEntryItemEventArgs() { Item = removed });
+ }
+
+ void OnItemAdded(object sender, MultiButtonEntryItemEventArgs e)
+ {
+ _children.Add(e.Item);
+ e.Item.Deleted += Item_Deleted;
+ ItemAdded?.Invoke(this, e);
+ }
+
+ bool FilterCallbackHandler(IntPtr obj, string label, IntPtr itemData, IntPtr data)
+ {
+ foreach (var func in _filters)
+ {
+ if (!func(label))
+ return false;
+ }
+ return true;
+ }
+
+ internal class EntryInner : Entry
+ {
+ internal EntryInner(EvasObject parent) : base(parent)
+ {
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ return Interop.Elementary.elm_multibuttonentry_entry_get(parent.Handle);
+ }
+ }
+ }
+
+ /// <summary>
+ /// It inherits System.EventArgs.
+ /// The MultiButtonEntryItemEventArgs is a argument for all events of MultiButtonEntry.
+ /// It contains Item which is <see cref="MultiButtonEntryItem"/> type.
+ /// </summary>
+ public class MultiButtonEntryItemEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Gets or sets MultiButtonEntryItem item. The return type is <see cref="MultiButtonEntryItem"/>.
+ /// </summary>
+ public MultiButtonEntryItem Item { get; set; }
+
+ internal static MultiButtonEntryItemEventArgs CreateFromSmartEvent(IntPtr data, IntPtr obj, IntPtr info)
+ {
+ MultiButtonEntryItem item = ItemObject.GetItemByHandle(info) as MultiButtonEntryItem;
+ return new MultiButtonEntryItemEventArgs() { Item = item };
+ }
+
+ internal static MultiButtonEntryItemEventArgs CreateAndAddFromSmartEvent(IntPtr data, IntPtr obj, IntPtr info)
+ {
+ // Item can be added throught calling Append method and user input.
+ // And since "item.added" event will be called before xx_append() method returns,
+ // ItemObject does NOT have an item that contains handle matched to "info" at this time.
+ // So, item should be created and added internally here.
+ MultiButtonEntryItem item = new MultiButtonEntryItem(info);
+ return new MultiButtonEntryItemEventArgs() { Item = item };
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/MultiButtonEntryItem.cs b/src/ElmSharp/ElmSharp/MultiButtonEntryItem.cs
new file mode 100755
index 0000000..583e1ee
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/MultiButtonEntryItem.cs
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// It inherits <see cref="ItemObject"/>.
+ /// MutltiButtonEntryItem is a item which is added to MultiButtonEntry.
+ /// It contains Next and Prev properties to get next and previous item.
+ /// </summary>
+ public class MultiButtonEntryItem : ItemObject
+ {
+ /// <summary>
+ /// Creates and initializes a new instance of the MultiButtonEntryItem class.
+ /// </summary>
+ /// <param name="text">The text of MultiButtonEntryItem's Label name.</param>
+ public MultiButtonEntryItem(string text) : base(IntPtr.Zero)
+ {
+ Label = text;
+ }
+
+ internal MultiButtonEntryItem(IntPtr handle) : base(handle)
+ {
+ Label = Interop.Elementary.elm_object_item_part_text_get(handle, null);
+ }
+
+ /// <summary>
+ /// Gets the label of this item.
+ /// </summary>
+ public string Label { get; private set; }
+
+ /// <summary>
+ /// Gets or sets the selected state of an item.
+ /// </summary>
+ public bool IsSelected
+ {
+ get
+ {
+ return Interop.Elementary.elm_multibuttonentry_item_selected_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_multibuttonentry_item_selected_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Get the next item in the multibuttonentry.
+ /// </summary>
+ public MultiButtonEntryItem Next
+ {
+ get
+ {
+ var next = Interop.Elementary.elm_multibuttonentry_item_next_get(Handle);
+ return ItemObject.GetItemByHandle(next) as MultiButtonEntryItem;
+ }
+ }
+
+ /// <summary>
+ /// Get the previous item in the multibuttonentry.
+ /// </summary>
+ public MultiButtonEntryItem Prev
+ {
+ get
+ {
+ var prev = Interop.Elementary.elm_multibuttonentry_item_prev_get(Handle);
+ return ItemObject.GetItemByHandle(prev) as MultiButtonEntryItem;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/NaviItem.cs b/src/ElmSharp/ElmSharp/NaviItem.cs
new file mode 100755
index 0000000..f7da156
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/NaviItem.cs
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The NaviItem is a widget to contain the contents to show in Naviframe.
+ /// Inherits ItemObject
+ /// </summary>
+ public class NaviItem : ItemObject
+ {
+ EvasObject _content;
+ bool _isPopped;
+ Color _barBackgroundColor = Color.Default;
+ Interop.Elementary.Elm_Naviframe_Item_Pop_Cb _popped;
+
+ NaviItem(IntPtr handle, EvasObject content) : base(handle)
+ {
+ _isPopped = false;
+ _content = content;
+ _popped = (d, i) =>
+ {
+ _isPopped = true;
+ Popped?.Invoke(this, EventArgs.Empty);
+ return true;
+ };
+ Interop.Elementary.elm_naviframe_item_pop_cb_set(handle, _popped, IntPtr.Zero);
+ }
+
+ /// <summary>
+ /// Popped will be triggered when NaviItem is removed.
+ /// </summary>
+ public event EventHandler Popped;
+
+ /// <summary>
+ /// Gets the content object. The name of content part is "elm.swallow.content".
+ /// </summary>
+ public EvasObject Content
+ {
+ get { return _content; }
+ }
+
+ /// <summary>
+ /// Sets or gets a value whether title area is enabled or not.
+ /// </summary>
+ public bool TitleBarVisible
+ {
+ get
+ {
+ return Interop.Elementary.elm_naviframe_item_title_enabled_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_naviframe_item_title_enabled_set(Handle, value, false);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the title bar background color
+ /// </summary>
+ public Color TitleBarBackgroundColor
+ {
+ get
+ {
+ return _barBackgroundColor;
+ }
+ set
+ {
+ if (value.IsDefault)
+ {
+ Interop.Elementary.elm_object_item_color_class_del(Handle, "bg_title");
+ }
+ else
+ {
+ SetPartColor("bg_title", value);
+ _barBackgroundColor = value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets an item style.
+ /// </summary>
+ public string Style
+ {
+ get
+ {
+ return Interop.Elementary.elm_naviframe_item_style_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_naviframe_item_style_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Invalidate the EventArgs if _isPopped is false.
+ /// The method should be overridden in children class.
+ /// </summary>
+ protected override void OnInvalidate()
+ {
+ if (!_isPopped)
+ Popped?.Invoke(this, EventArgs.Empty);
+ }
+
+ internal static NaviItem FromNativeHandle(IntPtr handle, EvasObject content)
+ {
+ return new NaviItem(handle, content);
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/Naviframe.cs b/src/ElmSharp/ElmSharp/Naviframe.cs
new file mode 100755
index 0000000..8d31756
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Naviframe.cs
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The NaviframeEventArgs is a event args class for navi frame.
+ /// Inherits EventArgs
+ /// </summary>
+ public class NaviframeEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Sets or gets the content object. The name of content part is "elm.swallow.content".
+ /// </summary>
+ public EvasObject Content { get; set; }
+ }
+ /// <summary>
+ /// Naviframe is a widget to stands for navigation frame. It's a views manager for applications.
+ /// Inherits Widget
+ /// </summary>
+ public class Naviframe : Widget
+ {
+ SmartEvent _transitionFinished;
+ readonly List<NaviItem> _itemStack = new List<NaviItem>();
+
+ /// <summary>
+ /// Creates and initializes a new instance of Naviframe class.
+ /// </summary>
+ /// <param name="parent">The parent is a given container which will be attached by Naviframe as a child. It's <see cref="EvasObject"/> type.</param>
+ public Naviframe(EvasObject parent) : base(parent)
+ {
+ _transitionFinished = new SmartEvent(this, this.RealHandle, "transition,finished");
+ _transitionFinished.On += (s, e) => AnimationFinished?.Invoke(this, EventArgs.Empty);
+ }
+
+ /// <summary>
+ /// Popped will be triggered when NaviItem is removed.
+ /// </summary>
+ /// <remarks>
+ /// It is always called when NaviItem was removed.
+ /// (even if removed by NaviItem.Delete())
+ /// This event will be invoked in progress of Pop/Delete operation.
+ /// After called Popped event, Pop/Delete method will be returned
+ /// </remarks>
+ public event EventHandler<NaviframeEventArgs> Popped;
+
+ /// <summary>
+ /// AnimationFinished will be triggered when animation is finished.
+ /// </summary>
+ public event EventHandler AnimationFinished;
+
+ /// <summary>
+ /// Gets the list of navi item
+ /// </summary>
+ public IReadOnlyList<NaviItem> NavigationStack
+ {
+ get { return _itemStack; }
+ }
+
+ /// <summary>
+ /// Sets or gets the the preserve content objects when items are popped.
+ /// </summary>
+ public bool PreserveContentOnPop
+ {
+ get
+ {
+ return Interop.Elementary.elm_naviframe_content_preserve_on_pop_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_naviframe_content_preserve_on_pop_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets whether the default back button is enabled
+ /// </summary>
+ public bool DefaultBackButtonEnabled
+ {
+ get
+ {
+ return Interop.Elementary.elm_naviframe_prev_btn_auto_pushed_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_naviframe_prev_btn_auto_pushed_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Push a new item to the top of the naviframe stack and show it.
+ /// The title and style are null.
+ /// </summary>
+ /// <param name="content">The main content object. The name of content part is "elm.swallow.content".</param>
+ /// <returns>The created item or null upon failure.</returns>
+ public NaviItem Push(EvasObject content)
+ {
+ return Push(content, null);
+ }
+
+ /// <summary>
+ /// Push a new item to the top of the naviframe stack and show it.
+ /// The style are null.
+ /// </summary>
+ /// <param name="content">The main content object. The name of content part is "elm.swallow.content".</param>
+ /// <param name="title">The current item title. null would be default.</param>
+ /// <returns></returns>
+ public NaviItem Push(EvasObject content, string title)
+ {
+ return Push(content, title, null);
+ }
+
+ /// <summary>
+ /// Push a new item to the top of the naviframe stack and show it.
+ /// </summary>
+ /// <param name="content">The main content object. The name of content part is "elm.swallow.content".</param>
+ /// <param name="title">The current item title. null would be default.</param>
+ /// <param name="style">The current item style name. null would be default.</param>
+ /// <returns>The created item or null upon failure.</returns>
+ public NaviItem Push(EvasObject content, string title, string style)
+ {
+ IntPtr item = Interop.Elementary.elm_naviframe_item_push(RealHandle, title, IntPtr.Zero, IntPtr.Zero, content.Handle, style);
+ NaviItem naviItem = NaviItem.FromNativeHandle(item, content);
+ _itemStack.Add(naviItem);
+ naviItem.Popped += ItemPoppedHandler;
+ return naviItem;
+ }
+
+ /// <summary>
+ /// Insert a new item into the naviframe before item.
+ /// The title is "" and the style is null.
+ /// </summary>
+ /// <param name="before">The item which the new item is inserted before.</param>
+ /// <param name="content">The main content object. The name of content part is "elm.swallow.content".</param>
+ /// <returns>The created item or null upon failure.</returns>
+ public NaviItem InsertBefore(NaviItem before, EvasObject content)
+ {
+ return InsertBefore(before, content, "");
+ }
+
+ /// <summary>
+ /// Insert a new item into the naviframe before item.
+ /// The style is null.
+ /// </summary>
+ /// <param name="before">The item which the new item is inserted before.</param>
+ /// <param name="content">The main content object. The name of content part is "elm.swallow.content".</param>
+ /// <param name="title">The current item title. null would be default.</param>
+ /// <returns>The created item or null upon failure.</returns>
+ public NaviItem InsertBefore(NaviItem before, EvasObject content, string title)
+ {
+ return InsertBefore(before, content, title, null);
+ }
+
+ /// <summary>
+ /// Insert a new item into the naviframe before item.
+ /// </summary>
+ /// <param name="before">The item which the new item is inserted before.</param>
+ /// <param name="content">The main content object. The name of content part is "elm.swallow.content".</param>
+ /// <param name="title">The current item title. null would be default.</param>
+ /// <param name="style">The current item style name. null would be default.</param>
+ /// <returns>The created item or null upon failure.</returns>
+ public NaviItem InsertBefore(NaviItem before, EvasObject content, string title, string style)
+ {
+ IntPtr item = Interop.Elementary.elm_naviframe_item_insert_before(RealHandle, before, title, IntPtr.Zero, IntPtr.Zero, content, null);
+ NaviItem naviItem = NaviItem.FromNativeHandle(item, content);
+ int idx = _itemStack.IndexOf(before);
+ _itemStack.Insert(idx, naviItem);
+ naviItem.Popped += ItemPoppedHandler;
+ return naviItem;
+ }
+
+ /// <summary>
+ /// Insert a new item into the naviframe after item.
+ /// The title is "" and the style is null.
+ /// </summary>
+ /// <param name="after">The item which the new item is inserted after.</param>
+ /// <param name="content">The main content object. The name of content part is "elm.swallow.content".</param>
+ /// <returns>The created item or null upon failure.</returns>
+ public NaviItem InsertAfter(NaviItem after, EvasObject content)
+ {
+ return InsertAfter(after, content, "");
+ }
+
+ /// <summary>
+ /// Insert a new item into the naviframe after item.
+ /// The style is null.
+ /// </summary>
+ /// <param name="after">The item which the new item is inserted after.</param>
+ /// <param name="content">The main content object. The name of content part is "elm.swallow.content".</param>
+ /// <param name="title">The current item title. null would be default.</param>
+ /// <returns>The created item or null upon failure.</returns>
+ public NaviItem InsertAfter(NaviItem after, EvasObject content, string title)
+ {
+ return InsertAfter(after, content, title, null);
+ }
+
+ /// <summary>
+ /// Insert a new item into the naviframe after item.
+ /// </summary>
+ /// <param name="after">The item which the new item is inserted after.</param>
+ /// <param name="content">The main content object. The name of content part is "elm.swallow.content".</param>
+ /// <param name="title">The current item title. null would be default.</param>
+ /// <param name="style">The current item style name. null would be default.</param>
+ /// <returns>The created item or null upon failure.</returns>
+ public NaviItem InsertAfter(NaviItem after, EvasObject content, string title, string style)
+ {
+ IntPtr item = Interop.Elementary.elm_naviframe_item_insert_after(RealHandle, after, title, IntPtr.Zero, IntPtr.Zero, content, null);
+ NaviItem naviItem = NaviItem.FromNativeHandle(item, content);
+ int idx = _itemStack.IndexOf(after);
+ _itemStack.Insert(idx + 1, naviItem);
+ naviItem.Popped += ItemPoppedHandler;
+ return naviItem;
+ }
+
+ /// <summary>
+ /// Pop an item that is on top of the stack.
+ /// </summary>
+ public void Pop()
+ {
+ Interop.Elementary.elm_naviframe_item_pop(RealHandle);
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ IntPtr handle = Interop.Elementary.elm_layout_add(parent);
+ Interop.Elementary.elm_layout_theme_set(handle, "layout", "elm_widget", "default");
+
+ RealHandle = Interop.Elementary.elm_naviframe_add(handle);
+ Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
+
+ return handle;
+ }
+
+ void ItemPoppedHandler(object sender, EventArgs e)
+ {
+ NaviItem item = sender as NaviItem;
+ if (item == null)
+ return;
+ _itemStack.Remove(item);
+ Popped?.Invoke(this, new NaviframeEventArgs() { Content = item.Content });
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/Panel.cs b/src/ElmSharp/ElmSharp/Panel.cs
new file mode 100755
index 0000000..f644d27
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Panel.cs
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// Enumeration for paneldirection type.
+ /// </summary>
+ public enum PanelDirection
+ {
+ /// <summary>
+ /// Top to bottom
+ /// </summary>
+ Top = 0,
+ /// <summary>
+ /// Bottom to top
+ /// </summary>
+ Bottom,
+ /// <summary>
+ /// Left to right
+ /// </summary>
+ Left,
+ /// <summary>
+ /// Right to left
+ /// </summary>
+ Right,
+ }
+
+ /// <summary>
+ /// The Panel is a container that can contain subobjects.
+ /// </summary>
+ public class Panel : Layout
+ {
+ SmartEvent _toggled;
+
+ /// <summary>
+ /// Creates and initializes a new instance of Panel class.
+ /// </summary>
+ /// <param name="parent">The EvasObject to which the new Panel will be attached as a child.</param>
+ public Panel(EvasObject parent) : base(parent)
+ {
+ _toggled = new SmartEvent(this, this.RealHandle, "toggled");
+ _toggled.On += (s, e) => Toggled?.Invoke(this, EventArgs.Empty);
+ }
+
+ /// <summary>
+ /// Sets or gets the hidden status of a given Panel widget.
+ /// </summary>
+ public bool IsOpen
+ {
+ get
+ {
+ return !Interop.Elementary.elm_panel_hidden_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_panel_hidden_set(RealHandle, !value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the direction of a given Panel widget.
+ /// </summary>
+ public PanelDirection Direction
+ {
+ get
+ {
+ return (PanelDirection)Interop.Elementary.elm_panel_orient_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_panel_orient_set(RealHandle, (int)value);
+ }
+ }
+
+ /// <summary>
+ /// Toggled will be triggered when toggles Panel.
+ /// </summary>
+ public event EventHandler Toggled;
+
+ /// <summary>
+ /// Enable or disable scrolling in the Panel.
+ /// </summary>
+ /// <param name="enable">
+ /// Bool value can be false or true.
+ /// </param>
+ public void SetScrollable(bool enable)
+ {
+ Interop.Elementary.elm_panel_scrollable_set(RealHandle, enable);
+ }
+
+ /// <summary>
+ /// Sets the scroll size of Panel.
+ /// </summary>
+ /// <param name="ratio">
+ /// The size of scroll area.
+ /// </param>
+ public void SetScrollableArea(double ratio)
+ {
+ Interop.Elementary.elm_panel_scrollable_content_size_set(RealHandle, ratio);
+ }
+
+ /// <summary>
+ /// Toggles the hidden state of the Panel.
+ /// </summary>
+ public void Toggle()
+ {
+ Interop.Elementary.elm_panel_toggle(RealHandle);
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ IntPtr handle = Interop.Elementary.elm_layout_add(parent);
+ Interop.Elementary.elm_layout_theme_set(handle, "layout", "elm_widget", "default");
+
+ RealHandle = Interop.Elementary.elm_panel_add(handle);
+ Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
+
+ return handle;
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/Panes.cs b/src/ElmSharp/ElmSharp/Panes.cs
new file mode 100755
index 0000000..d99b5b6
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Panes.cs
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The Panes is a widget that adds a draggable bar between two contents.
+ /// When dragged this bar resizes contents' size.
+ /// </summary>
+ public class Panes : Layout
+ {
+ SmartEvent _press;
+ SmartEvent _unpressed;
+
+ /// <summary>
+ /// Creates and initializes a new instance of the Panes class.
+ /// </summary>
+ /// <param name="parent">The EvasObject to which the new Panes will be attached as a child.</param>
+ public Panes(EvasObject parent) : base(parent)
+ {
+ _press = new SmartEvent(this, this.RealHandle, "press");
+ _unpressed = new SmartEvent(this, this.RealHandle, "unpress");
+
+ _press.On += (s, e) => Pressed?.Invoke(this, e);
+ _unpressed.On += (s, e) => Unpressed?.Invoke(this, e);
+ }
+
+ /// <summary>
+ /// Pressed will be triggered when panes have been pressed (button isn't released yet).
+ /// </summary>
+ public event EventHandler Pressed;
+
+ /// <summary>
+ /// Unpressed will be triggered when panes are released after being pressed.
+ /// </summary>
+ public event EventHandler Unpressed;
+
+ /// <summary>
+ /// Sets or gets resize mode of a given Panes widget.
+ /// True means the left and right panes resize homogeneously.
+ /// </summary>
+ public bool IsFixed
+ {
+ get
+ {
+ return Interop.Elementary.elm_panes_fixed_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_panes_fixed_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or Gets the size proportion of the Panes widget's left side.
+ /// </summary>
+ /// <remarks>
+ /// By default it's homogeneous, i.e., both sides have the same size.If something different is required,
+ /// it can be set with this function. For example, if the left content should be displayed over 75% of the panes size,
+ /// size should be passed as 0.75. This way, the right content is resized to 25% of the panes size.
+ /// If displayed vertically, left content is displayed at the top, and right content at the bottom.
+ /// This proportion changes when the user drags the panes bar.
+ ///
+ /// The value is float type and between 0.0 and 1.0 representing the size proportion of the left side.
+ /// </remarks>
+ public double Proportion
+ {
+ get
+ {
+ return Interop.Elementary.elm_panes_content_left_size_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_panes_content_left_size_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the orientation of a given Panes widget.
+ /// </summary>
+ /// <remarks>
+ /// Uses this function to change how your panes are to be disposed: vertically or horizontally.
+ /// By default it's displayed horizontally.
+ /// </remarks>
+ public bool IsHorizontal
+ {
+ get
+ {
+ return Interop.Elementary.elm_panes_horizontal_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_panes_horizontal_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the absolute minimum size of panes widget's left side.
+ /// If displayed vertically, left content is displayed at top.
+ /// value representing minimum size of left side in pixels.
+ /// </summary>
+ public int LeftMinimumSize
+ {
+ get
+ {
+ return Interop.Elementary.elm_panes_content_left_min_size_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_panes_content_left_min_size_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the relative minimum size of panes widget's left side.
+ /// proportion of minimum size of left side.
+ /// If displayed vertically, left content is displayed at top.
+ /// value between 0.0 and 1.0 representing size proportion of minimum size of left side.
+ /// </summary>
+ public double LeftMinimumRelativeSize
+ {
+ get
+ {
+ return Interop.Elementary.elm_panes_content_left_min_relative_size_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_panes_content_left_min_relative_size_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the absolute minimum size of panes widget's right side.
+ /// If displayed vertically, right content is displayed at top.
+ /// value representing minimum size of right side in pixels.
+ /// </summary>
+ public int RightMinimumSize
+ {
+ get
+ {
+ return Interop.Elementary.elm_panes_content_right_min_size_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_panes_content_right_min_size_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the relative minimum size of panes widget's right side.
+ /// proportion of minimum size of right side.
+ /// If displayed vertically, right content is displayed at top.
+ /// value between 0.0 and 1.0 representing size proportion of minimum size of right side.
+ /// </summary>
+ public double RightMinimumRelativeSize
+ {
+ get
+ {
+ return Interop.Elementary.elm_panes_content_right_min_relative_size_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_panes_content_right_min_relative_size_set(RealHandle, value);
+ }
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ IntPtr handle = Interop.Elementary.elm_layout_add(parent.Handle);
+ Interop.Elementary.elm_layout_theme_set(handle, "layout", "elm_widget", "default");
+
+ RealHandle = Interop.Elementary.elm_panes_add(handle);
+ Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
+
+ return handle;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/Point.cs b/src/ElmSharp/ElmSharp/Point.cs
new file mode 100755
index 0000000..3fe04cd
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Point.cs
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The Point is a struct that defines a 2-D point as a pair of generic type.
+ /// </summary>
+ public struct Point : IEquatable<Point>
+ {
+ /// <summary>
+ /// Location along the horizontal axis.
+ /// </summary>
+ public int X;
+
+ /// <summary>
+ /// Location along the vertical axis.
+ /// </summary>
+ public int Y;
+
+ public override string ToString()
+ {
+ return string.Format("{{X={0} Y={1}}}", X, Y);
+ }
+
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ return X.GetHashCode() ^ (Y.GetHashCode() * 397);
+ }
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (!(obj is Point))
+ return false;
+
+ return Equals((Point)obj);
+ }
+
+ public bool Equals(Point other)
+ {
+ return X.Equals(other.X) && Y.Equals(other.Y);
+ }
+
+ /// <summary>
+ /// Whether the two <see cref="T:Tizen.UI.Point" />s are equal.
+ /// </summary>
+ /// <param name="p1">A <see cref="T:Tizen.UI.Point" /> on the left hand side.</param>
+ /// <param name="p2">A <see cref="T:Tizen.UI.Point" /> on the right hand side.</param>
+ /// <returns>True if the two <see cref="T:Tizen.UI.Point" />s have equal values.</returns>
+ public static bool operator ==(Point p1, Point p2)
+ {
+ return p1.Equals(p2);
+ }
+
+ /// <summary>
+ /// Whether two <see cref="T:Tizen.UI.Point" />s are not equal.
+ /// </summary>
+ /// <param name="p1">A <see cref="T:Tizen.UI.Point" /> on the left hand side.</param>
+ /// <param name="p2">A <see cref="T:Tizen.UI.Point" /> on the right hand side.</param>
+ /// <returns>True if the two <see cref="T:Tizen.UI.Point" />s do not have equal values.</returns>
+ public static bool operator !=(Point p1, Point p2)
+ {
+ return !p1.Equals(p2);
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/Point3D.cs b/src/ElmSharp/ElmSharp/Point3D.cs
new file mode 100755
index 0000000..ebb8afb
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Point3D.cs
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The Point3D is a Struct that defining a 3-D point.
+ /// </summary>
+ public struct Point3D : IEquatable<Point3D>
+ {
+ /// <summary>
+ /// The X coordinate of a 3D point.
+ /// </summary>
+ public int X;
+
+ /// <summary>
+ /// The Y coordinate of a 3D point.
+ /// </summary>
+ public int Y;
+
+ /// <summary>
+ /// The Z coordinate of a 3D point.
+ /// </summary>
+ public int Z;
+
+ public override string ToString()
+ {
+ return string.Format("{{X={0} Y={1} Z={2}}}", X, Y, Z);
+ }
+
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ int hashCode = X.GetHashCode();
+ hashCode = (hashCode * 397) ^ Y.GetHashCode();
+ hashCode = (hashCode * 397) ^ Z.GetHashCode();
+ return hashCode;
+ }
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (!(obj is Point3D))
+ return false;
+
+ return Equals((Point3D)obj);
+ }
+
+ public bool Equals(Point3D other)
+ {
+ return X.Equals(other.X) && Y.Equals(other.Y) && Z.Equals(other.Z);
+ }
+
+ /// <summary>
+ /// Whether the two <see cref="T:Tizen.UI.Point3D" />s are equal.
+ /// </summary>
+ /// <param name="p1">A <see cref="T:Tizen.UI.Point3D" /> on the left hand side.</param>
+ /// <param name="p2">A <see cref="T:Tizen.UI.Point3D" /> on the right hand side.</param>
+ /// <returns>True if the two <see cref="T:Tizen.UI.Point3D" />s have equal values.</returns>
+ public static bool operator ==(Point3D p1, Point3D p2)
+ {
+ return p1.Equals(p2);
+ }
+
+ /// <summary>
+ /// Whether two <see cref="T:Tizen.UI.Point3D" />s are not equal.
+ /// </summary>
+ /// <param name="p1">A <see cref="T:Tizen.UI.Point3D" /> on the left hand side.</param>
+ /// <param name="p2">A <see cref="T:Tizen.UI.Point3D" /> on the right hand side.</param>
+ /// <returns>True if the two <see cref="T:Tizen.UI.Point3D" />s do not have equal values.</returns>
+ public static bool operator !=(Point3D p1, Point3D p2)
+ {
+ return !p1.Equals(p2);
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/Polygon.cs b/src/ElmSharp/ElmSharp/Polygon.cs
new file mode 100755
index 0000000..5db398d
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Polygon.cs
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The Polygon is a widget that used to draw a polygon (filled).
+ /// </summary>
+ public class Polygon : EvasObject
+ {
+ /// <summary>
+ /// Creates and initializes a new instance of the Polygon class.
+ /// <param name="parent">The EvasObject to which the new Polygon will be attached as a child.</param>
+ /// </summary>
+ public Polygon(EvasObject parent) : base(parent)
+ {
+ }
+
+ /// <summary>
+ /// Adds a new vertex to the Polygon.
+ /// <param name="x">The X coordinate of the new vertex.</param>
+ /// <param name="y">The Y coordinate of the new vertex.</param>
+ /// </summary>
+ public void AddPoint(int x, int y)
+ {
+ Interop.Evas.evas_object_polygon_point_add(Handle, x, y);
+ }
+
+ /// <summary>
+ /// Adds a new vertex to the Polygon.
+ /// <param name="p">The coordinates of the new vertex.</param>
+ /// </summary>
+ public void AddPoint(Point p)
+ {
+ AddPoint(p.X, p.Y);
+ }
+
+ /// <summary>
+ /// Removes all the vertices of the Polygon, making it empty.
+ /// </summary>
+ public void ClearPoints()
+ {
+ Interop.Evas.evas_object_polygon_points_clear(Handle);
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ IntPtr evas = Interop.Evas.evas_object_evas_get(parent.Handle);
+ return Interop.Evas.evas_object_polygon_add(evas);
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/Popup.cs b/src/ElmSharp/ElmSharp/Popup.cs
new file mode 100755
index 0000000..26f736d
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Popup.cs
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// Enumeration for the popup orientation type.
+ /// </summary>
+ public enum PopupOrientation
+ {
+ /// <summary>
+ /// Appears in the top of parent, default.
+ /// </summary>
+ Top,
+ /// <summary>
+ /// Appears in the center of parent.
+ /// </summary>
+ Center,
+ /// <summary>
+ /// Appears in the bottom of parent.
+ /// </summary>
+ Bottom,
+ /// <summary>
+ /// Appears in the left of parent.
+ /// </summary>
+ Left,
+ /// <summary>
+ /// Appears in the right of parent.
+ /// </summary>
+ Right,
+ /// <summary>
+ /// Appears in the top left of parent.
+ /// </summary>
+ TopLeft,
+ /// <summary>
+ /// Appears in the top right of parent.
+ /// </summary>
+ TopRight,
+ /// <summary>
+ /// Appears in the bottom left of parent.
+ /// </summary>
+ BottomLeft,
+ /// <summary>
+ /// Appears in the bottom right of parent.
+ /// </summary>
+ BottomRight
+ }
+
+ /// <summary>
+ /// The Popup is a widget that is an enhancement of Notify.
+ /// In addition to content area, there are two optional sections, namely title area and action area.
+ /// </summary>
+ public class Popup : Layout
+ {
+ HashSet<PopupItem> _children = new HashSet<PopupItem>();
+ SmartEvent _dismissed;
+ SmartEvent _blockClicked;
+ SmartEvent _timeout;
+ SmartEvent _showFinished;
+
+ /// <summary>
+ /// Creates and initializes a new instance of the Popup class.
+ /// </summary>
+ /// <param name="parent">The EvasObject to which the new Popup will be attached as a child.</param>
+ public Popup(EvasObject parent) : base(parent)
+ {
+ _dismissed = new SmartEvent(this, "dismissed");
+ _dismissed.On += (sender, e) =>
+ {
+ Dismissed?.Invoke(this, EventArgs.Empty);
+ };
+
+ _blockClicked = new SmartEvent(this, "block,clicked");
+ _blockClicked.On += (sender, e) =>
+ {
+ OutsideClicked?.Invoke(this, EventArgs.Empty);
+ };
+
+ _timeout = new SmartEvent(this, "timeout");
+ _timeout.On += (sender, e) =>
+ {
+ TimedOut?.Invoke(this, EventArgs.Empty);
+ };
+
+ _showFinished = new SmartEvent(this, "show,finished");
+ _showFinished.On += (sender, e) =>
+ {
+ ShowAnimationFinished?.Invoke(this, EventArgs.Empty);
+ };
+ }
+
+ /// <summary>
+ /// Dismissed will be triggered when Popup have been dismissed.
+ /// </summary>
+ public event EventHandler Dismissed;
+
+ /// <summary>
+ /// OutsideClicked will be triggered when users taps on the outside of Popup.
+ /// </summary>
+ public event EventHandler OutsideClicked;
+
+ /// <summary>
+ /// OutsideClicked will be triggered when Popup is closed as a result of timeout.
+ /// </summary>
+ public event EventHandler TimedOut;
+
+ /// <summary>
+ /// OutsideClicked will be triggered when the Popup transition is finished in showing.
+ /// </summary>
+ public event EventHandler ShowAnimationFinished;
+
+ /// <summary>
+ /// Sets or gets the position in which Popup will appear in its parent.
+ /// </summary>
+ public PopupOrientation Orientation
+ {
+ get
+ {
+ return (PopupOrientation)Interop.Elementary.elm_popup_orient_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_popup_orient_set(Handle, (int)value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the wrapping type of content text packed in content area of Popup widget.
+ /// </summary>
+ public WrapType ContentTextWrapType
+ {
+ get
+ {
+ return (WrapType)Interop.Elementary.elm_popup_content_text_wrap_type_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_popup_content_text_wrap_type_set(Handle, (int)value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the timeout value set to the Popup(in seconds).
+ /// </summary>
+ /// <remarks>
+ /// Since calling Show() on a popup restarts the timer controlling when it is hidden,
+ /// setting this before the popup is shown will in effect mean starting the timer when the popup is shown.
+ /// TimedOut is called afterwards which can be handled if needed.
+ /// Set a value <= 0.0 to disable a running timer.If the value > 0.0 and the popup is previously visible,
+ /// the timer will be started with this value, canceling any running timer.
+ /// </remarks>
+ public double Timeout
+ {
+ get
+ {
+ return Interop.Elementary.elm_popup_timeout_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_popup_timeout_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets whether events should be passed to event blocked area by a click outside.
+ /// </summary>
+ /// <remarks>
+ /// The visible region of popup is surrounded by a translucent region called Blocked Event area.
+ /// </remarks>
+ public bool AllowEvents
+ {
+ get
+ {
+ return Interop.Elementary.elm_popup_allow_events_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_popup_allow_events_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the AlignmentX in which the popup will appear in its parent.
+ /// </summary>
+ public override double AlignmentX
+ {
+ get
+ {
+ return Interop.Elementary.GetPopupAlignX(Handle);
+ }
+ set
+ {
+ Interop.Elementary.SetPopupAlignX(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the AlignmentY in which the popup will appear in its parent.
+ /// </summary>
+ public override double AlignmentY
+ {
+ get
+ {
+ return Interop.Elementary.GetPopupAlignY(Handle);
+ }
+ set
+ {
+ Interop.Elementary.SetPopupAlignY(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets the Opacity value of the Popup.
+ /// </summary>
+ public override int Opacity
+ {
+ get
+ {
+ return Color.Default.A;
+ }
+
+ set
+ {
+ Console.WriteLine("Popup instance doesn't support to set Opacity.");
+ }
+ }
+
+ /// <summary>
+ /// Adds label to a Popup widget.
+ /// </summary>
+ /// <param name="label"></param>
+ /// <returns>The new PopupItem which contains label .</returns>
+ public PopupItem Append(string label)
+ {
+ return Append(label, null);
+ }
+
+ /// <summary>
+ /// Adds Label and icon to a Popup widget.
+ /// </summary>
+ /// <param name="label">The Label which will be added into a new PopupItem. </param>
+ /// <param name="icon">The icon which will be added into a new PopupItem. </param>
+ /// <returns>The new PopupItem which contains label and icon.</returns>
+ public PopupItem Append(string label, EvasObject icon)
+ {
+ PopupItem item = new PopupItem(label, icon);
+ item.Handle = Interop.Elementary.elm_popup_item_append(Handle, label, icon, null, (IntPtr)item.Id);
+ AddInternal(item);
+ return item;
+ }
+
+ /// <summary>
+ /// Uses this function to dismiss the popup in hide effect.
+ /// when the Popup is dismissed, the "dismissed" signal will be emitted.
+ /// </summary>
+ public void Dismiss()
+ {
+ Interop.Elementary.elm_popup_dismiss(Handle);
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ return Interop.Elementary.elm_popup_add(parent.Handle);
+ }
+ void AddInternal(PopupItem item)
+ {
+ _children.Add(item);
+ item.Deleted += Item_Deleted;
+ }
+ void Item_Deleted(object sender, EventArgs e)
+ {
+ _children.Remove((PopupItem)sender);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/PopupItem.cs b/src/ElmSharp/ElmSharp/PopupItem.cs
new file mode 100755
index 0000000..1251c55
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/PopupItem.cs
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The PopupItem is a class that including icon and text.
+ /// </summary>
+ public class PopupItem : ItemObject
+ {
+ internal PopupItem(string text, EvasObject icon) : base(IntPtr.Zero)
+ {
+ Text = text;
+ Icon = icon;
+ }
+
+ /// <summary>
+ /// Gets the text label of popupitem.Return value is string.
+ /// </summary>
+ public string Text { get; internal set; }
+
+ /// <summary>
+ /// Gets the icon EvasObject of popupitem.
+ /// </summary>
+ public EvasObject Icon { get; internal set; }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/ProgressBar.cs b/src/ElmSharp/ElmSharp/ProgressBar.cs
new file mode 100755
index 0000000..28f6302
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/ProgressBar.cs
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The ProgressBar is a widget for visually representing the progress status of a given job/task.
+ /// </summary>
+ public class ProgressBar : Layout
+ {
+ SmartEvent _changed;
+
+ /// <summary>
+ /// Creates and initializes a new instance of the ProgressBar class.
+ /// </summary>
+ /// <param name="parent">The EvasObject to which the new ProgressBar will be attached as a child.</param>
+ public ProgressBar(EvasObject parent) : base(parent)
+ {
+ _changed = new SmartEvent(this, this.RealHandle, "changed");
+ _changed.On += (s, e) =>
+ {
+ ValueChanged?.Invoke(this, EventArgs.Empty);
+ };
+ }
+
+ /// <summary>
+ /// ValueChanged will be triggered when value of ProgressBar change.
+ /// </summary>
+ public event EventHandler ValueChanged;
+
+ /// <summary>
+ /// Sets or gets the value wheather a given ProgressBar widget is at the "pulsing mode".
+ /// </summary>
+ /// <remarks>
+ /// By default, progress bars display values from low to high value boundaries.
+ /// There are, though, contexts in which the progress of a given task is unknown.
+ /// For such cases, one can set a progress bar widget to a "pulsing state",
+ /// to give the user an idea that some computation is being held,
+ /// but without exact progress values. In the default theme,
+ /// it animates its bar with the contents filling in constantly and back to non-filled, in a loop.
+ /// </remarks>
+ public bool IsPulseMode
+ {
+ get
+ {
+ return Interop.Elementary.elm_progressbar_pulse_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_progressbar_pulse_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the value of ProgressBar.
+ /// </summary>
+ /// <remarks>
+ /// Use this property to set the progress bar levels.
+ /// If you pass a value out of the specified range(0.0~1.0),
+ /// it is interpreted as the closest of the boundary values in the range.
+ /// </remarks>
+ public double Value
+ {
+ get
+ {
+ return Interop.Elementary.elm_progressbar_value_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_progressbar_value_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the span value of ProgressBar.
+ /// </summary>
+ public int SpanSize
+ {
+ get
+ {
+ return Interop.Elementary.elm_progressbar_span_size_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_progressbar_span_size_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the value wheather a given ProgressBar widget is horizontal.
+ /// </summary>
+ public bool IsHorizontal
+ {
+ get
+ {
+ return Interop.Elementary.elm_progressbar_horizontal_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_progressbar_horizontal_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the value whether a given progress bar widget's displaying values are inverted.
+ /// </summary>
+ public bool IsInverted
+ {
+ get
+ {
+ return Interop.Elementary.elm_progressbar_inverted_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_progressbar_inverted_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets format string for a given progress bar widget's units label.
+ /// </summary>
+ /// <remarks>
+ /// If NULL is passed on format, it makes obj units area to be hidden completely.
+ /// If not, it sets the format string for the units label's text.
+ /// The units label is provided with a floating point value, so the units text displays at most one floating point value.
+ /// Note that the units label is optional. Use a format string such as "%1.2f meters" for example.
+ /// The default format string for a progress bar is an integer percentage, as in "%.0f %%".
+ /// </remarks>
+ public string UnitFormat
+ {
+ get
+ {
+ return Interop.Elementary.elm_progressbar_unit_format_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_progressbar_unit_format_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Starts a given progress bar "pulsing" animation, if its under that mode.
+ /// </summary>
+ public void PlayPulse()
+ {
+ Interop.Elementary.elm_progressbar_pulse(RealHandle, true);
+ }
+
+ [Obsolete("use StopPulse instead")]
+ public void StopPluse()
+ {
+ Interop.Elementary.elm_progressbar_pulse(RealHandle, false);
+ }
+
+ /// <summary>
+ /// Stops a given progress bar "pulsing" animation, if its under that mode.
+ /// </summary>
+ public void StopPulse()
+ {
+ Interop.Elementary.elm_progressbar_pulse(RealHandle, false);
+ }
+
+ /// <summary>
+ /// Gets the part value of the given part of the Progressbar.
+ /// </summary>
+ /// <param name="part">Part of the Progressbar.</param>
+ /// <returns>Returns value range is from 0.0 to 1.0.</returns>
+ public double GetPartValue(string part)
+ {
+ return Interop.Elementary.elm_progressbar_part_value_get(RealHandle, part);
+ }
+
+ /// <summary>
+ /// Sets or gets the general or main color of the given Progressbar.
+ /// </summary>
+ public override Color Color
+ {
+ get
+ {
+ return GetPartColor("bar");
+ }
+ set
+ {
+ SetPartColor("bar", value);
+ }
+ }
+
+ /// <summary>
+ /// Sets the part value of the give part of the Progressbar.
+ /// </summary>
+ /// <param name="part">Part of the Progressbar.</param>
+ /// <param name="value">Value range is from 0.0 to 1.0.</param>
+ public void SetPartValue(string part, double value)
+ {
+ Interop.Elementary.elm_progressbar_part_value_set(RealHandle, part, value);
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ IntPtr handle = Interop.Elementary.elm_layout_add(parent.Handle);
+ Interop.Elementary.elm_layout_theme_set(handle, "layout", "elm_widget", "default");
+
+ RealHandle = Interop.Elementary.elm_progressbar_add(handle);
+ Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
+
+ return handle;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/Radio.cs b/src/ElmSharp/ElmSharp/Radio.cs
new file mode 100755
index 0000000..9a5f2d5
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Radio.cs
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The Radio is a widget that allows for 1 or more options to be displayed and have the user choose only 1 of them.
+ /// </summary>
+ public class Radio : Layout
+ {
+ SmartEvent _changed;
+
+ /// <summary>
+ /// Creates and initializes a new instance of the Radio class.
+ /// </summary>
+ /// <param name="parent">The EvasObject to which the new Radio will be attached as a child.</param>
+ public Radio(EvasObject parent) : base(parent)
+ {
+ _changed = new SmartEvent(this, this.RealHandle, "changed");
+ _changed.On += (s, e) => ValueChanged?.Invoke(this, EventArgs.Empty);
+ }
+
+ /// <summary>
+ /// ValueChanged will be triggered when value of Radio change.
+ /// </summary>
+ public event EventHandler ValueChanged;
+
+ /// <summary>
+ /// Sets or gets a unique value to each Radio button.
+ /// </summary>
+ public int StateValue
+ {
+ get
+ {
+ return Interop.Elementary.elm_radio_state_value_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_radio_state_value_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the value of the radio group.
+ /// </summary>
+ public int GroupValue
+ {
+ get
+ {
+ return Interop.Elementary.elm_radio_value_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_radio_value_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Adds this radio to a group of other radio objects.
+ /// </summary>
+ /// <param name="group">Group which add radio in.</param>
+ public void SetGroup(Radio group)
+ {
+ if (group == null)
+ {
+ throw new ArgumentNullException("group");
+ }
+ Interop.Elementary.elm_radio_group_add(RealHandle, group.RealHandle);
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ IntPtr handle = Interop.Elementary.elm_layout_add(parent.Handle);
+ Interop.Elementary.elm_layout_theme_set(handle, "layout", "elm_widget", "default");
+
+ RealHandle = Interop.Elementary.elm_radio_add(handle);
+ Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
+
+ return handle;
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/ReadingInfoType.cs b/src/ElmSharp/ElmSharp/ReadingInfoType.cs
new file mode 100755
index 0000000..35df932
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/ReadingInfoType.cs
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp.Accessible
+{
+ /// <summary>
+ /// Enumeration for ReadingInfoType.
+ /// </summary>
+ [Flags]
+ public enum ReadingInfoType
+ {
+ /// <summary>
+ /// None
+ /// </summary>
+ None = 0,
+ /// <summary>
+ /// Name for reading info type
+ /// </summary>
+ Name = 0x1,
+ /// <summary>
+ /// Role for reading info type
+ /// </summary>
+ Role = 0x2,
+ /// <summary>
+ /// Description for reading info type
+ /// </summary>
+ Description = 0x4,
+ /// <summary>
+ /// State for reading info type
+ /// </summary>
+ State = 0x8
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/Rect.cs b/src/ElmSharp/ElmSharp/Rect.cs
new file mode 100644
index 0000000..2f7a544
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Rect.cs
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The Rect is a struct that represent rectangluar space.
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential)]
+ public struct Rect : IEquatable<Rect>
+ {
+ /// <summary>
+ /// Creates and initializes a new instance of the Rect class.
+ /// </summary>
+ /// <param name="x">X axis value.</param>
+ /// <param name="y">Y axis value.</param>
+ /// <param name="w">Width value.</param>
+ /// <param name="h">Height value.</param>
+ public Rect(int x, int y, int w, int h)
+ {
+ X = x;
+ Y = y;
+ Width = w;
+ Height = h;
+ }
+ /// <summary>
+ /// Gets or sets the position of this Rectangle on the X axis.
+ /// </summary>
+ public int X { get; set; }
+
+ /// <summary>
+ /// Gets or sets the position of this Rectangle on the Y axis.
+ /// </summary>
+ public int Y { get; set; }
+
+ /// <summary>
+ /// Gets or sets the width of this Rectangle.
+ /// </summary>
+ public int Width { get; set; }
+
+ /// <summary>
+ /// Gets or sets the height of this Rectangle.
+ /// </summary>
+ public int Height { get; set; }
+
+ /// <summary>
+ /// Gets the position of this Rectangle on the X axis.
+ /// </summary>
+ public int Left { get { return X; } }
+
+ /// <summary>
+ /// Gets the extent along the X axis.
+ /// </summary>
+ public int Right { get { return X + Width; } }
+
+ /// <summary>
+ /// Gets the position of this Rectangle on the Y axis.
+ /// </summary>
+ public int Top { get { return Y; } }
+
+ /// <summary>
+ /// Gets the extent along the Y axis.
+ /// </summary>
+ public int Bottom { get { return Y + Height; } }
+
+ /// <summary>
+ /// Gets the Point defined by Rectangle.Left and Rectangle.Top.
+ /// </summary>
+ public Point Location { get { return new Point { X = X, Y = Y }; } }
+
+ /// <summary>
+ /// Gets the extent of the Rectangle along its X and Y axis.
+ /// </summary>
+ public Size Size { get { return new Size { Width = Width, Height = Height }; } }
+
+ public override string ToString()
+ {
+ return string.Format("{{X={0} Y={1} Width={2} Height={3}}}", X, Y, Width, Height);
+ }
+
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ int hashCode = X.GetHashCode();
+ hashCode = (hashCode * 397) ^ Y.GetHashCode();
+ hashCode = (hashCode * 397) ^ Width.GetHashCode();
+ hashCode = (hashCode * 397) ^ Height.GetHashCode();
+ return hashCode;
+ }
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (!(obj is Rect))
+ return false;
+
+ return Equals((Rect)obj);
+ }
+
+ public bool Equals(Rect other)
+ {
+ return X.Equals(other.X) && Y.Equals(other.Y) && Width.Equals(other.Width) && Height.Equals(other.Height);
+ }
+
+ /// <summary>
+ /// Whether the two <see cref="T:Tizen.UI.Rectangle" />s are equal.
+ /// </summary>
+ /// <param name="r1">A <see cref="T:Tizen.UI.Rectangle" /> on the left hand side.</param>
+ /// <param name="r2">A <see cref="T:Tizen.UI.Rectangle" /> on the right hand side.</param>
+ /// <returns>True if the two <see cref="T:Tizen.UI.Rectangle" />s have equal values.</returns>
+ public static bool operator ==(Rect r1, Rect r2)
+ {
+ return r1.Equals(r2);
+ }
+
+ /// <summary>
+ /// Whether two <see cref="T:Tizen.UI.Rectangle" />s are not equal.
+ /// </summary>
+ /// <param name="r1">A <see cref="T:Tizen.UI.Rectangle" /> on the left hand side.</param>
+ /// <param name="r2">A <see cref="T:Tizen.UI.Rectangle" /> on the right hand side.</param>
+ /// <returns>True if the two <see cref="T:Tizen.UI.Rectangle" />s do not have equal values.</returns>
+ public static bool operator !=(Rect r1, Rect r2)
+ {
+ return !r1.Equals(r2);
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/Rectangle.cs b/src/ElmSharp/ElmSharp/Rectangle.cs
new file mode 100755
index 0000000..b0e69f8
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Rectangle.cs
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The Rectangle is a class that used to draw a solid colored rectangle.
+ /// </summary>
+ public class Rectangle : EvasObject
+ {
+ /// <summary>
+ /// Creates and initializes a new instance of the Rectangle class.
+ /// </summary>
+ /// <param name="parent">The <see cref="EvasObject"/> to which the new Slider will be attached as a child.</param>
+ public Rectangle(EvasObject parent) : base(parent)
+ {
+ Interop.Evas.evas_object_size_hint_weight_set(Handle, 1.0, 1.0);
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ IntPtr evas = Interop.Evas.evas_object_evas_get(parent.Handle);
+ return Interop.Evas.evas_object_rectangle_add(evas);
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/Scroller.cs b/src/ElmSharp/ElmSharp/Scroller.cs
new file mode 100755
index 0000000..2ceb38c
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Scroller.cs
@@ -0,0 +1,794 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// Enumeration for visible type of scrollbar.
+ /// </summary>
+ public enum ScrollBarVisiblePolicy
+ {
+ /// <summary>
+ /// Show scrollbars as needed
+ /// </summary>
+ Auto = 0,
+
+ /// <summary>
+ /// Always show scrollbars
+ /// </summary>
+ Visible,
+
+ /// <summary>
+ /// Never show scrollbars
+ /// </summary>
+ Invisible
+ }
+
+ /// <summary>
+ /// Enumeration for visible type of scrollbar.
+ /// </summary>
+ public enum ScrollBlock
+ {
+ /// <summary>
+ /// Scrolling movement is allowed in both direction.(X axis and Y axis)
+ /// </summary>
+ None = 1,
+
+ /// <summary>
+ /// Scrolling movement is not allowed in Y axis direction.
+ /// </summary>
+ Vertical = 2,
+
+ /// <summary>
+ /// Scrolling movement is not allowed in X axis direction.
+ /// </summary>
+ Horizontal = 4
+ }
+
+ /// <summary>
+ /// Type that controls how the content is scrolled.
+ /// </summary>
+ public enum ScrollSingleDirection
+ {
+ /// <summary>
+ /// Scroll every direction.
+ /// </summary>
+ None,
+
+ /// <summary>
+ /// Scroll single direction if the direction is certain.
+ /// </summary>
+ Soft,
+
+ /// <summary>
+ /// Scroll only single direction.
+ /// </summary>
+ Hard,
+ }
+
+ /// <summary>
+ /// The Scroller is a container that holds and clips a single object and allows you to scroll across it.
+ /// </summary>
+ public class Scroller : Layout
+ {
+ SmartEvent _scroll;
+ SmartEvent _dragStart;
+ SmartEvent _dragStop;
+ SmartEvent _scrollpage;
+
+ /// <summary>
+ /// Creates and initializes a new instance of the Scroller class.
+ /// </summary>
+ /// <param name="parent">The <see cref="EvasObject"/> to which the new Scroller will be attached as a child.</param>
+ public Scroller(EvasObject parent) : base(parent)
+ {
+ _scroll = new SmartEvent(this, this.RealHandle, "scroll");
+ _dragStart = new SmartEvent(this, this.RealHandle, "scroll,drag,start");
+ _dragStop = new SmartEvent(this, this.RealHandle, "scroll,drag,stop");
+ _scrollpage = new SmartEvent(this, this.RealHandle, "scroll,page,changed");
+ }
+
+ /// <summary>
+ /// Scrolled will be triggered when the content has been scrolled.
+ /// </summary>
+ public event EventHandler Scrolled
+ {
+ add
+ {
+ _scroll.On += value;
+ }
+ remove
+ {
+ _scroll.On -= value;
+ }
+ }
+
+ /// <summary>
+ /// DragStart will be triggered when dragging the contents around has started.
+ /// </summary>
+ public event EventHandler DragStart
+ {
+ add
+ {
+ _dragStart.On += value;
+ }
+ remove
+ {
+ _dragStart.On -= value;
+ }
+ }
+
+ /// <summary>
+ /// DragStop will be triggered when dragging the contents around has stopped.
+ /// </summary>
+ public event EventHandler DragStop
+ {
+ add
+ {
+ _dragStop.On += value;
+ }
+ remove
+ {
+ _dragStop.On -= value;
+ }
+ }
+
+ /// <summary>
+ /// PageScrolled will be triggered when the visible page has changed.
+ /// </summary>
+ public event EventHandler PageScrolled
+ {
+ add
+ {
+ _scrollpage.On += value;
+ }
+ remove
+ {
+ _scrollpage.On -= value;
+ }
+ }
+
+ /// <summary>
+ /// Gets the current region in the content object that is visible through the Scroller.
+ /// </summary>
+ public Rect CurrentRegion
+ {
+ get
+ {
+ int x, y, w, h;
+ Interop.Elementary.elm_scroller_region_get(RealHandle, out x, out y, out w, out h);
+ return new Rect(x, y, w, h);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the value of HorizontalScrollBarVisiblePolicy
+ /// </summary>
+ /// <remarks>
+ /// ScrollBarVisiblePolicy.Auto means the horizontal scrollbar is made visible if it is needed, and otherwise kept hidden.
+ /// ScrollBarVisiblePolicy.Visible turns it on all the time, and ScrollBarVisiblePolicy.Invisible always keeps it off.
+ /// </remarks>
+ public virtual ScrollBarVisiblePolicy HorizontalScrollBarVisiblePolicy
+ {
+ get
+ {
+ int policy;
+ Interop.Elementary.elm_scroller_policy_get(RealHandle, out policy, IntPtr.Zero);
+ return (ScrollBarVisiblePolicy)policy;
+ }
+ set
+ {
+ ScrollBarVisiblePolicy v = VerticalScrollBarVisiblePolicy;
+ Interop.Elementary.elm_scroller_policy_set(RealHandle, (int)value, (int)v);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the value of VerticalScrollBarVisiblePolicy
+ /// </summary>
+ /// <remarks>
+ /// ScrollBarVisiblePolicy.Auto means the vertical scrollbar is made visible if it is needed, and otherwise kept hidden.
+ /// ScrollBarVisiblePolicy.Visible turns it on all the time, and ScrollBarVisiblePolicy.Invisible always keeps it off.
+ /// </remarks>
+ public virtual ScrollBarVisiblePolicy VerticalScrollBarVisiblePolicy
+ {
+ get
+ {
+ int policy;
+ Interop.Elementary.elm_scroller_policy_get(RealHandle, IntPtr.Zero, out policy);
+ return (ScrollBarVisiblePolicy)policy;
+ }
+ set
+ {
+ ScrollBarVisiblePolicy h = HorizontalScrollBarVisiblePolicy;
+ Interop.Elementary.elm_scroller_policy_set(RealHandle, (int)h, (int)value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the value of ScrollBlock.
+ /// </summary>
+ /// <remarks>
+ /// This function will block scrolling movement in a given direction.One can disable movements in the X axis, the Y axis or both.
+ /// The default value is ScrollBlock.None, where movements are allowed in both directions.
+ /// </remarks>
+ public ScrollBlock ScrollBlock
+ {
+ get
+ {
+ return (ScrollBlock)Interop.Elementary.elm_scroller_movement_block_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_scroller_movement_block_set(RealHandle, (int)value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets scroll current page number.
+ /// </summary>
+ /// <remarks>
+ /// Current page means the page which meets the top of the viewport.
+ /// If there are two or more pages in the viewport, it returns the number of the page which meets the top of the viewport.
+ /// The page number starts from 0. 0 is the first page.
+ /// </remarks>
+ public int VerticalPageIndex
+ {
+ get
+ {
+ int v, h;
+ Interop.Elementary.elm_scroller_current_page_get(RealHandle, out h, out v);
+ return v;
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets scroll current page number.
+ /// </summary>
+ /// <remarks>
+ /// Current page means the page which meets the left of the viewport.
+ /// If there are two or more pages in the viewport, it returns the number of the page which meets the left of the viewport.
+ /// The page number starts from 0. 0 is the first page.
+ /// </remarks>
+ public int HorizontalPageIndex
+ {
+ get
+ {
+ int v, h;
+ Interop.Elementary.elm_scroller_current_page_get(RealHandle, out h, out v);
+ return h;
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the maximum limit of the movable page at vertical direction.
+ /// </summary>
+ public int VerticalPageScrollLimit
+ {
+ get
+ {
+ int v, h;
+ Interop.Elementary.elm_scroller_page_scroll_limit_get(RealHandle, out h, out v);
+ return v;
+ }
+ set
+ {
+ int h = HorizontalPageScrollLimit;
+ Interop.Elementary.elm_scroller_page_scroll_limit_set(RealHandle, h, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the maximum limit of the movable page at horizontal direction.
+ /// </summary>
+ public int HorizontalPageScrollLimit
+ {
+ get
+ {
+ int v, h;
+ Interop.Elementary.elm_scroller_page_scroll_limit_get(RealHandle, out h, out v);
+ return h;
+ }
+ set
+ {
+ int v = VerticalPageScrollLimit;
+ Interop.Elementary.elm_scroller_page_scroll_limit_set(RealHandle, value, v);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the vertical bounce behaviour.
+ /// When scrolling, the scroller may "bounce" when reaching an edge of the content object.
+ /// This is a visual way to indicate the end has been reached.
+ /// This is enabled by default for both axis.
+ /// This API will set if it is enabled for the given axis with the boolean parameters for each axis.
+ /// </summary>
+ public bool VerticalBounce
+ {
+ get
+ {
+ bool v, h;
+ Interop.Elementary.elm_scroller_bounce_get(RealHandle, out h, out v);
+ return v;
+ }
+ set
+ {
+ bool h = HorizontalBounce;
+ Interop.Elementary.elm_scroller_bounce_set(RealHandle, h, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the horizontal bounce behaviour.
+ /// When scrolling, the scroller may "bounce" when reaching an edge of the content object.
+ /// This is a visual way to indicate the end has been reached.
+ /// This is enabled by default for both axis.
+ /// This API will set if it is enabled for the given axis with the boolean parameters for each axis.
+ /// </summary>
+ public bool HorizontalBounce
+ {
+ get
+ {
+ bool v, h;
+ Interop.Elementary.elm_scroller_bounce_get(RealHandle, out h, out v);
+ return h;
+ }
+ set
+ {
+ bool v = VerticalBounce;
+ Interop.Elementary.elm_scroller_bounce_set(RealHandle, value, v);
+ }
+ }
+
+ /// <summary>
+ /// Gets the width of the content object of the scroller.
+ /// </summary>
+ public int ChildWidth
+ {
+ get
+ {
+ int w, h;
+ Interop.Elementary.elm_scroller_child_size_get(RealHandle, out w, out h);
+ return w;
+ }
+ }
+
+ /// <summary>
+ /// Gets the height of the content object of the scroller.
+ /// </summary>
+ public int ChildHeight
+ {
+ get
+ {
+ int w, h;
+ Interop.Elementary.elm_scroller_child_size_get(RealHandle, out w, out h);
+ return h;
+ }
+ }
+
+ /// <summary>
+ /// Set scrolling gravity values for a scroller.
+ /// The gravity, defines how the scroller will adjust its view when the size of the scroller contents increase.
+ /// The scroller will adjust the view to glue itself as follows.
+ /// x=0.0, for staying where it is relative to the left edge of the content x=1.0, for staying where it is relative to the rigth edge of the content y=0.0, for staying where it is relative to the top edge of the content y=1.0, for staying where it is relative to the bottom edge of the content
+ /// Default values for x and y are 0.0
+ /// </summary>
+ public double HorizontalGravity
+ {
+ get
+ {
+ double v, h;
+ Interop.Elementary.elm_scroller_gravity_get(RealHandle, out h, out v);
+ return h;
+ }
+ set
+ {
+ double v = VerticalGravity;
+ Interop.Elementary.elm_scroller_gravity_set(RealHandle, value, v);
+ }
+ }
+
+ /// <summary>
+ /// Set scrolling gravity values for a scroller.
+ /// The gravity, defines how the scroller will adjust its view when the size of the scroller contents increase.
+ /// The scroller will adjust the view to glue itself as follows.
+ /// x=0.0, for staying where it is relative to the left edge of the content x=1.0, for staying where it is relative to the rigth edge of the content y=0.0, for staying where it is relative to the top edge of the content y=1.0, for staying where it is relative to the bottom edge of the content
+ /// Default values for x and y are 0.0
+ /// </summary>
+ public double VerticalGravity
+ {
+ get
+ {
+ double v, h;
+ Interop.Elementary.elm_scroller_gravity_get(RealHandle, out h, out v);
+ return v;
+ }
+ set
+ {
+ double h = HorizontalGravity;
+ Interop.Elementary.elm_scroller_gravity_set(RealHandle, h, value);
+ }
+ }
+
+ /// <summary>
+ /// Get scroll last page number.
+ /// The page number starts from 0. 0 is the first page. This returns the last page number among the pages.
+ /// </summary>
+ public int LastVerticalPageNumber
+ {
+ get
+ {
+ int v, h;
+ Interop.Elementary.elm_scroller_last_page_get(RealHandle, out h, out v);
+ return v;
+ }
+ }
+
+ /// <summary>
+ /// Get scroll last page number.
+ /// The page number starts from 0. 0 is the first page. This returns the last page number among the pages.
+ /// </summary>
+ public int LastHorizontalPageNumber
+ {
+ get
+ {
+ int v, h;
+ Interop.Elementary.elm_scroller_last_page_get(RealHandle, out h, out v);
+ return h;
+ }
+ }
+
+ /// <summary>
+ /// Set an infinite loop_ for a scroller.
+ /// This function sets the infinite loop vertically.
+ /// If the content is set, it will be shown repeatedly.
+ /// </summary>
+ public bool VerticalLoop
+ {
+ get
+ {
+ bool v, h;
+ Interop.Elementary.elm_scroller_loop_get(RealHandle, out h, out v);
+ return v;
+ }
+ set
+ {
+ bool h = HorizontalLoop;
+ Interop.Elementary.elm_scroller_loop_set(RealHandle, h, value);
+ }
+ }
+
+ /// <summary>
+ /// Set an infinite loop_ for a scroller.
+ /// This function sets the infinite loop horizontally.
+ /// If the content is set, it will be shown repeatedly.
+ /// </summary>
+ public bool HorizontalLoop
+ {
+ get
+ {
+ bool v, h;
+ Interop.Elementary.elm_scroller_loop_get(RealHandle, out h, out v);
+ return h;
+ }
+ set
+ {
+ bool v = VerticalLoop;
+ Interop.Elementary.elm_scroller_loop_set(RealHandle, value, v);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a given scroller widget's scrolling page size, relative to its viewport size.
+ /// </summary>
+ public double VerticalRelativePageSize
+ {
+ get
+ {
+ double v, h;
+ Interop.Elementary.elm_scroller_page_relative_get(RealHandle, out h, out v);
+ return v;
+ }
+ set
+ {
+ double h = HorizontalRelativePageSize;
+ Interop.Elementary.elm_scroller_page_relative_set(RealHandle, h, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a given scroller widget's scrolling page size, relative to its viewport size.
+ /// </summary>
+ public double HorizontalRelativePageSize
+ {
+ get
+ {
+ double v, h;
+ Interop.Elementary.elm_scroller_page_relative_get(RealHandle, out h, out v);
+ return h;
+ }
+ set
+ {
+ double v = VerticalRelativePageSize;
+ Interop.Elementary.elm_scroller_page_relative_set(RealHandle, value, v);
+ }
+ }
+
+ /// <summary>
+ /// Gets or Sets the page snapping behavior of a scroller.
+ /// </summary>
+ /// <remarks>
+ /// When scrolling, if a scroller is paged (see VerticalRelativePageSize),
+ /// the scroller may snap to pages when being scrolled, i.e., even if it had momentum to scroll further,
+ /// it will stop at the next page boundaries. This is disabled, by default, for both axis.
+ /// This function will set if it that is enabled or not, for each axis.
+ /// </remarks>
+ public bool VerticalSnap
+ {
+ get
+ {
+ bool v, h;
+ Interop.Elementary.elm_scroller_page_snap_get(RealHandle, out h, out v);
+ return v;
+ }
+ set
+ {
+ bool h = HorizontalSnap;
+ Interop.Elementary.elm_scroller_page_snap_set(RealHandle, h, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or Sets the page snapping behavior of a scroller.
+ /// </summary>
+ /// <remarks>
+ /// When scrolling, if a scroller is paged (see HorizontalRelativePageSize),
+ /// the scroller may snap to pages when being scrolled, i.e., even if it had momentum to scroll further,
+ /// it will stop at the next page boundaries. This is disabled, by default, for both axis.
+ /// This function will set if it that is enabled or not, for each axis.
+ /// </remarks>
+ public bool HorizontalSnap
+ {
+ get
+ {
+ bool v, h;
+ Interop.Elementary.elm_scroller_page_snap_get(RealHandle, out h, out v);
+ return h;
+ }
+ set
+ {
+ bool v = VerticalSnap;
+ Interop.Elementary.elm_scroller_page_snap_set(RealHandle, value, v);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the page size to an absolute fixed value, with 0 turning it off for that axis.
+ /// </summary>
+ public int PageHeight
+ {
+ get
+ {
+ int w, h;
+ Interop.Elementary.elm_scroller_page_size_get(RealHandle, out w, out h);
+ return h;
+ }
+ set
+ {
+ int w = PageWidth;
+ Interop.Elementary.elm_scroller_page_size_set(RealHandle, w, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the page size to an absolute fixed value, with 0 turning it off for that axis.
+ /// </summary>
+ public int PageWidth
+ {
+ get
+ {
+ int w, h;
+ Interop.Elementary.elm_scroller_page_size_get(RealHandle, out w, out h);
+ return w;
+ }
+ set
+ {
+ int h = PageHeight;
+ Interop.Elementary.elm_scroller_page_size_set(RealHandle, value, h);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the event propagation for a scroller.
+ /// This enables or disables event propagation from the scroller content to the scroller and its parent.
+ /// By default event propagation is enabled.
+ /// </summary>
+ public bool ContentPropagateEvents
+ {
+ get
+ {
+ return Interop.Elementary.elm_scroller_propagate_events_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_scroller_propagate_events_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the step size to move scroller by key event.
+ /// </summary>
+ public int HorizontalStepSize
+ {
+ get
+ {
+ int h, v;
+ Interop.Elementary.elm_scroller_step_size_get(RealHandle, out h, out v);
+ return h;
+ }
+ set
+ {
+ int v = VerticalStepSize;
+ Interop.Elementary.elm_scroller_step_size_set(RealHandle, value, v);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the step size to move scroller by key event.
+ /// </summary>
+ public int VerticalStepSize
+ {
+ get
+ {
+ int h, v;
+ Interop.Elementary.elm_scroller_step_size_get(RealHandle, out h, out v);
+ return v;
+ }
+ set
+ {
+ int h = HorizontalStepSize;
+ Interop.Elementary.elm_scroller_step_size_set(RealHandle, h, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value whether mouse wheel is enabled or not over the scroller.
+ /// </summary>
+ public bool WheelDisabled
+ {
+ get
+ {
+ return Interop.Elementary.elm_scroller_wheel_disabled_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_scroller_wheel_disabled_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the type of single direction scroll.
+ /// </summary>
+ public ScrollSingleDirection SingleDirection
+ {
+ get
+ {
+ return (ScrollSingleDirection)Interop.Elementary.elm_scroller_single_direction_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_scroller_single_direction_set(RealHandle, (int)value);
+ }
+ }
+
+ /// <summary>
+ /// Sets the scroller minimum size limited to the minimum size of the content.
+ /// By default the scroller will be as small as its design allows, irrespective of its content.
+ /// This will make the scroller minimum size the right size horizontally and/or vertically to perfectly fit its content in that direction.
+ /// </summary>
+ /// <param name="horizontal">Enable limiting minimum size horizontally</param>
+ /// <param name="vertical">Enable limiting minimum size vertically</param>
+ public void MinimumLimit(bool horizontal, bool vertical)
+ {
+ Interop.Elementary.elm_scroller_content_min_limit(RealHandle, horizontal, vertical);
+ }
+
+ /// <summary>
+ /// Sets the page size to an absolute fixed value, with 0 turning it off for that axis.
+ /// </summary>
+ /// <param name="width">The horizontal page size.</param>
+ /// <param name="height">The vertical page size.</param>
+ public void SetPageSize(int width, int height)
+ {
+ Interop.Elementary.elm_scroller_page_size_set(RealHandle, width, height);
+ }
+
+ /// <summary>
+ /// Sets the scroll page size relative to the viewport size.
+ /// </summary>
+ /// <remarks>
+ /// The scroller is capable of limiting scrolling by the user to "pages".
+ /// That is to jump by and only show a "whole page" at a time as if the continuous area of the scroller
+ /// content is split into page sized pieces. This sets the size of a page relative to the viewport of the scroller.
+ /// 1.0 is "1 viewport" which is the size (horizontally or vertically). 0.0 turns it off in that axis.
+ /// This is mutually exclusive with the page size (see elm_scroller_page_size_set() for more information).
+ /// Likewise 0.5 is "half a viewport". Usable values are normally between 0.0 and 1.0 including 1.0.
+ /// If you only want 1 axis to be page "limited", use 0.0 for the other axis.
+ /// </remarks>
+ /// <param name="width">The horizontal page relative size.</param>
+ /// <param name="height">The vertical page relative size.</param>
+ public void SetPageSize(double width, double height)
+ {
+ Interop.Elementary.elm_scroller_page_relative_set(RealHandle, width, height);
+ }
+
+ /// <summary>
+ /// Shows a specific virtual region within the scroller content object by the page number.
+ /// (0, 0) of the indicated page is located at the top-left corner of the viewport.
+ /// </summary>
+ /// <param name="horizontalPageIndex">The horizontal page number.</param>
+ /// <param name="verticalPageIndex">The vertical page number.</param>
+ /// <param name="animated">True means slider with animation.</param>
+ public void ScrollTo(int horizontalPageIndex, int verticalPageIndex, bool animated)
+ {
+ if (animated)
+ {
+ Interop.Elementary.elm_scroller_page_bring_in(RealHandle, horizontalPageIndex, verticalPageIndex);
+ }
+ else
+ {
+ Interop.Elementary.elm_scroller_page_show(RealHandle, horizontalPageIndex, verticalPageIndex);
+ }
+ }
+
+ /// <summary>
+ /// Shows a specific virtual region within the scroller content object.
+ /// </summary>
+ /// <remarks>
+ /// This ensures that all (or part, if it does not fit) of the designated region in the virtual content object ((0, 0)
+ /// starting at the top-left of the virtual content object) is shown within the scroller.
+ /// If set "animated" to true, it will allows the scroller to "smoothly slide" to this location
+ /// (if configuration in general calls for transitions).
+ /// It may not jump immediately to the new location and may take a while and show other content along the way.
+ /// </remarks>
+ /// <param name="region">Rect struct of region.</param>
+ /// <param name="animated">True means allows the scroller to "smoothly slide" to this location.</param>
+ public void ScrollTo(Rect region, bool animated)
+ {
+ if (animated)
+ {
+ Interop.Elementary.elm_scroller_region_bring_in(RealHandle, region.X, region.Y, region.Width, region.Height);
+ }
+ else
+ {
+ Interop.Elementary.elm_scroller_region_show(RealHandle, region.X, region.Y, region.Width, region.Height);
+ }
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ IntPtr handle = Interop.Elementary.elm_layout_add(parent.Handle);
+ Interop.Elementary.elm_layout_theme_set(handle, "layout", "elm_widget", "default");
+
+ RealHandle = Interop.Elementary.elm_scroller_add(handle);
+ Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
+
+ return handle;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/Size.cs b/src/ElmSharp/ElmSharp/Size.cs
new file mode 100755
index 0000000..c2af5e2
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Size.cs
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The Size is a struct that defining height and width as a pair of generic type.
+ /// </summary>
+ public struct Size : IEquatable<Size>
+ {
+ /// <summary>
+ /// Magnitude along the horizontal axis, in platform-defined units.
+ /// </summary>
+ public int Width;
+
+ /// <summary>
+ /// Magnitude along the vertical axis, in platform-specific units.
+ /// </summary>
+ public int Height;
+
+ /// <summary>
+ /// Initializes a new instance of the Size structure from the specified dimensions.
+ /// </summary>
+ /// <param name="width">The width to set</param>
+ /// <param name="height">The height to set</param>
+ public Size(int width, int height)
+ {
+ Width = width;
+ Height = height;
+ }
+
+ /// <summary>
+ /// A human-readable representation of the <see cref="T:Tizen.UI.Size" />.
+ /// </summary>
+ /// <returns>The string is formatted as "{{Width={0} Height={1}}}".</returns>
+ public override string ToString()
+ {
+ return string.Format("{{Width={0} Height={1}}}", Width, Height);
+ }
+
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ return Width.GetHashCode() ^ (Height.GetHashCode() * 397);
+ }
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (!(obj is Size))
+ return false;
+
+ return Equals((Size)obj);
+ }
+
+ public bool Equals(Size other)
+ {
+ return Width.Equals(other.Width) && Height.Equals(other.Height);
+ }
+
+ /// <summary>
+ /// Whether the two <see cref="T:Tizen.UI.Size" />s are equal.
+ /// </summary>
+ /// <param name="s1">A <see cref="T:Tizen.UI.Size" /> on the left hand side.</param>
+ /// <param name="s2">A <see cref="T:Tizen.UI.Size" /> on the right hand side.</param>
+ /// <returns>True if the two <see cref="T:Tizen.UI.Size" />s have equal values.</returns>
+ public static bool operator ==(Size s1, Size s2)
+ {
+ return s1.Equals(s2);
+ }
+
+ /// <summary>
+ /// Whether two <see cref="T:Tizen.UI.Size" />s are not equal.
+ /// </summary>
+ /// <param name="s1">A <see cref="T:Tizen.UI.Size" /> on the left hand side.</param>
+ /// <param name="s2">A <see cref="T:Tizen.UI.Size" /> on the right hand side.</param>
+ /// <returns>True if the two <see cref="T:Tizen.UI.Size" />s do not have equal values.</returns>
+ public static bool operator !=(Size s1, Size s2)
+ {
+ return !s1.Equals(s2);
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/Slider.cs b/src/ElmSharp/ElmSharp/Slider.cs
new file mode 100755
index 0000000..41fb507
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Slider.cs
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// Enumeration for the Slider's indicator visiblity mode.
+ /// </summary>
+ public enum SliderIndicatorVisibleMode
+ {
+ /// <summary>
+ /// Show indicator on mouse down or change in slider value.
+ /// </summary>
+ Default,
+
+ /// <summary>
+ /// Always show the indicator.
+ /// </summary>
+ Always,
+
+ /// <summary>
+ /// Show the indicator on focus.
+ /// </summary>
+ OnFocus,
+
+ /// <summary>
+ /// Never show the indicator.
+ /// </summary>
+ None,
+ }
+
+ /// <summary>
+ /// The Slider is a widget that adds a draggable slider widget for selecting the value of something within a range.
+ /// </summary>
+ public class Slider : Layout
+ {
+ double _minimum = 0.0;
+ double _maximum = 1.0;
+
+ SmartEvent _changed;
+ SmartEvent _delayedChanged;
+ SmartEvent _dragStarted;
+ SmartEvent _dragStopped;
+
+ /// <summary>
+ /// Creates and initializes a new instance of the Slider class.
+ /// </summary>
+ /// <param name="parent">The <see cref="EvasObject"/> to which the new Slider will be attached as a child.</param>
+ public Slider(EvasObject parent) : base(parent)
+ {
+ _changed = new SmartEvent(this, this.RealHandle, "changed");
+ _changed.On += (s, e) => ValueChanged?.Invoke(this, EventArgs.Empty);
+
+ _delayedChanged = new SmartEvent(this, this.RealHandle, "delay,changed");
+ _delayedChanged.On += (s, e) => DelayedValueChanged?.Invoke(this, EventArgs.Empty);
+
+ _dragStarted = new SmartEvent(this, this.RealHandle, "slider,drag,start");
+ _dragStarted.On += (s, e) => DragStarted?.Invoke(this, EventArgs.Empty);
+
+ _dragStopped = new SmartEvent(this, this.RealHandle, "slider,drag,stop");
+ _dragStopped.On += (s, e) => DragStopped?.Invoke(this, EventArgs.Empty);
+ }
+
+ /// <summary>
+ /// ValueChanged will be triggered when the Slider value is changed by the user.
+ /// </summary>
+ public event EventHandler ValueChanged;
+
+ /// <summary>
+ /// DelayedValueChanged will be triggered when a short time after the value is changed by the user.
+ /// This will be called only when the user stops dragging for a very short period or when they release their finger/mouse,
+ /// so it avoids possibly expensive reactions to the value change.
+ /// </summary>
+ public event EventHandler DelayedValueChanged;
+
+ /// <summary>
+ /// DragStarted will be triggered when dragging the Slider indicator around has started.
+ /// </summary>
+ public event EventHandler DragStarted;
+
+ /// <summary>
+ /// DragStopped will be triggered when dragging the Slider indicator around has stopped.
+ /// </summary>
+ public event EventHandler DragStopped;
+
+ /// <summary>
+ /// Sets or gets the (exact) length of the bar region of a given Slider widget.
+ /// </summary>
+ /// <remarks>
+ /// This sets the minimum width (when in the horizontal mode) or height (when in the vertical mode)
+ /// of the actual bar area of the slider obj. This in turn affects the object's minimum size.
+ /// Use this when you're not setting other size hints expanding on the given direction
+ /// (like weight and alignment hints), and you would like it to have a specific size.
+ /// </remarks>
+ public int SpanSize
+ {
+ get
+ {
+ return Interop.Elementary.elm_slider_span_size_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_slider_span_size_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the format string for the indicator label.
+ /// </summary>
+ /// <remarks>
+ /// The slider may display its value somewhere other than the unit label,
+ /// for example, above the slider knob that is dragged around. This function sets the format string
+ /// used for this.If NULL, the indicator label won't be visible. If not, it sets the format string
+ /// for the label text. For the label text floating point value is provided, so the label text can
+ /// display up to 1 floating point value. Note that this is optional.Use a format string
+ /// such as "%1.2f meters" for example, and it displays values like: "3.14 meters" for a value
+ /// equal to 3.14159.By default, the indicator label is disabled.
+ /// </remarks>
+ public string IndicatorFormat
+ {
+ get
+ {
+ return Interop.Elementary.elm_slider_indicator_format_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_slider_indicator_format_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the orientation of a given slider widget.
+ /// </summary>
+ /// <remarks>
+ /// The orientation may be vertically or horizontally.By default, it's displayed horizontally.
+ /// </remarks>
+ public bool IsHorizontal
+ {
+ get
+ {
+ return Interop.Elementary.elm_slider_horizontal_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_slider_horizontal_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the minimum values for the slider.
+ /// </summary>
+ /// <remarks>
+ /// This defines the allowed minimum values to be selected by the user.
+ /// If the actual value is less than min, it is updated to min.
+ /// Actual value can be obtained with Value.By default, min is equal to 0.0.
+ /// </remarks>
+ public double Minimum
+ {
+ get
+ {
+ return _minimum;
+ }
+ set
+ {
+ _minimum = value;
+ Interop.Elementary.elm_slider_min_max_set(RealHandle, _minimum, _maximum);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the maximum values for the slider.
+ /// </summary>
+ /// <remarks>
+ /// This defines the allowed maximum values to be selected by the user.
+ /// If the actual value is bigger then max, it is updated to max.
+ /// Actual value can be obtained with Value.By default, min is equal to 0.0, and max is equal to 1.0.
+ /// Maximum must be greater than minimum, otherwise the behavior is undefined.
+ /// </remarks>
+ public double Maximum
+ {
+ get
+ {
+ return _maximum;
+ }
+ set
+ {
+ _maximum = value;
+ Interop.Elementary.elm_slider_min_max_set(RealHandle, _minimum, _maximum);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the value displayed by the slider.
+ /// </summary>
+ /// <remarks>
+ /// Value will be presented on the unit label following format specified with UnitFormat and
+ /// on indicator with IndicatorFormat.The value must to be between Minimum and Maximum values.
+ /// </remarks>
+ public double Value
+ {
+ get
+ {
+ return Interop.Elementary.elm_slider_value_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_slider_value_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the step by which the slider indicator moves.
+ /// </summary>
+ /// <remarks>
+ /// This value is used when the draggable object is moved automatically i.e.,
+ /// in case of a key event when up/down/left/right key is pressed or in case accessibility
+ /// is set and the flick event is used to inc/dec slider values.
+ /// By default, the step value is equal to 0.05.
+ /// </remarks>
+ public double Step
+ {
+ get
+ {
+ return Interop.Elementary.elm_slider_step_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_slider_step_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets whether a given slider widget's displaying values are inverted.
+ /// </summary>
+ /// <remarks>
+ /// A slider may be inverted, in which case it gets its values inverted,
+ /// with high values being on the left or top and low values on the right or bottom,
+ /// as opposed to normally have the low values on the former and high values on the latter,
+ /// respectively, for the horizontal and vertical modes.
+ /// </remarks>
+ public bool IsInverted
+ {
+ get
+ {
+ return Interop.Elementary.elm_slider_inverted_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_slider_inverted_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets whether to enlarge the slider indicator (augmented knob).
+ /// </summary>
+ /// <remarks>
+ /// By default, the indicator is bigger when dragged by the user.
+ /// It won't display values set with IndicatorFormat if you disable the indicator.
+ /// </remarks>
+ public bool IsIndicatorVisible
+ {
+ get
+ {
+ return Interop.Elementary.elm_slider_indicator_show_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_slider_indicator_show_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the visible mode of slider indicator.
+ /// </summary>
+ public SliderIndicatorVisibleMode IndicatorVisibleMode
+ {
+ get
+ {
+ return (SliderIndicatorVisibleMode)Interop.Elementary.elm_slider_indicator_visible_mode_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_slider_indicator_visible_mode_set(RealHandle, (int)value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets whether to Show the indicator of slider on focus.
+ /// </summary>
+ public bool IsIndicatorFocusable
+ {
+ get
+ {
+ return Interop.Elementary.elm_slider_indicator_show_on_focus_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_slider_indicator_show_on_focus_set(RealHandle, value);
+ }
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ IntPtr handle = Interop.Elementary.elm_layout_add(parent.Handle);
+ Interop.Elementary.elm_layout_theme_set(handle, "layout", "elm_widget", "default");
+
+ RealHandle = Interop.Elementary.elm_slider_add(handle);
+ Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
+
+ return handle;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/SmartEvent.cs b/src/ElmSharp/ElmSharp/SmartEvent.cs
new file mode 100755
index 0000000..6edbb7a
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/SmartEvent.cs
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.ComponentModel;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// It inherits <see cref="IInvalidatable"/>.
+ /// The event with TEventArgs for <see cref="EvasObject"/>.
+ /// EvasObject can elect SmartEvent occurring inside of them to be reported back to their users via delegates.
+ /// This way, you can extend EvasObject's own <see cref="EvasObjectEvent"/>.
+ /// They are defined by an event string, which identifies them uniquely.
+ /// </summary>
+ /// <typeparam name="TEventArgs">The parameter for the event.</typeparam>
+ public class SmartEvent<TEventArgs> : IInvalidatable where TEventArgs : EventArgs
+ {
+ /// <summary>
+ /// The delegate for creating smart event item args.
+ /// </summary>
+ /// <param name="data">The item data.</param>
+ /// <param name="obj">The sender obj.</param>
+ /// <param name="info">The item sender obj.</param>
+ /// <returns>Return smart event item args.</returns>
+ public delegate TEventArgs SmartEventInfoParser(IntPtr data, IntPtr obj, IntPtr info);
+
+ private EvasObject _sender;
+ private readonly string _eventName;
+ private IntPtr _handle;
+ private readonly SmartEventInfoParser _parser;
+ private readonly List<NativeCallback> _nativeCallbacks = new List<NativeCallback>();
+
+ /// <summary>
+ /// Creates and initializes a new instance of the SmartEvent class.
+ /// </summary>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="eventName">The event name.</param>
+ /// <param name="parser">The event parameter.</param>
+ public SmartEvent(EvasObject sender, string eventName, SmartEventInfoParser parser) : this(sender, sender.Handle, eventName, parser)
+ {
+ }
+
+ [EditorBrowsableAttribute(EditorBrowsableState.Never)]
+ public SmartEvent(EvasObject sender, IntPtr handle, string eventName, SmartEventInfoParser parser)
+ {
+ _sender = sender;
+ _eventName = eventName;
+ _handle = handle;
+ _parser = parser;
+ sender.AddToEventLifeTracker(this);
+ }
+
+ /// <summary>
+ /// Creates and initializes a new instance of the SmartEvent class.
+ /// </summary>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="eventName">The event name.</param>
+ public SmartEvent(EvasObject sender, string eventName) : this(sender, eventName, null)
+ {
+ }
+
+ ~SmartEvent()
+ {
+ Dispose(false);
+ }
+
+ private struct NativeCallback
+ {
+ public Interop.Evas.SmartCallback callback;
+ public EventHandler<TEventArgs> eventHandler;
+ }
+
+ /// <summary>
+ /// Adds or removes delegate for event.
+ /// </summary>
+ public event EventHandler<TEventArgs> On
+ {
+ add
+ {
+ if (_handle == IntPtr.Zero)
+ {
+ return;
+ }
+ EventHandler<TEventArgs> handler = value;
+ var cb = new Interop.Evas.SmartCallback((d, o, e) =>
+ {
+ TEventArgs ea = _parser == null ? (TEventArgs)EventArgs.Empty : _parser(d, o, e);
+ handler(_sender, ea);
+ });
+ _nativeCallbacks.Add(new NativeCallback { callback = cb, eventHandler = handler });
+ int i = _nativeCallbacks.Count - 1;
+ Interop.Evas.evas_object_smart_callback_add(_handle, _eventName, _nativeCallbacks[i].callback, IntPtr.Zero);
+ }
+
+ remove
+ {
+ if (_handle == IntPtr.Zero)
+ {
+ return;
+ }
+ EventHandler<TEventArgs> handler = value;
+ var callbacks = _nativeCallbacks.Where(cb => cb.eventHandler == handler);
+ foreach (var cb in callbacks)
+ {
+ Interop.Evas.evas_object_smart_callback_del(_handle, _eventName, cb.callback);
+ }
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Make current instance invalidate.
+ /// </summary>
+ public void MakeInvalidate()
+ {
+ _sender = null;
+ _handle = IntPtr.Zero;
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ // Place holder to dispose managed state (managed objects).
+ }
+ if (_handle != IntPtr.Zero)
+ {
+ foreach (var cb in _nativeCallbacks)
+ {
+ Interop.Evas.evas_object_smart_callback_del(_handle, _eventName, cb.callback);
+ }
+ }
+ _nativeCallbacks.Clear();
+ }
+ }
+
+ /// <summary>
+ /// It inherits <see cref="IInvalidatable"/>.
+ /// EvasObject can elect SmartEvent occurring inside of them to be reported back to their users via delegates.
+ /// This way, you can extend EvasObject's own <see cref="EvasObjectEvent"/>.
+ /// They are defined by an event string, which identifies them uniquely.
+ /// </summary>
+ /// <typeparam name="TEventArgs">The parameter for the event.</typeparam>
+ public class SmartEvent : IInvalidatable
+ {
+ private SmartEvent<EventArgs> _smartEvent;
+ private event EventHandler _handlers;
+
+ /// <summary>
+ /// Creates and initializes a new instance of the SmartEvent class.
+ /// </summary>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="eventName">The event name.</param>
+ public SmartEvent(EvasObject sender, string eventName) : this(sender, sender.RealHandle, eventName)
+ {
+ }
+
+ [EditorBrowsableAttribute(EditorBrowsableState.Never)]
+ public SmartEvent(EvasObject sender, IntPtr handle, string eventName)
+ {
+ _smartEvent = new SmartEvent<EventArgs>(sender, handle, eventName, null);
+ }
+
+ ~SmartEvent()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Adds or removes delegate for event.
+ /// </summary>
+ public event EventHandler On
+ {
+ add
+ {
+ if (_handlers == null)
+ {
+ _smartEvent.On += SendEvent;
+ }
+ _handlers += value;
+ }
+
+ remove
+ {
+ _handlers -= value;
+ if (_handlers == null)
+ {
+ _smartEvent.On -= SendEvent;
+ }
+ }
+ }
+
+ private void SendEvent(object sender, EventArgs e)
+ {
+ _handlers?.Invoke(sender, e);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Make current instance invalidate.
+ /// </summary>
+ public void MakeInvalidate()
+ {
+ _smartEvent.MakeInvalidate();
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ // Place holder to dispose managed state (managed objects).
+ _smartEvent.Dispose();
+ }
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/Spinner.cs b/src/ElmSharp/ElmSharp/Spinner.cs
new file mode 100755
index 0000000..e6a12e6
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Spinner.cs
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The Spinner is a widget that increase or decrease numeric values using arrow buttons, or edit values directly.
+ /// Inherits <see cref="Layout"/>.
+ /// </summary>
+ public class Spinner : Layout
+ {
+ double _minimum = 0.0;
+ double _maximum = 100.0;
+
+ SmartEvent _changed;
+ SmartEvent _delayedChanged;
+
+ /// <summary>
+ /// Creates and initializes a new instance of the Spinner class.
+ /// </summary>
+ /// <param name="parent">The parent of new Spinner instance</param>
+ public Spinner(EvasObject parent) : base(parent)
+ {
+ _changed = new SmartEvent(this, this.RealHandle, "changed");
+ _changed.On += (s, e) => ValueChanged?.Invoke(this, EventArgs.Empty);
+
+ _delayedChanged = new SmartEvent(this, this.RealHandle, "delay,changed");
+ _delayedChanged.On += (s, e) => DelayedValueChanged?.Invoke(this, EventArgs.Empty);
+ }
+
+ /// <summary>
+ /// ValueChanged will be triggered whenever the spinner value is changed.
+ /// </summary>
+ public event EventHandler ValueChanged;
+
+ /// <summary>
+ /// DelayedValueChanged will be triggered after a short time when the value is changed.
+ /// </summary>
+ public event EventHandler DelayedValueChanged;
+
+ /// <summary>
+ /// Sets or gets the label format of the spinner.
+ /// </summary>
+ public string LabelFormat
+ {
+ get
+ {
+ return Interop.Elementary.elm_spinner_label_format_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_spinner_label_format_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the minimum value for the spinner.
+ /// </summary>
+ public double Minimum
+ {
+ get
+ {
+ return _minimum;
+ }
+ set
+ {
+ _minimum = value;
+ Interop.Elementary.elm_spinner_min_max_set(RealHandle, _minimum, _maximum);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the maximum value for the spinner.
+ /// </summary>
+ public double Maximum
+ {
+ get
+ {
+ return _maximum;
+ }
+ set
+ {
+ _maximum = value;
+ Interop.Elementary.elm_spinner_min_max_set(RealHandle, _minimum, _maximum);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the step that used to increment or decrement the spinner value.
+ /// </summary>
+ public double Step
+ {
+ get
+ {
+ return Interop.Elementary.elm_spinner_step_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_spinner_step_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the value displayed by the spinner.
+ /// </summary>
+ public double Value
+ {
+ get
+ {
+ return Interop.Elementary.elm_spinner_value_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_spinner_value_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the interval on time updates for an user mouse button hold on spinner widgets' arrows.
+ /// </summary>
+ public double Interval
+ {
+ get
+ {
+ return Interop.Elementary.elm_spinner_interval_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_spinner_interval_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the base for rounding.
+ /// </summary>
+ public double RoundBase
+ {
+ get
+ {
+ return Interop.Elementary.elm_spinner_base_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_spinner_base_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the round value for rounding.
+ /// </summary>
+ public int RoundValue
+ {
+ get
+ {
+ return Interop.Elementary.elm_spinner_round_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_spinner_round_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the wrap of a given spinner widget.
+ /// </summary>
+ /// <remarks>
+ /// If wrap is disabled, when the user tries to increment the value, but displayed value plus step value is bigger than maximum value, the new value will be the maximum value.
+ /// If wrap is enabled, when the user tries to increment the value, but displayed value plus step value is bigger than maximum value, the new value will be the minimum value.
+ /// By default it's disabled.
+ /// </remarks>
+ public bool IsWrapEnabled
+ {
+ get
+ {
+ return Interop.Elementary.elm_spinner_wrap_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_spinner_wrap_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets whether the spinner can be directly edited by the user or not.
+ /// </summary>
+ /// <remarks>By default it is enabled</remarks>
+ public bool IsEditable
+ {
+ get
+ {
+ return Interop.Elementary.elm_spinner_editable_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_spinner_editable_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Set a special string to display in the place of the numerical value.
+ /// </summary>
+ /// <param name="value">The numerical value to be replaced</param>
+ /// <param name="label">The label to be used</param>
+ public void AddSpecialValue(double value, string label)
+ {
+ Interop.Elementary.elm_spinner_special_value_add(RealHandle, value, label);
+ }
+
+ /// <summary>
+ /// Remove a previously added special value, After this, the spinner will display the value itself instead of a label.
+ /// </summary>
+ /// <param name="value">The replaced numerical value</param>
+ public void RemoveSpecialValue(double value)
+ {
+ Interop.Elementary.elm_spinner_special_value_del(RealHandle, value);
+ }
+
+ /// <summary>
+ /// Get the special string display in the place of the numerical value.
+ /// </summary>
+ /// <param name="value">The replaced numerical value.</param>
+ /// <returns>The value of the spinner which replaced numerical value with special string</returns>
+ public string GetSpecialValue(double value)
+ {
+ return Interop.Elementary.elm_spinner_special_value_get(RealHandle, value);
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ IntPtr handle = Interop.Elementary.elm_layout_add(parent.Handle);
+ Interop.Elementary.elm_layout_theme_set(handle, "layout", "elm_widget", "default");
+
+ RealHandle = Interop.Elementary.elm_spinner_add(handle);
+ Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
+
+ return handle;
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/Table.cs b/src/ElmSharp/ElmSharp/Table.cs
new file mode 100755
index 0000000..707a34b
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Table.cs
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The Table is a container widget to arrange other widgets in a table where items can span multiple columns or rows .
+ /// Inherits <see cref="Container"/>.
+ /// </summary>
+ public class Table : Container
+ {
+ int _paddingX = 0;
+ int _paddingY = 0;
+
+ /// <summary>
+ /// Creates and initializes a new instance of the Table class.
+ /// </summary>
+ /// <param name="parent">
+ /// A <see cref="EvasObject"/> to which the new Table instance will be attached.
+ /// </param>
+ public Table(EvasObject parent) : base(parent)
+ {
+ }
+
+ /// <summary>
+ /// Sets or gets whether the layout of this table is homogeneous.
+ /// </summary>
+ /// <remarks>True for homogeneous, False for no homogeneous</remarks>
+ public bool Homogeneous
+ {
+ get
+ {
+ return Interop.Elementary.elm_table_homogeneous_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_table_homogeneous_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the horizontal padding between the cells.
+ /// </summary>
+ public int PaddingX
+ {
+ get
+ {
+ return _paddingX;
+ }
+ set
+ {
+ _paddingX = value;
+ Interop.Elementary.elm_table_padding_set(RealHandle, _paddingX, _paddingY);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the vertical padding between the cells.
+ /// </summary>
+ public int PaddingY
+ {
+ get
+ {
+ return _paddingY;
+ }
+ set
+ {
+ _paddingY = value;
+ Interop.Elementary.elm_table_padding_set(RealHandle, _paddingX, _paddingY);
+ }
+ }
+ /// <summary>
+ /// Adds a subobject on the table with the coordinates passed.
+ /// </summary>
+ /// <param name="obj">The subobject to be added to the table</param>
+ /// <param name="col">The column number</param>
+ /// <param name="row">The row number</param>
+ /// <param name="colspan">The column span</param>
+ /// <param name="rowspan">The row span</param>
+ public void Pack(EvasObject obj, int col, int row, int colspan, int rowspan)
+ {
+ if (obj == null)
+ throw new ArgumentNullException("obj");
+ Interop.Elementary.elm_table_pack(RealHandle, obj, col, row, colspan, rowspan);
+ AddChild(obj);
+ }
+
+ /// <summary>
+ /// Removes the child from the table.
+ /// </summary>
+ /// <param name="obj">The subobject</param>
+ public void Unpack(EvasObject obj)
+ {
+ if (obj == null)
+ throw new ArgumentNullException("obj");
+ Interop.Elementary.elm_table_unpack(RealHandle, obj);
+ RemoveChild(obj);
+ }
+
+ /// <summary>
+ /// Removes all child objects from a table object.
+ /// </summary>
+ public void Clear()
+ {
+ Interop.Elementary.elm_table_clear(RealHandle, false);
+ ClearChildren();
+ }
+
+ /// <summary>
+ /// Sets the color for particular part of the table.
+ /// </summary>
+ /// <param name="part">The name of part class</param>
+ /// <param name="color">The color</param>
+ public override void SetPartColor(string part, Color color)
+ {
+ Interop.Elementary.elm_object_color_class_color_set(Handle, part, color.R * color.A / 255,
+ color.G * color.A / 255,
+ color.B * color.A / 255,
+ color.A);
+ }
+
+ /// <summary>
+ /// Gets the color of particular part of the table.
+ /// </summary>
+ /// <param name="part">The name of part class, it could be 'bg', 'elm.swllow.content'</param>
+ /// <returns>The color of the particular part</returns>
+ public override Color GetPartColor(string part)
+ {
+ int r, g, b, a;
+ Interop.Elementary.elm_object_color_class_color_get(Handle, part, out r, out g, out b, out a);
+ return new Color((int)(r / (a / 255.0)), (int)(g / (a / 255.0)), (int)(b / (a / 255.0)), a);
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ IntPtr handle = Interop.Elementary.elm_layout_add(parent);
+ Interop.Elementary.elm_layout_theme_set(handle, "layout", "background", "default");
+
+ RealHandle = Interop.Elementary.elm_table_add(handle);
+ Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
+
+ return handle;
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/Toolbar.cs b/src/ElmSharp/ElmSharp/Toolbar.cs
new file mode 100644
index 0000000..d86614c
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Toolbar.cs
@@ -0,0 +1,468 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.ComponentModel;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// Enumeration for the selection mode of Toolbar.
+ /// </summary>
+ public enum ToolbarSelectionMode
+ {
+ /// <summary>
+ /// Default select mode.
+ /// </summary>
+ Default = 0,
+
+ /// <summary>
+ /// Always select mode.
+ /// </summary>
+ Always,
+
+ /// <summary>
+ /// No select mode.
+ /// </summary>
+ None,
+
+ /// <summary>
+ /// No select mode with no finger size rule.
+ /// </summary>
+ DisplayOnly,
+ }
+
+ /// <summary>
+ /// Enumeration that sets the toolbar items display behavior, it can be scrollable, can show a menu with exceeding items, or simply hide them.
+ /// </summary>
+ public enum ToolbarShrinkMode
+ {
+ /// <summary>
+ /// Sets minimum toolbar size to fit all the items.
+ /// </summary>
+ None = 0,
+
+ /// <summary>
+ /// Hides exceeding items.
+ /// </summary>
+ Hide,
+
+ /// <summary>
+ /// Allows accessing exceeding items through a scroller.
+ /// </summary>
+ Scroll,
+
+ /// <summary>
+ /// Inserts a button to pop up a menu with exceeding items.
+ /// </summary>
+ Menu,
+
+ /// <summary>
+ /// Expands all items according to the size of the toolbar.
+ /// </summary>
+ Expand
+ }
+
+ /// <summary>
+ /// Enumeration for the icon lookup order of Toolbar.
+ /// </summary>
+ public enum ToolbarIconLookupOrder
+ {
+ /// <summary>
+ /// Icon look up order: freedesktop, theme.
+ /// </summary>
+ FreedesktopTheme,
+
+ /// <summary>
+ /// Icon look up order: theme, freedesktop.
+ /// </summary>
+ ThemeFreedesktop,
+
+ /// <summary>
+ /// Icon look up order: freedesktop.
+ /// </summary>
+ Freedesktop,
+
+ /// <summary>
+ /// Icon look up order: theme.
+ /// </summary>
+ Theme,
+ }
+
+ /// <summary>
+ /// Event arguments for events of <see cref="ToolbarItem"/>.
+ /// </summary>
+ /// <remarks>
+ /// Inherits EventArgs.
+ /// </remarks>
+ public class ToolbarItemEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Gets the ToolbarItem.
+ /// </summary>
+ public ToolbarItem Item { get; private set; }
+
+ internal static ToolbarItemEventArgs CreateFromSmartEvent(IntPtr data, IntPtr obj, IntPtr info)
+ {
+ ToolbarItem item = ItemObject.GetItemByHandle(info) as ToolbarItem;
+ return new ToolbarItemEventArgs() { Item = item };
+ }
+ }
+
+ /// <summary>
+ /// The Toolbar is a widget that displays a list of items inside a box.
+ /// </summary>
+ public class Toolbar : Widget
+ {
+ SmartEvent<ToolbarItemEventArgs> _clicked;
+ SmartEvent<ToolbarItemEventArgs> _selected;
+ SmartEvent<ToolbarItemEventArgs> _longpressed;
+
+ /// <summary>
+ /// Creates and initializes a new instance of the Toolbar class.
+ /// </summary>
+ /// <param name="parent">
+ /// A EvasObject to which the new Table instance will be attached.
+ /// </param>
+ public Toolbar(EvasObject parent) : base(parent)
+ {
+ _selected = new SmartEvent<ToolbarItemEventArgs>(this, this.RealHandle, "selected", ToolbarItemEventArgs.CreateFromSmartEvent);
+ _selected.On += (s, e) =>
+ {
+ if (e.Item != null)
+ {
+ Selected?.Invoke(this, e);
+ e.Item.SendSelected();
+ }
+ };
+ _longpressed = new SmartEvent<ToolbarItemEventArgs>(this, this.RealHandle, "longpressed", ToolbarItemEventArgs.CreateFromSmartEvent);
+ _longpressed.On += (s, e) =>
+ {
+ e.Item?.SendLongPressed();
+ };
+ _clicked = new SmartEvent<ToolbarItemEventArgs>(this, this.RealHandle, "clicked", ToolbarItemEventArgs.CreateFromSmartEvent);
+ _clicked.On += (s, e) =>
+ {
+ e.Item?.SendClicked();
+ };
+ }
+
+ /// <summary>
+ /// Selected will be triggered when toolbar have been selected.
+ /// </summary>
+ public event EventHandler<ToolbarItemEventArgs> Selected;
+
+ /// <summary>
+ /// Sets or gets whether the layout of this toolbar is homogeneous.
+ /// </summary>
+ /// <remarks>True for homogeneous, False for no homogeneous</remarks>
+ public bool Homogeneous
+ {
+ get
+ {
+ return Interop.Elementary.elm_toolbar_homogeneous_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_toolbar_homogeneous_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the slection mode of a given Toolbar widget.
+ /// </summary>
+ public ToolbarSelectionMode SelectionMode
+ {
+ get
+ {
+ return (ToolbarSelectionMode)Interop.Elementary.elm_toolbar_select_mode_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_toolbar_select_mode_set(RealHandle, (int)value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the shrink mode of a given Toolbar widget.
+ /// </summary>
+ public ToolbarShrinkMode ShrinkMode
+ {
+ get
+ {
+ return (ToolbarShrinkMode)Interop.Elementary.elm_toolbar_shrink_mode_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_toolbar_shrink_mode_set(RealHandle, (int)value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the orientation of a given toolbar widget.
+ /// By default, a toolbar will be horizontal. Use this function to create a vertical toolbar.
+ /// </summary>
+ //TODO: Below browsable limitation will be removed when the EFL-929 issue is resolved.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public bool IsHorizontal
+ {
+ get
+ {
+ return Interop.Elementary.elm_toolbar_horizontal_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_toolbar_horizontal_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the icon lookup order, for toolbar items' icons.
+ /// The default lookup order is ToolbarIocnLookupOrder.ThemeFreedesktop.
+ /// Icons added before calling this function will not be affected.
+ /// </summary>
+ public ToolbarIconLookupOrder IconLookupOrder
+ {
+ get
+ {
+ return (ToolbarIconLookupOrder)Interop.Elementary.elm_toolbar_icon_order_lookup_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_toolbar_icon_order_lookup_set(RealHandle, (int)value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the icon size of a given toolbar widget.
+ /// Default value is 32 pixels, to be used by toolbar items.
+ /// </summary>
+ public int IconSize
+ {
+ get
+ {
+ return Interop.Elementary.elm_toolbar_icon_size_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_toolbar_icon_size_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets the number of items in a toolbar widget.
+ /// </summary>
+ public int ItemsCount
+ {
+ get
+ {
+ return Interop.Elementary.elm_toolbar_items_count(RealHandle);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the alignment of the items.
+ /// </summary>
+ /// <remarks>The toolbar items alignment, a float between 0.0 and 1.0</remarks>
+ public double ItemAlignment
+ {
+ get
+ {
+ return Interop.Elementary.elm_toolbar_align_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_toolbar_align_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the item's transverse expansion of a given toolbar widget.
+ /// </summary>
+ /// <remarks>
+ /// The transverse expansion of the item, true for on and false for off.
+ /// By default it's false.
+ /// </remarks>
+ public bool TransverseExpansion
+ {
+ get
+ {
+ return Interop.Elementary.elm_toolbar_transverse_expanded_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_toolbar_transverse_expanded_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Appends ToolbarItem which just contains label to the toolbar.
+ /// </summary>
+ /// <param name="label">The label of the item</param>
+ /// <returns>The new ToolbarItem which appended to the toolbar</returns>
+ /// <seealso cref="Append(string, string)"/>
+ /// <seealso cref="Prepend(string)"/>
+ public ToolbarItem Append(string label)
+ {
+ return Append(label, null);
+ }
+
+ /// <summary>
+ /// Appends ToolbarItem which contains label and icon to the toolbar.
+ /// </summary>
+ /// <param name="label">The label of the item</param>
+ /// <param name="icon">A string with the icon name or the absolute path of an image file</param>
+ /// <returns>The new ToolbarItem which appended to the toolbar</returns>
+ /// <seealso cref="Append(string)"/>
+ /// <seealso cref="Prepend(string)"/>
+ /// <seealso cref="Prepend(string, string)"/>
+ public ToolbarItem Append(string label, string icon)
+ {
+ ToolbarItem item = new ToolbarItem(label, icon);
+ item.Handle = Interop.Elementary.elm_toolbar_item_append(RealHandle, icon, label, null, (IntPtr)item.Id);
+ return item;
+ }
+
+ /// <summary>
+ /// Prepends ToolbarItem which just contains label to the toolbar.
+ /// </summary>
+ /// <param name="label">The label of the item</param>
+ /// <returns>The new ToolbarItem which prepended to the toolbar</returns>
+ /// <seealso cref="Append(string)"/>
+ /// <seealso cref="Append(string, string)"/>
+ /// <seealso cref="Prepend(string, string)"/>
+ public ToolbarItem Prepend(string label)
+ {
+ return Prepend(label, null);
+ }
+
+ /// <summary>
+ /// Prepends ToolbarItem which contains label and icon to the toolbar.
+ /// </summary>
+ /// <param name="label">The label of the item</param>
+ /// <param name="icon">A string with the icon name or the absolute path of an image file</param>
+ /// <returns>The new <see cref="ToolbarItem"/> which prepended to the toolbar</returns>
+ /// <seealso cref="Append(string)"/>
+ /// <seealso cref="Append(string, string)"/>
+ /// <seealso cref="Prepend(string)"/>
+ public ToolbarItem Prepend(string label, string icon)
+ {
+ ToolbarItem item = new ToolbarItem(label, icon);
+ item.Handle = Interop.Elementary.elm_toolbar_item_prepend(RealHandle, icon, label, null, (IntPtr)item.Id);
+ return item;
+ }
+
+ /// <summary>
+ /// Inserts a new item which just contains label into the toolbar object before item <paramref name="before"/>.
+ /// </summary>
+ /// <param name="before">The toolbar item to insert before</param>
+ /// <param name="label">The label of the item</param>
+ /// <returns>The new <see cref="ToolbarItem"/> which insert into the toolbar</returns>
+ /// <seealso cref="InsertBefore(ToolbarItem, string, string)"/>
+ public ToolbarItem InsertBefore(ToolbarItem before, string label)
+ {
+ return InsertBefore(before, label, string.Empty);
+ }
+
+ /// <summary>
+ /// Inserts a new item which contains label and icon into the toolbar object before item <paramref name="before"/>.
+ /// </summary>
+ /// <param name="before">The toolbar item to insert before</param>
+ /// <param name="label">The label of the item</param>
+ /// <param name="icon">A string with the icon name or the absolute path of an image file</param>
+ /// <returns>The new <see cref="ToolbarItem"/> which insert into the toolbar</returns>
+ /// <seealso cref="InsertBefore(ToolbarItem, string)"/>
+ public ToolbarItem InsertBefore(ToolbarItem before, string label, string icon)
+ {
+ ToolbarItem item = new ToolbarItem(label, icon);
+ item.Handle = Interop.Elementary.elm_toolbar_item_insert_before(RealHandle, before, icon, label, null, (IntPtr)item.Id);
+ return item;
+ }
+
+ /// <summary>
+ /// Inserts a new item which contains label and icon into the toolbar object after item <paramref name="after"/>.
+ /// </summary>
+ /// <param name="after">The toolbar item to insert after</param>
+ /// <param name="label">The label of the item</param>
+ /// <param name="icon">A string with the icon name or the absolute path of an image file</param>
+ /// <returns>The new <see cref="ToolbarItem"/> which insert into the toolbar</returns>
+ /// <seealso cref="InsertAfter(ToolbarItem, string)"/>
+ public ToolbarItem InsertAfter(ToolbarItem after, string label, string icon)
+ {
+ ToolbarItem item = new ToolbarItem(label, icon);
+ item.Handle = Interop.Elementary.elm_toolbar_item_insert_after(RealHandle, after, icon, label, null, (IntPtr)item.Id);
+ return item;
+ }
+
+ /// <summary>
+ /// Find the item with that label in the toolbar.
+ /// </summary>
+ /// <param name="label">The label of the item</param>
+ /// <returns>The <see cref="ToolbarItem"/> into the toolbar</returns>
+ public ToolbarItem FindItemByLabel(string label)
+ {
+ IntPtr handle = Interop.Elementary.elm_toolbar_item_find_by_label(RealHandle, label);
+ return ItemObject.GetItemByHandle(handle) as ToolbarItem;
+ }
+
+ /// <summary>
+ /// Gets the selected ToolbarItemItem of the toolbar.
+ /// </summary>
+ public ToolbarItem SelectedItem
+ {
+ get
+ {
+ IntPtr handle = Interop.Elementary.elm_toolbar_selected_item_get(RealHandle);
+ return ItemObject.GetItemByHandle(handle) as ToolbarItem;
+ }
+ }
+
+ /// <summary>
+ /// Gets the first ToolbarItemItem of the toolbar.
+ /// </summary>
+ public ToolbarItem FirstItem
+ {
+ get
+ {
+ IntPtr handle = Interop.Elementary.elm_toolbar_first_item_get(RealHandle);
+ return ItemObject.GetItemByHandle(handle) as ToolbarItem;
+ }
+ }
+
+ /// <summary>
+ /// Gets the last ToolbarItemItem of the toolbar.
+ /// </summary>
+ public ToolbarItem LastItem
+ {
+ get
+ {
+ IntPtr handle = Interop.Elementary.elm_toolbar_last_item_get(RealHandle);
+ return ItemObject.GetItemByHandle(handle) as ToolbarItem;
+ }
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ IntPtr handle = Interop.Elementary.elm_layout_add(parent.Handle);
+ Interop.Elementary.elm_layout_theme_set(handle, "layout", "elm_widget", "default");
+
+ RealHandle = Interop.Elementary.elm_toolbar_add(handle);
+ Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
+
+ return handle;
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/ToolbarItem.cs b/src/ElmSharp/ElmSharp/ToolbarItem.cs
new file mode 100755
index 0000000..072baab
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/ToolbarItem.cs
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The ToolbarItem is a item of Toolbar.
+ /// </summary>
+ public class ToolbarItem : ItemObject
+ {
+ string _icon;
+ string _text;
+ internal ToolbarItem(string text, string icon) : base(IntPtr.Zero)
+ {
+ _text = text;
+ _icon = icon;
+ }
+
+ /// <summary>
+ /// Sets or gets the icon path of the item.
+ /// </summary>
+ public string Icon
+ {
+ get
+ {
+ return _icon;
+ }
+ set
+ {
+ _icon = value;
+ Interop.Elementary.elm_toolbar_item_icon_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the text string of the item.
+ /// </summary>
+ public string Text
+ {
+ get
+ {
+ return _text;
+ }
+ set
+ {
+ _text = value;
+ SetPartText(null, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the enable of the item.
+ /// </summary>
+ [Obsolete("Enabled is obsolete as of version v1.1.0-beta-023. Please use IsEnabled instead.")]
+ public bool Enabled
+ {
+ get
+ {
+ return IsEnabled;
+ }
+ set
+ {
+ IsEnabled = value;
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets whether displaying the item as a separator.
+ /// </summary>
+ /// <remarks>Items aren't set as a separator by default. If set as a separator it displays a separator theme, so it won't display icons or labels.</remarks>
+ public bool IsSeparator
+ {
+ get
+ {
+ return Interop.Elementary.elm_toolbar_item_separator_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_toolbar_item_separator_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets whether the item is selected.
+ /// </summary>
+ public bool IsSelected
+ {
+ get
+ {
+ return Interop.Elementary.elm_toolbar_item_selected_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_toolbar_item_selected_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Selected will be triggered when the item is selected.
+ /// </summary>
+ public event EventHandler Selected;
+
+ /// <summary>
+ /// LongPressed will be triggered when the item is pressed long time.
+ /// </summary>
+ public event EventHandler LongPressed;
+
+ /// <summary>
+ /// Clicked will be triggered when the item is clicked.
+ /// </summary>
+ public event EventHandler Clicked;
+
+ internal void SendSelected()
+ {
+ Selected?.Invoke(this, EventArgs.Empty);
+ }
+ internal void SendLongPressed()
+ {
+ LongPressed?.Invoke(this, EventArgs.Empty);
+ }
+ internal void SendClicked()
+ {
+ Clicked?.Invoke(this, EventArgs.Empty);
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/Transit.cs b/src/ElmSharp/ElmSharp/Transit.cs
new file mode 100755
index 0000000..8ee276a
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Transit.cs
@@ -0,0 +1,386 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Collections.Specialized;
+using static Interop.Elementary;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// Transit is designed to apply various animated transition effects, such like translation, rotation, etc.
+ /// For using these effects, create an Transit and add the desired transition effects.
+ /// </summary>
+ /// <remarks>Transit is not reusable. If the effect ends, the transit is destroyed automatically.</remarks>
+ public class Transit : IDisposable
+ {
+ IntPtr _handle = IntPtr.Zero;
+ bool _isDisposed = false;
+ ObservableCollection<EvasObject> _objects = new ObservableCollection<EvasObject>();
+ ObservableCollection<Transit> _chains = new ObservableCollection<Transit>();
+ HashSet<object> _checker = new HashSet<object>();
+ Elm_Transit_Del_Cb DeletedCallback;
+ Elm_Transit_Effect_End_Cb EffectEndCallback;
+ Elm_Transit_Effect_Transition_Cb EffectTransitionCallback;
+
+ /// <summary>
+ /// A callback called when the transit is deleted.
+ /// </summary>
+ public event EventHandler Deleted;
+
+ /// <summary>
+ /// Creates and initializes a new instance of Transit class.
+ /// </summary>
+ public Transit()
+ {
+ _handle = Interop.Elementary.elm_transit_add();
+ DeletedCallback = (ptr1, ptr2) => {
+ Deleted?.Invoke(this, EventArgs.Empty);
+ Dispose(true);
+ };
+ Interop.Elementary.elm_transit_del_cb_set(_handle, DeletedCallback, IntPtr.Zero);
+ ((INotifyCollectionChanged)_objects).CollectionChanged += OnObjectCollectionChanged;
+ ((INotifyCollectionChanged)_chains).CollectionChanged += OnChaninCollectionChanged;
+ }
+
+ ~Transit()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Gets or sets the transit animation time
+ /// </summary>
+ public double Duration
+ {
+ get
+ {
+ return Interop.Elementary.elm_transit_duration_get(_handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_transit_duration_set(_handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value whether the objects states will be keep or not.
+ /// If it is not kept, the objects states will be reset when transition ends.
+ /// </summary>
+ public bool ObjectStateKeep
+ {
+ get
+ {
+ return Interop.Elementary.elm_transit_objects_final_state_keep_get(_handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_transit_objects_final_state_keep_set(_handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the transit animation acceleration type.
+ /// </summary>
+ public TweenMode TweenMode
+ {
+ get
+ {
+ return (TweenMode)Interop.Elementary.elm_transit_tween_mode_get(_handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_transit_tween_mode_set(_handle, (int)value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the transit repeat count.
+ /// If the repeat is a negative number, it will repeat infinite times.
+ /// </summary>
+ public int Repeat
+ {
+ get
+ {
+ return Interop.Elementary.elm_transit_repeat_times_get(_handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_transit_repeat_times_set(_handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets if the auto reverse is on.
+ /// </summary>
+ public bool AutoReverse
+ {
+ get
+ {
+ return Interop.Elementary.elm_transit_auto_reverse_get(_handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_transit_auto_reverse_set(_handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the event enabled when transit is operating.
+ /// </summary>
+ public bool EventEnabled
+ {
+ get
+ {
+ return Interop.Elementary.elm_transit_event_enabled_get(_handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_transit_event_enabled_set(_handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the smooth scaling for transit map rendering
+ /// This gets smooth scaling for transit map rendering.
+ /// </summary>
+ public bool Smooth
+ {
+ get
+ {
+ return Interop.Elementary.elm_transit_smooth_get(_handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_transit_smooth_set(_handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Get the time progression of the animation (a double value between 0.0 and 1.0).
+ /// The value returned is a fraction(current time / total time).
+ /// It represents the progression position relative to the total.
+ /// </summary>
+ public double Progress
+ {
+ get
+ {
+ return Interop.Elementary.elm_transit_progress_value_get(_handle);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the transit animation tween mode acceleration factor.
+ /// </summary>
+ /// <returns>A factor value from 0.0 to 1.0.</returns>
+ public double BeginAccelerationFactor
+ {
+ get
+ {
+ double begin = 1.0, end = 0.0;
+ Interop.Elementary.elm_transit_tween_mode_factor_get(_handle, out begin, out end);
+ return begin;
+ }
+ set
+ {
+ Interop.Elementary.elm_transit_tween_mode_factor_set(_handle, value, EndAccelerationFactor);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the transit animation tween mode acceleration factor.
+ /// </summary>
+ /// <returns>A factor value from 0.0 to 1.0.</returns>
+ public double EndAccelerationFactor
+ {
+ get
+ {
+ double begin = 1.0, end = 0.0;
+ Interop.Elementary.elm_transit_tween_mode_factor_get(_handle, out begin, out end);
+ return end;
+ }
+ set
+ {
+ Interop.Elementary.elm_transit_tween_mode_factor_set(_handle, BeginAccelerationFactor, value);
+ }
+ }
+
+ /// <summary>
+ /// Starts the transition in given seconds.
+ /// Once this API is called, the transit begins to measure the time.
+ /// </summary>
+ /// <param name="interval">The interval value in seconds</param>
+ public void Go(double interval = 0)
+ {
+ Interop.Elementary.elm_transit_go_in(_handle, interval);
+ }
+
+ /// <summary>
+ /// Pause the transition.
+ /// </summary>
+ public void Pause()
+ {
+ if (Interop.Elementary.elm_transit_paused_get(_handle) == false)
+ Interop.Elementary.elm_transit_paused_set(_handle, true);
+ }
+
+ /// <summary>
+ /// Resume the transition.
+ /// </summary>
+ public void Resume()
+ {
+ if (Interop.Elementary.elm_transit_paused_get(_handle) == true)
+ Interop.Elementary.elm_transit_paused_set(_handle, false);
+ }
+
+ /// <summary>
+ /// Get the current chained transit list.
+ /// </summary>
+ /// <remarks>Cannot add the duplicate transit.</remarks>
+ public IList<Transit> Chains
+ {
+ get { return _chains; }
+ }
+
+ /// <summary>
+ /// Get the objects list of the transit.
+ /// </summary>
+ /// <remarks>Cannot add the duplicate object.</remarks>
+ public IList<EvasObject> Objects
+ {
+ get { return _objects; }
+ }
+
+ /// <summary>
+ /// Add the effect.
+ /// </summary>
+ /// <param name="effect">EffectBase object.</param>
+ public void AddEffect(EffectBase effect)
+ {
+ IntPtr _effect = effect.CreateEffect(_handle);
+ EffectEndCallback = (effectPtr, transitPtr) => { effect.SendEffectEnd(); };
+ EffectTransitionCallback = (effectPtr, transitPtr, progress) => { };
+ Interop.Elementary.elm_transit_effect_add(_handle, EffectTransitionCallback, _effect, EffectEndCallback);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool isDisposing)
+ {
+ if (_isDisposed)
+ return;
+
+ if (isDisposing)
+ {
+ ((INotifyCollectionChanged)_chains).CollectionChanged -= OnChaninCollectionChanged;
+ _chains.Clear();
+ ((INotifyCollectionChanged)_objects).CollectionChanged -= OnObjectCollectionChanged;
+ _objects.Clear();
+ _checker.Clear();
+ }
+
+ _isDisposed = true;
+ }
+
+ void OnObjectCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
+ {
+ if (e.Action == NotifyCollectionChangedAction.Add)
+ {
+ foreach (EvasObject item in e.NewItems)
+ AddObject(item);
+ }
+ else if (e.Action == NotifyCollectionChangedAction.Remove)
+ {
+ foreach (EvasObject item in e.OldItems)
+ RemoveObject(item);
+ }
+ }
+
+ void OnChaninCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
+ {
+ if (e.Action == NotifyCollectionChangedAction.Add)
+ {
+ foreach (Transit item in e.NewItems)
+ AddChainedTransit(item);
+ }
+ else if (e.Action == NotifyCollectionChangedAction.Remove)
+ {
+ foreach (Transit item in e.OldItems)
+ DeleteChainedTransit(item);
+ }
+ }
+
+ /// <summary>
+ /// Add new object to apply the effects.
+ /// After the first addition of an object to transit, if its object list become empty again, the transit will be killed.
+ /// If the obj belongs to another transit, the obj will be removed from it and it will only belong to the other transit.
+ /// </summary>
+ /// <remarks>It is not allowed to add a new object after transit begins.</remarks>
+ /// <param name="obj">Object to be animated.</param>
+ void AddObject(EvasObject obj)
+ {
+ if (_checker.Contains(obj))
+ throw new Exception("Cannot add the duplicate object.");
+
+ _checker.Add(obj);
+ Interop.Elementary.elm_transit_object_add(_handle, obj);
+ }
+
+ /// <summary>
+ /// Removes an added object from the transit.
+ /// </summary>
+ /// <param name="obj">Object to be removed from transit.</param>
+ void RemoveObject(EvasObject obj)
+ {
+ if (_checker.Contains(obj))
+ _checker.Remove(obj);
+
+ Interop.Elementary.elm_transit_object_remove(_handle, obj);
+ }
+
+ /// <summary>
+ /// Makes the chain relationship between two transits.
+ /// </summary>
+ /// <param name="transit">The chain transit object. This transit will be operated after transit is done.</param>
+ void AddChainedTransit(Transit transit)
+ {
+ if (_checker.Contains(transit))
+ throw new Exception("Cannot add the duplicate transit.");
+
+ _checker.Add(transit);
+ Interop.Elementary.elm_transit_chain_transit_add(_handle, transit._handle);
+ }
+
+ /// <summary>
+ /// Cut off the chain relationship between two transits.
+ /// </summary>
+ /// <param name="transit">The chain transit object.</param>
+ void DeleteChainedTransit(Transit transit)
+ {
+ if (_checker.Contains(transit))
+ _checker.Remove(transit);
+
+ Interop.Elementary.elm_transit_chain_transit_del(_handle, transit._handle);
+ }
+ }
+}
diff --git a/src/ElmSharp/ElmSharp/TransitEffect.cs b/src/ElmSharp/ElmSharp/TransitEffect.cs
new file mode 100755
index 0000000..fd29499
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/TransitEffect.cs
@@ -0,0 +1,461 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// The axis along which flip effect should be applied.
+ /// </summary>
+ public enum FlipAxis
+ {
+ /// <summary>
+ /// Flip on X axis
+ /// </summary>
+ X,
+
+ /// <summary>
+ /// Flip on Y axis
+ /// </summary>
+ Y,
+ }
+
+ /// <summary>
+ /// The direction in which the wipe effect should occur.
+ /// </summary>
+ public enum WipeDirection
+ {
+ /// <summary>
+ /// Wipe to the left
+ /// </summary>
+ Left,
+
+ /// <summary>
+ /// Wipe to the right
+ /// </summary>
+ Right,
+
+ /// <summary>
+ /// Wipe to the up
+ /// </summary>
+ Up,
+
+ /// <summary>
+ /// Wipe to the down
+ /// </summary>
+ Down,
+ }
+
+ /// <summary>
+ /// Whether the wipe effect should show or hide the object.
+ /// </summary>
+ public enum WipeType
+ {
+ /// <summary>
+ /// Hide the object during the animation
+ /// </summary>
+ Hide,
+
+ /// <summary>
+ /// Show the object during the animation
+ /// </summary>
+ Show,
+ }
+
+ /// <summary>
+ /// The type of acceleration used in the transition.
+ /// </summary>
+ public enum TweenMode
+ {
+ /// <summary>
+ /// Constant speed
+ /// </summary>
+ Linear,
+
+ /// <summary>
+ /// Starts slow, increase speed over time, then decrease again and stop slowly, v1 being a power factor
+ /// </summary>
+ Sinusoidal,
+
+ /// <summary>
+ /// Starts fast and decrease speed over time, v1 being a power factor
+ /// </summary>
+ Decelerate,
+
+ /// <summary>
+ /// Starts slow and increase speed over time, v1 being a power factor
+ /// </summary>
+ Accelerate,
+
+ /// <summary>
+ /// Start at gradient v1, interpolated via power of v2 curve
+ /// </summary>
+ DivisorInterpolate,
+
+ /// <summary>
+ /// Start at 0.0 then "drop" like a ball bouncing to the ground at 1.0, and bounce v2 times, with decay factor of v1
+ /// </summary>
+ Bounce,
+
+ /// <summary>
+ /// Start at 0.0 then "wobble" like a spring rest position 1.0, and wobble v2 times, with decay factor of v1
+ /// </summary>
+ Spring,
+
+ /// <summary>
+ /// Follow the cubic-bezier curve calculated with the control points (x1, y1), (x2, y2)
+ /// </summary>
+ BezierCurve,
+ }
+
+ /// <summary>
+ /// Blend effect class.
+ /// </summary>
+ public class BlendEffect : EffectBase
+ {
+ /// <summary>
+ /// Creates and initializes a new instance of BlendEffect class.
+ /// </summary>
+ public BlendEffect()
+ {
+ }
+
+ internal override IntPtr CreateEffect(IntPtr transit)
+ {
+ return Interop.Elementary.elm_transit_effect_blend_add(transit);
+ }
+ }
+
+ /// <summary>
+ /// Color effect class.
+ /// </summary>
+ public class ColorEffect : EffectBase
+ {
+ Color _begin;
+ Color _end;
+
+ /// <summary>
+ /// Creates and initializes a new instance of ColorEffect class.
+ /// </summary>
+ /// <param name="beginColor">The begin color of the effect</param>
+ /// <param name="endColor">The end color of the effect</param>
+ public ColorEffect(Color beginColor, Color endColor)
+ {
+ _begin = beginColor;
+ _end = endColor;
+ }
+
+ /// <summary>
+ /// The begin color of the effect
+ /// </summary>
+ public Color BeginColor
+ {
+ get { return _begin; }
+ }
+
+ /// <summary>
+ /// The end color of the effect
+ /// </summary>
+ public Color EndColor
+ {
+ get { return _end; }
+ }
+
+ internal override IntPtr CreateEffect(IntPtr transit)
+ {
+ return Interop.Elementary.elm_transit_effect_color_add(transit, _begin.R, _begin.G, _begin.B, _begin.A, _end.R, _end.G, _end.B, _end.A);
+ }
+ }
+
+ /// <summary>
+ /// Fade effect class.
+ /// </summary>
+ public class FadeEffect : EffectBase
+ {
+ /// <summary>
+ /// Creates and initializes a new instance of FadeEffect class.
+ /// </summary>
+ public FadeEffect()
+ {
+ }
+
+ internal override IntPtr CreateEffect(IntPtr transit)
+ {
+ return Interop.Elementary.elm_transit_effect_fade_add(transit);
+ }
+ }
+
+ /// <summary>
+ /// Flip effect class.
+ /// </summary>
+ public class FlipEffect : EffectBase
+ {
+ FlipAxis _axis;
+ bool _clockWise;
+ bool _resizable;
+
+ /// <summary>
+ /// Creates and initializes a new instance of FlipEffect class.
+ /// </summary>
+ /// <param name="axis">Flipping Axis(X or Y).</param>
+ /// <param name="clockWise">Flipping Direction. True is clock-wise.</param>
+ /// <param name="resizable">Resizable effect with FlipEffect</param>
+ public FlipEffect(FlipAxis axis, bool clockWise, bool resizable = false)
+ {
+ _axis = axis;
+ _clockWise = clockWise;
+ _resizable = resizable;
+ }
+
+ /// <summary>
+ /// Flipping Axis(X or Y).
+ /// </summary>
+ public FlipAxis Axis
+ {
+ get { return _axis; }
+ }
+
+ /// <summary>
+ /// Flipping Direction. True is clock-wise.
+ /// </summary>
+ public bool ClockWise
+ {
+ get { return _clockWise; }
+ }
+
+ /// <summary>
+ /// Resizable FlipEffect.
+ /// </summary>
+ public bool Resizable
+ {
+ get { return _resizable; }
+ }
+
+ internal override IntPtr CreateEffect(IntPtr transit)
+ {
+ if (_resizable)
+ return Interop.Elementary.elm_transit_effect_resizable_flip_add(transit, (int)_axis, _clockWise);
+ return Interop.Elementary.elm_transit_effect_flip_add(transit, (int)_axis, _clockWise);
+ }
+ }
+
+ /// <summary>
+ /// Resizing effect class.
+ /// </summary>
+ public class ResizingEffect : EffectBase
+ {
+ Size _begin;
+ Size _end;
+
+ /// <summary>
+ /// Creates and initializes a new instance of FlipEffect class.
+ /// </summary>
+ /// <param name="beginSize">The begin Size of the effect</param>
+ /// <param name="endSize">The end Size of the effect</param>
+ public ResizingEffect(Size beginSize, Size endSize)
+ {
+ _begin = beginSize;
+ _end = endSize;
+ }
+
+ /// <summary>
+ /// The begin Size of the effect
+ /// </summary>
+ public Size BeginSize
+ {
+ get { return _begin; }
+ }
+
+ /// <summary>
+ /// The end Size of the effect
+ /// </summary>
+ public Size EndSize
+ {
+ get { return _end; }
+ }
+
+ internal override IntPtr CreateEffect(IntPtr transit)
+ {
+ return Interop.Elementary.elm_transit_effect_resizing_add(transit, _begin.Width, _begin.Height, _end.Width, _end.Height);
+ }
+ }
+
+ /// <summary>
+ /// Rotation effect class.
+ /// </summary>
+ public class RotationEffect : EffectBase
+ {
+ float _begin;
+ float _end;
+
+ /// <summary>
+ /// Creates and initializes a new instance of RotationEffect class.
+ /// </summary>
+ /// <param name="beginDegree">The begin degree of the effect</param>
+ /// <param name="endDegree">The end degree of the effect</param>
+ public RotationEffect(float beginDegree, float endDegree)
+ {
+ _begin = beginDegree;
+ _end = endDegree;
+ }
+
+ /// <summary>
+ /// The begin degree of the effect
+ /// </summary>
+ public float BeginDegree
+ {
+ get { return _begin; }
+ }
+
+ /// <summary>
+ /// The end degree of the effect
+ /// </summary>
+ public float EndDegree
+ {
+ get { return _end; }
+ }
+
+ internal override IntPtr CreateEffect(IntPtr transit)
+ {
+ return Interop.Elementary.elm_transit_effect_rotation_add(transit, _begin, _end);
+ }
+ }
+
+ /// <summary>
+ /// Translation effect class.
+ /// </summary>
+ public class TranslationEffect : EffectBase
+ {
+ Point _begin;
+ Point _end;
+
+ /// <summary>
+ /// Creates and initializes a new instance of FlipEffect class.
+ /// </summary>
+ /// <param name="beginPoint">The begin Point of the effect</param>
+ /// <param name="endPoint">The end Point of the effect</param>
+ public TranslationEffect(Point beginPoint, Point endPoint)
+ {
+ _begin = beginPoint;
+ _end = endPoint;
+ }
+
+ /// <summary>
+ /// The begin Point of the effect
+ /// </summary>
+ public Point BeginPoint
+ {
+ get { return _begin; }
+ }
+
+ /// <summary>
+ /// The end Point of the effect
+ /// </summary>
+ public Point EndPoint
+ {
+ get { return _end; }
+ }
+
+ internal override IntPtr CreateEffect(IntPtr transit)
+ {
+ return Interop.Elementary.elm_transit_effect_translation_add(transit, _begin.X, _begin.Y, _end.X, _end.Y);
+ }
+ }
+
+ /// <summary>
+ /// Wipe effect class.
+ /// </summary>
+ public class WipeEffect : EffectBase
+ {
+ WipeType _type;
+ WipeDirection _direction;
+
+ /// <summary>
+ /// Creates and initializes a new instance of WipeEffect class.
+ /// </summary>
+ /// <param name="type">Wipe type. Hide or show.</param>
+ /// <param name="direction">Wipe Direction.</param>
+ public WipeEffect(WipeType type, WipeDirection direction)
+ {
+ _type = type;
+ _direction = direction;
+ }
+
+ /// <summary>
+ /// Wipe type. Hide or show.
+ /// </summary>
+ public WipeType Type
+ {
+ get { return _type; }
+ }
+
+ /// <summary>
+ /// Wipe Direction.
+ /// </summary>
+ public WipeDirection Direction
+ {
+ get { return _direction; }
+ }
+
+ internal override IntPtr CreateEffect(IntPtr transit)
+ {
+ return Interop.Elementary.elm_transit_effect_wipe_add(transit, (int)_type, (int)_direction);
+ }
+ }
+
+ /// <summary>
+ /// Zoom effect class.
+ /// </summary>
+ public class ZoomEffect : EffectBase
+ {
+ float _begin;
+ float _end;
+
+ /// <summary>
+ /// Creates and initializes a new instance of ZoomEffect class.
+ /// </summary>
+ /// <param name="beginRate">The begin rate of the effect</param>
+ /// <param name="endRate">The end rate of the effect</param>
+ public ZoomEffect(float beginRate, float endRate)
+ {
+ _begin = beginRate;
+ _end = endRate;
+ }
+
+ /// <summary>
+ /// The begin rate of the effect
+ /// </summary>
+ public float BeginRate
+ {
+ get { return _begin; }
+ }
+
+ /// <summary>
+ /// The end rate of the effect
+ /// </summary>
+ public float EndRate
+ {
+ get { return _end; }
+ }
+
+ internal override IntPtr CreateEffect(IntPtr transit)
+ {
+ return Interop.Elementary.elm_transit_effect_zoom_add(transit, _begin, _end);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/Utility.cs b/src/ElmSharp/ElmSharp/Utility.cs
new file mode 100644
index 0000000..baff802
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Utility.cs
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace ElmSharp
+{
+ public static class Utility
+ {
+ /// <summary>
+ /// Appends a font path to the list of font paths used by the application.
+ /// </summary>
+ /// <param name="path">The new font path.</param>
+ public static void AppendGlobalFontPath(string path)
+ {
+ Interop.Evas.evas_font_path_global_append(path);
+ }
+
+ /// <summary>
+ /// Prepends a font path to the list of font paths used by the application.
+ /// </summary>
+ /// <param name="path">The new font path.</param>
+ public static void PrependEvasGlobalFontPath(string path)
+ {
+ Interop.Evas.evas_font_path_global_prepend(path);
+ }
+
+ /// <summary>
+ /// Removes all font paths loaded into memory by evas_font_path_app_* APIs for the application.
+ /// </summary>
+ public static void ClearEvasGlobalFontPath()
+ {
+ Interop.Evas.evas_font_path_global_clear();
+ }
+
+ /// <summary>
+ /// Sets Edje color class.
+ /// </summary>
+ /// <param name="colorClass">Color class</param>
+ /// <param name="red">Object Red value</param>
+ /// <param name="green">Object Red value</param>
+ /// <param name="blue">Object Red value</param>
+ /// <param name="alpha">Object Red value</param>
+ /// <param name="outlineRed">Outline Red value</param>
+ /// <param name="outlineGreen">Outline Green value</param>
+ /// <param name="outlineBlue">Outline Blue value</param>
+ /// <param name="outlineAlpha">Outline Alpha value</param>
+ /// <param name="shadowRed">Shadow Red value</param>
+ /// <param name="shadowGreen">Shadow Green value</param>
+ /// <param name="shadowBlue">Shadow Bluevalue</param>
+ /// <param name="shadowAlpha">Shadow Alpha value</param>
+ /// <returns></returns>
+ public static bool SetEdjeColorClass(string colorClass, int red, int green, int blue, int alpha, int outlineRed, int outlineGreen, int outlineBlue, int outlineAlpha,
+ int shadowRed, int shadowGreen, int shadowBlue, int shadowAlpha)
+ {
+ return Interop.Elementary.edje_color_class_set(colorClass, red, green, blue, alpha, outlineRed, outlineGreen, outlineBlue, outlineAlpha, shadowRed, shadowGreen, shadowBlue, shadowAlpha);
+ }
+
+ /// <summary>
+ /// Gets Edje color class.
+ /// </summary>
+ /// <param name="colorClass">Color class</param>
+ /// <param name="red">Object Red value</param>
+ /// <param name="green">Object Red value</param>
+ /// <param name="blue">Object Red value</param>
+ /// <param name="alpha">Object Red value</param>
+ /// <param name="outlineRed">Outline Red value</param>
+ /// <param name="outlineGreen">Outline Green value</param>
+ /// <param name="outlineBlue">Outline Blue value</param>
+ /// <param name="outlineAlpha">Outline Alpha value</param>
+ /// <param name="shadowRed">Shadow Red value</param>
+ /// <param name="shadowGreen">Shadow Green value</param>
+ /// <param name="shadowBlue">Shadow Bluevalue</param>
+ /// <param name="shadowAlpha">Shadow Alpha value</param>
+ /// <returns></returns>
+ public static bool GetEdjeColorClass(string colorClass, out int red, out int green, out int blue, out int alpha, out int outlineRed, out int outlineGreen, out int outlineBlue,
+ out int outlineAlpha, out int shadowRed, out int shadowGreen, out int shadowBlue, out int shadowAlpha)
+ {
+ return Interop.Elementary.edje_color_class_get(colorClass, out red, out green, out blue, out alpha, out outlineRed, out outlineGreen, out outlineBlue, out outlineAlpha,
+ out shadowRed, out shadowGreen, out shadowBlue, out shadowAlpha);
+ }
+
+ /// <summary>
+ /// Processes all queued up edje messages.
+ /// This function triggers the processing of messages addressed to any (alive) edje objects.
+ /// </summary>
+ public static void ProcessEdjeMessageSignal()
+ {
+ Interop.Elementary.edje_message_signal_process();
+ }
+
+ /// <summary>
+ /// Sets the Edje text class.
+ /// </summary>
+ /// <param name="textClass">The text class name</param>
+ /// <param name="font">The font name</param>
+ /// <param name="size">The font size</param>
+ /// <returns>True, on success or false, on error</returns>
+ public static bool SetEdjeTextClass(string textClass, string font, int size)
+ {
+ return Interop.Elementary.edje_text_class_set(textClass, font, size);
+ }
+
+ /// <summary>
+ /// Gets the Edje text class.
+ /// </summary>
+ /// <param name="textClass">The text class name</param>
+ /// <param name="font">The font name</param>
+ /// <param name="size">The font size</param>
+ /// <returns>True, on success or false, on error</returns>
+ public static bool GetEdjeTextClass(string textClass, out string font, out int size)
+ {
+ return Interop.Elementary.edje_text_class_get(textClass, out font, out size);
+ }
+
+ /// <summary>
+ /// Delete the text class.
+ /// </summary>
+ /// <param name="textClass"></param>
+ public static void DeleteEdjeTextClass(string textClass)
+ {
+ Interop.Elementary.edje_text_class_del(textClass);
+ }
+
+ /// <summary>
+ /// Pre-multiplies a rgb triplet by an alpha factor.
+ /// </summary>
+ /// <param name="alpha">The alpha factor</param>
+ /// <param name="red">The Red component of the color</param>
+ /// <param name="green">The Green component of the color</param>
+ /// <param name="blue">The Blue component of the color</param>
+ public static void PremulityplyEvasColorByAlpha(int alpha, ref int red, ref int green, ref int blue)
+ {
+ Interop.Evas.evas_color_argb_premul(alpha, ref red, ref green, ref blue);
+ }
+
+ /// <summary>
+ /// Undoes pre-multiplies a rgb triplet by an alpha factor.
+ /// </summary>
+ /// <param name="alpha">The alpha factor</param>
+ /// <param name="red">The Red component of the color</param>
+ /// <param name="green">The Green component of the color</param>
+ /// <param name="blue">The Blue component of the color</param>
+ public static void UnPremulityplyEvasColorByAlpha(int alpha, ref int red, ref int green, ref int blue)
+ {
+ Interop.Evas.evas_color_argb_unpremul(alpha, ref red, ref green, ref blue);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/Widget.cs b/src/ElmSharp/ElmSharp/Widget.cs
new file mode 100755
index 0000000..f1df744
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Widget.cs
@@ -0,0 +1,442 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using ElmSharp.Accessible;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// Enumeration for the focus direction.
+ /// </summary>
+ public enum FocusDirection
+ {
+ /// <summary>
+ /// Previous direction
+ /// </summary>
+ Previous,
+
+ /// <summary>
+ /// Next direction
+ /// </summary>
+ Next,
+
+ /// <summary>
+ /// Up direction
+ /// </summary>
+ Up,
+
+ /// <summary>
+ /// Down direction
+ /// </summary>
+ Down,
+
+ /// <summary>
+ /// Right direction
+ /// </summary>
+ Right,
+
+ /// <summary>
+ /// Left direction
+ /// </summary>
+ Left
+ }
+
+ /// <summary>
+ /// The Widget is abstract class, it is the parent of other widgets.
+ /// Inherits from <see cref="EvasObject"/>.
+ /// </summary>
+ public abstract class Widget : AccessibleObject
+ {
+ Dictionary<string, EvasObject> _partContents = new Dictionary<string, EvasObject>();
+
+ SmartEvent _focused;
+ SmartEvent _unfocused;
+
+ internal Color _backgroundColor = Color.Default;
+ internal int _opacity = Color.Default.A;
+
+ protected Widget()
+ {
+ }
+
+ /// <summary>
+ /// Creates and initializes a new instance of the Widget class.
+ /// </summary>
+ /// <param name="parent">The parent of new Widget instance</param>
+ protected Widget(EvasObject parent) : base(parent)
+ {
+ _focused = new SmartEvent(this, "focused");
+ _focused.On += (s, e) => Focused?.Invoke(this, EventArgs.Empty);
+
+ _unfocused = new SmartEvent(this, "unfocused");
+ _unfocused.On += (s, e) => Unfocused?.Invoke(this, EventArgs.Empty);
+ }
+
+ /// <summary>
+ /// Update the part contents
+ /// </summary>
+ /// <param name="content">The content which put to the part</param>
+ /// <param name="part">The updated part</param>
+ protected void UpdatePartContents(EvasObject content, string part = "__default__")
+ {
+ _partContents[part] = content;
+ }
+
+ /// <summary>
+ /// Focused will be triggered when the widget is focused.
+ /// </summary>
+ public event EventHandler Focused;
+
+ /// <summary>
+ /// Unfocused will be triggered when the widget is unfocused.
+ /// </summary>
+ public event EventHandler Unfocused;
+
+ /// <summary>
+ /// Sets or gets the state of the widget, which might be enabled or disabled.
+ /// </summary>
+ public bool IsEnabled
+ {
+ get
+ {
+ return !Interop.Elementary.elm_object_disabled_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_object_disabled_set(RealHandle, !value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the style of the widget.
+ /// </summary>
+ public string Style
+ {
+ get
+ {
+ return Interop.Elementary.elm_object_style_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_object_style_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets whether this widget is focused.
+ /// </summary>
+ public bool IsFocused
+ {
+ get
+ {
+ return Interop.Elementary.elm_object_focus_get(RealHandle);
+ }
+ }
+
+ /// <summary>
+ /// Gets whether a widget is focusable or not.
+ /// </summary>
+ /// <remarks>Widgets which are meant to be interacted with by input events are created able to be focused, by default</remarks>
+ public bool IsFocusAllowed
+ {
+ get
+ {
+ return Interop.Elementary.elm_object_focus_allow_get(RealHandle);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the text of the widget.
+ /// </summary>
+ /// <remarks>It could be override by special child class</remarks>
+ public virtual string Text
+ {
+ get
+ {
+ return Interop.Elementary.elm_object_part_text_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_object_part_text_set(RealHandle, IntPtr.Zero, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the background color of the widget.
+ /// </summary>
+ /// <remarks>It could be override by special child class</remarks>
+ public virtual Color BackgroundColor
+ {
+ get
+ {
+ if (!_backgroundColor.IsDefault)
+ {
+ _backgroundColor = GetPartColor("bg");
+ }
+ return _backgroundColor;
+ }
+ set
+ {
+ if (value.IsDefault)
+ {
+ Console.WriteLine("Widget instance doesn't support to set BackgroundColor to Color.Default.");
+ }
+ else
+ {
+ SetPartColor("bg", value);
+ _backgroundColor = value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the opacity of the widget.
+ /// </summary>
+ /// <remarks>It could be override by special child class</remarks>
+ public virtual int Opacity
+ {
+ get
+ {
+ if (_opacity != Color.Default.A)
+ {
+ _opacity = GetPartOpacity("opacity");
+ }
+ return _opacity;
+ }
+ set
+ {
+ SetPartOpacity("opacity", value);
+ _opacity = value;
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets whether a widget and its children are focusable or not.
+ /// </summary>
+ public bool AllowTreeFocus
+ {
+ get
+ {
+ return Interop.Elementary.elm_object_tree_focus_allow_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_object_tree_focus_allow_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the widget's mirrored mode.
+ /// </summary>
+ public bool IsMirroredMode
+ {
+ get
+ {
+ return Interop.Elementary.elm_object_mirrored_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_object_mirrored_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the widget's mirrored mode setting.
+ /// When widget set automatic mode(true), it follows the system mirrored mode.
+ /// </summary>
+ public bool IsAutoMirroredMode
+ {
+ get
+ {
+ return Interop.Elementary.elm_object_mirrored_automatic_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_object_mirrored_automatic_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets the widget to be focused or not.
+ /// </summary>
+ /// <param name="isFocus">Weather be focused</param>
+ public void SetFocus(bool isFocus)
+ {
+ Interop.Elementary.elm_object_focus_set(RealHandle, isFocus);
+ }
+
+ /// <summary>
+ /// Sets the ability for a widget to be focused.
+ /// </summary>
+ /// <param name="isAllowFocus">True if the object can be focused, false if not(and on errors)</param>
+ public void AllowFocus(bool isAllowFocus)
+ {
+ Interop.Elementary.elm_object_focus_allow_set(RealHandle, isAllowFocus);
+ }
+
+ /// <summary>
+ /// Gives focus to next widget in widget tree.
+ /// </summary>
+ /// <param name="direction">Direction to move the focus</param>
+ public void FocusNext(FocusDirection direction)
+ {
+ Interop.Elementary.elm_object_focus_next(RealHandle, (int)direction);
+ }
+
+ /// <summary>
+ /// Set next widget with specific focus direction.
+ /// </summary>
+ /// <param name="next">Focus next widget</param>
+ /// <param name="direction">Focus direction</param>
+ public void SetNextFocusObject(EvasObject next, FocusDirection direction)
+ {
+ Interop.Elementary.elm_object_focus_next_object_set(RealHandle, next.RealHandle, (int)direction);
+ }
+
+ /// <summary>
+ /// Sets content to particular part of the widget, and the preserve old content will not be unset.
+ /// </summary>
+ /// <param name="part">The name of particular part</param>
+ /// <param name="content">The content</param>
+ /// <seealso cref="SetPartContent(string, EvasObject, bool)"/>
+ public virtual bool SetPartContent(string part, EvasObject content)
+ {
+ return SetPartContent(part, content, false);
+ }
+
+ /// <summary>
+ /// Sets content to particular part of the widget.
+ /// </summary>
+ /// <param name="part">The name of particular part</param>
+ /// <param name="content">The content</param>
+ /// <param name="preserveOldContent">true, preserve old content will be unset. false, preserve old content will not be unset.</param>
+ /// <seealso cref="SetPartContent(string, EvasObject)"/>
+ public virtual bool SetPartContent(string part, EvasObject content, bool preserveOldContent)
+ {
+ if (preserveOldContent)
+ {
+ Interop.Elementary.elm_object_part_content_unset(RealHandle, part);
+ }
+ Interop.Elementary.elm_object_part_content_set(RealHandle, part, content);
+ UpdatePartContents(content, part);
+ return true;
+ }
+
+ /// <summary>
+ /// Sets content to the widget, and the preserve old content will not be unset.
+ /// </summary>
+ /// <param name="content">The content</param>
+ /// <seealso cref="SetContent(EvasObject, bool)"/>
+ public void SetContent(EvasObject content)
+ {
+ SetContent(content, false);
+ }
+
+ /// <summary>
+ /// Sets content the widget.
+ /// </summary>
+ /// <param name="content">The content</param>
+ /// <param name="preserveOldContent">true, preserve old content will be unset. false, preserve old content will not be unset.</param>
+ /// <seealso cref="SetContent(EvasObject)"/>
+ public void SetContent(EvasObject content, bool preserveOldContent)
+ {
+ if (preserveOldContent)
+ {
+ Interop.Elementary.elm_object_content_unset(RealHandle);
+ }
+
+ Interop.Elementary.elm_object_content_set(RealHandle, content);
+ UpdatePartContents(content);
+ }
+
+ /// <summary>
+ /// Sets text to particular part of the widget.
+ /// </summary>
+ /// <param name="part">The name of particular part</param>
+ /// <param name="text">The text</param>
+ public virtual bool SetPartText(string part, string text)
+ {
+ Interop.Elementary.elm_object_part_text_set(RealHandle, part, text);
+ return true;
+ }
+
+ /// <summary>
+ /// Gets text of a particular part of the widget.
+ /// </summary>
+ /// <param name="part">The name of particular part</param>
+ /// <returns>Text of the particular part of the widget</returns>
+ public virtual string GetPartText(string part)
+ {
+ return Interop.Elementary.elm_object_part_text_get(RealHandle, part);
+ }
+
+ /// <summary>
+ /// Sets color of a particular part of the widget.
+ /// </summary>
+ /// <param name="part">The name of particular part</param>
+ /// <param name="color">The color be set to widget</param>
+ /// <remarks>This method is a virtual method, it could be override by special child class</remarks>
+ public virtual void SetPartColor(string part, Color color)
+ {
+ Interop.Elementary.elm_object_color_class_color_set(RealHandle, part, color.R * color.A / 255,
+ color.G * color.A / 255,
+ color.B * color.A / 255,
+ color.A);
+ }
+
+ /// <summary>
+ /// Gets color of the particular part of the widget.
+ /// </summary>
+ /// <param name="part">The name of particular part</param>
+ /// <returns>The color of the particular part</returns>
+ /// <remarks>This method is a virtual method, it could be override by special child class</remarks>
+ public virtual Color GetPartColor(string part)
+ {
+ int r, g, b, a;
+ Interop.Elementary.elm_object_color_class_color_get(RealHandle, part, out r, out g, out b, out a);
+ return new Color((int)(r / (a / 255.0)), (int)(g / (a / 255.0)), (int)(b / (a / 255.0)), a);
+ }
+
+ /// <summary>
+ /// Sets opacity of the particular part of the widget.
+ /// </summary>
+ /// <param name="part">The name of particular part</param>
+ /// <param name="opacity">The opacity of the particular part</param>
+ public void SetPartOpacity(string part, int opacity)
+ {
+ Interop.Elementary.elm_object_color_class_color_set(Handle, part, 255, 255, 255, opacity);
+ }
+
+ /// <summary>
+ /// Gets opacity of the particular part of the widget.
+ /// </summary>
+ /// <param name="part">The name of particular part</param>
+ /// <returns>Opacity value of the particular part</returns>
+ public int GetPartOpacity(string part)
+ {
+ int r, g, b, a;
+ Interop.Elementary.elm_object_color_class_color_get(Handle, part, out r, out g, out b, out a);
+ return a;
+ }
+
+ internal IntPtr GetPartContent(string part)
+ {
+ return Interop.Elementary.elm_object_part_content_get(RealHandle, part);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/Window.cs b/src/ElmSharp/ElmSharp/Window.cs
new file mode 100644
index 0000000..71d18f5
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/Window.cs
@@ -0,0 +1,1058 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// Enumeration for the display rotation of window.
+ /// </summary>
+ [Flags]
+ public enum DisplayRotation
+ {
+ /// <summary>
+ /// Rotation value of window is 0 degree
+ /// </summary>
+ Degree_0 = 1,
+
+ /// <summary>
+ /// Rotation value of window is 90 degree
+ /// </summary>
+ Degree_90 = 2,
+
+ /// <summary>
+ /// Rotation value of window is 180 degree
+ /// </summary>
+ Degree_180 = 4,
+
+ /// <summary>
+ /// Rotation value of window is 270 degree
+ /// </summary>
+ Degree_270 = 8
+ };
+
+ /// <summary>
+ /// Enumeration for the indicator opacity
+ /// </summary>
+ public enum StatusBarMode
+ {
+ /// <summary>
+ /// Opacifies the status bar
+ /// </summary>
+ Opaque = 1,
+
+ /// <summary>
+ /// Be translucent the status bar
+ /// </summary>
+ /// <remarks>
+ /// Not supported.
+ /// </remarks>
+ Translucent = 2,
+
+ /// <summary>
+ /// Transparentizes the status bar
+ /// </summary>
+ Transparent = 3,
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public enum KeyGrabMode
+ {
+ Shared = 256,
+ Topmost = 512,
+ Exclusive = 1024,
+ OverrideExclusive = 2048,
+ }
+
+ /// <summary>
+ /// Enumeration for the indicator mode.
+ /// </summary>
+ public enum IndicatorMode
+ {
+ /// <summary>
+ /// Unknown indicator state.
+ /// </summary>
+ Unknown = 0,
+
+ /// <summary>
+ /// Hides the indicator.
+ /// </summary>
+ Hide,
+
+ /// <summary>
+ /// Shows the indicator.
+ /// </summary>
+ Show,
+ };
+
+ /// <summary>
+ /// Enumeration for the keyboard mode
+ /// </summary>
+ public enum KeyboardMode
+ {
+ /// <summary>
+ /// Unknown keyboard state
+ /// </summary>
+ Unknown,
+
+ /// <summary>
+ /// Request to deactivate the keyboard
+ /// </summary>
+ Off,
+
+ /// <summary>
+ /// Enable keyboard with default layout
+ /// </summary>
+ On,
+
+ /// <summary>
+ /// Alpha (a-z) keyboard layout
+ /// </summary>
+ Alpha,
+
+ /// <summary>
+ /// Numeric keyboard layout
+ /// </summary>
+ Numeric,
+
+ /// <summary>
+ /// PIN keyboard layout
+ /// </summary>
+ Pin,
+
+ /// <summary>
+ /// Phone keyboard layout
+ /// </summary>
+ PhoneNumber,
+
+ /// <summary>
+ /// Hexadecimal numeric keyboard layout
+ /// </summary>
+ Hex,
+
+ /// <summary>
+ /// Full (QWERTY) keyboard layout
+ /// </summary>
+ QWERTY,
+
+ /// <summary>
+ /// Password keyboard layout
+ /// </summary>
+ Password,
+
+ /// <summary>
+ /// IP keyboard layout
+ /// </summary>
+ IP,
+
+ /// <summary>
+ /// Host keyboard layout
+ /// </summary>
+ Host,
+
+ /// <summary>
+ /// File keyboard layout
+ /// </summary>
+ File,
+
+ /// <summary>
+ /// URL keyboard layout
+ /// </summary>
+ URL,
+
+ /// <summary>
+ /// Keypad layout
+ /// </summary>
+ Keypad,
+
+ /// <summary>
+ /// J2ME keyboard layout
+ /// </summary>
+ J2ME,
+ };
+
+ /// <summary>
+ /// Enumeration for the window type
+ /// </summary>
+ public enum WindowType
+ {
+ /// <summary>
+ /// Unknown
+ /// </summary>
+ Unknown,
+
+ /// <summary>
+ /// A normal window. Indicates a normal, top-level window. Almost every window will be created with this type.
+ /// </summary>
+ Basic,
+
+ /// <summary>
+ /// Used for simple dialog windows.
+ /// </summary>
+ Dialog,
+
+ /// <summary>
+ /// For special desktop windows, like a background window holding desktop icons.
+ /// </summary>
+ Desktop,
+
+ /// <summary>
+ /// The window is used as a dock or panel. Usually would be kept on top of any other window by the Window Manager.
+ /// </summary>
+ Dock,
+
+ /// <summary>
+ /// The window is used to hold a floating toolbar, or similar.
+ /// </summary>
+ Toolbar,
+
+ /// <summary>
+ /// Similar to Toolbar.
+ /// </summary>
+ Menu,
+
+ /// <summary>
+ /// A persistent utility window, like a toolbox or palette.
+ /// </summary>
+ Utility,
+
+ /// <summary>
+ /// Splash window for a starting up application.
+ /// </summary>
+ Splash,
+
+ /// <summary>
+ /// The window is a dropdown menu, as when an entry in a menubar is clicked.
+ /// </summary>
+ DropdownMenu,
+
+ /// <summary>
+ /// Like DropdownMenu, but for the menu triggered by right-clicking an object.
+ /// </summary>
+ PopupMenu,
+
+ /// <summary>
+ /// The window is a tooltip. A short piece of explanatory text that typically appear after the mouse cursor hovers over an object for a while.
+ /// </summary>
+ Tooltip,
+
+ /// <summary>
+ /// A notification window, like a warning about battery life or a new E-Mail received.
+ /// </summary>
+ Notification,
+
+ /// <summary>
+ /// A window holding the contents of a combo box.
+ /// </summary>
+ Combo,
+
+ /// <summary>
+ /// Used to indicate the window is a representation of an object being dragged across different windows, or even applications.
+ /// </summary>
+ DragAndDrop,
+
+ /// <summary>
+ /// The window is rendered onto an image buffer. No actual window is created for this type, instead the window and all of its contents will be rendered to an image buffer.
+ /// This allows to have children window inside a parent one just like any other object would be, and do other things like applying Evas_Map effects to it.
+ /// </summary>
+ InlinedImage,
+
+ /// <summary>
+ /// The window is rendered onto an image buffer and can be shown other process's plug image object.
+ /// No actual window is created for this type, instead the window and all of its contents will be rendered to an image buffer and can be shown other process's plug image object.
+ /// </summary>
+ SocketImage,
+
+ /// <summary>
+ /// This window was created using a pre-existing canvas. The window widget can be deleted, but the canvas must be managed externally.
+ /// </summary>
+ Fake,
+ };
+
+ /// <summary>
+ /// The Window is container that contain the graphical user interface of a program.
+ /// </summary>
+ public class Window : Widget
+ {
+ SmartEvent _deleteRequest;
+ SmartEvent _rotationChanged;
+ HashSet<EvasObject> _referenceHolder = new HashSet<EvasObject>();
+
+ /// <summary>
+ /// Creates and initializes a new instance of the Window class.
+ /// </summary>
+ /// <param name="name">Window name.</param>
+ public Window(string name) : this(null, name)
+ {
+ }
+
+ /// <summary>
+ /// Creates and initializes a new instance of the Window class.
+ /// </summary>
+ /// <param name="parent">
+ /// Parent widget which this widow created on.
+ /// </param>
+ /// <param name="name">
+ /// Window name.
+ /// </param>
+ /// <remarks>
+ /// Window constructor.show window indicator,set callback
+ /// When closing the window in any way outside the program control,
+ /// and set callback when window rotation changed.
+ /// </remarks>
+ public Window(Window parent, string name) : this(parent, name, WindowType.Basic)
+ {
+ }
+
+ /// <summary>
+ /// Creates and initializes a new instance of the Window class.
+ /// </summary>
+ /// <param name="parent">
+ /// Parent widget which this widow created on.
+ /// </param>
+ /// <param name="name">
+ /// Window name.
+ /// </param>
+ /// <param name="type">
+ /// Window type
+ /// </param>
+ /// <remarks>
+ /// Window constructor.show window indicator,set callback
+ /// When closing the window in any way outside the program control,
+ /// and set callback when window rotation changed.
+ /// </remarks>
+ public Window(Window parent, string name, WindowType type)
+ {
+ Name = name;
+ Type = type;
+ Realize(parent);
+ IndicatorMode = IndicatorMode.Show;
+
+ _deleteRequest = new SmartEvent(this, "delete,request");
+ _rotationChanged = new SmartEvent(this, "wm,rotation,changed");
+ _deleteRequest.On += (s, e) => CloseRequested?.Invoke(this, EventArgs.Empty);
+ _rotationChanged.On += (s, e) => RotationChanged?.Invoke(this, EventArgs.Empty);
+ }
+
+ protected Window()
+ {
+ }
+
+ /// <summary>
+ /// CloseRequested will be triggered when Window close.
+ /// </summary>
+ public event EventHandler CloseRequested;
+
+ /// <summary>
+ /// RotationChanged will be triggered when Window do rotation.
+ /// </summary>
+ public event EventHandler RotationChanged;
+
+ /// <summary>
+ /// Sets or gets Window name.
+ /// </summary>
+ public string Name { get; set; }
+
+ /// <summary>
+ /// Gets the Window type.
+ /// </summary>
+ public WindowType Type { get; } = WindowType.Basic;
+
+ /// <summary>
+ /// Gets Window size with Size value(w,h)
+ /// </summary>
+ public Size ScreenSize
+ {
+ get
+ {
+ int x, y, w, h;
+ Interop.Elementary.elm_win_screen_size_get(Handle, out x, out y, out w, out h);
+ return new Size(w, h);
+ }
+ }
+
+ /// <summary>
+ /// Gets the screen dpi for the screen that a Window is on.
+ /// </summary>
+ public Point ScreenDpi
+ {
+ get
+ {
+ Point point = default(Point);
+ Interop.Elementary.elm_win_screen_dpi_get(Handle, out point.X, out point.Y);
+ return point;
+ }
+ }
+
+ /// <summary>
+ /// Gets the rotation of the Window.The rotation of the window in degrees (0-360).
+ /// </summary>
+ public int Rotation
+ {
+ get
+ {
+ return Interop.Elementary.elm_win_rotation_get(Handle);
+ }
+ }
+
+ /// <summary>
+ /// Gets whether window manager supports window rotation or not.
+ /// </summary>
+ public bool IsRotationSupported
+ {
+ get
+ {
+ return Interop.Elementary.elm_win_wm_rotation_supported_get(Handle);
+ }
+ }
+
+ [Obsolete("Sorry, it's error typo of AvailableRotations, please use AvailableRotations")]
+ public DisplayRotation AavailableRotations { get; set; }
+
+ /// <summary>
+ /// Sets or gets available rotation degree.
+ /// </summary>
+ public DisplayRotation AvailableRotations
+ {
+ get
+ {
+ int[] rotations;
+ Interop.Elementary.elm_win_wm_rotation_available_rotations_get(Handle, out rotations);
+ if (rotations == null)
+ {
+ return 0;
+ }
+ return ConvertToDisplayRotation(rotations);
+ }
+ set
+ {
+ Interop.Elementary.elm_win_wm_rotation_available_rotations_set(Handle, ConvertDegreeArray(value));
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets whether auto deletion function is enable.
+ /// </summary>
+ /// <remarks>
+ /// If you enable auto deletion, the window is automatically destroyed after the signal is emitted.
+ /// If auto deletion is disabled, the window is not destroyed and the program has to handle it.
+ /// </remarks>
+ public bool AutoDeletion
+ {
+ get
+ {
+ return Interop.Elementary.elm_win_autodel_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_win_autodel_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the alpha channel state of a window.
+ /// </summary>
+ /// <remarks>
+ /// True if the window alpha channel is enabled, false otherwise.
+ /// If alpha is true, the alpha channel of the canvas will be enabled possibly making parts of the window completely or partially transparent.
+ /// </remarks>
+ public bool Alpha
+ {
+ get
+ {
+ return Interop.Elementary.elm_win_alpha_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_win_alpha_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the role of the window.
+ /// </summary>
+ /// <remarks>
+ /// The Role will be invalid if a new role is set or if the window is destroyed.
+ /// </remarks>
+ public string Role
+ {
+ get
+ {
+ return Interop.Elementary.elm_win_role_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_win_role_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the mode of status bar.
+ /// </summary>
+ public StatusBarMode StatusBarMode
+ {
+ get
+ {
+ return (StatusBarMode)Interop.Elementary.elm_win_indicator_opacity_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_win_indicator_opacity_set(Handle, (int)value);
+ }
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public bool Iconified
+ {
+ get
+ {
+ return Interop.Elementary.elm_win_iconified_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_win_iconified_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the window's indicator mode.
+ /// </summary>
+ /// <value>The indicator mode.</value>
+ public IndicatorMode IndicatorMode
+ {
+ get
+ {
+ return Interop.Elementary.elm_win_indicator_mode_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_win_indicator_mode_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the aspect ratio of a window.
+ /// </summary>
+ public double Aspect
+ {
+ get
+ {
+ return Interop.Elementary.elm_win_aspect_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_win_aspect_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Window's autohide state.
+ /// </summary>
+ public bool AutoHide
+ {
+ get
+ {
+ return Interop.Elementary.elm_win_autohide_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_win_autohide_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Get the borderless state of a window.
+ /// This function requests the Window Manager to not draw any decoration around the window.
+ /// </summary>
+ public bool Borderless
+ {
+ get
+ {
+ return Interop.Elementary.elm_win_borderless_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_win_borderless_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the demand attention state of a window.
+ /// </summary>
+ public bool DemandAttention
+ {
+ get
+ {
+ return Interop.Elementary.elm_win_demand_attention_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_win_demand_attention_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the floating mode of a window.
+ /// </summary>
+ public bool FloatingMode
+ {
+ get
+ {
+ return Interop.Elementary.elm_win_floating_mode_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_win_floating_mode_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the animate status for the focus highlight for this window.
+ /// This function will enable or disable the animation of focus highlight only for the given window, regardless of the global setting for it.
+ /// </summary>
+ public bool FocusHighlightAnimation
+ {
+ get
+ {
+ return Interop.Elementary.elm_win_focus_highlight_animate_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_win_focus_highlight_animate_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the enabled status for the focus highlight in a window.
+ /// This function will enable or disable the focus highlight only for the given window, regardless of the global setting for it.
+ /// </summary>
+ public bool FocusHighlightEnabled
+ {
+ get
+ {
+ return Interop.Elementary.elm_win_focus_highlight_enabled_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_win_focus_highlight_enabled_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the style for the focus highlight on this window.
+ /// Sets the style to use for theming the highlight of focused objects on the given window.If style is NULL, the default will be used.
+ /// </summary>
+ public string FocusHighlightStyle
+ {
+ get
+ {
+ return Interop.Elementary.elm_win_focus_highlight_style_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_win_focus_highlight_style_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Get the keyboard mode of the window.
+ /// </summary>
+ public KeyboardMode KeyboardMode
+ {
+ get
+ {
+ return (KeyboardMode)Interop.Elementary.elm_win_keyboard_mode_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_win_keyboard_mode_set(RealHandle, (int)value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the layer of the window.
+ /// What this means exactly will depend on the underlying engine used.
+ /// In the case of X11 backed engines, the value in layer has the following meanings
+ /// less than 3 means that the window will be placed below all others,
+ /// more than 5 means that the window will be placed above all others,
+ /// and anything else means that the window will be placed in the default layer.
+ /// </summary>
+ public override int Layer
+ {
+ get
+ {
+ return Interop.Elementary.elm_win_layer_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_win_layer_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the maximized state of a window.
+ /// </summary>
+ public bool Maximized
+ {
+ get
+ {
+ return Interop.Elementary.elm_win_maximized_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_win_maximized_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the modal state of a window.
+ /// </summary>
+ public bool Modal
+ {
+ get
+ {
+ return Interop.Elementary.elm_win_modal_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_win_modal_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the noblank property of a window.
+ /// This is a way to request the display on which the windowis shown does not blank, screensave or otherwise hide or obscure the window.It is intended for uses such as media playback on a television where a user may not want to be interrupted by an idle screen.
+ /// The noblank property may have no effect if the window is iconified/minimized or hidden.
+ /// </summary>
+ public bool NoBlank
+ {
+ get
+ {
+ return Interop.Elementary.elm_win_noblank_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_win_noblank_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Get the profile of a window.
+ /// </summary>
+ public string Profile
+ {
+ get
+ {
+ return Interop.Elementary.elm_win_profile_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_win_profile_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Get the constraints on the maximum width and height of a window relative to the width and height of its screen.
+ /// When this function returns true, obj will never resize larger than the screen.
+ /// </summary>
+ public bool ScreenConstrain
+ {
+ get
+ {
+ return Interop.Elementary.elm_win_screen_constrain_get(RealHandle);
+ }
+ set
+ {
+ Interop.Elementary.elm_win_screen_constrain_set(RealHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the base size of a window.
+ /// </summary>
+ public Size BaseSize
+ {
+ get
+ {
+ int w, h;
+ Interop.Elementary.elm_win_size_base_get(RealHandle, out w, out h);
+ return new Size(w, h);
+ }
+ set
+ {
+ Interop.Elementary.elm_win_size_base_set(RealHandle, value.Width, value.Height);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the step size of a window.
+ /// </summary>
+ public Size StepSize
+ {
+ get
+ {
+ int w, h;
+ Interop.Elementary.elm_win_size_step_get(RealHandle, out w, out h);
+ return new Size(w, h);
+ }
+ set
+ {
+ Interop.Elementary.elm_win_size_step_set(RealHandle, value.Width, value.Height);
+ }
+ }
+
+ /// <summary>
+ /// Get the screen position X of a window.
+ /// </summary>
+ public int ScreenPositionX
+ {
+ get
+ {
+ int x, y;
+ Interop.Elementary.elm_win_screen_position_get(Handle, out x, out y);
+ return x;
+ }
+ }
+
+ /// <summary>
+ /// Get the screen position Y of a window.
+ /// </summary>
+ public int ScreenPositionY
+ {
+ get
+ {
+ int x, y;
+ Interop.Elementary.elm_win_screen_position_get(Handle, out x, out y);
+ return y;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the title of the window.
+ /// </summary>
+ public string Title
+ {
+ get
+ {
+ return Interop.Elementary.elm_win_title_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_win_title_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the urgent state of a window.
+ /// </summary>
+ public bool Urgent
+ {
+ get
+ {
+ return Interop.Elementary.elm_win_urgent_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_win_urgent_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the withdrawn state of a window.
+ /// </summary>
+ public bool Withdrawn
+ {
+ get
+ {
+ return Interop.Elementary.elm_win_urgent_get(Handle);
+ }
+ set
+ {
+ Interop.Elementary.elm_win_urgent_set(Handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Create a socket to provide the service for Plug widget.
+ /// </summary>
+ /// <param name="serviceName">A service name</param>
+ /// <param name="serviceNumber">A number (any value, 0 being the common default) to differentiate multiple instances of services with the same name.</param>
+ /// <param name="systemWide">A boolean that if true, specifies to create a system-wide service all users can connect to, otherwise the service is private to the user id that created the service.</param>
+ /// <returns></returns>
+ public bool CreateServiceSocket(string name, int number, bool systemWide)
+ {
+ return Interop.Elementary.elm_win_socket_listen(RealHandle, name, number, systemWide);
+ }
+
+ /// <summary>
+ /// Set the rotation of the window.
+ /// </summary>
+ /// <param name="degree">The rotation of the window, in degrees (0-360), counter-clockwise.</param>
+ /// <param name="resize">Resizes the window's contents so that they fit inside the current window geometry.</param>
+ public void SetRotation(int degree, bool resize)
+ {
+ if (resize)
+ Interop.Elementary.elm_win_rotation_with_resize_set(RealHandle, degree);
+ else
+ Interop.Elementary.elm_win_rotation_set(RealHandle, degree);
+ }
+
+ /// <summary>
+ /// Set the window to be skipped by focus.
+ /// This sets the window to be skipped by normal input.
+ /// This means a window manager will be asked to not focus this window as well as omit it from things like the taskbar, pager etc.
+ /// Call this and enable it on a window BEFORE you show it for the first time, otherwise it may have no effect.
+ /// Use this for windows that have only output information or might only be interacted with by the mouse or fingers, and never for typing input.
+ /// Be careful that this may have side-effects like making the window non-accessible in some cases unless the window is specially handled. Use this with care.
+ /// </summary>
+ public void FocusSkip(bool skip)
+ {
+ Interop.Elementary.elm_win_prop_focus_skip_set(Handle, skip);
+ }
+
+ /// <summary>
+ /// Pull up the window object.
+ /// Places the window pointed by obj at the top of the stack, so that it's not covered by any other window.
+ /// </summary>
+ public void PullUp()
+ {
+ Interop.Elementary.elm_win_raise(Handle);
+ }
+
+ /// <summary>
+ /// Bring down the window object.
+ /// Places the window pointed by obj at the bottom of the stack, so that no other window is covered by it.
+ /// </summary>
+ public void BringDown()
+ {
+ Interop.Elementary.elm_win_lower(Handle);
+ }
+
+ /// <summary>
+ /// This function sends a request to the Windows Manager to activate the Window.
+ /// If honored by the WM, the window receives the keyboard focus.
+ /// </summary>
+ /// <remarks>
+ /// This is just a request that a Window Manager may ignore, so calling this function does not ensure
+ /// in any way that the window is going to be the active one after it.
+ /// </remarks>
+ public void Active()
+ {
+ Interop.Elementary.elm_win_activate(Handle);
+ }
+
+ /// <summary>
+ /// Delete subobj as a resize object of window obj.
+ /// This function removes the object subobj from the resize objects of the window obj.
+ /// It will not delete the object itself, which will be left unmanaged and should be deleted by the developer, manually handled or set as child of some other container.
+ /// </summary>
+ /// <param name="obj">Resize object.</param>
+ public void DeleteResizeObject(EvasObject obj)
+ {
+ Interop.Elementary.elm_win_resize_object_del(Handle, obj);
+ }
+
+ /// <summary>
+ /// Adds obj as a resize object of the Window.
+ /// </summary>
+ /// <remarks>
+ /// Setting an object as a resize object of the window means that the obj child's size and
+ /// position is controlled by the window directly. That is, the obj is resized to match the window size
+ /// and should never be moved or resized manually by the developer.In addition,
+ /// resize objects of the window control the minimum size of it as well as whether it can or cannot be resized by the user.
+ /// </remarks>
+ /// <param name="obj">
+ /// Resize object.
+ /// </param>
+ public void AddResizeObject(EvasObject obj)
+ {
+ Interop.Elementary.elm_win_resize_object_add(Handle, obj);
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public void WinKeyGrab(string keyname, KeyGrabMode mode)
+ {
+ Interop.Elementary.elm_win_keygrab_set(RealHandle, keyname, 0, 0, 0, mode);
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public void WinKeyUngrab(string keyname)
+ {
+ Interop.Elementary.elm_win_keygrab_unset(RealHandle, keyname, 0, 0);
+ }
+
+ /// <summary>
+ /// Set the keygrab of the window.
+ /// </summary>
+ /// <param name="keyname">keyname string to set keygrab</param>
+ public void KeyGrabEx(string keyname)
+ {
+ Interop.Elementary.eext_win_keygrab_set(RealHandle, keyname);
+ }
+
+ /// <summary>
+ /// Unset the keygrab of the window.
+ /// </summary>
+ /// <param name="keyname">keyname string to unset keygrab</param>
+ public void KeyUngrabEx(string keyname)
+ {
+ Interop.Elementary.eext_win_keygrab_unset(RealHandle, keyname);
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ Interop.Elementary.elm_config_accel_preference_set("3d");
+ return Interop.Elementary.elm_win_add(parent != null ? parent.Handle : IntPtr.Zero, Name, (int)Type);
+ }
+
+ internal void AddChild(EvasObject obj)
+ {
+ _referenceHolder.Add(obj);
+ }
+
+ internal void RemoveChild(EvasObject obj)
+ {
+ _referenceHolder.Remove(obj);
+ }
+
+ static int[] ConvertDegreeArray(DisplayRotation value)
+ {
+ List<int> rotations = new List<int>();
+ if (value.HasFlag(DisplayRotation.Degree_0))
+ rotations.Add(0);
+ if (value.HasFlag(DisplayRotation.Degree_90))
+ rotations.Add(90);
+ if (value.HasFlag(DisplayRotation.Degree_180))
+ rotations.Add(180);
+ if (value.HasFlag(DisplayRotation.Degree_270))
+ rotations.Add(270);
+ return rotations.ToArray();
+ }
+
+ static DisplayRotation ConvertToDisplayRotation(int[] values)
+ {
+ int orientation = 0;
+ foreach (int v in values)
+ {
+ orientation |= (1 << (v / 90));
+ }
+ return (DisplayRotation)orientation;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/ElmSharp/WrapType.cs b/src/ElmSharp/ElmSharp/WrapType.cs
new file mode 100755
index 0000000..5725790
--- /dev/null
+++ b/src/ElmSharp/ElmSharp/WrapType.cs
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace ElmSharp
+{
+ /// <summary>
+ /// Enumeration for the wrap type.
+ /// </summary>
+ public enum WrapType
+ {
+ /// <summary>
+ /// No wrap.
+ /// </summary>
+ None = 0,
+ /// <summary>
+ /// Char wrap - wrap between characters.
+ /// </summary>
+ Char,
+ /// <summary>
+ /// Word wrap - wrap within the allowed wrapping points
+ /// (as defined in the unicode standard).
+ /// </summary>
+ Word,
+ /// <summary>
+ /// Mixed wrap - Word wrap, if that fails, char wrap.
+ /// </summary>
+ Mixed
+ }
+}
diff --git a/src/ElmSharp/Interop/Interop.Ecore.cs b/src/ElmSharp/Interop/Interop.Ecore.cs
new file mode 100644
index 0000000..99b9ee1
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Ecore.cs
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Ecore
+ {
+ internal delegate void EcoreCallback(IntPtr data);
+ internal delegate bool EcoreTaskCallback(IntPtr data);
+ internal delegate void EcoreEventCallback(IntPtr data, int type, IntPtr evt);
+
+ [DllImport(Libraries.Ecore)]
+ internal static extern int ecore_init();
+
+ [DllImport(Libraries.Ecore)]
+ internal static extern int ecore_shutdown();
+
+ [DllImport(Libraries.Ecore)]
+ internal static extern void ecore_main_loop_begin();
+
+ [DllImport(Libraries.Ecore)]
+ internal static extern void ecore_main_loop_quit();
+
+ [DllImport(Libraries.Ecore)]
+ internal static extern bool ecore_main_loop_glib_integrate();
+
+ [DllImport(Libraries.Ecore)]
+ internal static extern IntPtr ecore_idler_add(EcoreTaskCallback callback, IntPtr data);
+
+ [DllImport(Libraries.Ecore)]
+ internal static extern void ecore_main_loop_thread_safe_call_async(EcoreTaskCallback callback, IntPtr data);
+
+ [DllImport(Libraries.Ecore)]
+ internal static extern IntPtr ecore_main_loop_thread_safe_call_sync(EcoreTaskCallback callback, IntPtr data);
+
+ [DllImport(Libraries.Ecore)]
+ internal static extern IntPtr ecore_idler_del(IntPtr idler);
+
+ [DllImport(Libraries.Ecore)]
+ internal static extern IntPtr ecore_timer_add(double interval, EcoreTaskCallback callback, IntPtr data);
+
+ [DllImport(Libraries.Ecore)]
+ internal static extern IntPtr ecore_timer_del(IntPtr timer);
+
+ [DllImport(Libraries.Ecore)]
+ internal static extern IntPtr ecore_animator_add(EcoreTaskCallback func, IntPtr data);
+
+ [DllImport(Libraries.Ecore)]
+ internal static extern IntPtr ecore_animator_del(IntPtr animator);
+
+ [DllImport(Libraries.Ecore)]
+ internal static extern double ecore_time_get();
+
+ [DllImport(Libraries.Ecore)]
+ internal static extern IntPtr ecore_event_handler_add(int type, EcoreEventCallback func, IntPtr data);
+
+ [DllImport(Libraries.Ecore)]
+ internal static extern IntPtr ecore_event_handler_del(IntPtr handler);
+ }
+}
diff --git a/src/ElmSharp/Interop/Interop.Eext.Event.cs b/src/ElmSharp/Interop/Interop.Eext.Event.cs
new file mode 100644
index 0000000..02420dc
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Eext.Event.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Eext
+ {
+ public enum EextCallbackType
+ {
+ EEXT_CALLBACK_BACK, // H/W Back Key Event
+ EEXT_CALLBACK_MORE, // H/W More Key Event
+ }
+ internal delegate void EextEventCallback(IntPtr data, IntPtr obj, IntPtr info);
+
+ [DllImport(Libraries.Eext)]
+ internal static extern void eext_object_event_callback_add(IntPtr obj, EextCallbackType type, EextEventCallback callback, IntPtr data);
+
+
+ [DllImport(Libraries.Eext)]
+ internal static extern void eext_object_event_callback_del(IntPtr obj, EextCallbackType type, EextEventCallback callback);
+ }
+}
diff --git a/src/ElmSharp/Interop/Interop.Eext.FloatingButton.cs b/src/ElmSharp/Interop/Interop.Eext.FloatingButton.cs
new file mode 100755
index 0000000..7ecef6a
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Eext.FloatingButton.cs
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Eext
+ {
+ [DllImport(Libraries.Eext)]
+ internal static extern IntPtr eext_floatingbutton_add(IntPtr parent);
+
+ [DllImport(Libraries.Eext)]
+ internal static extern int eext_floatingbutton_mode_get(IntPtr floatingButton);
+
+ [DllImport(Libraries.Eext)]
+ internal static extern void eext_floatingbutton_mode_set(IntPtr floatingButton, int mode);
+
+ [DllImport(Libraries.Eext)]
+ internal static extern int eext_floatingbutton_pos_get(IntPtr floatingButton);
+
+ [DllImport(Libraries.Eext)]
+ internal static extern bool eext_floatingbutton_pos_set(IntPtr floatingButton, int position);
+
+ [DllImport(Libraries.Eext)]
+ internal static extern bool eext_floatingbutton_movement_block_get(IntPtr floatingButton);
+
+ [DllImport(Libraries.Eext)]
+ internal static extern void eext_floatingbutton_movement_block_set(IntPtr floatingButton, bool block);
+
+ [DllImport(Libraries.Eext)]
+ internal static extern bool eext_floatingbutton_pos_bring_in(IntPtr floatingButton, int posposition);
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/Interop/Interop.Eina.cs b/src/ElmSharp/Interop/Interop.Eina.cs
new file mode 100644
index 0000000..1051b52
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Eina.cs
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Eina
+ {
+ [DllImport(Libraries.Eina)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool eina_main_loop_is();
+ }
+}
diff --git a/src/ElmSharp/Interop/Interop.Elementary.Accessibility.cs b/src/ElmSharp/Interop/Interop.Elementary.Accessibility.cs
new file mode 100644
index 0000000..fc3bc6b
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.Accessibility.cs
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ internal enum Elm_Atspi_Relation_Type
+ {
+ ELM_ATSPI_RELATION_NULL,
+ ELM_ATSPI_RELATION_LABEL_FOR,
+ ELM_ATSPI_RELATION_LABELLED_BY,
+ ELM_ATSPI_RELATION_CONTROLLER_FOR,
+ ELM_ATSPI_RELATION_CONTROLLED_BY,
+ ELM_ATSPI_RELATION_MEMBER_OF,
+ ELM_ATSPI_RELATION_TOOLTIP_FOR,
+ ELM_ATSPI_RELATION_NODE_CHILD_OF,
+ ELM_ATSPI_RELATION_NODE_PARENT_OF,
+ ELM_ATSPI_RELATION_EXTENDED,
+ ELM_ATSPI_RELATION_FLOWS_TO,
+ ELM_ATSPI_RELATION_FLOWS_FROM,
+ ELM_ATSPI_RELATION_SUBWINDOW_OF,
+ ELM_ATSPI_RELATION_EMBEDS,
+ ELM_ATSPI_RELATION_EMBEDDED_BY,
+ ELM_ATSPI_RELATION_POPUP_FOR,
+ ELM_ATSPI_RELATION_PARENT_WINDOW_OF,
+ ELM_ATSPI_RELATION_DESCRIPTION_FOR,
+ ELM_ATSPI_RELATION_DESCRIBED_BY,
+ ELM_ATSPI_RELATION_LAST_DEFINED,
+ }
+
+ internal enum Elm_Atspi_Role
+ {
+ ELM_ATSPI_ROLE_INVALID,
+ ELM_ATSPI_ROLE_ACCELERATOR_LABEL,
+ ELM_ATSPI_ROLE_ALERT,
+ ELM_ATSPI_ROLE_ANIMATION,
+ ELM_ATSPI_ROLE_ARROW,
+ ELM_ATSPI_ROLE_CALENDAR,
+ ELM_ATSPI_ROLE_CANVAS,
+ ELM_ATSPI_ROLE_CHECK_BOX,
+ ELM_ATSPI_ROLE_CHECK_MENU_ITEM,
+ ELM_ATSPI_ROLE_COLOR_CHOOSER,
+ ELM_ATSPI_ROLE_COLUMN_HEADER,
+ ELM_ATSPI_ROLE_COMBO_BOX,
+ ELM_ATSPI_ROLE_DATE_EDITOR,
+ ELM_ATSPI_ROLE_DESKTOP_ICON,
+ ELM_ATSPI_ROLE_DESKTOP_FRAME,
+ ELM_ATSPI_ROLE_DIAL,
+ ELM_ATSPI_ROLE_DIALOG,
+ ELM_ATSPI_ROLE_DIRECTORY_PANE,
+ ELM_ATSPI_ROLE_DRAWING_AREA,
+ ELM_ATSPI_ROLE_FILE_CHOOSER,
+ ELM_ATSPI_ROLE_FILLER,
+ ELM_ATSPI_ROLE_FOCUS_TRAVERSABLE,
+ ELM_ATSPI_ROLE_FONT_CHOOSER,
+ ELM_ATSPI_ROLE_FRAME,
+ ELM_ATSPI_ROLE_GLASS_PANE,
+ ELM_ATSPI_ROLE_HTML_CONTAINER,
+ ELM_ATSPI_ROLE_ICON,
+ ELM_ATSPI_ROLE_IMAGE,
+ ELM_ATSPI_ROLE_INTERNAL_FRAME,
+ ELM_ATSPI_ROLE_LABEL,
+ ELM_ATSPI_ROLE_LAYERED_PANE,
+ ELM_ATSPI_ROLE_LIST,
+ ELM_ATSPI_ROLE_LIST_ITEM,
+ ELM_ATSPI_ROLE_MENU,
+ ELM_ATSPI_ROLE_MENU_BAR,
+ ELM_ATSPI_ROLE_MENU_ITEM,
+ ELM_ATSPI_ROLE_OPTION_PANE,
+ ELM_ATSPI_ROLE_PAGE_TAB,
+ ELM_ATSPI_ROLE_PAGE_TAB_LIST,
+ ELM_ATSPI_ROLE_PANEL,
+ ELM_ATSPI_ROLE_PASSWORD_TEXT,
+ ELM_ATSPI_ROLE_POPUP_MENU,
+ ELM_ATSPI_ROLE_PROGRESS_BAR,
+ ELM_ATSPI_ROLE_PUSH_BUTTON,
+ ELM_ATSPI_ROLE_RADIO_BUTTON,
+ ELM_ATSPI_ROLE_RADIO_MENU_ITEM,
+ ELM_ATSPI_ROLE_ROOT_PANE,
+ ELM_ATSPI_ROLE_ROW_HEADER,
+ ELM_ATSPI_ROLE_SCROLL_BAR,
+ ELM_ATSPI_ROLE_SCROLL_PANE,
+ ELM_ATSPI_ROLE_SEPARATOR,
+ ELM_ATSPI_ROLE_SLIDER,
+ ELM_ATSPI_ROLE_SPIN_BUTTON,
+ ELM_ATSPI_ROLE_SPLIT_PANE,
+ ELM_ATSPI_ROLE_STATUS_BAR,
+ ELM_ATSPI_ROLE_TABLE,
+ ELM_ATSPI_ROLE_TABLE_CELL,
+ ELM_ATSPI_ROLE_TABLE_COLUMN_HEADER,
+ ELM_ATSPI_ROLE_TABLE_ROW_HEADER,
+ ELM_ATSPI_ROLE_TEAROFF_MENU_ITEM,
+ ELM_ATSPI_ROLE_TERMINAL,
+ ELM_ATSPI_ROLE_TEXT,
+ ELM_ATSPI_ROLE_TOGGLE_BUTTON,
+ ELM_ATSPI_ROLE_TOOL_BAR,
+ ELM_ATSPI_ROLE_TOOL_TIP,
+ ELM_ATSPI_ROLE_TREE,
+ ELM_ATSPI_ROLE_TREE_TABLE,
+ ELM_ATSPI_ROLE_UNKNOWN,
+ ELM_ATSPI_ROLE_VIEWPORT,
+ ELM_ATSPI_ROLE_WINDOW,
+ ELM_ATSPI_ROLE_EXTENDED,
+ ELM_ATSPI_ROLE_HEADER,
+ ELM_ATSPI_ROLE_FOOTER,
+ ELM_ATSPI_ROLE_PARAGRAPH,
+ ELM_ATSPI_ROLE_RULER,
+ ELM_ATSPI_ROLE_APPLICATION,
+ ELM_ATSPI_ROLE_AUTOCOMPLETE,
+ ELM_ATSPI_ROLE_EDITBAR,
+ ELM_ATSPI_ROLE_EMBEDDED,
+ ELM_ATSPI_ROLE_ENTRY,
+ ELM_ATSPI_ROLE_CHART,
+ ELM_ATSPI_ROLE_CAPTION,
+ ELM_ATSPI_ROLE_DOCUMENT_FRAME,
+ ELM_ATSPI_ROLE_HEADING,
+ ELM_ATSPI_ROLE_PAGE,
+ ELM_ATSPI_ROLE_SECTION,
+ ELM_ATSPI_ROLE_REDUNDANT_OBJECT,
+ ELM_ATSPI_ROLE_FORM,
+ ELM_ATSPI_ROLE_LINK,
+ ELM_ATSPI_ROLE_INPUT_METHOD_WINDOW,
+ ELM_ATSPI_ROLE_TABLE_ROW,
+ ELM_ATSPI_ROLE_TREE_ITEM,
+ ELM_ATSPI_ROLE_DOCUMENT_SPREADSHEET,
+ ELM_ATSPI_ROLE_DOCUMENT_PRESENTATION,
+ ELM_ATSPI_ROLE_DOCUMENT_TEXT,
+ ELM_ATSPI_ROLE_DOCUMENT_WEB,
+ ELM_ATSPI_ROLE_DOCUMENT_EMAIL,
+ ELM_ATSPI_ROLE_COMMENT,
+ ELM_ATSPI_ROLE_LIST_BOX,
+ ELM_ATSPI_ROLE_GROUPING,
+ ELM_ATSPI_ROLE_IMAGE_MAP,
+ ELM_ATSPI_ROLE_NOTIFICATION,
+ ELM_ATSPI_ROLE_INFO_BAR
+ }
+
+ [Flags]
+ internal enum Elm_Accessible_Reading_Info_Type
+ {
+ ELM_ACCESSIBLE_READING_INFO_TYPE_NAME = 0x1,
+ ELM_ACCESSIBLE_READING_INFO_TYPE_ROLE = 0x2,
+ ELM_ACCESSIBLE_READING_INFO_TYPE_DESCRIPTION = 0x4,
+ ELM_ACCESSIBLE_READING_INFO_TYPE_STATE = 0x8
+ }
+
+ internal delegate void Elm_Atspi_Say_Signal_Cb(IntPtr data, string say_signal);
+ internal delegate string Elm_Atspi_Reading_Info_Cb(IntPtr data, IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool elm_atspi_accessible_relationship_append(IntPtr obj, Elm_Atspi_Relation_Type type, IntPtr relationObj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_atspi_accessible_relationship_remove(IntPtr obj, Elm_Atspi_Relation_Type type, IntPtr relationObj);
+
+ [DllImport(Libraries.Elementary)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool elm_atspi_accessible_relationship_append(IntPtr obj, int type, IntPtr relationObj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_atspi_accessible_relationship_remove(IntPtr obj, int type, IntPtr relationObj);
+
+ [DllImport(Libraries.Elementary, EntryPoint = "elm_atspi_accessible_translation_domain_get")]
+ internal static extern IntPtr _elm_atspi_accessible_translation_domain_get(IntPtr obj);
+
+ internal static string elm_atspi_accessible_translation_domain_get(IntPtr obj)
+ {
+ var str = _elm_atspi_accessible_translation_domain_get(obj);
+ return Marshal.PtrToStringAnsi(str);
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_atspi_accessible_translation_domain_set(IntPtr obj, string domain);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_atspi_accessible_name_set(IntPtr obj, string name);
+
+ [DllImport(Libraries.Elementary, EntryPoint = "elm_atspi_accessible_name_get")]
+ internal static extern IntPtr _elm_atspi_accessible_name_get(IntPtr obj);
+
+ internal static string elm_atspi_accessible_name_get(IntPtr obj)
+ {
+ var str = _elm_atspi_accessible_name_get(obj);
+ return Marshal.PtrToStringAnsi(str);
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_atspi_accessible_name_cb_set(IntPtr obj, Elm_Atspi_Reading_Info_Cb name_cb, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern Elm_Atspi_Role elm_atspi_accessible_role_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_atspi_accessible_role_set(IntPtr obj, Elm_Atspi_Role role);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_atspi_accessible_description_set(IntPtr obj, string description);
+
+ [DllImport(Libraries.Elementary, EntryPoint = "elm_atspi_accessible_description_get")]
+ internal static extern IntPtr _elm_atspi_accessible_description_get(IntPtr obj);
+ internal static string elm_atspi_accessible_description_get(IntPtr obj)
+ {
+ var str = _elm_atspi_accessible_description_get(obj);
+ return Marshal.PtrToStringAnsi(str);
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_atspi_accessible_description_cb_set(IntPtr obj, Elm_Atspi_Reading_Info_Cb description_cb, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_atspi_accessible_reading_info_type_set(IntPtr obj, Elm_Accessible_Reading_Info_Type reading_info);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_atspi_accessible_reading_info_type_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_atspi_accessible_can_highlight_set(IntPtr obj, bool can_highlight);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_atspi_accessible_can_highlight_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_atspi_component_highlight_grab(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_atspi_component_highlight_clear(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_atspi_bridge_utils_say(string text, bool discardable, Elm_Atspi_Say_Signal_Cb func, IntPtr data);
+ }
+}
diff --git a/src/ElmSharp/Interop/Interop.Elementary.Bg.cs b/src/ElmSharp/Interop/Interop.Elementary.Bg.cs
new file mode 100644
index 0000000..2f6f732
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.Bg.cs
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ public enum BackgroundOptions
+ {
+ Center, Scale, Stretch, Tile
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_bg_add(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_bg_color_set(IntPtr obj, int r, int g, int b);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_bg_color_get(IntPtr obj, out int r, out int g, out int b);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_bg_file_set(IntPtr obj, string file, IntPtr group);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_bg_file_get(IntPtr obj, out IntPtr file, IntPtr group);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_bg_option_set(IntPtr obj, BackgroundOptions option);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_bg_load_size_set(IntPtr obj, int w, int h);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern BackgroundOptions elm_bg_option_get(IntPtr obj);
+
+ internal static string BackgroundFileGet(IntPtr obj)
+ {
+ IntPtr file = IntPtr.Zero;
+ elm_bg_file_get(obj, out file, IntPtr.Zero);
+ return Marshal.PtrToStringAnsi(file);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/Interop/Interop.Elementary.Box.cs b/src/ElmSharp/Interop/Interop.Elementary.Box.cs
new file mode 100644
index 0000000..cb104a6
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.Box.cs
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ public delegate void BoxLayoutCallback(IntPtr obj, IntPtr priv, IntPtr userData);
+
+ public delegate void BoxDataFreeCallback(IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_box_add(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_box_horizontal_set(IntPtr obj, bool horizontal);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_box_horizontal_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_box_pack_start(IntPtr obj, IntPtr subobj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_box_pack_end(IntPtr obj, IntPtr subobj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_box_pack_before(IntPtr obj, IntPtr subobj, IntPtr before);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_box_pack_after(IntPtr obj, IntPtr subobj, IntPtr after);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_box_unpack(IntPtr obj, IntPtr subobj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_box_unpack_all(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_box_align_set(IntPtr obj, double horizontal, double vertical);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_box_align_get(IntPtr obj, out double horizontal, out double vertical);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_box_align_get(IntPtr obj, IntPtr horizontal, out double vertical);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_box_align_get(IntPtr obj, out double horizontal, IntPtr vertical);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_box_children_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_box_clear(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_box_padding_set(IntPtr obj, int horizontal, int vertical);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_box_padding_get(IntPtr obj, out int horizontal, out int vertical);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_box_layout_set(IntPtr obj, BoxLayoutCallback cb, IntPtr data, BoxDataFreeCallback dataFreeCb);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_box_layout_set(IntPtr obj, BoxLayoutCallback cb, IntPtr data, IntPtr dataFreeCb);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_box_homogeneous_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_box_homogeneous_set(IntPtr obj, bool ishomogeneous);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_box_recalculate(IntPtr obj);
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/Interop/Interop.Elementary.Button.cs b/src/ElmSharp/Interop/Interop.Elementary.Button.cs
new file mode 100644
index 0000000..5d5279f
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.Button.cs
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_button_add(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_button_autorepeat_initial_timeout_set(IntPtr obj, double t);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_button_autorepeat_initial_timeout_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_button_autorepeat_gap_timeout_set(IntPtr obj, double t);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_button_autorepeat_gap_timeout_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_button_autorepeat_set(IntPtr obj, bool on);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_button_autorepeat_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_radio_add(IntPtr parent);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_radio_group_add(IntPtr obj, IntPtr group);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_radio_state_value_set(IntPtr obj, int value);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_radio_state_value_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_radio_value_set(IntPtr obj, int value);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_radio_value_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_radio_selected_object_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_check_add(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_check_state_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_check_state_set(IntPtr obj, bool value);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_check_state_pointer_set(IntPtr obj, bool value);
+ }
+}
diff --git a/src/ElmSharp/Interop/Interop.Elementary.CalendarView.cs b/src/ElmSharp/Interop/Interop.Elementary.CalendarView.cs
new file mode 100644
index 0000000..6885035
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.CalendarView.cs
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ internal enum Elm_Calendar_Mark_Repeat_Type
+ {
+ ELM_CALENDAR_UNIQUE = 0, /* Default value. Marks will be displayed only on event day. */
+ ELM_CALENDAR_DAILY, /* Marks will be displayed every day after event day (inclusive). */
+ ELM_CALENDAR_WEEKLY, /* Marks will be displayed every week after event day (inclusive) */
+ ELM_CALENDAR_MONTHLY, /* Marks will be displayed every month day that coincides to event day. */
+ ELM_CALENDAR_ANNUALLY, /* Marks will be displayed every year that coincides to event day (and month). */
+ LM_CALENDAR_LAST_DAY_OF_MONTH /* Marks will be displayed every last day of month after event day (inclusive). */
+ };
+
+ internal enum Elm_Calendar_Select_Mode
+ {
+ ELM_CALENDAR_SELECT_MODE_DEFAULT = 0, /* Default value. a day is always selected. */
+ ELM_CALENDAR_SELECT_MODE_ALWAYS, /* a day is always selected. */
+ ELM_CALENDAR_SELECT_MODE_NONE, /* None of the days can be selected. */
+ ELM_CALENDAR_SELECT_MODE_ONDEMAND /* User may have selected a day or not. */
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_calendar_add(IntPtr parent);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_calendar_weekdays_names_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_calendar_weekdays_names_set(IntPtr obj, string[] weekdays);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_calendar_min_max_year_set(IntPtr obj, int min, int max);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_calendar_min_max_year_get(IntPtr obj, out int min, out int max);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_calendar_selected_time_set(IntPtr obj, ref Libc.SystemTime selectedtime);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_calendar_selected_time_get(IntPtr obj, ref Libc.SystemTime selectedtime);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_calendar_first_day_of_week_set(IntPtr obj, int day);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_calendar_first_day_of_week_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_calendar_selectable_set(IntPtr obj, int SelectedField);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_calendar_selectable_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_calendar_displayed_time_get(IntPtr obj, out Libc.SystemTime displayedtime);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_calendar_interval_set(IntPtr obj, double interval);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_calendar_interval_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_calendar_select_mode_set(IntPtr obj, Elm_Calendar_Select_Mode mode);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_calendar_select_mode_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_calendar_mark_add(IntPtr obj, string type, ref Libc.SystemTime date, Elm_Calendar_Mark_Repeat_Type repeatType);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_calendar_mark_del(IntPtr markItem);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_calendar_marks_draw(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_calendar_marks_clear(IntPtr obj);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate string Elm_Calendar_Format_Cb(Libc.SystemTime date);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_calendar_format_function_set(IntPtr obj, Elm_Calendar_Format_Cb format_function);
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/Interop/Interop.Elementary.ColorPicker.cs b/src/ElmSharp/Interop/Interop.Elementary.ColorPicker.cs
new file mode 100755
index 0000000..231fc9d
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.ColorPicker.cs
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+
+ internal enum Elm_Colorselector_Mode
+ {
+ ELM_COLORSELECTOR_PALETTE = 0, /* Only color palette is displayed. */
+ ELM_COLORSELECTOR_COMPONENTS, /* Only color selector is displayed. */
+ ELM_COLORSELECTOR_BOTH, /* Both Palette and selector is displayed, default.*/
+ ELM_COLORSELECTOR_PICKER, /* Only color picker is displayed. */
+ ELM_COLORSELECTOR_ALL /* All possible color selector is displayed. */
+ };
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_colorselector_add(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_colorselector_color_set(IntPtr obj, int r, int g, int b, int a);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_colorselector_color_get(IntPtr obj, out int r, out int g, out int b, out int a);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_colorselector_palette_name_set(IntPtr obj, string name);
+
+ [DllImport(Libraries.Elementary, EntryPoint = "elm_colorselector_palette_name_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, CharSet = CharSet.Ansi)]
+ internal static extern IntPtr _elm_colorselector_palette_name_get(IntPtr obj);
+ internal static string elm_colorselector_palette_name_get(IntPtr obj)
+ {
+ var text = _elm_colorselector_palette_name_get(obj);
+ return Marshal.PtrToStringAnsi(text);
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_colorselector_mode_set(IntPtr obj, Elm_Colorselector_Mode mode);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern Elm_Colorselector_Mode elm_colorselector_mode_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_colorselector_palette_color_add(IntPtr obj, int r, int g, int b, int a);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_colorselector_palette_clear(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_colorselector_palette_selected_item_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_colorselector_palette_item_color_get(IntPtr obj, out int r, out int g, out int b, out int a);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_colorselector_palette_item_color_set(IntPtr obj, int r, int g, int b, int a);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_colorselector_palette_item_selected_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_colorselector_palette_item_selected_set(IntPtr obj, bool selected);
+
+ }
+}
diff --git a/src/ElmSharp/Interop/Interop.Elementary.CtxPopup.cs b/src/ElmSharp/Interop/Interop.Elementary.CtxPopup.cs
new file mode 100644
index 0000000..e2db4ba
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.CtxPopup.cs
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_ctxpopup_add(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_ctxpopup_horizontal_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_ctxpopup_horizontal_set(IntPtr obj, bool horizontal);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_ctxpopup_auto_hide_disabled_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_ctxpopup_auto_hide_disabled_set(IntPtr obj, bool disabled);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_ctxpopup_hover_parent_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_ctxpopup_hover_parent_set(IntPtr obj, IntPtr parent);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_ctxpopup_direction_available_get(IntPtr obj, int direction);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_ctxpopup_direction_priority_set(IntPtr obj, int first, int second, int third, int fourth);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_ctxpopup_direction_priority_get(IntPtr obj, out int first, out int second, out int third, out int fourth);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_ctxpopup_direction_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_ctxpopup_dismiss(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_ctxpopup_clear(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_ctxpopup_item_append(IntPtr obj, string label, IntPtr icon, Evas.SmartCallback func, IntPtr data);
+ }
+}
diff --git a/src/ElmSharp/Interop/Interop.Elementary.DateTimePicker.cs b/src/ElmSharp/Interop/Interop.Elementary.DateTimePicker.cs
new file mode 100644
index 0000000..e65b9ef
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.DateTimePicker.cs
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_datetime_add(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_datetime_value_set(IntPtr obj, ref Libc.SystemTime newtime);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_datetime_value_get(IntPtr obj, ref Libc.SystemTime currtime);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_datetime_format_set(IntPtr obj, string format);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr _elm_datetime_format_get(IntPtr obj);
+
+ internal static string elm_datetime_format_get(IntPtr obj)
+ {
+ var format = _elm_datetime_format_get(obj);
+ return Marshal.PtrToStringAnsi(format);
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_datetime_value_max_set(IntPtr obj, ref Libc.SystemTime maxtime);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_datetime_value_max_get(IntPtr obj, ref Libc.SystemTime maxtime);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_datetime_value_min_set(IntPtr obj, ref Libc.SystemTime mintime);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_datetime_value_min_get(IntPtr obj, ref Libc.SystemTime mintime);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_datetime_field_limit_set(IntPtr obj, int type, int min, int max);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_datetime_field_limit_get(IntPtr obj, int type, out int min, out int max);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_datetime_field_visible_set(IntPtr obj, int type, bool visible);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_datetime_field_visible_get(IntPtr obj, int type);
+
+ internal enum DateTimeFieldType
+ {
+ Year,
+ Month,
+ Date,
+ Hour,
+ Minute,
+ AmPm
+ }
+ }
+}
+
diff --git a/src/ElmSharp/Interop/Interop.Elementary.Entry.cs b/src/ElmSharp/Interop/Interop.Elementary.Entry.cs
new file mode 100644
index 0000000..23285a7
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.Entry.cs
@@ -0,0 +1,391 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ /// <summary>
+ /// Types of "Enter" keys available for different keyboards layout
+ /// </summary>
+ public enum ReturnKeyType
+ {
+ Default,
+ Done,
+ Go,
+ Join,
+ Login,
+ Next,
+ Search,
+ Send,
+ Signin
+ }
+
+ public enum InputPanelLayout
+ {
+ Normal,
+ Number,
+ Email,
+ Url,
+ PhoneNumber,
+ Ip,
+ Month,
+ NumberOnly,
+ Invalid,
+ Hex,
+ Terminal,
+ Password,
+ DateTime,
+ Emoticon
+ }
+
+ internal enum WrapType
+ {
+ None,
+ Char,
+ Word,
+ Mixed,
+ }
+
+ internal enum AutocapitalType
+ {
+ None,
+ Word,
+ Sentence,
+ AllCharacter,
+ }
+
+ internal enum InputHints
+ {
+ None,
+ AutoComplete,
+ SensitiveData,
+ }
+
+ internal enum InputPanelLanguage
+ {
+ Automatic,
+ Alphabet,
+ }
+
+ internal enum CopyAndPasteMode
+ {
+ Markup,
+ NoImage,
+ PlainText
+ }
+
+ internal enum TextFormat
+ {
+ PlainUtf8,
+ MarkupUtf8
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_entry_add(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_entry_editable_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_editable_set(IntPtr obj, bool value);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_entry_single_line_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_single_line_set(IntPtr obj, bool value);
+
+ [DllImport(Libraries.Elementary, EntryPoint = "elm_entry_entry_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, CharSet = CharSet.Ansi)]
+ internal static extern IntPtr _elm_entry_entry_get(IntPtr obj);
+
+ internal static string elm_entry_entry_get(IntPtr obj)
+ {
+ var text = _elm_entry_entry_get(obj);
+ return Marshal.PtrToStringAnsi(text);
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_entry_set(IntPtr obj, string value);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_entry_append(IntPtr obj, string value);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_entry_insert(IntPtr obj, string value);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_file_get(IntPtr obj, out string file, out TextFormat format);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_file_set(IntPtr obj, string file, TextFormat format);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_file_save(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_entry_password_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_password_set(IntPtr obj, bool value);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_entry_is_empty(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_entry_cursor_next(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_entry_cursor_prev(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_entry_cursor_up(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_entry_cursor_down(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_cursor_begin_set(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_cursor_end_set(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern string elm_entry_cursor_content_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_cursor_line_begin_set(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_cursor_line_end_set(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_entry_cursor_pos_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_cursor_pos_set(IntPtr obj, int pos);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_entry_cursor_geometry_get(IntPtr obj, out int x, out int y, out int w, out int h);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_entry_cursor_is_format_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_entry_cursor_is_visible_format_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_cursor_selection_begin(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_cursor_selection_end(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern string elm_entry_markup_to_utf8(IntPtr text);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern string elm_entry_markup_to_utf8(string text);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_input_panel_show(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_input_panel_enabled_set(IntPtr obj, bool enabled);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_entry_input_panel_enabled_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_input_panel_return_key_type_set(IntPtr obj, ReturnKeyType keyType);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_input_panel_layout_set(IntPtr obj, InputPanelLayout layout);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern InputPanelLayout elm_entry_input_panel_layout_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_select_all(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_select_none(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_text_style_user_pop(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_text_style_user_push(IntPtr obj, string style);
+
+ [DllImport(Libraries.Elementary, EntryPoint = "elm_entry_text_style_user_peek", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, CharSet = CharSet.Ansi)]
+ internal static extern IntPtr _elm_entry_text_style_user_peek(IntPtr obj);
+
+ internal static string elm_entry_text_style_user_peek(IntPtr obj)
+ {
+ var text = _elm_entry_text_style_user_peek(obj);
+ return Marshal.PtrToStringAnsi(text);
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_entry_scrollable_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_scrollable_set(IntPtr obj, bool scroll);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_input_panel_hide(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_input_panel_imdata_set(IntPtr obj, IntPtr data, int len);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_entry_input_panel_layout_variation_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_input_panel_layout_variation_set(IntPtr obj, int variation);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern WrapType elm_entry_line_wrap_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_line_wrap_set(IntPtr obj, WrapType wrap);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern AutocapitalType elm_entry_autocapital_type_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_autocapital_type_set(IntPtr obj, AutocapitalType autoCapitalType);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_entry_autosave_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_autosave_set(IntPtr obj, bool autosave);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern CopyAndPasteMode elm_entry_cnp_mode_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_cnp_mode_set(IntPtr obj, CopyAndPasteMode mode);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_calc_force(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_entry_imf_context_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern InputHints elm_entry_input_hint_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_input_hint_set(IntPtr obj, InputHints hints);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern InputPanelLanguage elm_entry_input_panel_language_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_input_panel_language_set(IntPtr obj, InputPanelLanguage lang);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_entry_input_panel_return_key_disabled_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_input_panel_return_key_disabled_set(IntPtr obj, bool disabled);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_input_panel_return_key_autoenabled_set(IntPtr obj, bool enabled);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_entry_input_panel_show_on_demand_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_input_panel_show_on_demand_set(IntPtr obj, bool onDemand);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_markup_filter_append(IntPtr obj, Elm_Entry_Filter_Cb func, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_markup_filter_prepend(IntPtr obj, Elm_Entry_Filter_Cb func, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_markup_filter_remove(IntPtr obj, Elm_Entry_Filter_Cb func, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_entry_prediction_allow_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_prediction_allow_set(IntPtr obj, bool prediction);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_select_allow_set(IntPtr obj, bool allow);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern string elm_entry_utf8_to_markup(string str);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void Elm_Entry_Filter_Cb(IntPtr data, IntPtr obj, ref IntPtr text);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_entry_anchor_hover_parent_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_anchor_hover_parent_set(IntPtr obj, IntPtr parent);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_anchor_hover_end(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern string elm_entry_anchor_hover_style_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_anchor_hover_style_set(IntPtr obj, string style);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_icon_visible_set(IntPtr obj, bool setting);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate IntPtr Elm_Entry_Item_Provider_Cb(IntPtr data, IntPtr entry, string text);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_item_provider_append(IntPtr obj, Elm_Entry_Item_Provider_Cb func, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_item_provider_prepend(IntPtr obj, Elm_Entry_Item_Provider_Cb func, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_item_provider_remove(IntPtr obj, Elm_Entry_Item_Provider_Cb func, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_selection_copy(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_selection_cut(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_selection_paste(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_entry_selection_handler_disabled_set(IntPtr obj, bool disabled);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern string elm_entry_selection_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern string elm_entry_select_region_set(IntPtr obj, int start, int end);
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/Interop/Interop.Elementary.FlipSelector.cs b/src/ElmSharp/Interop/Interop.Elementary.FlipSelector.cs
new file mode 100644
index 0000000..9768571
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.FlipSelector.cs
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_flipselector_add(IntPtr parent);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_flipselector_first_interval_get(IntPtr flipSelector);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_flipselector_first_interval_set(IntPtr flipSelector, double interval);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_flipselector_item_append(IntPtr flipSelector, string text, Evas.SmartCallback func, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_flipselector_item_prepend(IntPtr flipSelector, string text, Evas.SmartCallback func, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_flipselector_flip_next(IntPtr flipSelector);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_flipselector_flip_prev(IntPtr flipSelector);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_flipselector_selected_item_get(IntPtr flipSelector);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_flipselector_first_item_get(IntPtr flipSelector);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_flipselector_last_item_get(IntPtr flipSelector);
+ }
+}
diff --git a/src/ElmSharp/Interop/Interop.Elementary.GenGridView.cs b/src/ElmSharp/Interop/Interop.Elementary.GenGridView.cs
new file mode 100644
index 0000000..d4bfebb
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.GenGridView.cs
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_gengrid_add(IntPtr parent);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_align_set(IntPtr obj, double align_x, double align_y);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_align_get(IntPtr obj, out double align_x, out double align_y);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_align_get(IntPtr obj, IntPtr align_x, out double align_y);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_align_get(IntPtr obj, out double align_x, IntPtr align_y);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_horizontal_set(IntPtr obj, bool horizontal);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_gengrid_horizontal_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_multi_select_set(IntPtr obj, bool multi);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_gengrid_multi_select_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_gengrid_item_append(IntPtr obj, IntPtr itc, IntPtr data, Evas.SmartCallback func, IntPtr func_data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_gengrid_item_prepend(IntPtr obj, IntPtr itc, IntPtr data, Evas.SmartCallback func, IntPtr func_data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_gengrid_item_insert_before(IntPtr obj, IntPtr itc, IntPtr data, IntPtr before, Evas.SmartCallback func, IntPtr func_data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_gengrid_item_insert_after(IntPtr obj, IntPtr itc, IntPtr data, IntPtr after, Evas.SmartCallback func, IntPtr func_data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_gengrid_item_class_new();
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_item_size_set(IntPtr obj, int w, int h);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_item_size_get(IntPtr obj, out int w, out int h);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_item_size_get(IntPtr obj, IntPtr w, out int h);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_item_size_get(IntPtr obj, out int w, IntPtr h);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_filled_set(IntPtr obj, bool fill);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_gengrid_filled_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_gengrid_item_index_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_clear(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_item_selected_set(IntPtr obj, bool selected);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_gengrid_item_selected_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern uint elm_gengrid_items_count(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_highlight_mode_set(IntPtr obj, bool highlight);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_gengrid_highlight_mode_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_item_show(IntPtr obj, int type);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_item_bring_in(IntPtr obj, int type);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_item_select_mode_set(IntPtr it, Elm_Object_Select_Mode mode);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern Elm_Object_Select_Mode elm_gengrid_item_select_mode_get(IntPtr it);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_select_mode_set(IntPtr it, int mode);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_gengrid_select_mode_get(IntPtr it);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_realized_items_update(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_item_update(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_gengrid_at_xy_item_get(IntPtr obj, int x, int y, out int xposret, out int yposret);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_gengrid_selected_item_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_gengrid_first_item_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_item_class_free(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_gengrid_last_item_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern string elm_gengrid_item_cursor_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_item_cursor_set(IntPtr obj, string cursor);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_item_cursor_unset(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern string elm_gengrid_item_cursor_style_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_item_cursor_style_set(IntPtr obj, string cursor);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_gengrid_item_cursor_engine_only_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_item_cursor_engine_only_set(IntPtr obj, bool engine);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_item_tooltip_text_set(IntPtr obj, string text);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_item_tooltip_unset(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern string elm_gengrid_item_tooltip_style_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_item_tooltip_style_set(IntPtr obj, string style);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_gengrid_reorder_mode_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_reorder_mode_set(IntPtr obj, bool mode);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_item_pos_get(IntPtr obj, out int row, out int column);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_gengrid_item_sorted_insert(IntPtr obj, IntPtr itc, IntPtr data, Eina_Compare_Cb compare, Evas.SmartCallback func, IntPtr funcData);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gengrid_item_tooltip_content_cb_set(IntPtr obj, Elm_Tooltip_Item_Content_Cb func, IntPtr funcData, Evas.SmartCallback deleteFunc);
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/Interop/Interop.Elementary.GenListView.cs b/src/ElmSharp/Interop/Interop.Elementary.GenListView.cs
new file mode 100644
index 0000000..2205899
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.GenListView.cs
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ internal enum Elm_Genlist_Item_Scrollto_Type
+ {
+ ELM_GENLIST_ITEM_SCROLLTO_NONE = 0,
+
+ // Scrolls to nowhere
+ ELM_GENLIST_ITEM_SCROLLTO_IN = (1 << 0),
+
+ // Scrolls to the nearest viewport
+ ELM_GENLIST_ITEM_SCROLLTO_TOP = (1 << 1),
+
+ // Scrolls to the top of the viewport
+ ELM_GENLIST_ITEM_SCROLLTO_MIDDLE = (1 << 2),
+
+ // Scrolls to the middle of the viewport
+ ELM_GENLIST_ITEM_SCROLLTO_BOTTOM = (1 << 3)
+
+ // Scrolls to the bottom of the viewport
+ }
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void Evas_Smart_Cb(IntPtr data, IntPtr obj, IntPtr eventInfo);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_genlist_add(IntPtr parent);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_genlist_mode_set(IntPtr obj, int mode);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_genlist_mode_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_genlist_select_mode_set(IntPtr obj, int mode);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_genlist_select_mode_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_genlist_item_append(IntPtr obj, IntPtr itc, IntPtr data, IntPtr parent, int type, Evas.SmartCallback func, IntPtr func_data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_genlist_item_prepend(IntPtr obj, IntPtr itc, IntPtr data, IntPtr parent, int type, Evas.SmartCallback func, IntPtr func_data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_genlist_item_insert_before(IntPtr obj, IntPtr itc, IntPtr data, IntPtr parent, IntPtr before, int type, Evas.SmartCallback func, IntPtr func_data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_genlist_item_class_new();
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_genlist_item_class_free(IntPtr itemClass);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_genlist_block_count_set(IntPtr obj, int count);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_genlist_block_count_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_genlist_homogeneous_set(IntPtr obj, bool homogeneous);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_genlist_homogeneous_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_genlist_item_index_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_genlist_item_type_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_genlist_item_parent_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_genlist_realized_items_update(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_genlist_item_update(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_genlist_item_show(IntPtr item, Elm_Genlist_Item_Scrollto_Type type);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_genlist_item_bring_in(IntPtr item, Elm_Genlist_Item_Scrollto_Type type);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_genlist_items_count(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_genlist_first_item_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_genlist_last_item_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_genlist_item_next_get(IntPtr item);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_genlist_item_prev_get(IntPtr item);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_genlist_item_selected_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_genlist_item_selected_set(IntPtr obj, bool selected);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_genlist_item_select_mode_set(IntPtr obj, Elm_Object_Select_Mode mode);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern Elm_Object_Select_Mode elm_genlist_item_select_mode_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_genlist_item_item_class_update(IntPtr obj, IntPtr itc);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_genlist_clear(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_genlist_item_fields_update(IntPtr item, string part, uint type);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_genlist_reorder_mode_set(IntPtr obj, bool mode);
+
+ [DllImport(Libraries.Elementary)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool elm_genlist_reorder_mode_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern void elm_genlist_item_expanded_set(IntPtr obj, bool isExpanded);
+
+ [DllImport(Libraries.Elementary)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool elm_genlist_item_expanded_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_genlist_highlight_mode_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_genlist_highlight_mode_set(IntPtr obj, bool highlight);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_genlist_at_xy_item_get(IntPtr obj, int x, int y, out int posret);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_genlist_item_insert_after(IntPtr obj, IntPtr itc, IntPtr data, IntPtr parent, IntPtr after, int type, Evas.SmartCallback func, IntPtr func_data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_genlist_item_item_class_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_genlist_longpress_timeout_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_genlist_longpress_timeout_set(IntPtr obj, double timeout);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_genlist_multi_select_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_genlist_multi_select_set(IntPtr obj, bool multi);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_genlist_nth_item_get(IntPtr obj, int nth);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_genlist_selected_item_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern string elm_genlist_item_cursor_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_genlist_item_cursor_set(IntPtr obj, string cursor);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_genlist_item_cursor_unset(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_genlist_item_cursor_engine_only_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_genlist_item_cursor_engine_only_set(IntPtr obj, bool engineOnly);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern string elm_genlist_item_cursor_style_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_genlist_item_cursor_style_set(IntPtr obj, string style);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_genlist_item_demote(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_genlist_item_expanded_depth_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_genlist_item_subitems_clear(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_genlist_item_tooltip_text_set(IntPtr obj, string text);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_genlist_item_tooltip_unset(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern string elm_genlist_item_tooltip_style_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_genlist_item_tooltip_style_set(IntPtr obj, string style);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_genlist_item_tooltip_window_mode_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_genlist_item_tooltip_window_mode_set(IntPtr obj, bool disable);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_genlist_item_sorted_insert(IntPtr obj, IntPtr itc, IntPtr data, IntPtr parent, int type, Eina_Compare_Cb compare, Evas.SmartCallback func, IntPtr funcData);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_genlist_item_tooltip_content_cb_set(IntPtr obj, Elm_Tooltip_Item_Content_Cb func, IntPtr funcData, Evas.SmartCallback deleteFunc);
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/Interop/Interop.Elementary.GestureLayer.cs b/src/ElmSharp/Interop/Interop.Elementary.GestureLayer.cs
new file mode 100644
index 0000000..369eba1
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.GestureLayer.cs
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ public delegate void GestureEventCallback(IntPtr data, IntPtr event_info);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_gesture_layer_add(IntPtr parent);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_gesture_layer_attach(IntPtr obj, IntPtr target);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gesture_layer_zoom_step_set(IntPtr obj, double step);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_gesture_layer_zoom_step_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gesture_layer_tap_finger_size_set(IntPtr obj, int sz);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_gesture_layer_tap_finger_size_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gesture_layer_hold_events_set(IntPtr obj, bool hold_events);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_gesture_layer_hold_events_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gesture_layer_rotate_step_set(IntPtr obj, double step);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_gesture_layer_rotate_step_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gesture_layer_cb_set(IntPtr obj, ElmSharp.GestureLayer.GestureType idx, ElmSharp.GestureLayer.GestureState cb_type, GestureEventCallback cb, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gesture_layer_line_min_length_set(IntPtr obj, int line_min_length);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_gesture_layer_line_min_length_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gesture_layer_zoom_distance_tolerance_set(IntPtr obj, int zoom_distance_tolerance);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_gesture_layer_zoom_distance_tolerance_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gesture_layer_line_distance_tolerance_set(IntPtr obj, int line_distance_tolerance);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_gesture_layer_line_distance_tolerance_get (IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gesture_layer_line_angular_tolerance_set(IntPtr obj, double line_angular_tolerance);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_gesture_layer_line_angular_tolerance_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gesture_layer_zoom_wheel_factor_set(IntPtr obj, double zoom_wheel_factor);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_gesture_layer_zoom_wheel_factor_get (IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gesture_layer_zoom_finger_factor_set (IntPtr obj, double zoom_finger_factor);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_gesture_layer_zoom_finger_factor_get (IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gesture_layer_rotate_angular_tolerance_set (IntPtr obj, double rotate_angular_tolerance);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_gesture_layer_rotate_angular_tolerance_get (IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gesture_layer_flick_time_limit_ms_set (IntPtr obj, UInt32 flick_time_limit_ms);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern UInt32 elm_gesture_layer_flick_time_limit_ms_get (IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gesture_layer_long_tap_start_timeout_set(IntPtr obj, double long_tap_start_timeout);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_gesture_layer_long_tap_start_timeout_get (IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gesture_layer_continues_enable_set(IntPtr obj, bool continues_enable);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_gesture_layer_continues_enable_get (IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_gesture_layer_double_tap_timeout_set (IntPtr obj, double double_tap_timeout);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_gesture_layer_double_tap_timeout_get (IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_config_glayer_long_tap_start_timeout_get ();
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_config_glayer_long_tap_start_timeout_set(double long_tap_timeout);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_config_glayer_double_tap_timeout_get();
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_config_glayer_double_tap_timeout_set(double double_tap_timeout);
+ }
+}
+
diff --git a/src/ElmSharp/Interop/Interop.Elementary.Hoversel.cs b/src/ElmSharp/Interop/Interop.Elementary.Hoversel.cs
new file mode 100755
index 0000000..ca8cefe
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.Hoversel.cs
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_hoversel_add(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_hoversel_horizontal_set(IntPtr obj, bool horizontal);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_hoversel_horizontal_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_hoversel_hover_parent_set(IntPtr obj, IntPtr parent);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_hoversel_hover_parent_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_hoversel_expanded_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_hoversel_auto_update_set(IntPtr obj, bool auto_update);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_hoversel_auto_update_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_hoversel_hover_begin(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_hoversel_clear(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_hoversel_hover_end(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_hoversel_item_add(IntPtr obj, string label, string icon_file, int icon_type, Evas.SmartCallback func, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_hoversel_item_icon_set(IntPtr obj, string icon_file, string icon_group, int icon_type);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_hoversel_item_icon_get(IntPtr obj, out string icon_file, out string icon_group, int icon_type);
+ }
+}
+
diff --git a/src/ElmSharp/Interop/Interop.Elementary.Image.cs b/src/ElmSharp/Interop/Interop.Elementary.Image.cs
new file mode 100644
index 0000000..c49ff92
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.Image.cs
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_image_add(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_image_async_open_set(IntPtr obj, bool async);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_image_object_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_image_object_size_get(IntPtr obj, out int w, out int h);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_image_preload_disabled_set(IntPtr obj, bool disabled);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_image_file_set(IntPtr obj, string file, string group);
+
+ [DllImport(Libraries.Elementary, EntryPoint = "elm_image_file_get")]
+ internal static extern void _elm_image_file_get(IntPtr obj, out IntPtr file, out IntPtr group);
+ internal static string elm_image_file_get(IntPtr obj)
+ {
+ IntPtr file;
+ IntPtr group;
+ _elm_image_file_get(obj, out file, out group);
+ return Marshal.PtrToStringAnsi(file);
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static unsafe extern bool elm_image_memfile_set(IntPtr obj, byte* img, long size, IntPtr format, IntPtr key);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_image_smooth_set(IntPtr obj, bool smooth);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_image_smooth_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_image_resizable_set(IntPtr obj, bool up, bool down);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_image_resizable_get(IntPtr obj, out bool up, out bool down);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_image_no_scale_set(IntPtr obj, bool no_scale);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_image_no_scale_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_image_aspect_fixed_set(IntPtr obj, bool value);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_image_aspect_fixed_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_image_fill_outside_set(IntPtr obj, bool fill_outside);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_image_fill_outside_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_image_animated_available_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_image_animated_set(IntPtr obj, bool anim);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_image_animated_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_image_animated_play_set(IntPtr obj, bool play);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_image_animated_play_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_image_prescale_set(IntPtr obj, int size);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_image_prescale_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_image_editable_set(IntPtr obj, bool set);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_image_editable_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_image_orient_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_image_orient_set(IntPtr obj, int orient);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_icon_add(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_icon_standard_set(IntPtr obj, string name);
+
+ [DllImport(Libraries.Elementary, EntryPoint = "elm_icon_standard_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, CharSet = CharSet.Ansi)]
+ internal static extern IntPtr _elm_icon_standard_get(IntPtr obj);
+ internal static string elm_icon_standard_get(IntPtr obj)
+ {
+ var text = _elm_icon_standard_get(obj);
+ return Marshal.PtrToStringAnsi(text);
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_icon_thumb_set(IntPtr obj, string file, string group);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_icon_order_lookup_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_icon_order_lookup_set(IntPtr obj, int order);
+ }
+}
+
diff --git a/src/ElmSharp/Interop/Interop.Elementary.Index.cs b/src/ElmSharp/Interop/Interop.Elementary.Index.cs
new file mode 100644
index 0000000..f2ecacd
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.Index.cs
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ internal delegate void EventCallback(IntPtr data, IntPtr obj, IntPtr info);
+
+ internal delegate void SmartCallback(IntPtr data, IntPtr obj, IntPtr info);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_index_add(IntPtr parent);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_index_autohide_disabled_get(IntPtr index);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_index_autohide_disabled_set(IntPtr index, bool disabled);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_index_horizontal_get(IntPtr index);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_index_horizontal_set(IntPtr index, bool horizontal);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_index_item_append(IntPtr index, string text, EventCallback callback, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_index_item_prepend(IntPtr index, string text, EventCallback callback, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_index_selected_item_get(IntPtr index, int level);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_index_item_selected_set(IntPtr item, bool selected);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_index_level_go(IntPtr index, int level);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_index_indicator_disabled_get(IntPtr index);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_index_indicator_disabled_set(IntPtr index, bool disabled);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_index_omit_enabled_get(IntPtr index);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_index_omit_enabled_set(IntPtr index, bool enabled);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_index_item_insert_before(IntPtr obj, IntPtr before, string letter, EventCallback func, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_index_item_sorted_insert(IntPtr obj, string letter, Evas_Smart_Cb func, IntPtr data, Eina_Compare_Cb cmpFunc, Eina_Compare_Cb cmpDataFunc);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_index_delay_change_time_set(IntPtr obj, double time);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_index_delay_change_time_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_index_item_clear(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_index_item_find(IntPtr obj, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_index_item_insert_after(IntPtr obj, IntPtr after, string letter, SmartCallback func, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_index_item_level_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_index_item_level_set(IntPtr obj, int level);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_index_standard_priority_set(IntPtr obj, int priority);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_index_standard_priority_get(IntPtr obj);
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/Interop/Interop.Elementary.Item.cs b/src/ElmSharp/Interop/Interop.Elementary.Item.cs
new file mode 100644
index 0000000..0d516ec
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.Item.cs
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_item_part_content_set(IntPtr obj, string part, IntPtr content);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_object_item_part_content_unset(IntPtr obj, string part);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_item_part_content_set(IntPtr obj, IntPtr part, IntPtr content);
+
+ [DllImport(Libraries.Elementary, EntryPoint = "elm_object_item_part_text_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, CharSet = CharSet.Ansi)]
+ internal static extern IntPtr _elm_object_item_part_text_get(IntPtr obj, string part);
+
+ internal static string elm_object_item_part_text_get(IntPtr obj, string part)
+ {
+ var text = _elm_object_item_part_text_get(obj, part);
+ return Marshal.PtrToStringAnsi(text);
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_item_color_class_color_set(IntPtr it, string part, int r, int g, int b, int a);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_item_color_class_color_get(IntPtr obj, string part, out int r, out int g, out int b, out int a);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_item_color_class_del(IntPtr obj, string part);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_item_part_text_set(IntPtr obj, string part, string label);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_item_part_text_set(IntPtr obj, IntPtr part, string label);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_object_item_data_get(IntPtr it);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_item_data_set(IntPtr it, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_item_del(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_item_del_cb_set(IntPtr obj, Interop.Evas.SmartCallback callback);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_item_disabled_set(IntPtr obj, bool disable);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_object_item_disabled_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_object_item_part_content_get(IntPtr obj, string part);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_object_item_access_object_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_item_access_unregister(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_object_item_track(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_item_untrack(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_object_item_widget_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_item_signal_emit(IntPtr obj, string emission, string source);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_item_signal_callback_add(IntPtr obj, string emission, string source, Elm_Object_Item_Signal_Cb func, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_object_item_signal_callback_del(IntPtr obj, string emission, string source, Elm_Object_Item_Signal_Cb func);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool Elm_Object_Item_Signal_Cb(IntPtr data, IntPtr item, string emission, string source);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate IntPtr Elm_Tooltip_Item_Content_Cb(IntPtr data, IntPtr obj, IntPtr tooltip, IntPtr item);
+
+ internal enum Elm_Object_Select_Mode
+ {
+ ELM_OBJECT_SELECT_MODE_DEFAULT,
+ ELM_OBJECT_SELECT_MODE_ALWAYS,
+ ELM_OBJECT_SELECT_MODE_NONE,
+ ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/Interop/Interop.Elementary.Label.cs b/src/ElmSharp/Interop/Interop.Elementary.Label.cs
new file mode 100755
index 0000000..bf5c2d5
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.Label.cs
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_label_add(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_label_slide_mode_set(IntPtr obj, int mode);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_label_slide_mode_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_label_slide_duration_set(IntPtr obj, double duration);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_label_slide_duration_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_label_slide_speed_set(IntPtr obj, double speed);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_label_slide_speed_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_label_slide_go(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_label_line_wrap_set(IntPtr obj, int wrap);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_label_line_wrap_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_label_wrap_width_set(IntPtr obj, int w);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_label_wrap_width_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_label_ellipsis_set(IntPtr obj, bool ellipsis);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_label_ellipsis_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary, EntryPoint = "elm_label_text_style_user_peek", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, CharSet = CharSet.Ansi)]
+ internal static extern IntPtr _elm_label_text_style_user_peek(IntPtr obj);
+ internal static string elm_label_text_style_user_peek(IntPtr obj)
+ {
+ var text = _elm_label_text_style_user_peek(obj);
+ return Marshal.PtrToStringAnsi(text);
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_label_text_style_user_push(IntPtr obj, string style);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_label_text_style_user_pop(IntPtr obj);
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/Interop/Interop.Elementary.List.cs b/src/ElmSharp/Interop/Interop.Elementary.List.cs
new file mode 100644
index 0000000..40f4059
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.List.cs
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ public enum Elm_List_Mode
+ {
+ ELM_LIST_COMPRESS = 0,
+ ELM_LIST_SCROLL,
+ ELM_LIST_LIMIT,
+ ELM_LIST_EXPAND,
+ ELM_LIST_LAST
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_list_add(IntPtr parent);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_list_item_append(IntPtr obj, string label, IntPtr lefticon, IntPtr righticon, Evas.SmartCallback func, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_list_item_prepend(IntPtr obj, string label, IntPtr icon, IntPtr end, Evas.SmartCallback func, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_list_go(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_list_mode_set(IntPtr obj, Elm_List_Mode listMode);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern Elm_List_Mode elm_list_mode_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_list_item_selected_set(IntPtr obj, bool value);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_list_selected_item_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_list_clear(IntPtr obj);
+ }
+}
diff --git a/src/ElmSharp/Interop/Interop.Elementary.MultiButtonEntry.cs b/src/ElmSharp/Interop/Interop.Elementary.MultiButtonEntry.cs
new file mode 100644
index 0000000..0fa7ca5
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.MultiButtonEntry.cs
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ public delegate bool MultiButtonEntryItemFilterCallback(IntPtr obj, string label, IntPtr itemData, IntPtr data);
+
+ public delegate string MultiButtonEntryFormatCallback(int count, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_multibuttonentry_add(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_multibuttonentry_entry_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_multibuttonentry_expanded_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_multibuttonentry_expanded_set(IntPtr obj, bool expanded);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_multibuttonentry_editable_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_multibuttonentry_editable_set(IntPtr obj, bool editable);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_multibuttonentry_item_prepend(IntPtr obj, string label, Evas.SmartCallback func, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_multibuttonentry_item_append(IntPtr obj, string label, Evas.SmartCallback func, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_multibuttonentry_item_insert_before(IntPtr obj, IntPtr before, string label, Evas.SmartCallback func, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_multibuttonentry_item_insert_after(IntPtr obj, IntPtr after, string label, Evas.SmartCallback func, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_multibuttonentry_first_item_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_multibuttonentry_last_item_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_multibuttonentry_selected_item_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_multibuttonentry_item_selected_set(IntPtr obj, bool selected);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_multibuttonentry_item_selected_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_multibuttonentry_clear(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_multibuttonentry_item_prev_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_multibuttonentry_item_next_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_multibuttonentry_format_function_set(IntPtr obj, MultiButtonEntryFormatCallback callback, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_multibuttonentry_item_filter_append(IntPtr obj, MultiButtonEntryItemFilterCallback callback, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_multibuttonentry_item_filter_prepend(IntPtr obj, MultiButtonEntryItemFilterCallback callback, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_multibuttonentry_item_filter_remove(IntPtr obj, MultiButtonEntryItemFilterCallback callback, IntPtr data);
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/Interop/Interop.Elementary.Naviframe.cs b/src/ElmSharp/Interop/Interop.Elementary.Naviframe.cs
new file mode 100644
index 0000000..732ecee
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.Naviframe.cs
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_naviframe_item_pop_cb_set(IntPtr it, Elm_Naviframe_Item_Pop_Cb func, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_naviframe_add(IntPtr parent);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_naviframe_event_enabled_set(IntPtr obj, bool enabled);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_naviframe_prev_btn_auto_pushed_set(IntPtr obj, bool value);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_naviframe_prev_btn_auto_pushed_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_naviframe_item_title_enabled_set(IntPtr item, bool enable, bool transition);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_naviframe_item_title_enabled_get(IntPtr item);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_naviframe_item_push(IntPtr obj, string title, IntPtr prev, IntPtr next, IntPtr content, string style);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_naviframe_item_pop(IntPtr obj);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool Elm_Naviframe_Item_Pop_Cb(IntPtr data, IntPtr item);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_naviframe_content_preserve_on_pop_set(IntPtr obj, bool preserve);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_naviframe_content_preserve_on_pop_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_naviframe_item_insert_before(IntPtr naviframe, IntPtr before, string title, IntPtr prev, IntPtr next, IntPtr content, string style);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_naviframe_item_insert_after(IntPtr naviframe, IntPtr after, string title, IntPtr prev, IntPtr next, IntPtr content, string style);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_naviframe_top_item_get(IntPtr naviframe);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_naviframe_bottom_item_get(IntPtr naviframe);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_naviframe_item_pop_to(IntPtr item);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_naviframe_item_style_set(IntPtr item, string style);
+
+ [DllImport(Libraries.Elementary, EntryPoint = "elm_naviframe_item_style_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, CharSet = CharSet.Ansi)]
+ internal static extern IntPtr _elm_naviframe_item_style_get(IntPtr item);
+
+ internal static string elm_naviframe_item_style_get(IntPtr item)
+ {
+ var text = _elm_naviframe_item_style_get(item);
+ return Marshal.PtrToStringAnsi(text);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/Interop/Interop.Elementary.Panel.cs b/src/ElmSharp/Interop/Interop.Elementary.Panel.cs
new file mode 100644
index 0000000..c25f4fd
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.Panel.cs
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_panel_add(IntPtr parent);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_panel_toggle(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_panel_hidden_set(IntPtr obj, bool hidden);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_panel_hidden_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_panel_scrollable_set(IntPtr obj, bool scrollable);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_panel_scrollable_content_size_set(IntPtr obj, double ratio);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_panel_orient_set(IntPtr obj, int orient);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_panel_orient_get(IntPtr obj);
+ }
+}
diff --git a/src/ElmSharp/Interop/Interop.Elementary.Panes.cs b/src/ElmSharp/Interop/Interop.Elementary.Panes.cs
new file mode 100644
index 0000000..d3aa6e8
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.Panes.cs
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_panes_add(IntPtr parent);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_panes_content_left_size_set(IntPtr obj, double size);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_panes_content_left_size_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_panes_content_left_min_relative_size_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_panes_content_left_min_relative_size_set(IntPtr obj, double size);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_panes_content_left_min_size_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_panes_content_left_min_size_set(IntPtr obj, int size);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_panes_content_right_size_set(IntPtr obj, double size);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_panes_content_right_size_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_panes_content_right_min_relative_size_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_panes_content_right_min_relative_size_set(IntPtr obj, double size);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_panes_content_right_min_size_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_panes_content_right_min_size_set(IntPtr obj, int size);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_panes_horizontal_set(IntPtr obj, bool horizontal);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_panes_horizontal_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_panes_fixed_set(IntPtr obj, bool fix);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_panes_fixed_get(IntPtr obj);
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/Interop/Interop.Elementary.Popup.cs b/src/ElmSharp/Interop/Interop.Elementary.Popup.cs
new file mode 100644
index 0000000..aeae832
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.Popup.cs
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_popup_add(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_popup_timeout_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_popup_timeout_set(IntPtr obj, double timeout);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_popup_timeout_set(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_popup_orient_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_popup_orient_set(IntPtr obj, int orient);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_popup_orient_set(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_popup_allow_events_set(IntPtr obj, bool allow);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_popup_allow_events_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_popup_item_append(IntPtr obj, string label, IntPtr icon, Evas.SmartCallback func, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_popup_dismiss(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_popup_align_set(IntPtr obj, double horizontal, double vertical);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_popup_align_get(IntPtr obj, out double horizontal, out double vertical);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_popup_align_get(IntPtr obj, IntPtr horizontal, out double vertical);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_popup_align_get(IntPtr obj, out double horizontal, IntPtr vertical);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_popup_content_text_wrap_type_set(IntPtr obj, int type);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_popup_content_text_wrap_type_get(IntPtr obj);
+
+ internal static double GetPopupAlignX(IntPtr obj)
+ {
+ double x;
+ elm_popup_align_get(obj, out x, IntPtr.Zero);
+ return x;
+ }
+
+ internal static double GetPopupAlignY(IntPtr obj)
+ {
+ double y;
+ elm_popup_align_get(obj, IntPtr.Zero, out y);
+ return y;
+ }
+
+ internal static void SetPopupAlignX(IntPtr obj, double x)
+ {
+ double y = GetPopupAlignY(obj);
+ elm_popup_align_set(obj, x, y);
+ }
+
+ internal static void SetPopupAlignY(IntPtr obj, double y)
+ {
+ double x = GetPopupAlignX(obj);
+ elm_popup_align_set(obj, x, y);
+ }
+ }
+}
diff --git a/src/ElmSharp/Interop/Interop.Elementary.ProgressBar.cs b/src/ElmSharp/Interop/Interop.Elementary.ProgressBar.cs
new file mode 100644
index 0000000..259b53f
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.ProgressBar.cs
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_progressbar_add(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_progressbar_pulse_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_progressbar_pulse_set(IntPtr obj, bool pulse);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_progressbar_horizontal_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_progressbar_horizontal_set(IntPtr obj, bool horizontal);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_progressbar_inverted_set(IntPtr obj, bool inverted);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_progressbar_inverted_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_progressbar_value_set(IntPtr obj, double val);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_progressbar_value_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_progressbar_span_size_set(IntPtr obj, int size);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_progressbar_span_size_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_progressbar_pulse(IntPtr obj, bool state);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_progressbar_part_value_set(IntPtr obj, string part, double val);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_progressbar_part_value_get(IntPtr obj, string part);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_progressbar_unit_format_set(IntPtr obj, string format);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr _elm_progressbar_unit_format_get(IntPtr obj);
+
+ internal static string elm_progressbar_unit_format_get(IntPtr obj)
+ {
+ var format = _elm_progressbar_unit_format_get(obj);
+ return Marshal.PtrToStringAnsi(format);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/Interop/Interop.Elementary.ScrollView.cs b/src/ElmSharp/Interop/Interop.Elementary.ScrollView.cs
new file mode 100644
index 0000000..671aa5c
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.ScrollView.cs
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_interface_scrollable_content_size_get (out int w, out int h);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_interface_scrollable_page_bring_in (int pagenumber_h, int pagenumber_v);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_scroller_add (IntPtr parent);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_bounce_get(IntPtr obj, out bool h_bounce, out bool v_bounce);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_bounce_set(IntPtr obj, bool h_bounce, bool v_bounce);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_child_size_get (IntPtr obj, out int w, out int h);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_content_min_limit (IntPtr obj, bool w, bool h);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_current_page_get (IntPtr obj, out int h_pagenumber, out int v_pagenumber);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_gravity_get(IntPtr obj, out double x, out double y);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_gravity_set (IntPtr obj, double x, double y);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_last_page_get (IntPtr obj, out int h_pagenumber, out int v_pagenumber);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_loop_get(IntPtr obj, out bool loop_h, out bool loop_v);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_loop_set (IntPtr obj, bool loop_h, bool loop_v);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_scroller_movement_block_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_movement_block_set(IntPtr obj, int block);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_page_bring_in (IntPtr obj, int h_pagenumber, int v_pagenumber);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_page_relative_get (IntPtr obj, out double h_pagerel, out double v_pagerel);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_page_relative_set (IntPtr obj, double h_pagerel, double v_pagerel);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_page_show (IntPtr obj, int h_pagenumber, int v_pagenumber);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_page_size_get (IntPtr obj, out int h_pagesize, out int v_pagesize);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_page_size_set (IntPtr obj, int h_pagesize, int v_pagesize);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_page_snap_get (IntPtr obj, out bool page_h_snap, out bool page_v_snap);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_page_snap_set (IntPtr obj, bool page_h_snap, bool page_v_snap);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_policy_get(IntPtr obj, out int policy_h, out int policy_v);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_policy_get(IntPtr obj, out int policy_h, IntPtr policy_v);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_policy_get(IntPtr obj, IntPtr policy_h, out int policy_v);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_policy_set(IntPtr obj, int policy_h, int policy_v);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_region_bring_in (IntPtr obj, int x, int y, int w, int h);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_region_get (IntPtr obj, out int x, out int y, out int w, out int h);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_region_show (IntPtr obj, int x, int y, int w, int h);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_scroller_single_direction_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_single_direction_set(IntPtr obj, int singleDirection);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_step_size_get (IntPtr obj, out int x, out int y);
+
+ [DllImportAttribute(Libraries.Elementary)]
+ internal static extern void elm_scroller_step_size_set (IntPtr obj, int x, int y);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_scroller_wheel_disabled_get (IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_wheel_disabled_set (IntPtr obj, bool disabled);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_scroller_propagate_events_get (IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_propagate_events_set (IntPtr obj, bool propagation);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_page_scroll_limit_get (IntPtr obj, out int page_limit_h_, out int page_limit_v_);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_scroller_page_scroll_limit_set (IntPtr obj, int page_limit_h_, int page_limit_v_);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_scroll_lock_y_set(IntPtr obj, bool enable);
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/Interop/Interop.Elementary.Slider.cs b/src/ElmSharp/Interop/Interop.Elementary.Slider.cs
new file mode 100755
index 0000000..6f30f31
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.Slider.cs
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ internal enum Elm_Slider_Indicator_Visible_Mode
+ {
+ ELM_SLIDER_INDICATOR_VISIBLE_MODE_DEFAULT, /* show indicator on mouse down or change in slider value */
+ ELM_SLIDER_INDICATOR_VISIBLE_MODE_ALWAYS, /* Always show the indicator. */
+ ELM_SLIDER_INDICATOR_VISIBLE_MODE_ON_FOCUS, /* Show the indicator on focus */
+ ELM_SLIDER_INDICATOR_VISIBLE_MODE_NONE /* Never show the indicator */
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_slider_add(IntPtr parent);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_slider_indicator_show_set(IntPtr obj, bool show);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_slider_indicator_show_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_slider_indicator_show_on_focus_set(IntPtr obj, bool focus);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_slider_indicator_show_on_focus_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_slider_indicator_format_set(IntPtr obj, string indicator);
+
+ [DllImport(Libraries.Elementary, EntryPoint = "elm_slider_indicator_format_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, CharSet = CharSet.Ansi)]
+ internal static extern IntPtr _elm_slider_indicator_format_get(IntPtr obj);
+
+ internal static string elm_slider_indicator_format_get(IntPtr obj)
+ {
+ var text = _elm_slider_indicator_format_get(obj);
+ return Marshal.PtrToStringAnsi(text);
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_slider_unit_format_set(IntPtr obj, string units);
+
+ [DllImport(Libraries.Elementary, EntryPoint = "elm_slider_unit_format_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, CharSet = CharSet.Ansi)]
+ internal static extern IntPtr _elm_slider_unit_format_get(IntPtr obj);
+
+ internal static string elm_slider_unit_format_get(IntPtr obj)
+ {
+ var text = _elm_slider_unit_format_get(obj);
+ return Marshal.PtrToStringAnsi(text);
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_slider_inverted_set(IntPtr obj, bool inverted);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_slider_inverted_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_slider_horizontal_set(IntPtr obj, bool value);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_slider_horizontal_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_slider_min_max_set(IntPtr obj, double min, double max);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_slider_min_max_get(IntPtr obj, out double min, out double max);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_slider_min_max_get(IntPtr obj, out double min, IntPtr max);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_slider_min_max_get(IntPtr obj, IntPtr min, out double max);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_slider_value_set(IntPtr obj, double val);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_slider_value_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_slider_span_size_set(IntPtr obj, int size);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_slider_span_size_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_slider_step_set(IntPtr obj, double step);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_slider_step_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_slider_indicator_visible_mode_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_slider_indicator_visible_mode_set(IntPtr obj, int mode);
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/Interop/Interop.Elementary.Spinner.cs b/src/ElmSharp/Interop/Interop.Elementary.Spinner.cs
new file mode 100644
index 0000000..338b4cc
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.Spinner.cs
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_spinner_add(IntPtr parent);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_spinner_min_max_set(IntPtr obj, double min, double max);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_spinner_min_max_get(IntPtr obj, out double min, IntPtr max);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_spinner_min_max_get(IntPtr obj, IntPtr min, out double max);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_spinner_step_set(IntPtr obj, double step);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_spinner_step_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_spinner_wrap_set(IntPtr obj, bool wrap);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_spinner_wrap_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_spinner_interval_set(IntPtr obj, double interval);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_spinner_interval_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_spinner_round_set(IntPtr obj, int rnd);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_spinner_round_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_spinner_editable_set(IntPtr obj, bool editable);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_spinner_editable_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_spinner_base_set(IntPtr obj, double value);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_spinner_base_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_spinner_value_set(IntPtr obj, double val);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_spinner_value_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_spinner_label_format_set(IntPtr obj, string fmt);
+
+ [DllImport(Libraries.Elementary, EntryPoint = "elm_spinner_label_format_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, CharSet = CharSet.Ansi)]
+ internal static extern IntPtr _elm_spinner_label_format_get(IntPtr obj);
+ internal static string elm_spinner_label_format_get(IntPtr obj)
+ {
+ var text = _elm_spinner_label_format_get(obj);
+ return Marshal.PtrToStringAnsi(text);
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_spinner_special_value_add(IntPtr obj, double value, string label);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_spinner_special_value_del(IntPtr obj, double value);
+
+ [DllImport(Libraries.Elementary, EntryPoint = "elm_spinner_special_value_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, CharSet = CharSet.Ansi)]
+ internal static extern IntPtr _elm_spinner_special_value_get(IntPtr obj, double value);
+ internal static string elm_spinner_special_value_get(IntPtr obj, double value)
+ {
+ var text = _elm_spinner_special_value_get(obj, value);
+ return Marshal.PtrToStringAnsi(text);
+ }
+ }
+}
diff --git a/src/ElmSharp/Interop/Interop.Elementary.Table.cs b/src/ElmSharp/Interop/Interop.Elementary.Table.cs
new file mode 100644
index 0000000..d793a75
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.Table.cs
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_table_add(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_table_homogeneous_set(IntPtr obj, bool homogeneous);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_table_homogeneous_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_table_padding_set(IntPtr obj, int horizontal, int vertical);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_table_padding_get(IntPtr obj, out int horizontal, out int vertical);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_table_clear (IntPtr obj, bool clear);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_table_unpack (IntPtr obj, IntPtr subobj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_table_pack(IntPtr obj, IntPtr subobj, int column, int row, int colspan, int rowspan);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_table_pack_set(IntPtr subobj, int col, int row, int colspan, int rowspan);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_table_pack_get(IntPtr subobj, out int col, out int row, out int colspan, out int rowspan);
+ }
+}
diff --git a/src/ElmSharp/Interop/Interop.Elementary.Toolbar.cs b/src/ElmSharp/Interop/Interop.Elementary.Toolbar.cs
new file mode 100644
index 0000000..d753827
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.Toolbar.cs
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_toolbar_add(IntPtr parent);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_toolbar_shrink_mode_set(IntPtr obj, int shrink_mode);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_toolbar_shrink_mode_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_toolbar_item_append(IntPtr obj, string icon, string label, Evas.SmartCallback func, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_toolbar_item_prepend(IntPtr obj, string icon, string label, Evas.SmartCallback func, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_toolbar_item_insert_before(IntPtr obj, IntPtr before, string icon, string label, Evas.SmartCallback func, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_toolbar_transverse_expanded_set(IntPtr obj, bool transverse_expanded);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_toolbar_transverse_expanded_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_toolbar_select_mode_set(IntPtr obj, int mode);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_toolbar_select_mode_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_toolbar_align_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_toolbar_align_set(IntPtr obj, double align);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_toolbar_homogeneous_set(IntPtr obj, bool homogeneous);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_toolbar_homogeneous_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_toolbar_horizontal_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_toolbar_horizontal_set(IntPtr obj, bool horizontal);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_toolbar_icon_order_lookup_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_toolbar_icon_order_lookup_set(IntPtr obj, int order);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_toolbar_icon_size_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_toolbar_icon_size_set(IntPtr obj, int size);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_toolbar_item_icon_set(IntPtr obj, string icon);
+
+ [DllImport(Libraries.Elementary, EntryPoint = "elm_toolbar_item_icon_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, CharSet = CharSet.Ansi)]
+ internal static extern IntPtr _elm_toolbar_item_icon_get(IntPtr obj);
+ internal static string elm_toolbar_item_icon_get(IntPtr obj)
+ {
+ var text = _elm_toolbar_item_icon_get(obj);
+ return Marshal.PtrToStringAnsi(text);
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_toolbar_first_item_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_toolbar_last_item_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_toolbar_item_selected_set(IntPtr obj, bool selected);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_toolbar_item_selected_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_toolbar_selected_item_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_toolbar_item_separator_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_toolbar_item_separator_set(IntPtr obj, bool separator);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_toolbar_item_find_by_label(IntPtr obj, string label);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_toolbar_item_insert_after(IntPtr obj, IntPtr after, string icon, string label, Evas_Smart_Cb func, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_toolbar_items_count(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_toolbar_menu_parent_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_toolbar_menu_parent_set(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_toolbar_more_item_get(IntPtr obj);
+ }
+}
diff --git a/src/ElmSharp/Interop/Interop.Elementary.Win.cs b/src/ElmSharp/Interop/Interop.Elementary.Win.cs
new file mode 100755
index 0000000..3b86ee2
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.Win.cs
@@ -0,0 +1,429 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using ElmSharp;
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_win_add(IntPtr parent, string name, int type);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_win_util_standard_add(string name, string title);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_activate(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_title_set(IntPtr obj, string title);
+
+ [DllImport(Libraries.Elementary, EntryPoint = "elm_win_title_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, CharSet = CharSet.Ansi)]
+ internal static extern IntPtr _elm_win_title_get(IntPtr obj);
+
+ internal static string elm_win_title_get(IntPtr obj)
+ {
+ var text = _elm_win_title_get(obj);
+ return Marshal.PtrToStringAnsi(text);
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_screen_size_get(IntPtr obj, out int x, out int y, out int w, out int h);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_resize_object_del(IntPtr obj, IntPtr subobj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_resize_object_add(IntPtr obj, IntPtr subobj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_raise(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_lower(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_win_alpha_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_alpha_set(IntPtr obj, bool alpha);
+
+ [DllImport(Libraries.Elementary, EntryPoint = "elm_win_role_get")]
+ internal static extern IntPtr _elm_win_role_get(IntPtr obj);
+
+ internal static string elm_win_role_get(IntPtr obj)
+ {
+ var text = _elm_win_role_get(obj);
+ return Marshal.PtrToStringAnsi(text);
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_role_set(IntPtr obj, string role);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern string elm_win_focus_highlight_style_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_focus_highlight_style_set(IntPtr obj, string style);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_win_borderless_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_borderless_set(IntPtr obj, bool borderless);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_focus_highlight_enabled_set(IntPtr obj, bool enabled);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_win_focus_highlight_enabled_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_autodel_set(IntPtr obj, bool autodel);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_win_autodel_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_win_override_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_override_set(IntPtr obj, bool isOverride);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_indicator_opacity_set(IntPtr obj, int opacity);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_win_indicator_opacity_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_indicator_mode_set(IntPtr obj, IndicatorMode mode);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IndicatorMode elm_win_indicator_mode_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_win_demand_attention_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_demand_attention_set(IntPtr obj, bool demandAttention);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_win_conformant_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_conformant_set(IntPtr obj, bool conformant);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_win_fullscreen_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_fullscreen_set(IntPtr obj, bool fullscreen);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_rotation_set(IntPtr obj, int rotation);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_win_rotation_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_rotation_with_resize_set(IntPtr obj, int rotation);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_prop_focus_skip_set(IntPtr obj, bool skip);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_win_wm_rotation_supported_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_win_focus_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary, EntryPoint = "elm_win_wm_rotation_available_rotations_set")]
+ internal static extern void _elm_win_wm_rotation_available_rotations_set(IntPtr obj, IntPtr rotations, uint count);
+
+ internal static void elm_win_wm_rotation_available_rotations_set(IntPtr obj, int[] rotations)
+ {
+ IntPtr pRotations = Marshal.AllocHGlobal(Marshal.SizeOf<int>() * rotations.Length);
+ Marshal.Copy(rotations, 0, pRotations, rotations.Length);
+ _elm_win_wm_rotation_available_rotations_set(obj, pRotations, (uint)rotations.Length);
+ Marshal.FreeHGlobal(pRotations);
+ }
+
+ [DllImport(Libraries.Elementary, EntryPoint = "elm_win_wm_rotation_available_rotations_get")]
+ internal static extern bool _elm_win_wm_rotation_available_rotations_get(IntPtr obj, out IntPtr rotations, out int count);
+
+ internal static bool elm_win_wm_rotation_available_rotations_get(IntPtr obj, out int[] rotations)
+ {
+ IntPtr rotationArrPtr;
+ int count;
+ if (_elm_win_wm_rotation_available_rotations_get(obj, out rotationArrPtr, out count))
+ {
+ rotations = new int[count];
+ Marshal.Copy(rotationArrPtr, rotations, 0, count);
+ Libc.Free(rotationArrPtr);
+ return true;
+ }
+ rotations = null;
+ return false;
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_win_layer_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_layer_set(IntPtr obj, int layer);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_win_sticky_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_sticky_set(IntPtr obj, bool sticky);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_screen_dpi_get(IntPtr obj, out int xdpi, out int ydpi);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_iconified_set(IntPtr obj, bool iconified);
+
+ [DllImport(Libraries.Elementary)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool elm_win_iconified_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_win_floating_mode_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_floating_mode_set(IntPtr obj, bool floating);
+
+ [DllImport(Libraries.Elementary)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool elm_win_keygrab_set(IntPtr obj, string key, ulong modifiers, ulong notModifiers, int proirity, KeyGrabMode grabMode);
+
+ [DllImport(Libraries.Elementary)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool elm_win_keygrab_unset(IntPtr obj, string key, ulong modifiers, ulong notModifiers);
+
+ [DllImport(Libraries.Eext)]
+ internal static extern bool eext_win_keygrab_set(IntPtr obj, string key);
+
+ [DllImport(Libraries.Eext)]
+ internal static extern bool eext_win_keygrab_unset(IntPtr obj, string key);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_win_keyboard_win_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_keyboard_win_set(IntPtr obj, bool isKeyboard);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_win_keyboard_mode_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_keyboard_mode_set(IntPtr obj, int mode);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_inwin_activate(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_win_inwin_add(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_win_inwin_content_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_inwin_content_set(IntPtr obj, IntPtr content);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_win_inwin_content_unset(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_win_aspect_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_aspect_set(IntPtr obj, double aspect);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_win_autohide_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_autohide_set(IntPtr obj, bool autohide);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_center(IntPtr obj, bool h, bool v);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_win_focus_highlight_animate_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_focus_highlight_animate_set(IntPtr obj, bool animate);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern string elm_win_icon_name_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_icon_name_set(IntPtr obj, string iconName);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_win_icon_object_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_icon_object_set(IntPtr obj, IntPtr icon);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_win_inlined_image_object_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_win_maximized_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_maximized_set(IntPtr obj, bool maximized);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_win_modal_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_modal_set(IntPtr obj, bool modal);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_win_noblank_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_noblank_set(IntPtr obj, bool noblank);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_win_norender_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_norender_pop(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_norender_push(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern string elm_win_profile_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_profile_set(IntPtr obj, string profile);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_win_quickpanel_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_win_quickpanel_priority_major_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_quickpanel_priority_major_set(IntPtr obj, int priority);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_win_quickpanel_priority_minor_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_quickpanel_priority_minor_set(IntPtr obj, int priority);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_quickpanel_set(IntPtr obj, bool quickpanel);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_win_quickpanel_zone_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_quickpanel_zone_set(IntPtr obj, int zone);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_render(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_win_screen_constrain_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_screen_constrain_set(IntPtr obj, bool constrain);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_screen_position_get(IntPtr obj, out int x, out int y);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_win_shaped_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_shaped_set(IntPtr obj, bool shaped);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_size_base_get(IntPtr obj, out int w, out int h);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_size_base_set(IntPtr obj, int w, int h);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_size_step_get(IntPtr obj, out int w, out int h);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_size_step_set(IntPtr obj, int w, int h);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_win_socket_listen(IntPtr obj, string svcname, int svcnum, bool svcsys);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_win_trap_data_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_win_trap_set(IntPtr obj, IntPtr trap);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_win_urgent_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_urgent_set(IntPtr obj, bool urgent);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_win_util_dialog_add(IntPtr obj, string name, string title);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_win_withdrawn_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_withdrawn_set(IntPtr obj, bool withdrawn);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_wm_rotation_manual_rotation_done(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_win_wm_rotation_manual_rotation_done_get(IntPtr obj, bool withdrawn);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_wm_rotation_manual_rotation_done_set(IntPtr obj, bool set);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_win_wm_rotation_preferred_rotation_get(IntPtr obj, bool withdrawn);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_win_available_profiles_get(IntPtr obj, out string[] profiles, out int count);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_available_profiles_set(IntPtr obj, string[] profiles, int count);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_win_fake_add(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_fake_canvas_set(IntPtr obj, IntPtr oee);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_illume_command_send(IntPtr obj, IntPtr param);
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/Interop/Interop.Elementary.cs b/src/ElmSharp/Interop/Interop.Elementary.cs
new file mode 100644
index 0000000..3791d11
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Elementary.cs
@@ -0,0 +1,763 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ internal enum Edje_Message_Type
+ {
+ EDJE_MESSAGE_NONE = 0,
+
+ // A message with a string as value. Use #Edje_Message_String structs as message body, for this type.
+ EDJE_MESSAGE_STRING = 2,
+
+ // A message with an integer number as value. Use #Edje_Message_Int structs as message body, for this type.
+ EDJE_MESSAGE_INT = 3,
+
+ // A message with a floating pointer number as value. Use #Edje_Message_Float structs as message body, for this type.
+ EDJE_MESSAGE_FLOAT = 4,
+
+ // A message with a list of strings as value. Use #Edje_Message_String_Set structs as message body, for this type.
+ EDJE_MESSAGE_STRING_SET = 5,
+
+ // A message with a list of integer numbers as value. Use #Edje_Message_Int_Set structs as message body, for this type.
+ EDJE_MESSAGE_INT_SET = 6,
+
+ // A message with a list of floating point numbers as value. Use #Edje_Message_Float_Set structs as message body, for this type.
+ EDJE_MESSAGE_FLOAT_SET = 7,
+
+ // A message with a struct containing a string and an integer number as value. Use #Edje_Message_String_Int structs as message body, for this type.
+ EDJE_MESSAGE_STRING_INT = 8,
+
+ // A message with a struct containing a string and a floating point number as value. Use #Edje_Message_String_Float structs as message body, for this type.
+ EDJE_MESSAGE_STRING_FLOAT = 9,
+
+ // A message with a struct containing a string and list of integer numbers as value. Use #Edje_Message_String_Int_Set structs as message body, for this type.
+ EDJE_MESSAGE_STRING_INT_SET = 10,
+
+ // A message with a struct containing a string and list of floating point numbers as value. Use #Edje_Message_String_Float_Set structs as message body, for this type.
+ EDJE_MESSAGE_STRING_FLOAT_SET = 11
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_config_scroll_bring_in_scroll_friction_set(double time);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_config_scroll_bring_in_scroll_friction_get();
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_config_accel_preference_set(string preference);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_config_scale_set(double scale);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_config_scale_get();
+
+ [DllImport(Libraries.Elementary, EntryPoint = "elm_config_profile_get")]
+ internal static extern IntPtr _elm_config_profile_get();
+
+ internal static string elm_config_profile_get()
+ {
+ var str = _elm_config_profile_get();
+ return Marshal.PtrToStringAnsi(str);
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_config_preferred_engine_set(string name);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_config_longpress_timeout_get();
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_config_reload();
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_config_all_flush();
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_config_finger_size_set(int size);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_config_finger_size_get();
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_config_mirrored_get();
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_config_mirrored_set(bool mirrored);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_object_mirrored_automatic_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_mirrored_automatic_set(IntPtr obj, bool automatic);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_object_mirrored_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_mirrored_set(IntPtr obj, bool mirrored);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_grid_add(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_grid_pack(IntPtr obj, IntPtr subObj, int x, int y, int w, int h);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_grid_pack_get(IntPtr subObj, out int x, out int y, out int w, out int h);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_grid_pack_set(IntPtr subObj, int x, int y, int w, int h);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_grid_size_set(IntPtr obj, int w, int h);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_tree_dump(IntPtr top);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_object_disabled_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_disabled_set(IntPtr obj, bool disabled);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_init(int argc, string[] argv);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool ecore_main_loop_glib_integrate();
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_run();
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_exit();
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_shutdown();
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_app_base_scale_set(double base_scale);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_app_base_scale_get();
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_conformant_add(IntPtr obj);
+
+ [DllImport(Libraries.Elementary, EntryPoint = "elm_object_part_text_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, CharSet = CharSet.Ansi)]
+ internal static extern IntPtr _elm_object_part_text_get(IntPtr obj, IntPtr part);
+
+ [DllImport(Libraries.Elementary, EntryPoint = "elm_object_part_text_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, CharSet = CharSet.Ansi)]
+ internal static extern IntPtr _elm_object_part_text_get(IntPtr obj, string part);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_tooltip_text_set(IntPtr obj, string text);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_tooltip_unset(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern string elm_object_tooltip_style_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_tooltip_style_set(IntPtr obj, string style);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_object_tooltip_window_mode_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_object_tooltip_window_mode_set(IntPtr obj, bool disable);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_tooltip_move_freeze_push(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_tooltip_move_freeze_pop(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_object_tooltip_move_freeze_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_tooltip_show(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_tooltip_hide(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_tooltip_orient_set(IntPtr obj, int orient);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_object_tooltip_orient_get(IntPtr obj);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate IntPtr Elm_Tooltip_Content_Cb(IntPtr data, IntPtr obj, IntPtr tooltip);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_tooltip_content_cb_set(IntPtr obj, Elm_Tooltip_Content_Cb func, IntPtr data, Interop.Evas.SmartCallback del);
+
+ internal static string elm_object_part_text_get(IntPtr obj, string part)
+ {
+ var text = _elm_object_part_text_get(obj, part);
+ return Marshal.PtrToStringAnsi(text);
+ }
+
+ internal static string elm_object_part_text_get(IntPtr obj)
+ {
+ var text = _elm_object_part_text_get(obj, IntPtr.Zero);
+ return Marshal.PtrToStringAnsi(text);
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_object_part_content_get(IntPtr obj, string part);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_part_content_set(IntPtr obj, string part, IntPtr content);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_part_content_set(IntPtr obj, IntPtr part, IntPtr content);
+
+ internal static void elm_object_content_set(IntPtr obj, IntPtr content)
+ {
+ elm_object_part_content_set(obj, IntPtr.Zero, content);
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_object_part_content_unset(IntPtr obj, string part);
+
+ internal static void elm_object_content_unset(IntPtr obj)
+ {
+ elm_object_part_content_unset(obj, null);
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_layout_add(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_layout_content_get(IntPtr obj, string swallow);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_layout_content_set(IntPtr obj, string swallow, IntPtr content);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_layout_content_unset(IntPtr obj, string swallow);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_layout_text_set(IntPtr obj, string part, string text);
+
+ [DllImport(Libraries.Elementary, EntryPoint = "elm_layout_text_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, CharSet = CharSet.Ansi)]
+ internal static extern IntPtr _elm_layout_text_get(IntPtr obj, string part);
+
+ internal static string elm_layout_text_get(IntPtr obj, string part)
+ {
+ var text = _elm_layout_text_get(obj, part);
+ return Marshal.PtrToStringAnsi(text);
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_layout_theme_set(IntPtr obj, string klass, string group, string style);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_layout_file_get(IntPtr obj, IntPtr file, IntPtr group);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_layout_file_set(IntPtr obj, string file, string group);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_layout_signal_emit(IntPtr obj, string emission, string source);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_layout_signal_callback_add(IntPtr obj, string emission, string source, Edje_Signal_Cb func, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_layout_signal_callback_del(IntPtr obj, string emission, string source, Edje_Signal_Cb func);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void Edje_Signal_Cb(IntPtr data, IntPtr obj, string emission, string source);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_layout_box_append(IntPtr obj, string part, IntPtr child);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_layout_box_prepend(IntPtr obj, string part, IntPtr child);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_layout_box_remove(IntPtr obj, string part, IntPtr child);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_layout_box_remove_all(IntPtr obj, string part, bool clear);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern string elm_layout_data_get(IntPtr obj, string key);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_layout_text_valign_set(IntPtr obj, string part, double valign);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_layout_text_valign_get(IntPtr obj, string part);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_notify_add(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_notify_align_set(IntPtr obj, double horizontal, double vertical);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_notify_timeout_set(IntPtr obj, double timeout);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_object_scale_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_scale_set(IntPtr obj, double scale);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_signal_emit(IntPtr obj, string emission, string source);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_object_signal_callback_del(IntPtr obj, string emission, string source, Edje_Signal_Cb func);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_signal_callback_add(IntPtr obj, string emission, string source, Edje_Signal_Cb func, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_object_style_set(IntPtr obj, string style);
+
+ [DllImport(Libraries.Elementary, EntryPoint = "elm_object_style_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, CharSet = CharSet.Ansi)]
+ internal static extern IntPtr _elm_object_style_get(IntPtr obj);
+
+ internal static string elm_object_style_get(IntPtr obj)
+ {
+ var text = _elm_object_style_get(obj);
+ return Marshal.PtrToStringAnsi(text);
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_color_class_color_get(IntPtr obj, string colorClass, out int r, out int g, out int b, out int a);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_color_class_color_set(IntPtr obj, string colorClass, int r, int g, int b, int a);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_part_text_set(IntPtr obj, string part, string text);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_part_text_set(IntPtr obj, IntPtr part, string text);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_config_focus_highlight_animate_set(bool animate);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_config_focus_highlight_animate_get();
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_config_focus_highlight_enabled_set(bool enable);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_config_focus_highlight_enabled_get();
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_tree_focus_allow_set(IntPtr obj, bool focusable);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_object_tree_focus_allow_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_object_focus_next_object_get(IntPtr obj, int dir);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_object_focused_object_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_object_focus_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_focus_set(IntPtr obj, bool focus);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_object_focus_allow_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_focus_allow_set(IntPtr obj, bool enable);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_focus_next(IntPtr obj, int direction);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_focus_next_object_set(IntPtr obj, IntPtr next, int direction);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_focus_next_item_set(IntPtr obj, IntPtr nextItem, int direction);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_theme_extension_add(IntPtr theme, string path);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_theme_overlay_add(IntPtr theme, string path);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern string elm_language_set(string lang);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_policy_set(uint policy, int value);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_theme_new();
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_theme_free(IntPtr theme);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_theme_ref_set(IntPtr theme, IntPtr themeRef);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_theme_extension_del(IntPtr theme, string item);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_theme_overlay_del(IntPtr theme, string item);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_theme_set(IntPtr obj, string theme);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_theme_flush(IntPtr theme);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_theme_full_flush();
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_theme_set(IntPtr obj, IntPtr theme);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_layout_edje_get(IntPtr obj);
+
+ internal static void SetObjectText(IntPtr obj, string text)
+ {
+ elm_object_part_text_set(obj, IntPtr.Zero, text);
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_cache_all_flush();
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_domain_translatable_part_text_set(IntPtr obj, string part, string domain, string text);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void edje_object_color_class_del(IntPtr obj, string colorClass);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool edje_object_part_exists(IntPtr obj, string part);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr edje_object_part_object_get(IntPtr obj, string part);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool edje_object_part_geometry_get(IntPtr obj, string part, out int x, out int y, out int w, out int h);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool edje_object_part_text_set(IntPtr obj, string part, string text);
+
+ [DllImport(Libraries.Elementary, EntryPoint = "edje_object_part_text_get", CharSet = CharSet.Ansi)]
+ internal static extern IntPtr _edje_object_part_text_get(IntPtr obj, string part);
+
+ internal static string edje_object_part_text_get(IntPtr obj, string part)
+ {
+ var text = _edje_object_part_text_get(obj, part);
+ return Marshal.PtrToStringAnsi(text);
+ }
+
+ [DllImport(Libraries.Elementary, EntryPoint = "edje_object_part_text_style_user_peek", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, CharSet = CharSet.Ansi)]
+ internal static extern IntPtr _edje_object_part_text_style_user_peek(IntPtr obj, string part);
+
+ internal static string edje_object_part_text_style_user_peek(IntPtr obj, string part)
+ {
+ var text = _edje_object_part_text_style_user_peek(obj, part);
+ return Marshal.PtrToStringAnsi(text);
+ }
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void edje_object_part_text_style_user_push(IntPtr obj, string part, string style);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void edje_object_part_text_style_user_pop(IntPtr obj, string part);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void edje_object_signal_emit(IntPtr obj, string emission, string source);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void edje_object_mirrored_set(IntPtr obj, bool rtl);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr edje_object_add(IntPtr evas);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool edje_object_file_set(IntPtr obj, string file, string group);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool edje_object_part_box_append(IntPtr obj, string part, IntPtr child);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool edje_object_part_box_prepend(IntPtr obj, string part, IntPtr child);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern string edje_object_part_state_get(IntPtr obj, string part, out double value);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void edje_object_signal_callback_add(IntPtr obj, string emission, string source, Edje_Signal_Cb func, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr edje_object_signal_callback_del(IntPtr obj, string emission, string source, Edje_Signal_Cb func);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void edje_object_signal_callback_del_full(IntPtr obj, string emission, string source, Edje_Signal_Cb func, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool edje_color_class_set(string colorClass, int r, int g, int b, int a, int r2, int g2, int b2, int a2, int r3, int g3, int b3, int a3);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool edje_color_class_get(string colorClass, out int r, out int g, out int b, out int a, out int r2, out int g2, out int b2, out int a2,
+ out int r3, out int g3, out int b3, out int a3);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool edje_object_color_class_set(IntPtr obj, string colorClass, int r, int g, int b, int a, int r2, int g2, int b2, int a2, int r3, int g3, int b3, int a3);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool edje_object_color_class_get(IntPtr obj, string colorClass, out int r, out int g, out int b, out int a, out int r2, out int g2, out int b2, out int a2,
+ out int r3, out int g3, out int b3, out int a3);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void edje_message_signal_process();
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void edje_object_message_handler_set(IntPtr obj, Edje_Message_Handler_Cb func, IntPtr data);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void Edje_Message_Handler_Cb(IntPtr data, IntPtr obj, Edje_Message_Type type, int id, IntPtr msg);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void edje_object_message_send(IntPtr obj, Edje_Message_Type type, int id, IntPtr msg);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void edje_object_message_signal_process(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool edje_object_text_class_set(IntPtr obj, string textClass, string font, int size);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool edje_object_text_class_get(IntPtr obj, string textClass, out string font, out int size);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool edje_text_class_set(string textClass, string font, int size);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool edje_text_class_get(string textClass, out string font, out int size);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void edje_text_class_del(string textClass);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_transit_add();
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_transit_del(IntPtr transit);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_transit_object_add(IntPtr transit, IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_transit_effect_translation_add(IntPtr transit, int fromDx, int fromDy, int toDx, int toDy);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_transit_objects_final_state_keep_set(IntPtr transit, bool stateKeep);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_transit_tween_mode_set(IntPtr transit, int tweenMode);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_transit_repeat_times_set(IntPtr transit, int repeat);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_transit_duration_set(IntPtr transit, double duration);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_transit_go(IntPtr transit);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_transit_effect_zoom_add(IntPtr transit, float fromRate, float toRate);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_transit_effect_color_add(IntPtr transit, int fromR, int fromG, int fromB, int fromA, int toR, int toG, int toB, int toA);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_transit_auto_reverse_set(IntPtr transit, bool reverse);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_transit_effect_add(IntPtr transit, Elm_Transit_Effect_Transition_Cb transitionCb, IntPtr effect, Elm_Transit_Effect_End_Cb endCb);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_transit_effect_fade_add(IntPtr transit);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_transit_effect_resizing_add(IntPtr transit, int fromW, int fromH, int toW, int toH);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_transit_event_enabled_set(IntPtr transit, bool enabled);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_transit_smooth_set(IntPtr transit, bool enabled);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_transit_effect_del(IntPtr transit, Elm_Transit_Effect_Transition_Cb transitionCb, IntPtr effect);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_transit_object_remove(IntPtr transit, IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_transit_objects_final_state_keep_get(IntPtr transit);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_transit_event_enabled_get(IntPtr transit);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_transit_del_cb_set(IntPtr transit, Elm_Transit_Del_Cb cb, IntPtr data);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_transit_auto_reverse_get(IntPtr transit);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_transit_repeat_times_get(IntPtr transit);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_transit_tween_mode_get(IntPtr transit);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_transit_tween_mode_factor_set(IntPtr transit, double v1, double v2);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_transit_tween_mode_factor_get(IntPtr transit, out double v1, out double v2);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_transit_tween_mode_factor_n_set(IntPtr transit, int vSize, out double v);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_transit_duration_get(IntPtr transit);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_transit_go_in(IntPtr transit, double interval);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_transit_paused_set(IntPtr transit, bool paused);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_transit_paused_get(IntPtr transit);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern double elm_transit_progress_value_get(IntPtr transit);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_transit_chain_transit_add(IntPtr transit, IntPtr chainTransit);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_transit_chain_transit_del(IntPtr transit, IntPtr chainTransit);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_transit_chain_transits_get(IntPtr transit);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_transit_smooth_get(IntPtr transit);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_transit_effect_flip_add(IntPtr transit, int axis, bool cw);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_transit_effect_resizable_flip_add(IntPtr transit, int axis, bool cw);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_transit_effect_wipe_add(IntPtr transit, int type, int dir);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_transit_effect_blend_add(IntPtr transit);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_transit_effect_rotation_add(IntPtr transit, float fromDegree, float toDegree);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_transit_effect_image_animation_add(IntPtr transit, IntPtr images);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate int Eina_Compare_Cb(IntPtr data1, IntPtr data2);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void Elm_Transit_Effect_Transition_Cb(IntPtr effect, IntPtr transit, double progress);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void Elm_Transit_Effect_End_Cb(IntPtr effect, IntPtr transit);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void Elm_Transit_Del_Cb(IntPtr data, IntPtr transit);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_layout_box_insert_at(IntPtr obj, string part, IntPtr child, uint pos);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_layout_box_insert_before(IntPtr obj, string part, IntPtr child, IntPtr reference);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_layout_edje_object_can_access_get(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_layout_edje_object_can_access_set(IntPtr obj, bool canAccess);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_layout_freeze(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_layout_part_cursor_engine_only_get(IntPtr obj, string part);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_layout_part_cursor_engine_only_set(IntPtr obj, string part, bool engineOnly);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern string elm_layout_part_cursor_get(IntPtr obj, string part);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_layout_part_cursor_set(IntPtr obj, string part, string cursor);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern string elm_layout_part_cursor_style_get(IntPtr obj, string part);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_layout_part_cursor_style_set(IntPtr obj, string part, string style);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern bool elm_layout_part_cursor_unset(IntPtr obj, string part);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_layout_sizing_eval(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_layout_sizing_restricted_eval(IntPtr obj, bool width, bool height);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern int elm_layout_thaw(IntPtr obj);
+ }
+}
diff --git a/src/ElmSharp/Interop/Interop.Eo.cs b/src/ElmSharp/Interop/Interop.Eo.cs
new file mode 100644
index 0000000..9ff0936
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Eo.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Eo
+ {
+ [DllImport(Libraries.Eo)]
+ internal static extern IntPtr eo_class_get(IntPtr obj);
+
+ [DllImport(Libraries.Eo, EntryPoint = "eo_class_name_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, CharSet = CharSet.Ansi)]
+ internal static extern IntPtr _eo_class_name_get(IntPtr klass);
+
+ internal static string eo_class_name_get(IntPtr obj)
+ {
+ var name = _eo_class_name_get(obj);
+ return Marshal.PtrToStringAnsi(name);
+ }
+
+ }
+
+} \ No newline at end of file
diff --git a/src/ElmSharp/Interop/Interop.Evas.Image.cs b/src/ElmSharp/Interop/Interop.Evas.Image.cs
new file mode 100644
index 0000000..c18cbdd
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Evas.Image.cs
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Evas
+ {
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_image_file_set(IntPtr obj, string file, string key);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_image_border_set(IntPtr obj, int l, int r, int t, int b);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern int evas_object_image_border_center_fill_get(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_image_border_center_fill_set(IntPtr obj, int filled);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_image_alpha_set(IntPtr obj, bool has_alpha);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern bool evas_object_image_alpha_get(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern LoadError evas_object_image_load_error_get(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_image_size_get(IntPtr obj, IntPtr x, out int y);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_image_size_get(IntPtr obj, out int x, IntPtr y);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_image_size_get(IntPtr obj, out int x, out int y);
+ }
+} \ No newline at end of file
diff --git a/src/ElmSharp/Interop/Interop.Evas.cs b/src/ElmSharp/Interop/Interop.Evas.cs
new file mode 100755
index 0000000..f37ae6f
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Evas.cs
@@ -0,0 +1,808 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Evas
+ {
+ public enum ObjectCallbackType
+ {
+ MouseIn,
+ MouseOut,
+ MouseDown,
+ MouseUp,
+ MouseMove,
+ MouseWheel,
+ MultiDown,
+ MultiUp,
+ MultiMove,
+ Free,
+ KeyDown,
+ KeyUp,
+ FocusIn,
+ FocusOut,
+ Show,
+ Hide,
+ Move,
+ Resize,
+ Restack,
+ Del,
+ Hold,
+ ChangedSizeHints,
+ ImagePreloaded,
+ CanvasFocusIn,
+ CanvasFocusOut,
+ RenderFlushPre,
+ RenderFlushPost,
+ CanvasObjectFocusIn,
+ CanvasObjectFocusOut,
+ ImageUnloaded,
+ RenderPre,
+ RenderPost,
+ ImageResize,
+ DeviceChanged,
+ AxisUpdate,
+ CanvasViewportResize
+ }
+
+ public enum LoadError
+ {
+ None = 0, /* No error on load */
+ Generic = 1, /* A non-specific error occurred */
+ DoesNotRxist = 2, /* File (or file path) does not exist */
+ PermissionDenied = 3, /* Permission denied to an existing file (or path) */
+ ResourceAllocationFailed = 4, /* Allocation of resources failure prevented load */
+ CorruptFile = 5, /* File corrupt (but was detected as a known format) */
+ UnknownFormat = 6 /* File is not a known format */
+ }
+
+ public enum Colorspace
+ {
+ Argb8888, /* ARGB 32 bits per pixel, high-byte is Alpha, accessed 1 32bit word at a time */
+ Ycbcr422p709pl, /* YCbCr 4:2:2 Planar, ITU.BT-709 specifications. The data pointed to is just an array of row pointer, pointing to the Y rows, then the Cb, then Cr rows */
+ Ergb565a5p, /* 16bit rgb565 + Alpha plane at end - 5 bits of the 8 being used per alpha byte */
+ Egry8, /* 8bit grayscale */
+ Eycbcr422601pl, /* YCbCr 4:2:2, ITU.BT-601 specifications. The data pointed to is just an array of row pointer, pointing to line of Y,Cb,Y,Cr bytes */
+ Eycbcr420nv12601pl, /* YCbCr 4:2:0, ITU.BT-601 specification. The data pointed to is just an array of row pointer, pointing to the Y rows, then the Cb,Cr rows. */
+ Eycbcr420tm12601pl, /* YCbCr 4:2:0, ITU.BT-601 specification. The data pointed to is just an array of tiled row pointer, pointing to the Y rows, then the Cb,Cr rows. */
+ Eagry88, /* AY 8bits Alpha and 8bits Grey, accessed 1 16bits at a time */
+ Eetc1, /* OpenGL ETC1 encoding of RGB texture (4 bit per pixel) @since 1.10 */
+ Ergb8etc2, /* OpenGL GL_COMPRESSED_RGB8_ETC2 texture compression format (4 bit per pixel) @since 1.10 */
+ Ergba8etc2eac, /* OpenGL GL_COMPRESSED_RGBA8_ETC2_EAC texture compression format, supports alpha (8 bit per pixel) @since 1.10 */
+ Eetc1alpha, /* ETC1 with alpha support using two planes: ETC1 RGB and ETC1 grey for alpha @since 1.11 */
+ }
+
+ public enum ImageScaleHint
+ {
+ None = 0, /* No scale hint at all */
+ Dynamic = 1, /* Image is being re-scaled over time, thus turning scaling cache @b off for its data */
+ Static = 2 /* Image is not being re-scaled over time, thus turning scaling cache @b on for its data */
+ }
+
+ public enum RenderOp
+ {
+ Blend = 0, /* default op: d = d*(1-sa) + s */
+ BlendRel = 1, /* d = d*(1 - sa) + s*da */
+ Copy = 2, /* d = s */
+ CopyRel = 3, /* d = s*da */
+ Add = 4, /* d = d + s */
+ AddRel = 5, /* d = d + s*da */
+ Sub = 6, /* d = d - s */
+ SubRel = 7, /* d = d - s*da */
+ Tint = 8, /* d = d*s + d*(1 - sa) + s*(1 - da) */
+ TintRel = 9, /* d = d*(1 - sa + s) */
+ Mask = 10, /* d = d*sa */
+ Mul = 11 /* d = d*s */
+ }
+
+ public enum ObjectCallbackPriority
+ {
+ After = 100,
+ Before = -100,
+ Default = 0
+ }
+
+ public enum TableHomogeneousMode
+ {
+ None = 0,
+ Table = 1,
+ Item = 2
+ }
+
+ public enum TextStyleType
+ {
+ Plain, /* plain, standard text */
+ Shadow, /* text with shadow underneath */
+ Outline, /* text with an outline */
+ SoftOutline, /* text with a soft outline */
+ Glow, /* text with a glow effect */
+ OutlineShadow, /* text with both outline and shadow effects */
+ FarShadow, /* text with (far) shadow underneath */
+ OutlineSoftShadow, /* text with outline and soft shadow effects combined */
+ SoftShadow, /* text with(soft) shadow underneath */
+ FarSoftShadow, /* text with(far soft) shadow underneath */
+ ShadowDirectionBottomRight, /* shadow growing to bottom right */
+ ShadowDirectionBottom, /* shadow growing to the bottom */
+ ShadowDirectionBottomLeft, /* shadow growing to bottom left */
+ ShadowDirectionLeft, /* shadow growing to the left */
+ ShadowDirectionTopLeft, /* shadow growing to top left */
+ ShadowDirectionTop, /* shadow growing to the top */
+ ShadowDirectionTopRight, /* shadow growing to top right */
+ ShadowDirectionRight, /* shadow growing to the right */
+ }
+
+ //public struct TextBlockStyle
+ //{
+ // string StyleText;
+ // string DefaultTag;
+
+ // List objects;
+ // bool DeleteMe;
+ //}
+
+ //public struct StyleTag
+ //{
+ //}
+
+ internal delegate void EventCallback(IntPtr data, IntPtr evas, IntPtr obj, IntPtr info);
+
+ internal delegate void EvasCallback(IntPtr data, IntPtr evas, IntPtr info);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_event_callback_add(IntPtr obj, ObjectCallbackType type, EvasCallback func, IntPtr data);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_event_callback_del(IntPtr obj, ObjectCallbackType type, EvasCallback func);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_event_callback_add(IntPtr obj, ObjectCallbackType type, EventCallback func, IntPtr data);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_event_callback_del(IntPtr obj, ObjectCallbackType type, EventCallback func);
+
+ public delegate void SmartCallback(IntPtr data, IntPtr obj, IntPtr info);
+
+ public static readonly string BackKeyName = "XF86Back";
+ public static readonly string MenuKeyName = "XF86Menu";
+
+ public enum ButtonFlags
+ {
+ None, DoubleClick, TripleClick
+ }
+
+ [DllImport(Libraries.Evas)]
+ internal static extern bool evas_object_key_grab(IntPtr obj, string keyname, ulong modifier, ulong not_modifier, bool exclusive);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_key_ungrab(IntPtr obj, string keyname, ulong modifier, ulong not_modifier);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern IntPtr evas_object_data_get(IntPtr obj, string keyname);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_data_set(IntPtr obj, string keyname, IntPtr data);
+
+ [DllImport(Libraries.Evas, EntryPoint = "evas_object_type_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, CharSet = CharSet.Ansi)]
+ internal static extern IntPtr _evas_object_type_get(IntPtr obj);
+
+ internal static string evas_object_type_get(IntPtr obj)
+ {
+ var text = _evas_object_type_get(obj);
+ return Marshal.PtrToStringAnsi(text);
+ }
+
+ [DllImport(Libraries.Evas)]
+ internal static extern IntPtr evas_object_evas_get(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern IntPtr evas_object_image_add(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_del(IntPtr objectPtr);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_show(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_hide(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern bool evas_object_visible_get(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_smart_callback_add(IntPtr obj, string eventName, SmartCallback seh, IntPtr data);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_smart_callback_del(IntPtr obj, string eventName, SmartCallback seh);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_size_hint_min_set(IntPtr obj, int w, int h);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_size_hint_min_get(IntPtr obj, out int w, out int h);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_size_hint_min_get(IntPtr obj, IntPtr w, out int h);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_size_hint_min_get(IntPtr obj, out int w, IntPtr h);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_size_hint_max_set(IntPtr obj, int w, int h);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_size_hint_max_get(IntPtr obj, out int w, out int h);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_size_hint_max_get(IntPtr obj, IntPtr w, out int h);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_size_hint_max_get(IntPtr obj, out int w, IntPtr h);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_size_hint_weight_get(IntPtr obj, out double x, out double y);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_size_hint_weight_get(IntPtr obj, out double x, IntPtr y);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_size_hint_weight_get(IntPtr obj, IntPtr x, out double y);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_size_hint_align_get(IntPtr obj, out double x, out double y);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_size_hint_align_get(IntPtr obj, out double x, IntPtr y);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_size_hint_align_get(IntPtr obj, IntPtr x, out double y);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_size_hint_weight_set(IntPtr obj, double x, double y);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_size_hint_align_set(IntPtr obj, double x, double y);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_move(IntPtr obj, int x, int y);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_resize(IntPtr obj, int w, int h);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_geometry_set(IntPtr obj, int x, int y, int w, int h);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_geometry_get(IntPtr obj, out int x, out int y, out int w, out int h);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_geometry_get(IntPtr obj, out int x, IntPtr y, IntPtr w, IntPtr h);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_geometry_get(IntPtr obj, IntPtr x, out int y, IntPtr w, IntPtr h);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_geometry_get(IntPtr obj, IntPtr x, IntPtr y, out int w, IntPtr h);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_geometry_get(IntPtr obj, IntPtr x, IntPtr y, IntPtr w, out int h);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_geometry_get(IntPtr obj, IntPtr x, IntPtr y, out int w, out int h);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_geometry_get(IntPtr obj, out int x, out int y, IntPtr w, IntPtr h);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern IntPtr evas_object_smart_members_get(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern IntPtr evas_map_new(int count);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_map_util_points_populate_from_object_full(IntPtr map, IntPtr obj, int z);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_map_util_points_populate_from_geometry(IntPtr map, int x, int y, int w, int h, int z);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_map_util_3d_rotate(IntPtr map, double dx, double dy, double dz, int cx, int cy, int cz);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_map_util_zoom(IntPtr map, double x, double y, int cx, int cy);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_map_point_coord_set(IntPtr map, int idx, int x, int y, int z);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_map_point_coord_get(IntPtr map, int idx, out int x, out int y, out int z);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_map_enable_set(IntPtr obj, bool enabled);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern bool evas_object_map_enable_get(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_map_util_object_move_sync_set(IntPtr map, bool enabled);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern bool evas_map_util_object_move_sync_get(IntPtr map);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_map_set(IntPtr obj, IntPtr map);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern IntPtr evas_object_map_get(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_map_free(IntPtr map);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern IntPtr evas_object_polygon_add(IntPtr evas);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern IntPtr evas_object_polygon_point_add(IntPtr evas, int x, int y);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern IntPtr evas_object_polygon_points_clear(IntPtr evas);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern IntPtr evas_object_rectangle_add(IntPtr evas);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_color_set(IntPtr obj, int r, int g, int b, int a);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_color_get(IntPtr obj, out int r, out int g, out int b, out int a);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_color_get(IntPtr obj, IntPtr r, IntPtr g, IntPtr b, out int a);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_clip_set(IntPtr obj, IntPtr clip);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_clip_unset(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern IntPtr evas_object_clip_get(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_lower(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_event_feed_mouse_move(IntPtr obj, int x, int y, int timestamp, IntPtr data);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_event_feed_mouse_down(IntPtr obj, int b, ButtonFlags flags, int timestamp, IntPtr data);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_event_feed_mouse_up(IntPtr obj, int b, ButtonFlags flags, int timestamp, IntPtr data);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_event_feed_key_down(IntPtr obj, string keyname, string key, string str, string compose, int timestamp, IntPtr data);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_event_feed_key_up(IntPtr obj, string keyname, string key, string str, string compose, int timestamp, IntPtr data);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_ref(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_unref(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern int evas_object_ref_get(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_repeat_events_set(IntPtr obj, bool repeat);
+
+ [DllImport(Libraries.Evas)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool evas_object_repeat_events_get(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_propagate_events_set(IntPtr obj, bool propagate);
+
+ [DllImport(Libraries.Evas)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool evas_object_propagate_events_get(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_pass_events_set(IntPtr obj, bool propagate);
+
+ [DllImport(Libraries.Evas)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool evas_object_pass_events_get(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_textblock_size_native_get(IntPtr obj, out int w, out int h);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_textblock_size_formatted_get(IntPtr obj, out int w, out int h);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_smart_changed(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_smart_calculate(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_color_argb_premul(int a, ref int r, ref int g, ref int b);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_damage_rectangle_add(IntPtr obj, int x, int y, int w, int h);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_data_argb_premul(uint data, uint length);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_event_callback_del_full(IntPtr obj, ObjectCallbackType type, EvasCallback func, IntPtr data);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_font_path_global_append(string path);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_image_cache_flush(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_image_cache_set(IntPtr obj, int size);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern string evas_load_error_str(LoadError error);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern IntPtr evas_object_data_del(IntPtr obj, string key);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_focus_set(IntPtr obj, bool focus);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_freeze_events_set(IntPtr obj, bool freeze);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_image_colorspace_set(IntPtr obj, Colorspace colorSpace);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_image_data_copy_set(IntPtr obj, IntPtr data);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern IntPtr evas_object_image_data_get(IntPtr obj, bool forWriting);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_image_data_set(IntPtr obj, IntPtr data);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_image_data_update_add(IntPtr obj, int x, int y, int w, int h);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_image_fill_set(IntPtr obj, int x, int y, int w, int h);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern IntPtr evas_object_image_filled_add(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_image_filled_set(IntPtr obj, bool setting);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_image_memfile_set(IntPtr obj, IntPtr data, int size, string format, string key);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_image_pixels_dirty_set(IntPtr obj, bool dirty);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_image_save(IntPtr obj, string file, string key, string flags);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_image_scale_hint_set(IntPtr obj, ImageScaleHint hint);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_image_size_set(IntPtr obj, int w, int h);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_image_smooth_scale_set(IntPtr obj, bool smoothScale);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_image_source_set(IntPtr obj, IntPtr src);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_image_source_visible_set(IntPtr obj, bool visible);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_layer_set(IntPtr obj, int layer);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_raise(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_render_op_set(IntPtr obj, RenderOp op);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_size_hint_aspect_set(IntPtr obj, int aspect, int w, int h);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern IntPtr evas_object_smart_add(IntPtr obj, IntPtr smart);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern IntPtr evas_object_smart_data_get(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_smart_data_set(IntPtr obj, IntPtr data);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_smart_member_add(IntPtr obj, IntPtr smart);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_smart_member_del(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_stack_above(IntPtr obj, IntPtr avobe);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern IntPtr evas_object_text_add(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_text_font_set(IntPtr obj, string font, int size);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_text_text_set(IntPtr obj, string text);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern IntPtr evas_object_textblock_add(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern IntPtr evas_object_textblock_style_set(IntPtr obj, IntPtr textBlockStyle);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_textblock_text_markup_set(IntPtr obj, string text);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_obscured_clear(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern IntPtr evas_smart_class_new(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern string evas_device_name_get(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern string evas_font_path_global_clear();
+
+ [DllImport(Libraries.Evas)]
+ internal static extern IntPtr evas_object_above_get(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_event_callback_priority_add(IntPtr obj, ObjectCallbackType type, ObjectCallbackPriority priority, EventCallback func, IntPtr data);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern bool evas_object_focus_get(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern bool evas_object_freeze_events_get(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern int evas_object_layer_get(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_smart_callback_priority_add(IntPtr obj, string eventName, ObjectCallbackPriority priority, EventCallback func, IntPtr data);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_smart_clipped_smart_set(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_table_homogeneous_set(IntPtr obj, TableHomogeneousMode mode);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern bool evas_object_table_pack(IntPtr obj, IntPtr child, uint col, uint row, uint colspan, uint rowspan);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_table_padding_set(IntPtr obj, int horizontal, int vertical);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_text_filter_program_set(IntPtr obj, string program);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_text_glow_color_set(IntPtr obj, int r, int g, int b, int a);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_text_outline_color_set(IntPtr obj, int r, int g, int b, int a);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_text_shadow_color_set(IntPtr obj, int r, int g, int b, int a);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_text_style_set(IntPtr obj, TextStyleType type);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern bool evas_object_textblock_line_number_geometry_get(IntPtr obj, int line, out int x, out int y, out int w, out int h);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_textblock_valign_set(IntPtr obj, double align);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern int evas_string_char_len_get(string str);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern int evas_textblock_style_free(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern IntPtr evas_textblock_style_new();
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_textblock_style_set(IntPtr obj, string text);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern string evas_textblock_text_markup_to_utf8(IntPtr obj, string text);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern string evas_textblock_text_utf8_to_markup(IntPtr obj, string text);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_obscured_rectangle_add(IntPtr obj, int x, int y, int w, int h);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_render(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_norender(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern int evas_image_cache_get(IntPtr obj);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_font_path_global_prepend(string path);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_color_argb_unpremul(int a, ref int r, ref int g, ref int b);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_color_hsv_to_rgb(int r, int g, int b, out float h, out float s, out float v);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_color_rgb_to_hsv(float h, float s, float v, out int r, out int g, out int b);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_stack_below(IntPtr obj, IntPtr below);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_size_hint_aspect_get(IntPtr obj, out int aspect, out int w, out int h);
+
+ internal static void SetX(IntPtr obj, int x)
+ {
+ int y = GetY(obj);
+ evas_object_move(obj, x, y);
+ }
+
+ internal static void SetY(IntPtr obj, int y)
+ {
+ int x = GetX(obj);
+ evas_object_move(obj, x, y);
+ }
+
+ internal static void SetWidth(IntPtr obj, int w)
+ {
+ int h = GetHeight(obj);
+ evas_object_resize(obj, w, h);
+ }
+
+ internal static void SetHeight(IntPtr obj, int h)
+ {
+ int w = GetWidth(obj);
+ evas_object_resize(obj, w, h);
+ }
+
+ internal static int GetX(IntPtr obj)
+ {
+ int x;
+ evas_object_geometry_get(obj, out x, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
+ return x;
+ }
+
+ internal static int GetY(IntPtr obj)
+ {
+ int y;
+ evas_object_geometry_get(obj, IntPtr.Zero, out y, IntPtr.Zero, IntPtr.Zero);
+ return y;
+ }
+
+ internal static int GetWidth(IntPtr obj)
+ {
+ int w;
+ evas_object_geometry_get(obj, IntPtr.Zero, IntPtr.Zero, out w, IntPtr.Zero);
+ return w;
+ }
+
+ internal static int GetHeight(IntPtr obj)
+ {
+ int h;
+ evas_object_geometry_get(obj, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, out h);
+ return h;
+ }
+
+ internal static double GetAlignX(IntPtr obj)
+ {
+ double x;
+ evas_object_size_hint_align_get(obj, out x, IntPtr.Zero);
+ return x;
+ }
+
+ internal static double GetAlignY(IntPtr obj)
+ {
+ double y;
+ evas_object_size_hint_align_get(obj, IntPtr.Zero, out y);
+ return y;
+ }
+
+ internal static void SetAlignX(IntPtr obj, double x)
+ {
+ double y = GetAlignY(obj);
+ evas_object_size_hint_align_set(obj, x, y);
+ }
+
+ internal static void SetAlignY(IntPtr obj, double y)
+ {
+ double x = GetAlignX(obj);
+ evas_object_size_hint_align_set(obj, x, y);
+ }
+
+ internal static double GetWeightX(IntPtr obj)
+ {
+ double x;
+ evas_object_size_hint_weight_get(obj, out x, IntPtr.Zero);
+ return x;
+ }
+
+ internal static double GetWeightY(IntPtr obj)
+ {
+ double y;
+ evas_object_size_hint_weight_get(obj, IntPtr.Zero, out y);
+ return y;
+ }
+
+ internal static void SetWeightX(IntPtr obj, double x)
+ {
+ double y = GetWeightY(obj);
+ evas_object_size_hint_weight_set(obj, x, y);
+ }
+
+ internal static void SetWeightY(IntPtr obj, double y)
+ {
+ double x = GetWeightX(obj);
+ evas_object_size_hint_weight_set(obj, x, y);
+ }
+
+ internal static int GetAlpha(IntPtr obj)
+ {
+ int a;
+ evas_object_color_get(obj, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, out a);
+ return a;
+ }
+
+ internal static void SetAlpha(IntPtr obj, int a)
+ {
+ evas_object_color_set(obj, a, a, a, a);
+ }
+
+ internal static void SetPremultipliedColor(IntPtr obj, int r, int g, int b, int a)
+ {
+ evas_object_color_set(obj, r * a / 255, g * a / 255, b * a / 255, a);
+ }
+ }
+}
diff --git a/src/ElmSharp/Interop/Interop.Libc.cs b/src/ElmSharp/Interop/Interop.Libc.cs
new file mode 100644
index 0000000..1e29684
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Libc.cs
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Libc
+ {
+ [DllImport(Libraries.Libc, EntryPoint = "free", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int Free(IntPtr ptr);
+
+ // Broken-down time is stored in the structure tm which is defined in <time.h> as follows:
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct SystemTime
+ {
+ public int tm_sec;
+ public int tm_min;
+ public int tm_hour;
+ public int tm_mday;
+ public int tm_mon;
+ public int tm_year;
+ public int tm_wday;
+ public int tm_yday;
+ public int tm_isdst;
+
+ // The glibc version of struct tm has additional fields
+ public long tm_gmtoff;
+ public IntPtr tm_zone;
+
+ public static implicit operator SystemTime(DateTime value)
+ {
+ SystemTime tm = new SystemTime();
+ tm.tm_sec = value.Second;
+ tm.tm_min = value.Minute;
+ tm.tm_hour = value.Hour;
+ tm.tm_mday = value.Day;
+ tm.tm_mon = value.Month - 1;
+ tm.tm_year = value.Year - 1900;
+ tm.tm_wday = (int)value.DayOfWeek;
+ tm.tm_yday = value.DayOfYear;
+ tm.tm_isdst = value.IsDaylightSavingTime() ? 1 : 0;
+ return tm;
+ }
+
+ public static implicit operator DateTime(SystemTime value)
+ {
+ DateTime date = new DateTime(value.tm_year + 1900, value.tm_mon + 1, value.tm_mday, value.tm_hour, value.tm_min, value.tm_sec);
+ return date;
+ }
+ }
+ }
+}
diff --git a/src/ElmSharp/Interop/Interop.Libdl.cs b/src/ElmSharp/Interop/Interop.Libdl.cs
new file mode 100644
index 0000000..4f233f8
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Libdl.cs
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Libdl
+ {
+ private const int RTLD_NOW = 2;
+
+ [DllImport(Libraries.Libdl)]
+ private static extern IntPtr dlopen(string filename, int flags);
+
+ [DllImport(Libraries.Libdl)]
+ private static extern int dlclose(IntPtr handle);
+
+ [DllImport(Libraries.Libdl)]
+ private static extern IntPtr dlsym(IntPtr handle, string symbol);
+
+ [DllImport(Libraries.Libdl)]
+ private static extern IntPtr dlerror();
+
+ internal static IntPtr LoadLibrary(string filename)
+ {
+ return dlopen(filename, RTLD_NOW);
+ }
+
+ internal static void FreeLibrary(IntPtr handle)
+ {
+ dlclose(handle);
+ }
+
+ internal static IntPtr GetProcAddress(IntPtr handle, string name)
+ {
+ dlerror();
+ var res = dlsym(handle, name);
+ var errPtr = dlerror();
+ if (errPtr != IntPtr.Zero)
+ {
+ throw new Exception("dlsym : " + Marshal.PtrToStringAnsi(errPtr));
+ }
+ return res;
+ }
+ }
+}
diff --git a/src/ElmSharp/Interop/Interop.Libraries.cs b/src/ElmSharp/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..7f1ca6a
--- /dev/null
+++ b/src/ElmSharp/Interop/Interop.Libraries.cs
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static class Libraries
+ {
+ internal const string Libc = "libc.so.6";
+ internal const string Libdl = "libdl.so.2";
+ internal const string Evas = "libevas.so.1";
+ internal const string Elementary = "libelementary.so.1";
+ internal const string Eina = "libeina.so.1";
+ internal const string Ecore = "libecore.so.1";
+ internal const string EcoreInput = "libecore_input.so.1";
+ internal const string Eo = "libeo.so.1";
+ internal const string Eext = "libefl-extension.so.0";
+ }
+}
diff --git a/src/Tizen.Account.AccountManager/Interop/Interop.Account.cs b/src/Tizen.Account.AccountManager/Interop/Interop.Account.cs
new file mode 100644
index 0000000..9789044
--- /dev/null
+++ b/src/Tizen.Account.AccountManager/Interop/Interop.Account.cs
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Account.AccountManager;
+/// <summary>
+/// Interop for Account class APIs
+/// </summary>
+/// <since_tizen> 3 </since_tizen>
+internal static partial class Interop
+{
+ /// <summary>
+ /// Interop for Account class APIs
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ internal static partial class Account
+ {
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_create", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int Create(out IntPtr handle);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_destroy", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int Destroy(IntPtr handle);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_get_account_id", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int GetAccountId(IntPtr data, out int accountId);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_get_user_name", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int GetAccountUserName(IntPtr data, out string userName);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_set_user_name", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int SetAccountUserName(IntPtr handle, string userName);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_get_display_name", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int GetAccountDisplayName(IntPtr handle, out string displayName);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_set_display_name", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int SetAccountDisplayName(IntPtr handle, string displayName);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_get_capability", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int GetAccountCapability(IntPtr handle, string capabilityType, out int capabilityValue);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_set_capability", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int SetAccountCapability(IntPtr handle, string capabilityType, int capabilityValue);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_get_icon_path", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int GetAccountIconPath(IntPtr handle, out string iconPath);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_set_icon_path", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int SetAccountIconPath(IntPtr handle, string iconPath);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_get_domain_name", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int GetAccountDomainName(IntPtr handle, out string domainName);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_set_domain_name", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int SetAccountDomainName(IntPtr handle, string domainName);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_get_email_address", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int GetAccountEmail(IntPtr handle, out string email);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_set_email_address", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int SetAccountEmail(IntPtr handle, string email);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_get_package_name", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int GetAccountPackageName(IntPtr handle, out string name);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_set_package_name", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int SetAccountPackageName(IntPtr handle, string name);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_get_access_token", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int GetAccountAccessToken(IntPtr handle, out string accessToken);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_set_access_token", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int SetAccountAccessToken(IntPtr handle, string accessToken);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_get_user_text", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int GetAccountUserText(IntPtr handle, int index, out string userText);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_set_user_text", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int SetAccountUserText(IntPtr handle, int index, string userText);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_get_user_int", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int GetAccountUserInt(IntPtr handle, int index, out int value);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_set_user_int", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int SetAccountUserInt(IntPtr handle, int index, int value);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_get_auth_type", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int GetAccountAuthType(IntPtr handle, out int authType);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_set_auth_type", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int SetAccountAuthType(IntPtr handle, int authType);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_get_secret", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int GetAccountSercet(IntPtr handle, out int secretType);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_set_secret", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int SetAccountSecret(IntPtr handle, int secretType);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_get_sync_support", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int GetAccountSyncSupport(IntPtr handle, out int syncType);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_set_sync_support", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int SetAccountSyncSupport(IntPtr handle, int syncType);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_get_source", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int GetAccountSource(IntPtr handle, out string source);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_set_source", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int SetAccountSource(IntPtr handle, string source);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_get_custom", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int GetAccountCustomValue(IntPtr handle, string key, out string value);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_set_custom", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int SetAccountCustomValue(IntPtr handle, string key, string value);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_update_sync_status_by_id", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int UpdateAccountSyncStatusById(int accountId, int status);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_get_capability_all")]
+ internal static extern int GetAllAccountCapabilities(IntPtr handle, AccountCapabilityCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_query_capability_by_account_id")]
+ internal static extern int QueryAccountCapabilityById(AccountCapabilityCallback callback, int accountId, IntPtr userData);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_get_custom_all")]
+ internal static extern int GetAllAccountCustomValues(IntPtr handle, AccountCustomCallback callback, IntPtr userData);
+
+ //Callbacks
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool AccountCapabilityCallback(string capabilityType, int capabilityState, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool AccountCustomCallback(string key, string value, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool AccountCallback(IntPtr data, IntPtr userData);
+ }
+}
diff --git a/src/Tizen.Account.AccountManager/Interop/Interop.AccountProvider.cs b/src/Tizen.Account.AccountManager/Interop/Interop.AccountProvider.cs
new file mode 100644
index 0000000..f201061
--- /dev/null
+++ b/src/Tizen.Account.AccountManager/Interop/Interop.AccountProvider.cs
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Account.AccountManager;
+
+/// <summary>
+/// Interop for AccountProvider class APIs
+/// </summary>
+/// <since_tizen> 3 </since_tizen>
+internal static partial class Interop
+{
+ /// <summary>
+ /// Interop for AccountProvider class APIs
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ internal static partial class AccountProvider
+ {
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_type_create", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int Create(out IntPtr handle);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_type_destroy", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int Destroy(IntPtr handle);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_type_get_app_id", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int GetAppId(IntPtr handle, out string appId);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_type_query_supported_feature", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
+ internal static extern bool IsFeatureSupported(string appId, string capability);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_type_get_service_provider_id", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int GetServiceProviderId(IntPtr handle, out string providerId);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_type_get_icon_path", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int GetAccountProviderIconPath(IntPtr handle, out string iconPath);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_type_get_small_icon_path", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int GetAccountProviderSmallIconPath(IntPtr handle, out string iconPath);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_type_get_multiple_account_support", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int GetMultipleAccountSupport(IntPtr handle, out int suppport);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_type_get_label_by_locale", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int GetlabelbyLocale(IntPtr handle, string locale, out string label);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_type_query_app_id_exist", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int GetAppIdExists(string appId);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_type_foreach_account_type_from_db", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int GetAllAccountProviders(AccountProviderCallback callback, IntPtr data);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_type_query_provider_feature_by_app_id")]
+ internal static extern int GetAccountProviderFeaturesByAppId(AccountProviderFeatureCallback callback, string appId, IntPtr userData);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_type_get_provider_feature_all")]
+ internal static extern int GetAccountProviderFeatures(IntPtr handle, AccountProviderFeatureCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_type_get_label")]
+ internal static extern int GetAccountProviderLabels(IntPtr handle, LabelCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_type_query_label_by_app_id")]
+ internal static extern int GetLablesByAppId(LabelCallback callback, string appId, IntPtr userData);
+
+
+ //Callbacks
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool AccountProviderFeatureCallback(string appId, string key, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool AccountProviderCallback(IntPtr handle, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool LabelCallback(string appId, string label, string locale, IntPtr user_data);
+
+ }
+}
diff --git a/src/Tizen.Account.AccountManager/Interop/Interop.AccountService.cs b/src/Tizen.Account.AccountManager/Interop/Interop.AccountService.cs
new file mode 100644
index 0000000..7bb1275
--- /dev/null
+++ b/src/Tizen.Account.AccountManager/Interop/Interop.AccountService.cs
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+/// <summary>
+/// Interop for Account class APIs
+/// </summary>
+/// <since_tizen> 3 </since_tizen>
+internal static partial class Interop
+{
+ /// <summary>
+ /// Interop for Account class APIs
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ internal static partial class AccountService
+ {
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_update_to_db_by_id", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int UpdateAccountToDBById(IntPtr handle, int id);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_update_to_db_by_user_name", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int UpdateAccountToDBByUserName(IntPtr handle, string userName, string packageName);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_query_account_by_account_id", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int QueryAccountById(int accountId, out IntPtr handle);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_query_account_by_user_name", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int QueryAccountByUserName(Interop.Account.AccountCallback callback, string userName, IntPtr userData);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_query_account_by_package_name", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int QueryAccountByPackageName(Interop.Account.AccountCallback callback, string packageName, IntPtr userData);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_query_capability_by_account_id", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int QueryAccountCapabilityById(Interop.Account.AccountCapabilityCallback callback, int accoutId, IntPtr data);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_update_sync_status_by_id", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int UpdateAccountSyncStatusById(int accoutId, int status);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_insert_to_db", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int AddAccount(IntPtr handle, out int accountId);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_delete_from_db_by_id", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int DeleteAccountById(int accountId);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_delete_from_db_by_user_name", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int DeleteAccountByUser(string userName, string packageName);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_delete_from_db_by_package_name", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int DeleteAccountByPackage(string packageName);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_get_total_count_from_db", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int GetAccountCount(out int count);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_foreach_account_from_db")]
+ internal static extern int AccountForeachAccountFromDb(Interop.Account.AccountCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_query_account_by_capability")]
+ internal static extern int GetAccountByCapability(Interop.Account.AccountCallback callback, string capabilityType, int value, IntPtr userData);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_query_account_by_capability_type")]
+ internal static extern int GetAccountByCapabilityType(Interop.Account.AccountCallback callback, string capabilityType, IntPtr userData);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_type_foreach_account_type_from_db")]
+ internal static extern int GetAllAccountproviders(Interop.AccountProvider.AccountProviderCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_type_query_by_provider_feature")]
+ internal static extern int GetAccountProviderByFeature(Interop.AccountProvider.AccountProviderCallback callback, string key, IntPtr userData);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_type_query_by_app_id")]
+ internal static extern int GetAccountProviderByAppId(string appId, out IntPtr handle);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_subscribe_create")]
+ internal static extern int CreateAccountSubscriber(out Interop.AccountService.SafeAccountSubscriberHandle handle);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_subscribe_notification")]
+ internal static extern int RegisterSubscriber(Interop.AccountService.SafeAccountSubscriberHandle handle, Interop.AccountService.SubscribeCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.AccountSvc, EntryPoint = "account_unsubscribe_notification")]
+ internal static extern int UnregisterSubscriber(Interop.AccountService.SafeAccountSubscriberHandle handle);
+
+ //Callbacks
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool SubscribeCallback(string eventType, int accountId, IntPtr userData);
+
+ internal sealed class SafeAccountSubscriberHandle : SafeHandle
+ {
+ public SafeAccountSubscriberHandle()
+ : base(IntPtr.Zero, true)
+ {
+ }
+
+ public override bool IsInvalid
+ {
+ get { return this.handle == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ this.SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Account.AccountManager/Interop/Interop.Libraries.cs b/src/Tizen.Account.AccountManager/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..f1530bd
--- /dev/null
+++ b/src/Tizen.Account.AccountManager/Interop/Interop.Libraries.cs
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/// <summary>
+/// Interop for Library reference
+/// </summary>
+/// <since_tizen> 3 </since_tizen>
+internal static partial class Interop
+{
+ /// <summary>
+ /// Interop for Library reference
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ internal static partial class Libraries
+ {
+ public const string AccountSvc = "libaccounts-svc.so.0";
+ public const string Glib = "libglib-2.0.so.0";
+ public const string Libc = "libc.so.6";
+ }
+}
diff --git a/src/Tizen.Account.AccountManager/Tizen.Account.AccountManager.csproj b/src/Tizen.Account.AccountManager/Tizen.Account.AccountManager.csproj
new file mode 100644
index 0000000..8f0f722
--- /dev/null
+++ b/src/Tizen.Account.AccountManager/Tizen.Account.AccountManager.csproj
@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="../Tizen/Tizen.csproj" />
+ <ProjectReference Include="../Tizen.Log/Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Account.AccountManager/Tizen.Account.AccountManager/Account.cs b/src/Tizen.Account.AccountManager/Tizen.Account.AccountManager/Account.cs
new file mode 100644
index 0000000..df10a15
--- /dev/null
+++ b/src/Tizen.Account.AccountManager/Tizen.Account.AccountManager/Account.cs
@@ -0,0 +1,619 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Account.AccountManager
+{
+ /// <summary>
+ /// Represents the Account Information.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class Account : IDisposable
+ {
+ private IntPtr _handle = IntPtr.Zero;
+ internal Account(IntPtr handle)
+ {
+ Handle = handle;
+ }
+
+ ~Account()
+ {
+ Dispose(false);
+ }
+ /// <summary>
+ /// Creates a new Account instance.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>Account Instance.</returns>
+ public static Account CreateAccount()
+ {
+ IntPtr handle;
+ AccountError err = (AccountError)Interop.Account.Create(out handle);
+ if (err != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(err, "Failed to create new error.");
+ }
+
+ return new Account(handle);
+ }
+
+ /// <summary>
+ /// Id of the Account.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>Account Id shall be created only when account is added to the database.</remarks>
+ public int AccountId
+ {
+ get
+ {
+ int id = 0;
+ AccountError res = (AccountError)Interop.Account.GetAccountId(_handle, out id);
+ if (res != AccountError.None)
+ {
+ Log.Warn(AccountErrorFactory.LogTag, "Failed to get Id for the Account");
+ }
+
+ return id;
+ }
+ }
+
+ /// <summary>
+ /// UserName of the Account.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>User Name of the Account.</value>
+ public string UserName
+ {
+ get
+ {
+ string name = "";
+ AccountError res = (AccountError)Interop.Account.GetAccountUserName(_handle, out name);
+ if (res != AccountError.None)
+ {
+ Log.Warn(AccountErrorFactory.LogTag, "Failed to get UserName for the Account");
+ }
+
+ return name;
+ }
+
+ set
+ {
+ AccountError res = (AccountError)Interop.Account.SetAccountUserName(_handle, value);
+ if (res != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(res, "Failed to Set UserName for Account");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Display Name of the Account.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>DisplayName of the Account.</value>
+ public string DisplayName
+ {
+ get
+ {
+ string name = "";
+ AccountError res = (AccountError)Interop.Account.GetAccountDisplayName(_handle, out name);
+ if (res != AccountError.None)
+ {
+ Log.Warn(AccountErrorFactory.LogTag, "Failed to get DisplayName for the Account");
+ }
+
+ return name;
+ }
+
+ set
+ {
+ AccountError res = (AccountError)Interop.Account.SetAccountDisplayName(_handle, value);
+ if (res != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(res, "Failed to Set DisplayName for Account");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Icon path of the Account.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Icon path of the Account.</value>
+ public string IconPath
+ {
+ get
+ {
+ string path = "";
+ AccountError res = (AccountError)Interop.Account.GetAccountIconPath(_handle, out path);
+ if (res != AccountError.None)
+ {
+ Log.Warn(AccountErrorFactory.LogTag, "Failed to get IconPath for the Account");
+ }
+
+ return path;
+ }
+
+ set
+ {
+ AccountError res = (AccountError)Interop.Account.SetAccountIconPath(_handle, value);
+ if (res != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(res, "Failed to Set IconPath for Account");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Domain name of the Account.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Domain name of the Account.</value>
+ public string DomainName
+ {
+ get
+ {
+ string name = "";
+ AccountError res = (AccountError)Interop.Account.GetAccountDomainName(_handle, out name);
+ if (res != AccountError.None)
+ {
+ Log.Warn(AccountErrorFactory.LogTag, "Failed to get DomainName for the Account");
+ }
+
+ return name;
+ }
+
+ set
+ {
+ AccountError res = (AccountError)Interop.Account.SetAccountDomainName(_handle, value);
+ if (res != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(res, "Failed to Set DomainName for Account");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Email Id of the Account.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Email Id of the Account.</value>
+ public string EmailId
+ {
+ get
+ {
+ string email = "";
+ AccountError res = (AccountError)Interop.Account.GetAccountEmail(_handle, out email);
+ if (res != AccountError.None)
+ {
+ Log.Warn(AccountErrorFactory.LogTag, "Failed to get email for the Account");
+ }
+
+ return email;
+ }
+
+ set
+ {
+ AccountError res = (AccountError)Interop.Account.SetAccountEmail(_handle, value);
+ if (res != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(res, "Failed to Set email for Account");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Package Name of the Account.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Package Name.</value>
+ public string PackageName
+ {
+ get
+ {
+ string name = "";
+ AccountError res = (AccountError)Interop.Account.GetAccountPackageName(_handle, out name);
+ if (res != AccountError.None)
+ {
+ Log.Warn(AccountErrorFactory.LogTag, "Failed to get PacakageName for the Account");
+ }
+
+ return name;
+ }
+
+ set
+ {
+ AccountError res = (AccountError)Interop.Account.SetAccountPackageName(_handle, value);
+ if (res != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(res, "Failed to Set PacakageName for Account");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Access Token of the Account.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Access Token.</value>
+ public string AccessToken
+ {
+ get
+ {
+ string token = "";
+ AccountError res = (AccountError)Interop.Account.GetAccountAccessToken(_handle, out token);
+ if (res != AccountError.None)
+ {
+ Log.Warn(AccountErrorFactory.LogTag, "Failed to get token for the Account");
+ }
+
+ return token;
+ }
+
+ set
+ {
+ AccountError res = (AccountError)Interop.Account.SetAccountAccessToken(_handle, value);
+ if (res != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(res, "Failed to Set token for Account");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Authentication type of the Account.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Authentication type.</value>
+ public AccountAuthType AuthType
+ {
+ get
+ {
+ int user;
+ AccountError res = (AccountError)Interop.Account.GetAccountAuthType(_handle, out user);
+ if (res != AccountError.None)
+ {
+ Log.Warn(AccountErrorFactory.LogTag, "Failed to get AuthType for the Account");
+ }
+
+ return (AccountAuthType)user;
+ }
+
+ set
+ {
+ AccountError res = (AccountError)Interop.Account.SetAccountAuthType(_handle, (int)value);
+ if (res != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(res, "Failed to Set AuthType for Account");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Secrecy State of the Account.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Secrecy State.</value>
+ public AccountSecrecyState SecrecyState
+ {
+ get
+ {
+ int state;
+ AccountError res = (AccountError)Interop.Account.GetAccountSercet(_handle, out state);
+ if (res != AccountError.None)
+ {
+ Log.Warn(AccountErrorFactory.LogTag, "Failed to get User Secret for the Account");
+ }
+
+ return (AccountSecrecyState)state;
+ }
+
+ set
+ {
+ AccountError res = (AccountError)Interop.Account.SetAccountSecret(_handle, (int)value);
+ if (res != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(res, "Failed to Set User Secret for Account");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Sync State of the Account.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Sync State.</value>
+ public AccountSyncState SyncState
+ {
+ get
+ {
+ int supported;
+ AccountError res = (AccountError)Interop.Account.GetAccountSyncSupport(_handle, out supported);
+ if (res != AccountError.None)
+ {
+ Log.Warn(AccountErrorFactory.LogTag, "Failed to get AuthType for the Account");
+ }
+
+ return (AccountSyncState)supported;
+ }
+
+ set
+ {
+ AccountError res = (AccountError)Interop.Account.SetAccountSyncSupport(_handle, (int)value);
+ if (res != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(res, "Failed to Set AuthType for Account");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Source of the Account .
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Account Source.</value>
+ public string Source
+ {
+ get
+ {
+ string text = "";
+ AccountError res = (AccountError)Interop.Account.GetAccountSource(_handle, out text);
+ if (res != AccountError.None)
+ {
+ Log.Warn(AccountErrorFactory.LogTag, "Failed to get User Secret for the Account");
+ }
+
+ return text;
+ }
+
+ set
+ {
+ AccountError res = (AccountError)Interop.Account.SetAccountSource(_handle, value);
+ if (res != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(res, "Failed to Set User Secret for Account");
+ }
+ }
+ }
+
+ internal IntPtr Handle
+ {
+ get
+ {
+ return _handle;
+ }
+
+ set
+ {
+ _handle = value;
+ }
+ }
+ /// <summary>
+ /// Sets the account capability.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="capabilityType"> The Account capability type</param>
+ /// <param name="state">The Account capability state</param>
+ /// <exception cref="ArgumentException">In case of invalid parameters</exception>
+ public void SetCapability(string capabilityType, CapabilityState state)
+ {
+ AccountError ret = (AccountError)Interop.Account.SetAccountCapability(_handle, capabilityType, (int)state);
+ if (ret != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(ret, "failed to set account capability");
+ }
+ }
+ /// <summary>
+ /// Gets all the capabilities of an account.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="capabilityType"> The capability type to get the capability value.</param>
+ /// <returns>The capability value (on/off) of the specified CapabilityState .</returns>
+ /// <exception cref="ArgumentException">In case of invalid parameters</exception>
+ public CapabilityState GetCapability(string capabilityType)
+ {
+ int type;
+ AccountError res = (AccountError)Interop.Account.GetAccountCapability(_handle, capabilityType, out type);
+ if (res != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(res, "Failed to GetCapability for Account");
+ }
+
+ return (CapabilityState)type;
+ }
+
+ /// <summary>
+ /// Gets all the capabilities of an account.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>List of Cpabailities as Dictionary</returns>
+ public Dictionary<string, CapabilityState> GetAllCapabilities()
+ {
+
+ AccountError res = AccountError.None;
+ Dictionary<string, CapabilityState> list = new Dictionary<string, CapabilityState>();
+ Interop.Account.AccountCapabilityCallback capabilityCallback = (string type, int state, IntPtr data) =>
+ {
+ list.Add(type, (CapabilityState)state);
+ return true;
+ };
+
+ res = (AccountError)Interop.Account.GetAllAccountCapabilities(_handle, capabilityCallback, IntPtr.Zero);
+ if (res != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(res, "Failed to get account capabilities");
+ }
+
+ return list;
+ }
+
+ /// <summary>
+ /// Sets the Custom Value to the Account.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="key">key to be added to the Account.</param>
+ /// <param name="value">value to be updated for respective key for the Account.</param>
+ /// <exception cref="ArgumentException">In case of invalid parameters</exception>
+ public void SetCustomValue(string key, string value)
+ {
+ AccountError err = (AccountError)Interop.Account.SetAccountCustomValue(_handle, key, value);
+ if (err != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(err, "Failed to set the value for : " + key);
+ }
+ }
+
+ /// <summary>
+ /// Gets the user specific custom text of an account key.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="key">The key to retrieve custom text .</param>
+ /// <returns>The text of the given key</returns>
+ /// <exception cref="ArgumentException">In case of invalid parameters</exception>
+ /// <exception cref="InvalidOperationException">If there is no given capability type in the account </exception>
+ public string GetCustomValue(string key)
+ {
+ string result = "";
+ AccountError err = (AccountError)Interop.Account.GetAccountCustomValue(_handle, key, out result);
+ if (err != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(err, "Failed to get the value for : " + key);
+ }
+
+ return result;
+ }
+
+ /// <summary>
+ /// Gets All the custome values.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>List of custom key, value pairs as Dictionary.</returns>
+ public Dictionary<string, string> GetAllCustomValues()
+ {
+ AccountError res = AccountError.None;
+ Dictionary<string, string> list = new Dictionary<string, string>();
+
+ Interop.Account.AccountCustomCallback customCallback = (string key, string value, IntPtr data) =>
+ {
+ list.Add(key, value);
+ return true;
+ };
+
+ res = (AccountError)Interop.Account.GetAllAccountCustomValues(_handle, customCallback, IntPtr.Zero);
+
+ if (res != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(res, "Failed to get account capabilities");
+ }
+
+ return list;
+ }
+
+ /// <summary>
+ /// Sets the user text.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="index">The index of the user text (must be in range from 0 to 4) </param>
+ /// <param name="text">The text string to set as the user text</param>
+ /// <exception cref="ArgumentException">In case of invalid parameters</exception>
+ public void SetUserText(int index, string text)
+ {
+ AccountError err = (AccountError)Interop.Account.SetAccountUserText(_handle, index, text);
+ if (err != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(err, "Failed to get the value for : " + index);
+ }
+ }
+
+ /// <summary>
+ /// Gets the user text.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="index">The index of the user text (range: 0 ~ 4)</param>
+ /// <returns>The user text of the given key</returns>
+ /// <exception cref="ArgumentException">In case of invalid parameters</exception>
+ /// <exception cref="OutOfMemoryException">In case of out of memory</exception>
+ public string GetUserText(int index)
+ {
+ string result = "";
+ AccountError err = (AccountError)Interop.Account.GetAccountUserText(_handle, index, out result);
+ if (err != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(err, "Failed to get the value for : " + index);
+ }
+
+ return result;
+ }
+
+ /// <summary>
+ /// Gets the user int value.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="index">The index of the user int (range: 0 ~ 4)</param>
+ /// <returns>The user int of the given key</returns>
+ /// <exception cref="ArgumentException">In case of invalid parameters</exception>
+ public int GetUserInt(int index)
+ {
+ int result = -1;
+ AccountError err = (AccountError)Interop.Account.GetAccountUserInt(_handle, index, out result);
+ if (err != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(err, "Failed to get the value for : " + index);
+ }
+
+ return result;
+ }
+
+ /// <summary>
+ /// Sets the user integer value.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="index">The index of the user integer (must be in range from 0 to 4) </param>
+ /// <param name="value">The integer to set as the user integer</param>
+ /// <exception cref="ArgumentException">In case of invalid parameters</exception>
+ public void SetUserInt(int index, int value)
+ {
+ AccountError err = (AccountError)Interop.Account.SetAccountUserInt(_handle, index, value);
+ if (err != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(err, "Failed to get the value for : " + index);
+ }
+ }
+
+ /// <summary>
+ /// Overloaded Dispose API for destroying the Account Handle.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (!disposing)
+ {
+ if (_handle != IntPtr.Zero)
+ {
+ _handle = IntPtr.Zero;
+ }
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Account.AccountManager/Tizen.Account.AccountManager/AccountEnums.cs b/src/Tizen.Account.AccountManager/Tizen.Account.AccountManager/AccountEnums.cs
new file mode 100644
index 0000000..b55a458
--- /dev/null
+++ b/src/Tizen.Account.AccountManager/Tizen.Account.AccountManager/AccountEnums.cs
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Account.AccountManager
+{
+ /// <summary>
+ /// Enumeration for the state of capability
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CapabilityState
+ {
+ /// <summary>
+ /// Account capability is invalid
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ InvalidState,
+
+ /// <summary>
+ /// Account capability is disabled
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Disabled,
+
+ /// <summary>
+ /// Account capability is enabled
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Enabled
+ }
+
+ /// <summary>
+ /// Enumeration for the state of account secrecy.
+ /// </summary>
+ public enum AccountSecrecyState
+ {
+ /// <summary>
+ /// Account secrecy is invalid
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ InvalidState,
+
+ /// <summary>
+ /// Account is not visible
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Invisible,
+
+ /// <summary>
+ /// Account is visible
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Visible
+ }
+
+ /// <summary>
+ /// Enumeration for the account sync status.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum AccountSyncState
+ {
+ /// <summary>
+ /// Account sync is invalid
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ InvalidState,
+
+ /// <summary>
+ /// Account sync not supported
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ NotSupported,
+
+ /// <summary>
+ /// Account sync supported but all synchronization functionalities are off
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Off,
+
+ /// <summary>
+ /// Account sync support and sync status is idle
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Idle,
+
+ /// <summary>
+ /// Account sync support and sync status is running
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Running
+ }
+
+ /// <summary>
+ /// Enumeration for the account auth type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum AccountAuthType
+ {
+ /// <summary>
+ /// Auth type is invalid
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Invalid,
+
+ /// <summary>
+ /// XAuth type
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ XAuth,
+
+ /// <summary>
+ /// OAuth type
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ OAuth,
+
+ /// <summary>
+ /// Client-Login type
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ ClientLogin
+ }
+
+ /// <summary>
+ /// Account information change notification type
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// When the account database is changed, You can distinguish one event type from the other which are set for subscribing notification.
+ /// </remarks>
+ public enum AccountNotificationType
+ {
+ /// <summary>
+ /// The insert notification type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Insert,
+ /// <summary>
+ /// The delete notification type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Delete,
+ /// <summary>
+ /// The update notification type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Update,
+ /// <summary>
+ /// The sync update notification type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ syncUpdate
+ }
+}
diff --git a/src/Tizen.Account.AccountManager/Tizen.Account.AccountManager/AccountErrorFactory.cs b/src/Tizen.Account.AccountManager/Tizen.Account.AccountManager/AccountErrorFactory.cs
new file mode 100644
index 0000000..48f9164
--- /dev/null
+++ b/src/Tizen.Account.AccountManager/Tizen.Account.AccountManager/AccountErrorFactory.cs
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Tizen;
+
+namespace Tizen.Account.AccountManager
+{
+ /// <summary>
+ /// Enum to give the type of error occured, if any.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum AccountError
+ {
+ //TIZEN_ERROR_ACCOUNT = -0x01000000
+ /// <summary>
+ /// Successful.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ None = Tizen.Internals.Errors.ErrorCode.None,
+ /// <summary>
+ /// Invalid parameter.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+ /// <summary>
+ /// Out of memory.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
+ /// <summary>
+ /// Same user name exists in your application
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Duplcated = -0x01000000 | 0x01,
+ /// <summary>
+ /// Empty Data
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ NoData = Tizen.Internals.Errors.ErrorCode.NoData,
+ /// <summary>
+ /// elated record does not exist
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ RecordNotFound = -0x01000000 | 0x03,
+ /// <summary>
+ /// Invalid Operation.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ InvalidOperation = Tizen.Internals.Errors.ErrorCode.InvalidOperation,
+ /// <summary>
+ /// DB operation failed.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ DBFailed = -0x01000000 | 0x04,
+ /// <summary>
+ /// DB is not connected.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ DBNotOpened = -0x01000000 | 0x05,
+ /// <summary>
+ /// DB query syntax error
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ QuerySyntaxError = -0x01000000 | 0x06,
+ /// <summary>
+ /// Iterator has reached the end
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ IteratorEnd = -0x01000000 | 0x07,
+ /// <summary>
+ /// Notification failed
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ NotificationFailed = -0x01000000 | 0x08,
+ /// <summary>
+ /// Permission denied.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied,
+ /// <summary>
+ /// XML parse failed
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ XMLParseFailed = -0x01000000 | 0x0a,
+ /// <summary>
+ /// XML File not found
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ XMLFileNotFound = -0x01000000 | 0x0b,
+ /// <summary>
+ /// Subscription failed
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ EventSubscriptionFailed = -0x01000000 | 0x0c,
+ /// <summary>
+ /// Account provider is not registered
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ ProviderNotRegistered = -0x01000000 | 0x0d,
+ /// <summary>
+ /// Multiple accounts are not supported.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ MultipleNotAllowed = -0x01000000 | 0x0e,
+ /// <summary>
+ /// SQLite busy handler expired
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ DBBusy = -0x01000000 | 0x10
+ };
+
+ internal class AccountErrorFactory
+ {
+ internal const string LogTag = "Tizen.Account.AccountManager";
+
+ internal static Exception CreateException(AccountError err, string msg)
+ {
+ Log.Info(LogTag, "Got Error " + err + " throwing Exception with msg " + msg);
+ Exception exp;
+ switch (err)
+ {
+ case AccountError.InvalidParameter:
+ {
+ exp = new ArgumentException(msg + " Invalid Parameters Provided");
+ break;
+ }
+
+ case AccountError.OutOfMemory:
+ {
+ exp = new OutOfMemoryException(msg + " Out Of Memory");
+ break;
+ }
+
+ case AccountError.InvalidOperation:
+ {
+ exp = new InvalidOperationException(msg + " Inavlid operation");
+ break;
+ }
+
+ case AccountError.NoData:
+ {
+ exp = new InvalidOperationException(msg + " Empty Data");
+ break;
+ }
+
+ case AccountError.PermissionDenied:
+ {
+ exp = new UnauthorizedAccessException(msg + " Permission Denied");
+ break;
+ }
+
+ case AccountError.DBFailed:
+ {
+ exp = new InvalidOperationException(msg + " DataBase Failed");
+ break;
+ }
+
+ case AccountError.DBBusy:
+ {
+ exp = new InvalidOperationException(msg + " DataBase Busy");
+ break;
+ }
+
+ case AccountError.QuerySyntaxError:
+ {
+ exp = new InvalidOperationException(msg + " Network Error");
+ break;
+ }
+ case AccountError.XMLFileNotFound:
+ {
+ exp = new System.IO.FileNotFoundException(msg + " XML File not found");
+ break;
+ }
+ case AccountError.XMLParseFailed:
+ {
+ exp = new System.IO.InvalidDataException(msg + " XML parse error");
+ break;
+ }
+
+ default:
+ {
+ exp = new InvalidOperationException(err + " " + msg);
+ break;
+ }
+ }
+
+ return exp;
+ }
+ }
+}
diff --git a/src/Tizen.Account.AccountManager/Tizen.Account.AccountManager/AccountProvider.cs b/src/Tizen.Account.AccountManager/Tizen.Account.AccountManager/AccountProvider.cs
new file mode 100644
index 0000000..606a286
--- /dev/null
+++ b/src/Tizen.Account.AccountManager/Tizen.Account.AccountManager/AccountProvider.cs
@@ -0,0 +1,366 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Account.AccountManager
+{
+ /// <summary>
+ /// Account Id.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class AccountProvider : IDisposable
+ {
+ internal IntPtr _handle;
+ internal AccountProvider(IntPtr handle)
+ {
+ Handle = handle;
+ }
+
+ ~AccountProvider()
+ {
+ Dispose(false);
+ }
+
+ internal IntPtr Handle
+ {
+ get
+ {
+ return _handle;
+ }
+
+ set
+ {
+ _handle = value;
+ }
+ }
+ /// <summary>
+ /// Account Id.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string AppId
+ {
+ get
+ {
+ string id = "";
+ AccountError res = (AccountError)Interop.AccountProvider.GetAppId(Handle, out id);
+ if (res != AccountError.None)
+ {
+ Log.Warn(AccountErrorFactory.LogTag, "Failed to get AppId for the AccountProvider");
+ }
+
+ return id;
+ }
+ }
+
+ /// <summary>
+ /// Serviceprovider Id of the account provider.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string ServiceProviderId
+ {
+ get
+ {
+ string id = "";
+ AccountError res = (AccountError)Interop.AccountProvider.GetServiceProviderId(Handle, out id);
+ if (res != AccountError.None)
+ {
+ Log.Warn(AccountErrorFactory.LogTag, "Failed to get ServiceProviderId for the AccountProvider");
+ }
+
+ return id;
+ }
+ }
+
+ /// <summary>
+ /// Icon path of an account provider.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string IconPath
+ {
+ get
+ {
+ string path = "";
+ AccountError res = (AccountError)Interop.AccountProvider.GetAccountProviderIconPath(Handle, out path);
+ if (res != AccountError.None)
+ {
+ Log.Warn(AccountErrorFactory.LogTag, "Failed to get IconPath for the AccountProvider");
+ }
+
+ return path;
+ }
+ }
+
+ /// <summary>
+ /// Small icon path of an account provider.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string SmallIconPath
+ {
+ get
+ {
+ string path = "";
+ AccountError res = (AccountError)Interop.AccountProvider.GetAccountProviderSmallIconPath(Handle, out path);
+ if (res != AccountError.None)
+ {
+ Log.Warn(AccountErrorFactory.LogTag, "Failed to get SmallIconPath for the AccountProvider");
+ }
+
+ return path;
+ }
+ }
+
+ /// <summary>
+ /// Flag for account provider If supports multiple accounts.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool MultipleAccountSupport
+ {
+ get
+ {
+ int multiple = 0;
+ AccountError res = (AccountError)Interop.AccountProvider.GetMultipleAccountSupport(Handle, out multiple);
+ if (res != AccountError.None)
+ {
+ Log.Warn(AccountErrorFactory.LogTag, "Failed to get SmallIconPath for the AccountProvider");
+ }
+
+ return (multiple == 0) ? false : true;
+ }
+ }
+
+ /// <summary>
+ /// Retrieves all the capability information of the account provider.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/account.read</privilege>
+ /// <returns>
+ /// list of capability information.
+ /// </returns>
+ /// <exception cref="InvalidOperationException">In case of any DB error</exception>
+ /// <exception cref="UnauthorizedAccessException"> In case of privilege not defined.</exception>
+ public IEnumerable<string> GetAllCapabilities()
+ {
+ List<string> capabilities = new List<string>();
+ AccountError res;
+ Interop.AccountProvider.AccountProviderFeatureCallback callback = (string appId, string key, IntPtr data) =>
+ {
+ capabilities.Add(key);
+ return true;
+ };
+
+ res = (AccountError)Interop.AccountProvider.GetAccountProviderFeatures(Handle, callback, IntPtr.Zero);
+ if (res != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(res, "Failed to GetAllCapabilities for AccountProvider");
+ }
+
+ return capabilities;
+ }
+
+ /// <summary>
+ /// Gets the specific label information detail of an account provider.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="locale">
+ /// The locale is specified as an ISO 3166 alpha-2 two letter country-code followed by ISO 639-1 for the two-letter language code.
+ /// For example, "ko_KR" or "ko-kr" for Korean, "en_US" or "en-us" for American English.
+ /// </param>
+ /// <returns>The label text given for the locale</returns>
+ /// <privilege>http://tizen.org/privilege/account.read</privilege>
+ /// <exception cref="InvalidOperationException">In case of any DB error or record not found for given locale</exception>
+ /// <exception cref="UnauthorizedAccessException"> In case of privilege not defined.</exception>
+ public string GetLabel(string locale)
+ {
+ string label;
+ AccountError res = (AccountError)Interop.AccountProvider.GetlabelbyLocale(Handle, locale, out label);
+ if (res != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(res, "Failed to GetLabel for AccountProvider");
+ }
+
+ return label;
+ }
+
+ /// <summary>
+ /// Gets the specific label information detail of an account provider.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="appId">
+ /// The application ID to search
+ /// </param>
+ /// <returns> All the labels information for the given application Id.</returns>
+ /// <privilege>http://tizen.org/privilege/account.read</privilege>
+ /// <exception cref="InvalidOperationException">In case of any DB error or record not found for given appid</exception>
+ /// <exception cref="ArgumentException"> In case of invalid parameter</exception>
+ /// <exception cref="UnauthorizedAccessException"> In case of privilege not defined.</exception>
+ public static Dictionary<string, string> GetLabelsByAppId(string appId)
+ {
+
+ Dictionary<string, string> labels = new Dictionary<string, string>();
+ Interop.AccountProvider.LabelCallback callback = (string applicationId, string label, string locale, IntPtr userData) =>
+ {
+ labels.Add(locale, label);
+ return true;
+ };
+
+ AccountError err = (AccountError)Interop.AccountProvider.GetLablesByAppId(callback, appId, IntPtr.Zero);
+ if (err != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(err, "Failed to GetLablesByAppId");
+ }
+
+ return labels;
+ }
+
+ /// <summary>
+ /// Gets the label information detail of an account provider.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns> All the labels information for the given account provider.</returns>
+ /// <privilege>http://tizen.org/privilege/account.read</privilege>
+ /// <exception cref="InvalidOperationException">In case of any DB error</exception>
+ /// <exception cref="UnauthorizedAccessException"> In case of privilege not defined.</exception>
+ public Dictionary<string, string> GetLabels()
+ {
+
+ Dictionary<string, string> labels = new Dictionary<string, string>();
+ Interop.AccountProvider.LabelCallback callback = (string applicationId, string label, string locale, IntPtr userData) =>
+ {
+ labels.Add(locale, label);
+ return true;
+ };
+
+ AccountError err = (AccountError)Interop.AccountProvider.GetAccountProviderLabels(Handle, callback, IntPtr.Zero);
+ if (err != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(err, "Failed to GetAccountProviderLabels");
+ }
+
+ return labels;
+ }
+
+ /// <summary>
+ /// Checks whether the given appId exists in the account provider DB.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="appId">The application ID to check.</param>
+ /// <returns>returns true If App is supported </returns>
+ /// <privilege>http://tizen.org/privilege/account.read</privilege>
+ /// <exception cref="InvalidOperationException">In case of any DB error or record not found for given appid</exception>
+ /// <exception cref="ArgumentException"> In case of invalid parameter</exception>
+ /// <exception cref="UnauthorizedAccessException"> In case of privilege not defined.</exception>
+ public bool IsAppSupported(string appId)
+ {
+ bool isSupported = false;
+ AccountError res = (AccountError)Interop.AccountProvider.GetAppIdExists(appId);
+
+ if (res != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(res, "Failed to GetLabel for AccountProvider");
+ }
+ else
+ {
+ isSupported = true;
+ }
+
+ return isSupported;
+ }
+
+ /// <summary>
+ /// Checks whether the given application ID supports the capability.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="appId">The application Id</param>
+ /// <param name="capability">The capability information</param>
+ /// <returns>
+ /// TRUE if the application supports the given capability,
+ /// otherwise FALSE if the application does not support the given capability
+ /// </returns>
+ /// <privilege>http://tizen.org/privilege/account.read</privilege>
+ /// <exception cref="InvalidOperationException">In case of any DB error</exception>
+ /// <exception cref="ArgumentException"> In case of invalid parameter</exception>
+ /// <exception cref="UnauthorizedAccessException"> In case of privilege not defined.</exception>
+ public static bool IsFeatureSupportedByApp(string appId, string capability)
+ {
+ bool supported = Interop.AccountProvider.IsFeatureSupported(appId, capability);
+ if (!supported)
+ {
+ //Get last result and validate error code.
+ AccountError err = (AccountError)ErrorFacts.GetLastResult();
+ if ((err != AccountError.None) && (err != AccountError.RecordNotFound))
+ {
+ throw AccountErrorFactory.CreateException(err, "Failed to get IsFeatureSupported");
+ }
+ }
+
+ return supported;
+ }
+
+ /// <summary>
+ /// Retrieves capability information with application ID.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="appId">application Id</param>
+ /// <returns> Capability information list for the given appId.</returns>
+ /// <privilege>http://tizen.org/privilege/account.read</privilege>
+ /// <exception cref="InvalidOperationException">In case of any DB error or record not found for given appid</exception>
+ /// <exception cref="ArgumentException"> In case of invalid parameter</exception>
+ /// <exception cref="UnauthorizedAccessException"> In case of privilege not defined.</exception>
+ public static IEnumerable<string> GetFeaturesByAppId(string appId)
+ {
+
+ List<string> features = new List<string>();
+ Interop.AccountProvider.AccountProviderFeatureCallback callback = (string applicationId, string key, IntPtr userData) =>
+ {
+ features.Add(key);
+ return true;
+ };
+
+ AccountError err = (AccountError)Interop.AccountProvider.GetAccountProviderFeaturesByAppId(callback, appId, IntPtr.Zero);
+ if (err != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(err, "Failed to GetAccountProviderFeaturesByAppId");
+ }
+
+ return (IEnumerable<string>)features;
+ }
+
+ /// <summary>
+ /// Overloaded Dispose API for destroying the AccountProvider Handle.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (!disposing)
+ {
+ if (_handle != IntPtr.Zero)
+ {
+ Interop.AccountProvider.Destroy(_handle);
+ _handle = IntPtr.Zero;
+ }
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Account.AccountManager/Tizen.Account.AccountManager/AccountService.cs b/src/Tizen.Account.AccountManager/Tizen.Account.AccountManager/AccountService.cs
new file mode 100644
index 0000000..fc7cbd4
--- /dev/null
+++ b/src/Tizen.Account.AccountManager/Tizen.Account.AccountManager/AccountService.cs
@@ -0,0 +1,606 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Account.AccountManager
+{
+ /// <summary>
+ /// The AccountManager APIs is separated into two major sections:
+ /// 1. Registering an account provider while an application is installed. This information will be used for the Add account screen.
+ /// 2. Adding an account information when an application signs in successfully to share the account information to the Tizen system. This information will be shown in the Tizen settings account menu.
+ ///
+ /// The APIs of both of the sections consist of the following functionality:
+ /// <list>
+ /// <item> Create an account or account provider </item>
+ /// <item> Update an account or account provider(Only available for the creator) </item>
+ /// <item> Delete an account or account provider(Only available for the creator) </item>
+ /// <item> Read an account or account provider with some filter </item>
+ /// </list>
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+
+ public static class AccountService
+ {
+ /// <summary>
+ /// This is contact capability string.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static readonly string ContactCapability = "http://tizen.org/account/capability/contact";
+
+ /// <summary>
+ /// This is calendar capability string.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static readonly string CalendarCapability = "http://tizen.org/account/capability/calendar";
+
+ /// <summary>
+ /// This is email capability string.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static readonly string EmailCapability = "http://tizen.org/account/capability/email";
+
+ /// <summary>
+ /// This is photo capability string.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static readonly string PhotoCapability = "http://tizen.org/account/capability/photo";
+
+ /// <summary>
+ /// This is video capability string.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static readonly string VideoCapability = "http://tizen.org/account/capability/video";
+
+ /// <summary>
+ /// This is music capability string.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static readonly string MusicCapability = "http://tizen.org/account/capability/music";
+
+ /// <summary>
+ /// This is document capability string.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static readonly string DocumentCapability = "http://tizen.org/account/capability/document";
+
+ /// <summary>
+ /// This is message capability string.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static readonly string MessageCapability = "http://tizen.org/account/capability/message";
+
+ /// <summary>
+ /// This is game capability string.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static readonly string GameCapability = "http://tizen.org/account/capability/game";
+
+ /// <summary>
+ /// Retrieves all accounts details from the account database.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>List of Accounts</returns>
+ /// <privilege>http://tizen.org/privilege/account.read</privilege>
+ /// <exception cref="InvalidOperationException">In case of any DB error. </exception>
+ /// <exception cref="UnauthorizedAccessException"> In case of privilege not defined.</exception>
+ public static IEnumerable<Account> GetAccountsAsync()
+ {
+ List<Account> accounts = new List<Account>();
+ List<int> values = new List<int>();
+ Interop.Account.AccountCallback accountCallback = (IntPtr data, IntPtr userdata) =>
+ {
+ Account account = new Account(data);
+ values.Add(account.AccountId);
+ account.Dispose();
+ return true;
+ };
+
+ AccountError res = (AccountError)Interop.AccountService.AccountForeachAccountFromDb(accountCallback, IntPtr.Zero);
+ if (res != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(res, "Failed to AccountForeachAccountFromDb");
+ }
+
+ foreach (int i in values)
+ {
+ Account account = AccountService.GetAccountById(i);
+ accounts.Add(account);
+ }
+
+ return accounts;
+ }
+
+ /// <summary>
+ /// Retrieve an account with the account ID.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="accountId"> The account Id to be searched.</param>
+ /// <returns>Account instance with reference to the given id.</returns>
+ /// <privilege>http://tizen.org/privilege/account.read</privilege>
+ /// <exception cref="InvalidOperationException">In case of any DB error or record not found for given account id</exception>
+ /// <exception cref="ArgumentException"> In case of invalid parameter</exception>
+ /// <exception cref="UnauthorizedAccessException"> In case of privilege not defined.</exception>
+ public static Account GetAccountById(int accountId)
+ {
+ Account account = Account.CreateAccount();
+ IntPtr handle = account.Handle;
+ AccountError res = (AccountError)Interop.AccountService.QueryAccountById(accountId, out handle);
+ if (res != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(res, "Failed to get accounts from the database for account id: " + accountId);
+ }
+
+ account.Handle = handle;
+ return account;
+ }
+
+ /// <summary>
+ /// Retrieves all AccountProviders details from the account database.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>List of AccountProviders</returns>
+ /// <privilege>http://tizen.org/privilege/account.read</privilege>
+ /// <exception cref="InvalidOperationException">In case of any DB error</exception>
+ /// <exception cref="UnauthorizedAccessException"> In case of privilege not defined.</exception>
+ public static IEnumerable<AccountProvider> GetAccountProviders()
+ {
+ List<string> values = new List<string>();
+ List<AccountProvider> providers = new List<AccountProvider>();
+ Interop.AccountProvider.AccountProviderCallback accountCallback = (IntPtr handle, IntPtr data) =>
+ {
+ AccountProvider provider = new AccountProvider(handle);
+ values.Add(provider.AppId);
+ provider.Dispose();
+ return true;
+ };
+
+ AccountError res = (AccountError)Interop.AccountService.GetAllAccountproviders(accountCallback, IntPtr.Zero);
+ if (res != AccountError.None)
+ {
+ Log.Warn(AccountErrorFactory.LogTag, "Failed to get account providers from the database");
+ throw AccountErrorFactory.CreateException(res, "Failed to get account providers from the database");
+ }
+
+ foreach (string val in values)
+ {
+ AccountProvider provider = GetAccountProviderByAppId(val);
+ providers.Add(provider);
+ }
+
+ return providers;
+ }
+
+ /// <summary>
+ /// Retrieves the account provider information with application Id.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="appId">Application Id.</param>
+ /// <returns>The AccountProvider instance associated with the given application Id.</returns>
+ /// <privilege>http://tizen.org/privilege/account.read</privilege>
+ /// <exception cref="InvalidOperationException">In case of any DB error or record not found for given appid</exception>
+ /// <exception cref="ArgumentException"> In case of invalid parameter</exception>
+ /// <exception cref="UnauthorizedAccessException"> In case of privilege not defined.</exception>
+ public static AccountProvider GetAccountProviderByAppId(string appId)
+ {
+ IntPtr handle;
+ Interop.AccountProvider.Create(out handle);
+ AccountError err = (AccountError)Interop.AccountService.GetAccountProviderByAppId(appId, out handle);
+ if (err != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(err, "Failed to GetAccountProviderByAppId");
+ }
+
+ AccountProvider provider = new AccountProvider(handle);
+ return provider;
+ }
+
+ /// <summary>
+ /// Retrieves all the account providers information with feature.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="feature">The capability value to search for account providers.</param>
+ /// <returns>Retrieves AccountProviders information with the capability name.</returns>
+ /// <privilege>http://tizen.org/privilege/account.read</privilege>
+ /// <exception cref="InvalidOperationException">In case of any DB error or record not found for given feature</exception>
+ /// <exception cref="ArgumentException"> In case of invalid parameter</exception>
+ /// <exception cref="UnauthorizedAccessException"> In case of privilege not defined.</exception>
+ public static IEnumerable<AccountProvider> GetAccountProvidersByFeature(string feature)
+ {
+ List<string> values = new List<string>();
+ List<AccountProvider> providers = new List<AccountProvider>();
+ Interop.AccountProvider.AccountProviderCallback providerCallback = (IntPtr handle, IntPtr data) =>
+ {
+ AccountProvider provider = new AccountProvider(handle);
+ values.Add(provider.AppId);
+ provider.Dispose();
+ return true;
+ };
+
+ AccountError err = (AccountError)Interop.AccountService.GetAccountProviderByFeature(providerCallback, feature, IntPtr.Zero);
+ if (err != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(err, "Failed to GetAccountProviderByFeature");
+ }
+
+ foreach (string val in values)
+ {
+ AccountProvider provider = GetAccountProviderByAppId(val);
+ providers.Add(provider);
+ }
+
+ return providers;
+ }
+
+ /// <summary>
+ /// Inserts into the Database with the new account Infomration.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="account">New Account instance to be added.</param>
+ /// <privilege>http://tizen.org/privilege/account.read</privilege>
+ /// <privilege>http://tizen.org/privilege/account.write </privilege>
+ /// <exception cref="InvalidOperationException">In case of any DB error</exception>
+ /// <exception cref="ArgumentException"> In case of invalid parameter</exception>
+ /// <exception cref="UnauthorizedAccessException"> In case of privilege not defined.</exception>
+ /// <exception cref="OutOfMemoryException"> In case of OutOfMemory error.</exception>
+ public static int AddAccount(Account account)
+ {
+ if (account == null)
+ {
+ throw AccountErrorFactory.CreateException(AccountError.InvalidParameter, "Failed to AddAccount");
+ }
+
+ int id = -1;
+ AccountError err = (AccountError)Interop.AccountService.AddAccount(account.Handle, out id);
+ if (err != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(err, "Failed to AddAccount");
+ }
+
+ return id;
+ }
+
+ /// <summary>
+ /// Updates the account details to the account database.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="account">account instance to be updated.</param>
+ /// <privilege>http://tizen.org/privilege/account.read</privilege>
+ /// <privilege>http://tizen.org/privilege/account.write </privilege>
+ /// <exception cref="InvalidOperationException">In case of any DB error </exception>
+ /// <exception cref="ArgumentException"> In case of invalid parameter</exception>
+ /// <exception cref="UnauthorizedAccessException"> In case of privilege not defined.</exception>
+ /// <exception cref="OutOfMemoryException"> In case of OutOfMemory error.</exception>
+ public static void UpdateAccount(Account account)
+ {
+ if (account == null)
+ {
+ throw AccountErrorFactory.CreateException(AccountError.InvalidParameter, "Failed to UpdateAccount");
+ }
+
+ AccountError err = (AccountError)Interop.AccountService.UpdateAccountToDBById(account.Handle, account.AccountId);
+ if (err != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(err, "Failed to UpdateAccount");
+ }
+ }
+
+ /// <summary>
+ /// Deletes the account information from the Database.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="account">Account instance to be deleted from the database.</param>
+ /// <privilege>http://tizen.org/privilege/account.read</privilege>
+ /// <privilege>http://tizen.org/privilege/account.write </privilege>
+ /// <exception cref="InvalidOperationException">In case of any DB error </exception>
+ /// <exception cref="ArgumentException"> In case of invalid parameter</exception>
+ /// <exception cref="UnauthorizedAccessException"> In case of privilege not defined.</exception>
+ public static void DeleteAccount(Account account)
+ {
+ if (account == null)
+ {
+ throw AccountErrorFactory.CreateException(AccountError.InvalidParameter, "Failed to DeleteAccount");
+ }
+
+ AccountError err = (AccountError)Interop.AccountService.DeleteAccountById(account.AccountId);
+ if (err != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(err, "Failed to delete the account by Id: " + account.AccountId);
+ }
+ }
+
+ /// <summary>
+ /// Deletes an account from the account database by user name.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="userName">The user name of the account to delete.</param>
+ /// <param name="packageName">The package name of the account to delete.</param>
+ /// <privilege>http://tizen.org/privilege/account.read</privilege>
+ /// <privilege>http://tizen.org/privilege/account.write </privilege>
+ /// <exception cref="InvalidOperationException">In case of any DB error</exception>
+ /// <exception cref="ArgumentException"> In case of invalid parameter</exception>
+ /// <exception cref="UnauthorizedAccessException"> In case of privilege not defined.</exception>
+ public static void DeleteAccount(string userName, string packageName)
+ {
+ AccountError err = (AccountError)Interop.AccountService.DeleteAccountByUser(userName, packageName);
+ if (err != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(err, "Failed to delete the account by userName: " + userName);
+ }
+ }
+
+ /// <summary>
+ /// Deletes an account from the account database by package name.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="packageName">The package name of the account to delete.</param>
+ /// <privilege>http://tizen.org/privilege/account.read</privilege>
+ /// <privilege>http://tizen.org/privilege/account.write </privilege>
+ /// <exception cref="InvalidOperationException">In case of any DB error</exception>
+ /// <exception cref="ArgumentException"> In case of invalid parameter</exception>
+ /// <exception cref="UnauthorizedAccessException"> In case of privilege not defined.</exception>
+ public static void DeleteAccount(string packageName)
+ {
+ AccountError err = (AccountError)Interop.AccountService.DeleteAccountByPackage(packageName);
+ if (err != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(err, "Failed to delete the account by package name: " + packageName);
+ }
+
+ }
+
+ /// <summary>
+ /// Retrieves all accounts with the given user name.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="userName">The user name to search .</param>
+ /// <returns>Accounts list matched with the user name</returns>
+ /// <privilege>http://tizen.org/privilege/account.read</privilege>
+ /// <exception cref="InvalidOperationException">In case of any DB error or record not found for given username</exception>
+ /// <exception cref="ArgumentException"> In case of invalid parameter</exception>
+ /// <exception cref="UnauthorizedAccessException"> In case of privilege not defined.</exception>
+ public static IEnumerable<Account> GetAccountsByUserName(string userName)
+ {
+ List<Account> accounts = new List<Account>();
+ List<int> values = new List<int>();
+ Interop.Account.AccountCallback accountCallback = (IntPtr handle, IntPtr data) =>
+ {
+ Account account = new Account(handle);
+ values.Add(account.AccountId);
+ account.Dispose();
+ return true;
+ };
+
+ AccountError err = (AccountError)Interop.AccountService.QueryAccountByUserName(accountCallback, userName, IntPtr.Zero);
+ if (err != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(err, "Failed to GetAccountByUserName");
+ }
+
+ foreach (int i in values)
+ {
+ Account account = AccountService.GetAccountById(i);
+ accounts.Add(account);
+ }
+
+ return accounts;
+ }
+
+ /// <summary>
+ /// Retrieves all accounts with the given package name.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="packageName"> The package name to Search</param>
+ /// <returns>Accounts list matched with the package name</returns>
+ /// <privilege>http://tizen.org/privilege/account.read</privilege>
+ /// <exception cref="InvalidOperationException">In case of any DB error or record not found for given package name</exception>
+ /// <exception cref="ArgumentException"> In case of invalid parameter</exception>
+ /// <exception cref="UnauthorizedAccessException"> In case of privilege not defined.</exception>
+ public static IEnumerable<Account> GetAccountsByPackageName(string packageName)
+ {
+ List<Account> accounts = new List<Account>();
+ List<int> values = new List<int>();
+ Interop.Account.AccountCallback accountCallback = (IntPtr handle, IntPtr data) =>
+ {
+ Account account = new Account(handle);
+ values.Add(account.AccountId);
+ account.Dispose();
+ return true;
+ };
+
+ AccountError err = (AccountError)Interop.AccountService.QueryAccountByPackageName(accountCallback, packageName, IntPtr.Zero);
+ if (err != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(err, "Failed to GetAccountByPackageName");
+ }
+
+ foreach (int i in values)
+ {
+ Account account = AccountService.GetAccountById(i);
+ accounts.Add(account);
+ }
+
+ return accounts;
+ }
+
+ /// <summary>
+ /// Retrieves all accounts with the given cpability type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="type"> Capability type</param>
+ /// <returns>Accounts list matched with the capability type</returns>
+ /// <privilege>http://tizen.org/privilege/account.read</privilege>
+ /// <exception cref="InvalidOperationException">In case of any DB error or record not found for given capability type</exception>
+ /// <exception cref="ArgumentException"> In case of invalid parameter</exception>
+ /// <exception cref="UnauthorizedAccessException"> In case of privilege not defined.</exception>
+ public static IEnumerable<Account> GetAccountsByCapabilityType(string type)
+ {
+ List<Account> accounts = new List<Account>();
+ List<int> values = new List<int>();
+ Interop.Account.AccountCallback accountCallback = (IntPtr handle, IntPtr data) =>
+ {
+ Account account = new Account(handle);
+ values.Add(account.AccountId);
+ account.Dispose();
+ return true;
+ };
+
+ AccountError err = (AccountError)Interop.AccountService.GetAccountByCapabilityType(accountCallback, type, IntPtr.Zero);
+ if (err != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(err, "Failed to GetAccountByCapabilityType");
+ }
+
+ foreach (int i in values)
+ {
+ Account account = AccountService.GetAccountById(i);
+ accounts.Add(account);
+ }
+
+ return accounts;
+ }
+
+ /// <summary>
+ /// Retrieves all capabilities with the given account
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="accountId">account instance</param>
+ /// <returns>Capabilities list as Dictionary of Capability type and State.</returns>
+ /// <privilege>http://tizen.org/privilege/account.read</privilege>
+ /// <exception cref="InvalidOperationException">In case of any DB error or record not found for given account id</exception>
+ /// <exception cref="ArgumentException"> In case of invalid parameter</exception>
+ /// <exception cref="UnauthorizedAccessException"> In case of privilege not defined.</exception>
+ public static Dictionary<string, CapabilityState> GetCapabilitiesById(int accountId)
+ {
+ Dictionary<string, CapabilityState> capabilities = new Dictionary<string, CapabilityState>();
+ Interop.Account.AccountCapabilityCallback capabilityCallback = (string type, int capabilityState, IntPtr data) =>
+ {
+ capabilities.Add(type, (CapabilityState)capabilityState);
+ return true;
+ };
+
+ AccountError err = (AccountError)Interop.AccountService.QueryAccountCapabilityById(capabilityCallback, accountId, IntPtr.Zero);
+ if (err != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(err, "Failed to GetAllCapabilitiesById");
+ }
+
+ return capabilities;
+ }
+
+ /// <summary>
+ /// Gets the count of accounts in the account database.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>The number of accounts in the database</returns>
+ /// <privilege>http://tizen.org/privilege/account.read</privilege>
+ /// <exception cref="InvalidOperationException">In case of any DB error </exception>
+ /// <exception cref="UnauthorizedAccessException"> In case of privilege not defined.</exception>
+ public static int GetAccountsCount()
+ {
+ int count = 0;
+ AccountError err = (AccountError)Interop.AccountService.GetAccountCount(out count);
+ if (err != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(err, "Failed to GetAccountCount");
+ }
+
+ return count;
+ }
+
+ /// <summary>
+ /// Updates the sync status of the given account.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="account"> Account for which sync status needs to be updated</param>
+ /// <param name="status">Sync State</param>
+ /// <privilege>http://tizen.org/privilege/account.read</privilege>
+ /// <privilege>http://tizen.org/privilege/account.write</privilege>
+ /// <exception cref="InvalidOperationException">In case of any DB error </exception>
+ /// <exception cref="ArgumentException"> In case of invalid parameter</exception>
+ /// <exception cref="UnauthorizedAccessException"> In case of privilege not defined.</exception>
+ public static void UpdateSyncStatusById(Account account, AccountSyncState status)
+ {
+ AccountError err = (AccountError)Interop.AccountService.UpdateAccountSyncStatusById(account.AccountId, (int)status);
+ if (err != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(err, "Failed to UpdateSyncStatusById");
+ }
+ }
+
+ private static readonly Interop.AccountService.SubscribeCallback s_accountUpdatedCallback = (string eventType, int accountId, IntPtr userData) =>
+ {
+ AccountSubscriberEventArgs eventArgs = new AccountSubscriberEventArgs(eventType, accountId);
+ s_accountUpdated?.Invoke(null, eventArgs);
+ return true;
+ };
+
+ private static Interop.AccountService.SafeAccountSubscriberHandle s_subscriberHandle;
+
+ private static event EventHandler<AccountSubscriberEventArgs> s_accountUpdated;
+ /// <summary>
+ /// ContentUpdated event is triggered when the media item info from DB changes.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// ContentUpdate event is triggered if the MediaInformaion updated/deleted or new Inforamtion is Inserted.
+ /// </remarks>
+ /// <param name="sender"></param>
+ /// <param name="e">A ContentUpdatedEventArgs object that contains information about the update operation.</param>
+ /// <privilege>http://tizen.org/privilege/account.read</privilege>
+ /// <exception cref="InvalidOperationException">In case of any DB error </exception>
+ /// <exception cref="ArgumentException"> In case of invalid parameter</exception>
+ /// <exception cref="UnauthorizedAccessException"> In case of privilege not defined.</exception>
+ public static event EventHandler<AccountSubscriberEventArgs> AccountUpdated
+ {
+ add
+ {
+ if (s_accountUpdated == null)
+ {
+ if (s_subscriberHandle == null)
+ {
+ Interop.AccountService.CreateAccountSubscriber(out s_subscriberHandle);
+ }
+
+ AccountError ret = (AccountError)Interop.AccountService.RegisterSubscriber(s_subscriberHandle, s_accountUpdatedCallback, IntPtr.Zero);
+
+ if (ret != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+
+ s_accountUpdated += value;
+ }
+
+ remove
+ {
+ s_accountUpdated -= value;
+ if (s_accountUpdated == null)
+ {
+ AccountError ret = (AccountError)Interop.AccountService.UnregisterSubscriber(s_subscriberHandle);
+ if (ret != AccountError.None)
+ {
+ throw AccountErrorFactory.CreateException(ret, "Error in callback handling");
+ }
+ s_subscriberHandle = null;
+ }
+ }
+ }
+
+ }
+}
diff --git a/src/Tizen.Account.AccountManager/Tizen.Account.AccountManager/AccountSubscriberEventArgs.cs b/src/Tizen.Account.AccountManager/Tizen.Account.AccountManager/AccountSubscriberEventArgs.cs
new file mode 100644
index 0000000..153c427
--- /dev/null
+++ b/src/Tizen.Account.AccountManager/Tizen.Account.AccountManager/AccountSubscriberEventArgs.cs
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Account.AccountManager
+{
+ /// <summary>
+ /// Event arguments passed when Event is triggered to notify that account is updated/removed from the account database.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class AccountSubscriberEventArgs : EventArgs
+ {
+ private const string NotiInsert = "insert";
+ private const string NotiDelete = "delete";
+ private const string NotiUpdate = "update";
+ private const string NotiSyncUpdate = "sync_update";
+ internal AccountSubscriberEventArgs(string eventType, int accountId)
+ {
+ if (eventType.CompareTo(NotiInsert) == 0)
+ {
+ EventType = AccountNotificationType.Insert;
+ }
+ else if (eventType.CompareTo(NotiDelete) == 0)
+ {
+ EventType = AccountNotificationType.Delete;
+ }
+ else if (eventType.CompareTo(NotiUpdate) == 0)
+ {
+ EventType = AccountNotificationType.Update;
+ }
+ else if (eventType.CompareTo(NotiSyncUpdate) == 0)
+ {
+ EventType = AccountNotificationType.syncUpdate;
+ }
+
+ AccountId = accountId;
+ }
+
+ /// <summary>
+ /// The account event type
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public AccountNotificationType EventType
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// The account ID to update
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int AccountId
+ {
+ get;
+ internal set;
+ }
+ }
+}
diff --git a/src/Tizen.Account.FidoClient/Interop/Interop.Libc.cs b/src/Tizen.Account.FidoClient/Interop/Interop.Libc.cs
new file mode 100755
index 0000000..13c7170
--- /dev/null
+++ b/src/Tizen.Account.FidoClient/Interop/Interop.Libc.cs
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Libc
+ {
+ [DllImport(Libraries.Libc, EntryPoint = "free", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int Free(IntPtr ptr);
+ }
+}
diff --git a/src/Tizen.Account.FidoClient/Interop/Interop.Libraries.cs b/src/Tizen.Account.FidoClient/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..955fffe
--- /dev/null
+++ b/src/Tizen.Account.FidoClient/Interop/Interop.Libraries.cs
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ /// <summary>
+ /// Wrapper class for maintaining names of dependent native libraries.
+ /// </summary>
+ internal static partial class Libraries
+ {
+ public const string FidoClient = "libfido-client.so.0";
+ public const string Glib = "libglib-2.0.so.0";
+ public const string Libc = "libc.so.6";
+ }
+}
diff --git a/src/Tizen.Account.FidoClient/Interop/Interop.Uaf.Authenticator.cs b/src/Tizen.Account.FidoClient/Interop/Interop.Uaf.Authenticator.cs
new file mode 100755
index 0000000..7cbd9f9
--- /dev/null
+++ b/src/Tizen.Account.FidoClient/Interop/Interop.Uaf.Authenticator.cs
@@ -0,0 +1,68 @@
+// Copyright 2016 by Samsung Electronics, Inc.,
+//
+// This software is the confidential and proprietary information
+// of Samsung Electronics, Inc. ("Confidential Information"). You
+// shall not disclose such Confidential Information and shall use
+// it only in accordance with the terms of the license agreement
+// you entered into with Samsung.
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Internals.Errors;
+
+internal static partial class Interop
+{
+ internal static partial class UafAuthenticator
+ {
+ [DllImport(Libraries.FidoClient, EntryPoint = "fido_foreach_authenticator")]
+ internal static extern int ForeachAuthenticator(FidoAuthenticatorCallback cb, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.FidoClient, EntryPoint = "fido_authenticator_get_title")]
+ internal static extern int GetTitle(IntPtr /* fido_authenticator_h */ auth, out IntPtr title);
+
+ [DllImport(Libraries.FidoClient, EntryPoint = "fido_authenticator_get_aaid")]
+ internal static extern int GetAaid(IntPtr /* fido_authenticator_h */ auth, out IntPtr aaid);
+
+ [DllImport(Libraries.FidoClient, EntryPoint = "fido_authenticator_get_description")]
+ internal static extern int GetDescription(IntPtr /* fido_authenticator_h */ auth, out IntPtr desc);
+
+ [DllImport(Libraries.FidoClient, EntryPoint = "fido_authenticator_get_assertion_scheme")]
+ internal static extern int GetAssertionScheme(IntPtr /* fido_authenticator_h */ auth, out IntPtr scheme);
+
+ [DllImport(Libraries.FidoClient, EntryPoint = "fido_authenticator_get_algorithm")]
+ internal static extern int GetAlgorithm(IntPtr /* fido_authenticator_h */ auth, out int /* fido_auth_algo_e */ algo);
+
+ [DllImport(Libraries.FidoClient, EntryPoint = "fido_authenticator_foreach_attestation_type")]
+ internal static extern int ForeachAttestationType(IntPtr /* fido_authenticator_h */ auth, FidoAttestationTypeCallback cb, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.FidoClient, EntryPoint = "fido_authenticator_get_verification_method")]
+ internal static extern int GetVerificationMethod(IntPtr /* fido_authenticator_h */ auth, out int /* fido_auth_user_verify_type_e */ userVerification);
+
+ [DllImport(Libraries.FidoClient, EntryPoint = "fido_authenticator_get_key_protection_method")]
+ internal static extern int GetKeyProtectionMethod(IntPtr /* fido_authenticator_h */ auth, out int /* fido_auth_key_protection_type_e */ keyProtection);
+
+ [DllImport(Libraries.FidoClient, EntryPoint = "fido_authenticator_get_matcher_protection_method")]
+ internal static extern int GetMatcherProtectionMethod(IntPtr /* fido_authenticator_h */ auth, out int /* fido_auth_matcher_protection_type_e */ matcherProtection);
+
+ [DllImport(Libraries.FidoClient, EntryPoint = "fido_authenticator_get_attachment_hint")]
+ internal static extern int GetAttachmentHint(IntPtr /* fido_authenticator_h */ auth, out int /* fido_auth_attachment_hint_e */ attachmentHint);
+
+ [DllImport(Libraries.FidoClient, EntryPoint = "fido_authenticator_get_is_second_factor_only")]
+ internal static extern bool GetIsSecondFactorOnly(IntPtr /* fido_authenticator_h */ auth);
+
+ [DllImport(Libraries.FidoClient, EntryPoint = "fido_authenticator_get_tc_discplay")]
+ internal static extern int GetTcDiscplay(IntPtr /* fido_authenticator_h */ auth, out int /* fido_auth_tc_display_type_e */ tcDisplay);
+
+ [DllImport(Libraries.FidoClient, EntryPoint = "fido_authenticator_get_tc_display_type")]
+ internal static extern int GetTcDisplayType(IntPtr /* fido_authenticator_h */ auth, out IntPtr tcDisplayContentType);
+
+ [DllImport(Libraries.FidoClient, EntryPoint = "fido_authenticator_get_icon")]
+ internal static extern int GetIcon(IntPtr /* fido_authenticator_h */ auth, out IntPtr icon);
+
+ [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+ internal delegate void FidoAuthenticatorCallback(IntPtr /* fido_authenticator_h */ authInfo, IntPtr /* void */ userData);
+
+ [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+ internal delegate void FidoAttestationTypeCallback(int /* fido_auth_attestation_type_e */ attType, IntPtr /* void */ userData);
+ }
+}
diff --git a/src/Tizen.Account.FidoClient/Interop/Interop.Uaf.Client.cs b/src/Tizen.Account.FidoClient/Interop/Interop.Uaf.Client.cs
new file mode 100755
index 0000000..2c4072d
--- /dev/null
+++ b/src/Tizen.Account.FidoClient/Interop/Interop.Uaf.Client.cs
@@ -0,0 +1,35 @@
+// Copyright 2016 by Samsung Electronics, Inc.,
+//
+// This software is the confidential and proprietary information
+// of Samsung Electronics, Inc. ("Confidential Information"). You
+// shall not disclose such Confidential Information and shall use
+// it only in accordance with the terms of the license agreement
+// you entered into with Samsung.
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Internals.Errors;
+
+internal static partial class Interop
+{
+ internal static partial class UafClient
+ {
+ [DllImport(Libraries.FidoClient, EntryPoint = "fido_get_client_vendor")]
+ internal static extern int FidoGetClientVendor(out string vendorName);
+
+ [DllImport(Libraries.FidoClient, EntryPoint = "fido_get_client_version")]
+ internal static extern int FidoGetClientVersion(out int clientMajorVersion, out int clientMinorVersion);
+
+ [DllImport(Libraries.FidoClient, EntryPoint = "fido_uaf_is_supported")]
+ internal static extern int FidoUafIsSupported(string uafMessageJson, out bool isSupported);
+
+ [DllImport(Libraries.FidoClient, EntryPoint = "fido_uaf_get_response_message")]
+ internal static extern int FidoUafGetResponseMessage(string uafRequestJson, string channelBinding, FidoUafResponseMessageCallback callback, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.FidoClient, EntryPoint = "fido_uaf_set_server_result")]
+ internal static extern int FidoUafSetServerResult(int responseCode, string uafResponseJson);
+
+ [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+ internal delegate void FidoUafResponseMessageCallback(int /* fido_error_e */ tizenErrorCode, string uafResponseJson, IntPtr /* void */ userData);
+ }
+}
diff --git a/src/Tizen.Account.FidoClient/Tizen.Account.FidoClient.csproj b/src/Tizen.Account.FidoClient/Tizen.Account.FidoClient.csproj
new file mode 100644
index 0000000..3af885e
--- /dev/null
+++ b/src/Tizen.Account.FidoClient/Tizen.Account.FidoClient.csproj
@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="../Tizen/Tizen.csproj" />
+ <ProjectReference Include="../Tizen.Log/Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project> \ No newline at end of file
diff --git a/src/Tizen.Account.FidoClient/Tizen.Account.FidoClient/AuthenticatorInformation.cs b/src/Tizen.Account.FidoClient/Tizen.Account.FidoClient/AuthenticatorInformation.cs
new file mode 100755
index 0000000..220b131
--- /dev/null
+++ b/src/Tizen.Account.FidoClient/Tizen.Account.FidoClient/AuthenticatorInformation.cs
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Account.FidoClient
+{
+ /// <summary>
+ /// Contains information about the authenticators registered on the device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <example>
+ /// <code>
+ /// IEnumerable<AuthenticatorInformation> authInfos = await UafAuthenticatorFinder.DiscoverAuthenticatorsAsync();
+ /// foreach (AuthenticatorInformation authInfo in authInfos)
+ /// {
+ /// string aaid = authInfo.Aaid;
+ /// string title = authInfo.Title;
+ /// }
+ /// </code>
+ /// </example>
+ public class AuthenticatorInformation
+ {
+ internal AuthenticatorInformation()
+ {
+ }
+
+ /// <summary>
+ /// The authenticator Title
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Title { get; internal set; }
+
+ /// <summary>
+ /// The Authenticator AAID (Authenticator Attestation ID)
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Aaid { get; internal set; }
+
+ /// <summary>
+ /// The Authenticator description
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Description { get; internal set; }
+
+ /// <summary>
+ /// The Authenticator assertion scheme.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string AssertionScheme { get; internal set; }
+
+ /// <summary>
+ /// The Authenticator algorithm.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public AuthenticationAlgorithm AuthenticationAlgorithm { get; internal set; }
+
+ /// <summary>
+ /// The user verification method of this Authenticator
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public UserVerificationMethod UserVerification { get; internal set; }
+
+ /// <summary>
+ /// The key protection method of this Authenticator.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public KeyProtectionType KeyProtection { get; internal set; }
+
+ /// <summary>
+ /// The matcher protection method of this Authenticator.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public MatcherProtectionType MatcherProtection { get; internal set; }
+
+ /// <summary>
+ /// The attachment hint of this Authenticator.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public AuthenticatorAttachmentHint AttachmentHint { get; internal set; }
+
+ /// <summary>
+ /// Denotes the Authenticator is Second factor only which is supported by U2F standards.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool IsSecondFactorOnly { get; internal set; }
+
+ /// <summary>
+ /// The available attestation types for this Authenticator.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public IEnumerable<AuthenticatorAttestationType> AttestationTypes { get; internal set; }
+
+ /// <summary>
+ /// The Transaction Confirmation display type of this Authenticator.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public TransactionConfirmationDisplayType TcDisplayType { get; internal set; }
+
+ /// <summary>
+ /// The Transaction Confirmation display type of this Authenticator.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string TcDisplayContentType { get; internal set; }
+
+ /// <summary>
+ /// The icon of this Authenticator.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Icon { get; internal set; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Account.FidoClient/Tizen.Account.FidoClient/ErrorFactory.cs b/src/Tizen.Account.FidoClient/Tizen.Account.FidoClient/ErrorFactory.cs
new file mode 100755
index 0000000..ef3191a
--- /dev/null
+++ b/src/Tizen.Account.FidoClient/Tizen.Account.FidoClient/ErrorFactory.cs
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Account.FidoClient
+{
+ internal enum FidoErrorCode
+ {
+ None = ErrorCode.None,
+ OutOfMemory = ErrorCode.OutOfMemory,
+ InvalidParameter = ErrorCode.InvalidParameter,
+ NoData = ErrorCode.NoData,
+ NotSupported = ErrorCode.NotSupported,
+ PermissionDenied = ErrorCode.PermissionDenied,
+ UserActionInProgress = -0x01030000 | 0x01,
+ UserCancelled = -0x01030000 | 0x02,
+ UnsupportedVersion = -0x01030000 | 0x03,
+ NoSuitableAuthenticator = -0x01030000 | 0x04,
+ ProtocolError = -0x01030000 | 0x05,
+ UntrustedFacetId = -0x01030000 | 0x06,
+ Unknown = ErrorCode.Unknown
+ }
+
+ internal class ErrorFactory
+ {
+ internal static string LogTag = "Tizen.Account.FidoClient";
+
+ internal static Exception GetException(int error)
+ {
+ if ((FidoErrorCode)error == FidoErrorCode.OutOfMemory)
+ {
+ return new OutOfMemoryException("Out of memory");
+ }
+ else if ((FidoErrorCode)error == FidoErrorCode.InvalidParameter)
+ {
+ return new ArgumentException("Invalid parameter");
+ }
+ else if ((FidoErrorCode)error == FidoErrorCode.UserActionInProgress)
+ {
+ return new InvalidOperationException("User action already in progress");
+ }
+ else if ((FidoErrorCode)error == FidoErrorCode.NotSupported)
+ {
+ return new NotSupportedException("FIDO is unsupported.");
+ }
+ else if ((FidoErrorCode)error == FidoErrorCode.PermissionDenied)
+ {
+ return new UnauthorizedAccessException("Permission denied");
+ }
+ else if ((FidoErrorCode)error == FidoErrorCode.UnsupportedVersion)
+ {
+ return new NotSupportedException("UAF message's version is not supported.");
+ }
+ else if ((FidoErrorCode)error == FidoErrorCode.NoSuitableAuthenticator)
+ {
+ return new Exception("Suitable authenticator can't be found");
+ }
+ else if ((FidoErrorCode)error == FidoErrorCode.ProtocolError)
+ {
+ return new ArgumentException("Protocol error, the interaction may have timed out, or the UAF message is malformed.");
+ }
+ else if ((FidoErrorCode)error == FidoErrorCode.UserCancelled)
+ {
+ return new Exception("User has canceled the operation.");
+ }
+ else if ((FidoErrorCode)error == FidoErrorCode.UntrustedFacetId)
+ {
+ return new Exception(" The caller's id is not allowed to use this operation.");
+ }
+ else
+ {
+ return new Exception("Unknown error");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Account.FidoClient/Tizen.Account.FidoClient/UafAuthenticatorFinder.cs b/src/Tizen.Account.FidoClient/Tizen.Account.FidoClient/UafAuthenticatorFinder.cs
new file mode 100755
index 0000000..537408c
--- /dev/null
+++ b/src/Tizen.Account.FidoClient/Tizen.Account.FidoClient/UafAuthenticatorFinder.cs
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Account.FidoClient
+{
+ /// <summary>
+ /// Class to find available FIDO specific authenticators on the device
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static class UafAuthenticatorFinder
+ {
+ /// <summary>
+ /// Retrieves all the available FIDO authenticators supported by this Device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>Enumerable list of authenticators</returns>
+ /// <privilege>http://tizen.org/privilege/fido.client</privilege>
+ /// <exception cref="UnauthorizedAccessException">Thrown when the application does not have privilege to access this method</exception>
+ /// <example>
+ /// <code>
+ /// IEnumerable<AuthenticatorInformation> authInfos = await UafAuthenticatorFinder.DiscoverAuthenticatorsAsync();
+ /// foreach (AuthenticatorInformation authInfo in authInfos)
+ /// {
+ /// string aaid = authInfo.Aaid;
+ /// string title = authInfo.Title;
+ /// }
+ /// </code>
+ /// </example>
+ public static async Task<IEnumerable<AuthenticatorInformation>> DiscoverAuthenticatorsAsync()
+ {
+ IEnumerable<AuthenticatorInformation> result = null;
+ await Task.Run(() => result = Discover());
+ return result;
+ }
+
+ private static IEnumerable<AuthenticatorInformation> Discover()
+ {
+ IList<AuthenticatorInformation> result = new List<AuthenticatorInformation>();
+
+ Interop.UafAuthenticator.FidoAuthenticatorCallback cb = (IntPtr authHandle, IntPtr userData) =>
+ {
+ Log.Info(ErrorFactory.LogTag, "Iterating authenticators");
+ result.Add(GetAuthInfo(authHandle));
+ };
+
+ int ret = Interop.UafAuthenticator.ForeachAuthenticator(cb, IntPtr.Zero);
+ if(ret != (int)FidoErrorCode.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop API failed with error code: [" + ret + "]");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ return result;
+ }
+
+ private static AuthenticatorInformation GetAuthInfo(IntPtr authHandle)
+ {
+ var authInfo = new AuthenticatorInformation();
+
+ IntPtr stringPtr;
+ int ret = Interop.UafAuthenticator.GetTitle(authHandle, out stringPtr);
+ if (ret != (int)FidoErrorCode.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop API failed with error code: [" + ret + "]");
+ throw ErrorFactory.GetException(ret);
+ }
+ authInfo.Title = Marshal.PtrToStringAnsi(stringPtr);
+ Interop.Libc.Free(stringPtr);
+
+ ret = Interop.UafAuthenticator.GetAaid(authHandle, out stringPtr);
+ if (ret != (int)FidoErrorCode.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop API failed with error code: [" + ret + "]");
+ throw ErrorFactory.GetException(ret);
+ }
+ authInfo.Aaid = Marshal.PtrToStringAnsi(stringPtr);
+ Interop.Libc.Free(stringPtr);
+
+ ret = Interop.UafAuthenticator.GetDescription(authHandle, out stringPtr);
+ if (ret != (int)FidoErrorCode.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop API failed with error code: [" + ret + "]");
+ throw ErrorFactory.GetException(ret);
+ }
+ authInfo.Description = Marshal.PtrToStringAnsi(stringPtr);
+ Interop.Libc.Free(stringPtr);
+
+ ret = Interop.UafAuthenticator.GetAssertionScheme(authHandle, out stringPtr);
+ if (ret != (int)FidoErrorCode.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop API failed with error code: [" + ret + "]");
+ throw ErrorFactory.GetException(ret);
+ }
+ authInfo.AssertionScheme = Marshal.PtrToStringAnsi(stringPtr);
+ Interop.Libc.Free(stringPtr);
+
+ int authAlgo;
+ ret = Interop.UafAuthenticator.GetAlgorithm(authHandle, out authAlgo);
+ if (ret != (int)FidoErrorCode.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop API failed with error code: [" + ret + "]");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ int usrVerificationMethod;
+ ret = Interop.UafAuthenticator.GetVerificationMethod(authHandle, out usrVerificationMethod);
+ if (ret != (int)FidoErrorCode.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop API failed with error code: [" + ret + "]");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ int keyProtectionType;
+ ret = Interop.UafAuthenticator.GetKeyProtectionMethod(authHandle, out keyProtectionType);
+ if (ret != (int)FidoErrorCode.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop API failed with error code: [" + ret + "]");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ int matcherProtection;
+ ret = Interop.UafAuthenticator.GetMatcherProtectionMethod(authHandle, out matcherProtection);
+ if (ret != (int)FidoErrorCode.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop API failed with error code: [" + ret + "]");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ int attachmentHint;
+ ret = Interop.UafAuthenticator.GetAttachmentHint(authHandle, out attachmentHint);
+ if (ret != (int)FidoErrorCode.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop API failed with error code: [" + ret + "]");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ bool isSecondaryOnly = Interop.UafAuthenticator.GetIsSecondFactorOnly(authHandle);
+
+ int tcDisplayType;
+ ret = Interop.UafAuthenticator.GetTcDiscplay(authHandle, out tcDisplayType);
+ if (ret != (int)FidoErrorCode.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop API failed with error code: [" + ret + "]");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ ret = Interop.UafAuthenticator.GetTcDisplayType(authHandle, out stringPtr);
+ if (ret != (int)FidoErrorCode.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop API failed with error code: [" + ret + "]");
+ throw ErrorFactory.GetException(ret);
+ }
+ authInfo.TcDisplayContentType = Marshal.PtrToStringAnsi(stringPtr);
+ Interop.Libc.Free(stringPtr);
+
+ ret = Interop.UafAuthenticator.GetIcon(authHandle, out stringPtr);
+ if (ret != (int)FidoErrorCode.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop API failed with error code: [" + ret + "]");
+ throw ErrorFactory.GetException(ret);
+ }
+ authInfo.Icon = Marshal.PtrToStringAnsi(stringPtr);
+ Interop.Libc.Free(stringPtr);
+
+ var attestationTypes = new List<AuthenticatorAttestationType> ();
+ Interop.UafAuthenticator.FidoAttestationTypeCallback cb = (int type, IntPtr usrData) =>
+ {
+ attestationTypes.Add((AuthenticatorAttestationType)type);
+ };
+
+ ret = Interop.UafAuthenticator.ForeachAttestationType(authHandle, cb, IntPtr.Zero);
+ if (ret != (int)FidoErrorCode.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop API failed with error code: [" + ret + "]");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ authInfo.AuthenticationAlgorithm = (AuthenticationAlgorithm)authAlgo;
+ authInfo.UserVerification = (UserVerificationMethod)usrVerificationMethod;
+ authInfo.KeyProtection = (KeyProtectionType)keyProtectionType;
+ authInfo.MatcherProtection = (MatcherProtectionType)matcherProtection;
+ authInfo.AttachmentHint = (AuthenticatorAttachmentHint)attachmentHint;
+ authInfo.IsSecondFactorOnly = isSecondaryOnly;
+ authInfo.TcDisplayType = (TransactionConfirmationDisplayType)tcDisplayType;
+ authInfo.AttestationTypes = attestationTypes;
+
+ return authInfo;
+ }
+ }
+}
diff --git a/src/Tizen.Account.FidoClient/Tizen.Account.FidoClient/UafClient.cs b/src/Tizen.Account.FidoClient/Tizen.Account.FidoClient/UafClient.cs
new file mode 100755
index 0000000..9493e8c
--- /dev/null
+++ b/src/Tizen.Account.FidoClient/Tizen.Account.FidoClient/UafClient.cs
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Threading.Tasks;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Account.FidoClient
+{
+ /// <summary>
+ /// The FIDO UAF Client APIs
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static class UafClient
+ {
+ private static string _vendorName = null;
+ private static int _majorVersion;
+ private static int _minorVersion;
+
+ static UafClient()
+ {
+ int ret = Interop.UafClient.FidoGetClientVendor(out _vendorName);
+ if (ret != (int)FidoErrorCode.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop API failed with error code: [" + ret + "]");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ ret = Interop.UafClient.FidoGetClientVersion(out _majorVersion, out _minorVersion);
+ if (ret != (int)FidoErrorCode.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop API failed with error code: [" + ret + "]");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+
+ /// <summary>
+ /// The FIDO Client vendor name
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static string VendorName
+ {
+ get
+ {
+ return _vendorName;
+ }
+ }
+
+ /// <summary>
+ /// The FIDO Client Major version
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static int MajorVersion
+ {
+ get
+ {
+ return _majorVersion;
+ }
+ }
+
+ /// <summary>
+ /// The FIDO Client Minor version
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static int MinorVersion
+ {
+ get
+ {
+ return _minorVersion;
+ }
+ }
+
+ /// <summary>
+ /// The FIDO Server response for successfull interaction.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static int StautsOk
+ {
+ get
+ {
+ return 1200;
+ }
+ }
+
+ /// <summary>
+ /// Checks whether the FIDO message can be processed
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="uafMessage">The FIDO UAF message which is received from the relying party server</param>
+ /// <returns>True if the message can be handled by the device, else false</returns>
+ /// <privilege>http://tizen.org/privilege/fido.client</privilege>
+ /// <exception cref="ArgumentException"> In case of invalid parameter</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when the application does not have privilege to access this method</exception>
+ /// <example>
+ /// <code>
+ /// UafMessage uafRequest = new UafMessage()
+ /// {
+ /// Operation = "UafRequestJson"
+ /// };
+ /// bool response = await UafClient.CheckPolicyAsync(uafRequest);
+ /// </code>
+ /// </example>
+ public static async Task<bool> CheckPolicyAsync(UafMessage uafMessage)
+ {
+ if (uafMessage == null)
+ {
+ Log.Error(ErrorFactory.LogTag, "Invalid request or request is null");
+ throw ErrorFactory.GetException((int)FidoErrorCode.InvalidParameter);
+ }
+
+ bool result = false;
+ await Task.Run(() => result = CheckPolicy(uafMessage.Operation));
+ return result;
+ }
+
+ /// <summary>
+ /// Processes the given FIDO UAF message.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="uafMessage">The FIDO UAF message which is received from the relying party server</param>
+ /// <param name="channelBindng">The channel binding data in JSON format which is received from the relying party server</param>
+ /// <returns>FIDO response message</returns>
+ /// <privilege>http://tizen.org/privilege/fido.client</privilege>
+ /// <exception cref="ArgumentException"> In case of invalid parameter</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when the application does not have privilege to access this method</exception>
+ /// <exception cref="NotSupportedException">FIDO is not supported</exception>
+ /// <example>
+ /// <code>
+ /// UafMessage uafRequest = new UafMessage()
+ /// {
+ /// Operation = "UafAuthRequestJson"
+ /// };
+ ///
+ /// var response = await UafClient.ProcessRequestAsync(uafRequest, null);
+ /// </code>
+ /// </example>
+ public static async Task<UafResponse> ProcessRequestAsync(UafMessage uafMessage, string channelBindng)
+ {
+ if (uafMessage == null)
+ {
+ Log.Error(ErrorFactory.LogTag, "Invalid request or request is null");
+ throw ErrorFactory.GetException((int)FidoErrorCode.InvalidParameter);
+ }
+
+ TaskCompletionSource<UafResponse> tcs = new TaskCompletionSource<UafResponse>();
+ Interop.UafClient.FidoUafResponseMessageCallback cb = (int errorCode, string uafResponseJson, IntPtr userData) =>
+ {
+ if (uafMessage == null)
+ {
+ Log.Error(ErrorFactory.LogTag, "Invalid request or request is null");
+ tcs.SetException(ErrorFactory.GetException((int)FidoErrorCode.InvalidParameter));
+ }
+
+ if (errorCode != (int)FidoErrorCode.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop callback failed with error code: [" + errorCode + "]");
+ tcs.SetException(ErrorFactory.GetException(errorCode));
+ }
+
+ tcs.SetResult(new UafResponse() { Response = uafResponseJson });
+ };
+
+ int ret = Interop.UafClient.FidoUafGetResponseMessage(uafMessage.Operation, channelBindng, cb, IntPtr.Zero);
+ if (ret != (int)FidoErrorCode.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop API failed with error code: [" + ret + "]");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ return await tcs.Task;
+ }
+
+ /// <summary>
+ /// Notifies the FIDO client about the server result. FIDO Server sends the result of processing a UAF message to FIDO client.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="responseCode">The status code received from Server.(StautsOk implies success)</param>
+ /// <param name="response">The FIDO response message sent to server in JSON format</param>
+ /// <privilege>http://tizen.org/privilege/fido.client</privilege>
+ /// <remarks>
+ /// This is especially important for cases when a new registration may be considered by the client to be in a pending state until it is communicated that the server accepted it
+ /// </remarks>
+ /// <exception cref="ArgumentException"> In case of invalid parameter</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when the application does not have privilege to access this method</exception>
+ /// <example>
+ /// <code>
+ /// UafResponse response = new UafResponse()
+ /// {
+ /// Response = "Responsejson"
+ /// };
+ ///
+ /// await UafClient.NotifyResultAsync(UafClient.StautsOk, response);
+ /// </code>
+ /// </example>
+ public static async Task NotifyResultAsync(int responseCode, UafResponse response)
+ {
+ if (response == null)
+ {
+ Log.Error(ErrorFactory.LogTag, "Invalid parameter");
+ throw ErrorFactory.GetException((int)FidoErrorCode.InvalidParameter);
+ }
+
+ await Task.Run(() => NotifyResult(responseCode, response.Response));
+ }
+
+ private static bool CheckPolicy(string uafOperation)
+ {
+ bool isSupported;
+ int ret = Interop.UafClient.FidoUafIsSupported(uafOperation, out isSupported);
+ if (ret != (int)FidoErrorCode.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop API failed with error code: [" + ret + "]");
+ throw ErrorFactory.GetException(ret);
+ }
+ return isSupported;
+ }
+
+ private static void NotifyResult(int responseCode, string response)
+ {
+ int ret = Interop.UafClient.FidoUafSetServerResult(responseCode, response);
+ if (ret != (int)FidoErrorCode.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop API failed with error code: [" + ErrorFacts.GetErrorMessage(ret) + "]");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+
+ }
+}
diff --git a/src/Tizen.Account.FidoClient/Tizen.Account.FidoClient/UafEnumerations.cs b/src/Tizen.Account.FidoClient/Tizen.Account.FidoClient/UafEnumerations.cs
new file mode 100755
index 0000000..89367ff
--- /dev/null
+++ b/src/Tizen.Account.FidoClient/Tizen.Account.FidoClient/UafEnumerations.cs
@@ -0,0 +1,312 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Account.FidoClient
+{
+ /// <summary>
+ /// Authenticator's supported algorithm and encoding
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum AuthenticationAlgorithm
+ {
+ /// <summary>
+ /// SECP256R1 ECDSA SHA256 Raw
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Secp256r1EcdsaSha256Raw = 0X01,
+
+ /// <summary>
+ /// SECP256R1 ECDSA SHA256 DER
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Secp256r1EcdsaSha256Der = 0X02,
+
+ /// <summary>
+ /// RSA PSS SHA256 Raw
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ RsassaPssSha256Raw = 0X03,
+
+ /// <summary>
+ /// RSA PSS SHA256 DER
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ RsassaPssSha256Der = 0X04,
+
+ /// <summary>
+ /// SECP256K1 ECDSA SHA256 Raw
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Secp256k1EcdsaSha256Raw = 0X05,
+
+ /// <summary>
+ /// SECP256K1 ECDSA SHA256 DER
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Secp256k1EcdsaSha256Der = 0X06
+ }
+
+ /// <summary>
+ /// Authenticator's supported user verification method type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum UserVerificationMethod
+ {
+ /// <summary>
+ /// User presence verification.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Presence = 0X01,
+
+ /// <summary>
+ /// User fingerprint verification.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Fingerprint = 0X02,
+
+ /// <summary>
+ /// User passcode verification.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Passcode = 0X04,
+
+ /// <summary>
+ /// User voiceprint verification.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Voiceprint = 0X08,
+
+ /// <summary>
+ /// User faceprint verification.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Faceprint = 0X10,
+ /// <summary>
+ /// User location verification.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Location = 0X20,
+
+ /// <summary>
+ /// User eyeprint verification.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Eyeprint = 0X40,
+
+ /// <summary>
+ /// User pattern verification.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Pattern = 0X80,
+
+ /// <summary>
+ /// User handprint verification.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Handprint = 0X100,
+
+ /// <summary>
+ /// Silent verification.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ None = 0X200,
+
+ /// <summary>
+ /// If an authenticator sets multiple flags for user verification types, it may also set this flag to indicate that all verification methods will be enforced (e.g. faceprint AND voiceprint). If flags for multiple user verification methods are set and this flag is not set, verification with only one is necessary (e.g. fingerprint OR passcode).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ All = 0X400
+ }
+
+ /// <summary>
+ /// Authenticator's supported key protection method type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum KeyProtectionType
+ {
+ /// <summary>
+ /// Software based key management.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Software = 0X01,
+
+ /// <summary>
+ /// Hardware based key management.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Hardware = 0X02,
+
+ /// <summary>
+ /// Trusted Execution Environment based key management.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Tee = 0X04,
+
+ /// <summary>
+ /// Secure Element based key management.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ SecureElement = 0X08,
+
+ /// <summary>
+ /// Authenticator does not store (wrapped) UAuth keys at the client, but relies on a server-provided key handle.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ RemoteHandle = 0X10
+ }
+
+ /// <summary>
+ /// Authenticator's supported matcher protection type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum MatcherProtectionType
+ {
+ /// <summary>
+ /// Authenticator's matcher is running in software.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Software = 0X01,
+
+ /// <summary>
+ /// Authenticator's matcher is running inside the Trusted Execution Environment.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Tee = 0X02,
+
+ /// <summary>
+ /// Aauthenticator's matcher is running on the chip.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ OnChip = 0X04
+ }
+
+ /// <summary>
+ /// Authenticator's supproted method to communicate to FIDO user device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum AuthenticatorAttachmentHint
+ {
+ /// <summary>
+ /// Authenticator is permanently attached to the FIDO User Device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Internal = 0X01,
+
+ /// <summary>
+ /// Authenticator is removable or remote from the FIDO User Device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ External = 0X02,
+
+ /// <summary>
+ /// The external authenticator currently has an exclusive wired connection.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Wired = 0X04,
+
+ /// <summary>
+ /// The external authenticator communicates with the FIDO User Device through wireless means.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Wireless = 0X08,
+
+ /// <summary>
+ /// Authenticator is able to communicate by NFC to the FIDO User Device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Nfc = 0X10,
+
+ /// <summary>
+ /// Authenticator is able to communicate by Bluetooth to the FIDO User Device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Bt = 0X20,
+
+ /// <summary>
+ /// Authenticator is connected to the FIDO User Device ver a non-exclusive network (e.g. over a TCP/IP LAN or WAN, as opposed to a PAN or point-to-point connection).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Nw = 0X40,
+
+ /// <summary>
+ /// The external authenticator is in a "ready" state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Ready = 0X80,
+
+ /// <summary>
+ /// The external authenticator is able to communicate using WiFi Direct with the FIDO User Device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ WifiDirect = 0X100
+ }
+
+ /// <summary>
+ /// Authenticator's supported Attestation type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum AuthenticatorAttestationType
+ {
+ /// <summary>
+ /// Full basic attestation.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ BasicFull = 0X3e07,
+
+ /// <summary>
+ /// Surrogate basic attestation.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ BasicSurrogate = 0X3e08,
+ }
+
+ /// <summary>
+ /// Transaction confirmation display capability type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum TransactionConfirmationDisplayType
+ {
+ /// <summary>
+ /// Some form of transaction confirmation display is available on this authenticator.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Any = 0X01,
+
+ /// <summary>
+ /// Software-based transaction confirmation display operating in a privileged context is available on this authenticator.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ PrivilegedSoftware = 0X02,
+
+ /// <summary>
+ /// Transaction confirmation display is in a Trusted Execution Environment.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Tee = 0X04,
+
+ /// <summary>
+ /// Transaction confirmation display based on hardware assisted capabilities is available on this authenticator.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Hw = 0X08,
+
+ /// <summary>
+ /// Transaction confirmation display is provided on a distinct device from the FIDO User Device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Remote = 0X10
+ }
+}
diff --git a/src/Tizen.Account.FidoClient/Tizen.Account.FidoClient/UafMessage.cs b/src/Tizen.Account.FidoClient/Tizen.Account.FidoClient/UafMessage.cs
new file mode 100755
index 0000000..92fe2fe
--- /dev/null
+++ b/src/Tizen.Account.FidoClient/Tizen.Account.FidoClient/UafMessage.cs
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Account.FidoClient
+{
+ /// <summary>
+ /// The FIDO message received from the relying party server
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class UafMessage
+ {
+ /// <summary>
+ /// The constructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public UafMessage()
+ {
+ }
+
+ /// <summary>
+ /// The FIDO message in JSON format which is received from the relying party server
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Operation { get; set; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Account.FidoClient/Tizen.Account.FidoClient/UafResponse.cs b/src/Tizen.Account.FidoClient/Tizen.Account.FidoClient/UafResponse.cs
new file mode 100755
index 0000000..bc63076
--- /dev/null
+++ b/src/Tizen.Account.FidoClient/Tizen.Account.FidoClient/UafResponse.cs
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Account.FidoClient
+{
+ /// <summary>
+ /// Represents FIDO response message
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class UafResponse
+ {
+ /// <summary>
+ /// The constructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public UafResponse()
+ {
+ }
+
+ /// <summary>
+ /// FIDO response message in JSON format
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Response { set; get; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Account.OAuth2/Interop/Interop.Common.cs b/src/Tizen.Account.OAuth2/Interop/Interop.Common.cs
new file mode 100644
index 0000000..b16906f
--- /dev/null
+++ b/src/Tizen.Account.OAuth2/Interop/Interop.Common.cs
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+/// <summary>
+/// Contains Interop declarations of OAuth2 classes.
+/// </summary>
+internal static partial class Interop
+{
+ /// <summary>
+ /// Safehandle wrapper for OAuth2 native handles.
+ /// </summary>
+ internal abstract class SafeOauth2Handle : SafeHandle
+ {
+ public SafeOauth2Handle() : base(IntPtr.Zero, true)
+ {
+ }
+
+ public SafeOauth2Handle(IntPtr handle) : base(handle, true)
+ {
+ }
+
+ public override bool IsInvalid
+ {
+ get
+ {
+ return handle == IntPtr.Zero;
+ }
+ }
+
+ public abstract void Destroy();
+
+ protected override bool ReleaseHandle()
+ {
+ Destroy();
+ SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+}
diff --git a/src/Tizen.Account.OAuth2/Interop/Interop.Error.cs b/src/Tizen.Account.OAuth2/Interop/Interop.Error.cs
new file mode 100644
index 0000000..de77168
--- /dev/null
+++ b/src/Tizen.Account.OAuth2/Interop/Interop.Error.cs
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+/// <summary>
+/// Contains Interop declarations of OAuth2 classes.
+/// </summary>
+internal static partial class Interop
+{
+ /// <summary>
+ /// Wrapper class for OAuth2 native API.
+ /// </summary>
+ internal static partial class Error
+ {
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_error_get_code")]
+ internal static extern int GetCode(IntPtr /* oauth2_error_h */ handle, out int serverErrorCode, out int platformErrorCode);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_error_get_description")]
+ internal static extern int GetDescription(IntPtr /* oauth2_error_h */ handle, out string description);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_error_get_uri")]
+ internal static extern int GetUri(IntPtr /* oauth2_error_h */ handle, out string uri);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_error_get_custom_data")]
+ internal static extern int GetCustomData(IntPtr /* oauth2_error_h */ handle, string customKey, out string customValue);
+
+
+ }
+}
diff --git a/src/Tizen.Account.OAuth2/Interop/Interop.Libraries.cs b/src/Tizen.Account.OAuth2/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..b446467
--- /dev/null
+++ b/src/Tizen.Account.OAuth2/Interop/Interop.Libraries.cs
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ /// <summary>
+ /// Wrapper class for maintaining names of dependent native libraries.
+ /// </summary>
+ internal static partial class Libraries
+ {
+ public const string OAuth2 = "liboauth2.so.0";
+ public const string Glib = "libglib-2.0.so.0";
+ public const string Libc = "libc.so.6";
+ }
+}
diff --git a/src/Tizen.Account.OAuth2/Interop/Interop.Manager.cs b/src/Tizen.Account.OAuth2/Interop/Interop.Manager.cs
new file mode 100755
index 0000000..3970b6b
--- /dev/null
+++ b/src/Tizen.Account.OAuth2/Interop/Interop.Manager.cs
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+/// <summary>
+/// Contains Interop declarations of OAuth2 classes.
+/// </summary>
+internal static partial class Interop
+{
+ /// <summary>
+ /// Wrapper class for OAuth2 native API.
+ /// </summary>
+ internal static partial class Manager
+ {
+ [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+ internal delegate void Oauth2TokenCallback(IntPtr /* oauth2_response_h */ response, IntPtr /* void */ userData);
+
+ [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+ internal delegate void Oauth2AuthGrantCallback(IntPtr /* oauth2_response_h */ response, IntPtr /* void */ userData);
+
+ [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+ internal delegate void Oauth2AccessTokenCallback(IntPtr /* oauth2_response_h */ response, IntPtr /* void */ userData);
+
+ [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+ internal delegate void Oauth2RefreshTokenCallback(IntPtr /* oauth2_response_h */ response, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_manager_create")]
+ internal static extern int Create(out IntPtr /* oauth2_manager_h */ handle);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_manager_destroy")]
+ internal static extern int Destroy(IntPtr /* oauth2_manager_h */ handle);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_manager_request_token")]
+ internal static extern int RequestToken(IntPtr /* oauth2_manager_h */ handle, IntPtr /* oauth2_request_h */ request, Oauth2TokenCallback callback, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_manager_request_authorization_grant")]
+ internal static extern int RequestAuthorizationGrant(IntPtr /* oauth2_manager_h */ handle, IntPtr /* oauth2_request_h */ request, Oauth2AuthGrantCallback callback, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_manager_request_access_token")]
+ internal static extern int RequestAccessToken(IntPtr /* oauth2_manager_h */ handle, IntPtr /* oauth2_request_h */ request, Oauth2AccessTokenCallback callback, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_manager_refresh_access_token")]
+ internal static extern int RefreshAccessToken(IntPtr /* oauth2_manager_h */ handle, IntPtr /* oauth2_request_h */ request, Oauth2RefreshTokenCallback callback, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_manager_is_request_in_progress")]
+ [return: MarshalAs(UnmanagedType.I1)]
+ internal static extern bool IsRequestInProgress(IntPtr /* oauth2_manager_h */ handle);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_manager_clear_cookies")]
+ internal static extern int ClearCookies(IntPtr /* oauth2_manager_h */ handle);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_manager_clear_cache")]
+ internal static extern int ClearCache(IntPtr /* oauth2_manager_h */ handle);
+ }
+}
diff --git a/src/Tizen.Account.OAuth2/Interop/Interop.Request.cs b/src/Tizen.Account.OAuth2/Interop/Interop.Request.cs
new file mode 100644
index 0000000..c76dba0
--- /dev/null
+++ b/src/Tizen.Account.OAuth2/Interop/Interop.Request.cs
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+/// <summary>
+/// Contains Interop declarations of OAuth2 classes.
+/// </summary>
+internal static partial class Interop
+{
+ /// <summary>
+ /// Wrapper class for OAuth2 native API.
+ /// </summary>
+ internal static partial class Request
+ {
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_create")]
+ internal static extern int Create(out IntPtr /* oauth2_request_h */ handle);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_destroy")]
+ internal static extern int Destroy(IntPtr /* oauth2_request_h */ handle);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_set_auth_end_point_url")]
+ internal static extern int SetAuthEndPointUrl(IntPtr /* oauth2_request_h */ handle, string url);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_set_token_end_point_url")]
+ internal static extern int SetTokenEndPointUrl(IntPtr /* oauth2_request_h */ handle, string url);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_set_redirection_url")]
+ internal static extern int SetRedirectionUrl(IntPtr /* oauth2_request_h */ handle, string url);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_set_refresh_token_url")]
+ internal static extern int SetRefreshTokenUrl(IntPtr /* oauth2_request_h */ handle, string url);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_set_refresh_token")]
+ internal static extern int SetRefreshToken(IntPtr /* oauth2_request_h */ handle, string refreshToken);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_set_response_type")]
+ internal static extern int SetResponseType(IntPtr /* oauth2_request_h */ handle, ResponseType /* oauth2_response_type_e */ responseType);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_set_client_id")]
+ internal static extern int SetClientId(IntPtr /* oauth2_request_h */ handle, string clientId);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_set_client_secret")]
+ internal static extern int SetClientSecret(IntPtr /* oauth2_request_h */ handle, string clientSecret);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_set_client_authentication_type")]
+ internal static extern int SetClientAuthenticationType(IntPtr /* oauth2_request_h */ handle, int /* oauth2_client_authentication_type_e */ clientAuthType);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_set_scope")]
+ internal static extern int SetScope(IntPtr /* oauth2_request_h */ handle, string scope);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_set_state")]
+ internal static extern int SetState(IntPtr /* oauth2_request_h */ handle, string state);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_set_grant_type")]
+ internal static extern int SetGrantType(IntPtr /* oauth2_request_h */ handle, GrantType /* oauth2_grant_type_e */ grantType);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_set_authorization_code")]
+ internal static extern int SetAuthorizationCode(IntPtr /* oauth2_request_h */ handle, string code);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_set_user_name")]
+ internal static extern int SetUserName(IntPtr /* oauth2_request_h */ handle, string userName);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_set_password")]
+ internal static extern int SetPassword(IntPtr /* oauth2_request_h */ handle, string password);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_add_custom_data")]
+ internal static extern int AddCustomData(IntPtr /* oauth2_request_h */ handle, string key, string value);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_get_auth_end_point_url")]
+ internal static extern int GetAuthEndPointUrl(IntPtr /* oauth2_request_h */ handle, out string url);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_get_token_end_point_url")]
+ internal static extern int GetTokenEndPointUrl(IntPtr /* oauth2_request_h */ handle, out string url);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_get_redirection_url")]
+ internal static extern int GetRedirectionUrl(IntPtr /* oauth2_request_h */ handle, out string url);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_get_refresh_token_url")]
+ internal static extern int GetRefreshTokenUrl(IntPtr /* oauth2_request_h */ handle, out string url);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_get_refresh_token")]
+ internal static extern int GetRefreshToken(IntPtr /* oauth2_request_h */ handle, out string refreshToken);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_get_response_type")]
+ internal static extern int GetResponseType(IntPtr /* oauth2_request_h */ handle, out ResponseType /* oauth2_response_type_e */ responseType);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_get_client_id")]
+ internal static extern int GetClientId(IntPtr /* oauth2_request_h */ handle, out string clientId);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_get_client_secret")]
+ internal static extern int GetClientSecret(IntPtr /* oauth2_request_h */ handle, out string clientSecret);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_get_scope")]
+ internal static extern int GetScope(IntPtr /* oauth2_request_h */ handle, out string scope);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_get_state")]
+ internal static extern int GetState(IntPtr /* oauth2_request_h */ handle, out string state);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_get_grant_type")]
+ internal static extern int GetGrantType(IntPtr /* oauth2_request_h */ handle, out GrantType /* oauth2_grant_type_e */ grantType);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_get_authorization_code")]
+ internal static extern int GetAuthorizationCode(IntPtr /* oauth2_request_h */ handle, out string code);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_get_user_name")]
+ internal static extern int GetUserName(IntPtr /* oauth2_request_h */ handle, out string userName);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_get_password")]
+ internal static extern int GetPassword(IntPtr /* oauth2_request_h */ handle, out string password);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_request_get_custom_data")]
+ internal static extern int GetCustomData(IntPtr /* oauth2_request_h */ handle, string customKey, out string customValue);
+ }
+}
diff --git a/src/Tizen.Account.OAuth2/Interop/Interop.Response.cs b/src/Tizen.Account.OAuth2/Interop/Interop.Response.cs
new file mode 100644
index 0000000..6131414
--- /dev/null
+++ b/src/Tizen.Account.OAuth2/Interop/Interop.Response.cs
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+/// <summary>
+/// Contains Interop declarations of OAuth2 classes.
+/// </summary>
+internal static partial class Interop
+{
+ /// <summary>
+ /// Wrapper class for OAuth2 native API.
+ /// </summary>
+ internal static partial class Response
+ {
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_response_destroy")]
+ internal static extern int Destroy(IntPtr /* oauth2_response_h */ handle);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_response_get_authorization_code")]
+ internal static extern int GetAuthorizationCode(IntPtr /* oauth2_response_h */ handle, out IntPtr code);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_response_get_state")]
+ internal static extern int GetState(IntPtr /* oauth2_response_h */ handle, out IntPtr state);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_response_get_access_token")]
+ internal static extern int GetAccessToken(IntPtr /* oauth2_response_h */ handle, out IntPtr accessToken);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_response_get_token_type")]
+ internal static extern int GetTokenType(IntPtr /* oauth2_response_h */ handle, out IntPtr tokenType);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_response_get_expires_in")]
+ internal static extern int GetExpiresIn(IntPtr /* oauth2_response_h */ handle, out long expiresIn);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_response_get_refresh_token")]
+ internal static extern int GetRefreshToken(IntPtr /* oauth2_response_h */ handle, out IntPtr refreshToken);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_response_get_scope")]
+ internal static extern int GetScope(IntPtr /* oauth2_response_h */ handle, out IntPtr scope);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_response_get_error")]
+ internal static extern int GetError(IntPtr /* oauth2_response_h */ handle, out IntPtr /* oauth2_error_h */ error);
+
+ [DllImport(Libraries.OAuth2, EntryPoint = "oauth2_response_get_custom_data")]
+ internal static extern int GetCustomData(IntPtr /* oauth2_response_h */ handle, string customKey, out IntPtr customValue);
+
+
+ }
+}
diff --git a/src/Tizen.Account.OAuth2/Interop/Interop.Types.cs b/src/Tizen.Account.OAuth2/Interop/Interop.Types.cs
new file mode 100644
index 0000000..27bf2cb
--- /dev/null
+++ b/src/Tizen.Account.OAuth2/Interop/Interop.Types.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+/// <summary>
+/// Contains Interop declarations of OAuth2 classes.
+/// </summary>
+internal static partial class Interop
+{
+ internal enum GrantType
+ {
+ AuthCode, // OAUTH2_GRANT_TYPE_AUTH_CODE
+ Password, // OAUTH2_GRANT_TYPE_PASSWORD
+ ClientCredentials, // OAUTH2_GRANT_TYPE_CLIENT_CREDENTIALS
+ Refresh, // OAUTH2_GRANT_TYPE_REFRESH
+ }
+
+ internal enum ResponseType
+ {
+ Code, // OAUTH2_RESPONSE_TYPE_CODE
+ Token, // OAUTH2_RESPONSE_TYPE_TOKEN
+ }
+}
diff --git a/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2.csproj b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2.csproj
new file mode 100644
index 0000000..3af885e
--- /dev/null
+++ b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2.csproj
@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="../Tizen/Tizen.csproj" />
+ <ProjectReference Include="../Tizen.Log/Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project> \ No newline at end of file
diff --git a/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/AccessToken.cs b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/AccessToken.cs
new file mode 100755
index 0000000..4d185a0
--- /dev/null
+++ b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/AccessToken.cs
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System.Collections.Generic;
+
+namespace Tizen.Account.OAuth2
+{
+ /// <summary>
+ /// Class containing access token and related information.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class AccessToken
+ {
+ internal AccessToken()
+ {
+ }
+
+ /// <summary>
+ /// The lifetime in seconds of the access token.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public long ExpiresIn { get; internal set;}
+
+ /// <summary>
+ /// The access token issued by the authorization server.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Token { get; internal set;}
+
+ /// <summary>
+ /// The scope of the access token.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public IEnumerable<string> Scope { get; internal set;}
+
+ /// <summary>
+ /// The type of the access token.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string TokenType { get; internal set;}
+ }
+}
diff --git a/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/AuthenticationScheme.cs b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/AuthenticationScheme.cs
new file mode 100755
index 0000000..6f385e7
--- /dev/null
+++ b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/AuthenticationScheme.cs
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Account.OAuth2
+{
+ /// <summary>
+ /// Enumerations for Client authentication scheme, used to sign client id and client secret accordingly.
+ /// Default is Basic (http://tools.ietf.org/html/rfc2617#section-2)
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>Facebook and Google does not support HTTP Basic Authentication, instead they require client credentials to be sent via request body.</remarks>
+ public enum AuthenticationScheme
+ {
+ /// <summary>
+ /// HTTP Basic Authentication for client authentication
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Basic = 0,
+
+ /// <summary>
+ /// HTTP Basic Authentication for client authentication
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Digest,
+
+ /// <summary>
+ /// Client credentials are sent via request body
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ RequestBody
+ }
+}
diff --git a/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/AuthorizationRequest.cs b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/AuthorizationRequest.cs
new file mode 100755
index 0000000..e6a4a4d
--- /dev/null
+++ b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/AuthorizationRequest.cs
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Account.OAuth2
+{
+ /// <summary>
+ /// The request parameters to be sent to authorization end point.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public abstract class AuthorizationRequest
+ {
+ /// <summary>
+ /// The desired response type from the OAuth authorization end point.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public abstract string ResponseType { get; }
+
+ /// <summary>
+ /// Client secret credentials.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ClientCredentials ClientSecrets { get; set; }
+
+ /// <summary>
+ /// The scope of the access.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public IEnumerable<string> Scopes { get; set; }
+
+ /// <summary>
+ /// The authorization end point URL.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public Uri AuthorizationEndpoint { get; set; }
+
+ /// <summary>
+ /// The redirection endpoint of the auhorization flow.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public Uri RedirectionEndPoint { get; set; }
+
+ /// <summary>
+ /// The access token end point URL.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public Uri TokenEndpoint { get; set; }
+
+ /// <summary>
+ /// The client's state which is maintained between request and response.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string State { get; set; }
+
+ /// <summary>
+ /// Custom key-value parameters to be sent to the server
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public IEnumerable<KeyValuePair<string, string>> CustomData { get; set; }
+ }
+}
diff --git a/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/AuthorizationResponse.cs b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/AuthorizationResponse.cs
new file mode 100755
index 0000000..c12422a
--- /dev/null
+++ b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/AuthorizationResponse.cs
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Account.OAuth2
+{
+ /// <summary>
+ /// The response containing authroization code from the authorization server.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class AuthorizationResponse : IDisposable
+ {
+ private bool _disposed = false;
+ private IntPtr _responseHandle;
+
+ internal AuthorizationResponse(IntPtr handle)
+ {
+ _responseHandle = handle;
+ }
+
+ /// <summary>
+ /// Destructor of the AuthorizationResponse class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ ~AuthorizationResponse()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// The authroization code.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Code { get; internal set; }
+
+ /// <summary>
+ /// The state parameter present in authorization request.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// The value can be null depending on the server specifications.
+ /// </remarks>
+ public string State { get; internal set; }
+
+ /// <summary>
+ /// Custom key-value parameter received from service provider
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// The return value can be null depending on the server specifications.
+ /// </remarks>
+ public string GetCustomValue(string key)
+ {
+ IntPtr value = IntPtr.Zero;
+ int ret = Interop.Response.GetCustomData(_responseHandle, key, out value);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ return Marshal.PtrToStringAnsi(value);
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects
+ }
+
+ Interop.Response.Destroy(_responseHandle);
+ _disposed = true;
+ }
+ }
+}
diff --git a/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/Authorizer.cs b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/Authorizer.cs
new file mode 100755
index 0000000..bf0496c
--- /dev/null
+++ b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/Authorizer.cs
@@ -0,0 +1,490 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+
+namespace Tizen.Account.OAuth2
+{
+ /// <summary>
+ /// An abstract class to represent various OAuth 2.0 authorization code flows.
+ /// Refer to http://tools.ietf.org/html/rfc6749 about OAuth 2.0 protocols.
+ /// Also service provider document needs to be referred for using end points and additional parameters.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public abstract class Authorizer : IDisposable
+ {
+
+ internal IntPtr _managerHandle;
+ private bool _disposed = false;
+
+ /// <summary>
+ /// Constructor for Authoirzer instances
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public Authorizer()
+ {
+ int ret = Interop.Manager.Create(out _managerHandle);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Destructor of the Authorizer class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ ~Authorizer()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Indicates if the current instance is already handling an authorization request
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool IsRequestInProgress
+ {
+ get
+ {
+ return Interop.Manager.IsRequestInProgress(_managerHandle);
+ }
+ }
+
+ /// <summary>
+ /// Authorizes the client with access toekn / authorizaion code in Implicit and Authorization Code grant flows respectively.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <see cref="CodeGrantAuthorizer.AuthorizeAsync(AuthorizationRequest)"/>
+ /// <see cref="ImplicitGrantAuthorizer.AuthorizeAsync(AuthorizationRequest)"/>
+ /// <param name="request">An authorization request</param>
+ /// <returns> The authorization response from server</returns>
+ public virtual Task<AuthorizationResponse> AuthorizeAsync(AuthorizationRequest request)
+ {
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Gets the access token in OAuth2 supported grant flows except Implicit Grant flow.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <see cref="CodeGrantAuthorizer.AuthorizeAsync(AuthorizationRequest)"/>
+ /// <see cref="ImplicitGrantAuthorizer.AuthorizeAsync(AuthorizationRequest)"/>
+ /// <param name="request">A token request</param>
+ /// <returns>The response from server</returns>
+ public virtual Task<TokenResponse> GetAccessTokenAsync(TokenRequest request)
+ {
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Retrieves access token using a refresh token.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="request">Request containing refresh token</param>
+ /// <returns>The response containing access token.</returns>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ /// <exception cref="ArgumentException">Thrown when method failed due to invalid argumets</exception>
+ /// <exception cref="OAuth2Exception">Thrown when method fails due to server error</exception>
+ public virtual async Task<TokenResponse> RefreshAccessTokenAsync(RefreshTokenRequest request)
+ {
+ IntPtr requestHandle = GetRequestHandle(request);
+ return await Task.Run(() => GetRefreshToken(requestHandle));
+ }
+
+ private TokenResponse GetRefreshToken(IntPtr requestHandle)
+ {
+ int ret = (int)OAuth2Error.None;
+ IntPtr error = IntPtr.Zero;
+ TokenResponse response = null;
+ Interop.Manager.Oauth2RefreshTokenCallback accessTokenCb = (IntPtr responseHandle, IntPtr usrData) =>
+ {
+ Interop.Response.GetError(responseHandle, out error);
+ if (error != IntPtr.Zero)
+ {
+ Log.Error(ErrorFactory.LogTag, "Error occured");
+ }
+ else
+ {
+ IntPtr accessToken;
+ ret = Interop.Response.GetAccessToken(responseHandle, out accessToken);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ IntPtr tokenType;
+ ret = Interop.Response.GetTokenType(responseHandle, out tokenType);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Failed to get token type");
+ }
+
+ long expiresIn;
+ ret = Interop.Response.GetExpiresIn(responseHandle, out expiresIn);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Failed to get expires in");
+ }
+
+ IntPtr refreshToken;
+ ret = Interop.Response.GetRefreshToken(responseHandle, out refreshToken);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ IntPtr scope;
+ ret = Interop.Response.GetScope(responseHandle, out scope);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Failed to get scope");
+ }
+
+ IEnumerable<string> scopes = (scope == IntPtr.Zero) ? null : Marshal.PtrToStringAnsi(scope)?.Split(' ');
+
+ var token = new AccessToken();
+ token.Token = (accessToken == IntPtr.Zero) ? null : Marshal.PtrToStringAnsi(accessToken);
+ token.TokenType = (tokenType == IntPtr.Zero) ? null : Marshal.PtrToStringAnsi(tokenType);
+ token.Scope = scopes;
+ token.ExpiresIn = expiresIn;
+
+ response = new TokenResponse(responseHandle);
+ response.AccessToken = token;
+ response.RefreshToken = (refreshToken == IntPtr.Zero) ? null : new RefreshToken() { Token = Marshal.PtrToStringAnsi(refreshToken) };
+ }
+ };
+
+ ret = Interop.Manager.RefreshAccessToken(_managerHandle, requestHandle, accessTokenCb, IntPtr.Zero);
+ Interop.Request.Destroy(requestHandle);
+ if (ret != (int)OAuth2Error.None || error != IntPtr.Zero)
+ {
+ if (error != IntPtr.Zero)
+ {
+ throw ErrorFactory.GetException(error);
+ }
+ else
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+
+ return response;
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects
+ }
+
+ Interop.Manager.Destroy(_managerHandle);
+ _disposed = true;
+ }
+
+ // Fill device request handle for refreshing access token
+ internal IntPtr GetRequestHandle(RefreshTokenRequest request)
+ {
+ IntPtr requestHandle;
+ int ret = Interop.Request.Create(out requestHandle);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ ret = Interop.Request.SetRefreshTokenUrl(requestHandle, request.TokenEndpoint.ToString());
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ ret = Interop.Request.SetGrantType(requestHandle, Interop.GrantType.Refresh);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ ret = Interop.Request.SetRefreshToken(requestHandle, request.RefreshToken);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ if (request.ClientSecrets.Id != null)
+ {
+ ret = Interop.Request.SetClientId(requestHandle, request.ClientSecrets.Id);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+
+ if (request.ClientSecrets.Secret != null)
+ {
+ ret = Interop.Request.SetClientSecret(requestHandle, request.ClientSecrets.Secret);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+
+ if (request.Scopes != null)
+ {
+ string scope = string.Join(" ", request.Scopes);
+ ret = Interop.Request.SetScope(requestHandle, scope);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+
+ ret = Interop.Request.SetClientAuthenticationType(requestHandle, (int)request.AuthenticationScheme);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ return requestHandle;
+ }
+
+ internal TokenResponse GetAccessToken(IntPtr requestHandle)
+ {
+ int ret = (int)OAuth2Error.None;
+ IntPtr error = IntPtr.Zero;
+ TokenResponse response = null;
+ Interop.Manager.Oauth2TokenCallback accessTokenCb = (IntPtr responseHandle, IntPtr usrData) =>
+ {
+ if (responseHandle == IntPtr.Zero)
+ {
+ Log.Error(ErrorFactory.LogTag, "Error occured");
+ throw (new ArgumentNullException());
+ }
+
+ Interop.Response.GetError(responseHandle, out error);
+ if (error != IntPtr.Zero)
+ {
+ Log.Error(ErrorFactory.LogTag, "Server Error occured");
+ }
+ else
+ {
+ IntPtr accessToken = IntPtr.Zero;
+ ret = Interop.Response.GetAccessToken(responseHandle, out accessToken);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Failed to get access token");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ IntPtr tokenType;
+ ret = Interop.Response.GetTokenType(responseHandle, out tokenType);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Debug(ErrorFactory.LogTag, "TokenType can't be found");
+ }
+
+ long expiresIn = -1;
+ ret = Interop.Response.GetExpiresIn(responseHandle, out expiresIn);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Debug(ErrorFactory.LogTag, "ExpiresIn can't be found");
+ }
+
+ IntPtr refreshToken;
+ ret = Interop.Response.GetRefreshToken(responseHandle, out refreshToken);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Debug(ErrorFactory.LogTag, "Refresh Token can't be found");
+ }
+
+ IntPtr scope;
+ ret = Interop.Response.GetScope(responseHandle, out scope);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Debug(ErrorFactory.LogTag, "Scope can't be found");
+ }
+
+ IntPtr state;
+ ret = Interop.Response.GetState(responseHandle, out state);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Debug(ErrorFactory.LogTag, "State can't be found");
+ }
+
+ IEnumerable<string> scopes = (scope == IntPtr.Zero) ? null : Marshal.PtrToStringAnsi(scope)?.Split(' ');
+
+ var token = new AccessToken();
+ token.Token = (accessToken == IntPtr.Zero)? null : Marshal.PtrToStringAnsi(accessToken);
+ token.TokenType = (tokenType == IntPtr.Zero) ? null : Marshal.PtrToStringAnsi(tokenType);
+ token.Scope = scopes;
+ token.ExpiresIn = expiresIn;
+
+ response = new TokenResponse(responseHandle);
+ response.AccessToken = token;
+ response.State = (state == IntPtr.Zero) ? null : Marshal.PtrToStringAnsi(state);
+ response.RefreshToken = (refreshToken == IntPtr.Zero) ? null : new RefreshToken() { Token = Marshal.PtrToStringAnsi(refreshToken) };
+ }
+ };
+
+ ret = Interop.Manager.RequestToken(_managerHandle, requestHandle, accessTokenCb, IntPtr.Zero);
+ Interop.Request.Destroy(requestHandle);
+ if (ret != (int)OAuth2Error.None || error != IntPtr.Zero)
+ {
+ if (error != IntPtr.Zero)
+ {
+ throw ErrorFactory.GetException(error);
+ }
+ else
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+
+ return response;
+ }
+
+ internal TokenResponse GetAccessTokenByCode(IntPtr requestHandle)
+ {
+ int ret = (int)OAuth2Error.None;
+ IntPtr error = IntPtr.Zero;
+ TokenResponse response = null;
+ Interop.Manager.Oauth2AccessTokenCallback accessTokenCb = (IntPtr responseHandle, IntPtr usrData) =>
+ {
+ if (responseHandle == IntPtr.Zero)
+ {
+ Log.Error(ErrorFactory.LogTag, "Error occured");
+ throw (new ArgumentNullException());
+ }
+
+ Interop.Response.GetError(responseHandle, out error);
+ if (error != IntPtr.Zero)
+ {
+ Log.Error(ErrorFactory.LogTag, "Server Error occured");
+ }
+ else
+ {
+ IntPtr accessToken = IntPtr.Zero;
+ ret = Interop.Response.GetAccessToken(responseHandle, out accessToken);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Failed to get access token");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ IntPtr tokenType;
+ ret = Interop.Response.GetTokenType(responseHandle, out tokenType);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Debug(ErrorFactory.LogTag, "TokenType can't be found");
+ }
+
+ long expiresIn = -1;
+ ret = Interop.Response.GetExpiresIn(responseHandle, out expiresIn);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Debug(ErrorFactory.LogTag, "ExpiresIn can't be found");
+ }
+
+ IntPtr refreshToken;
+ ret = Interop.Response.GetRefreshToken(responseHandle, out refreshToken);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Debug(ErrorFactory.LogTag, "Refresh Token can't be found");
+ }
+
+ IntPtr scope;
+ ret = Interop.Response.GetScope(responseHandle, out scope);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Debug(ErrorFactory.LogTag, "Scope can't be found");
+ }
+
+ IntPtr state;
+ ret = Interop.Response.GetState(responseHandle, out state);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Debug(ErrorFactory.LogTag, "State can't be found");
+ }
+
+ IEnumerable<string> scopes = (scope == IntPtr.Zero) ? null : Marshal.PtrToStringAnsi(scope)?.Split(' ');
+
+ var token = new AccessToken();
+ token.Token = (accessToken == IntPtr.Zero) ? null : Marshal.PtrToStringAnsi(accessToken);
+ token.TokenType = (tokenType == IntPtr.Zero) ? null : Marshal.PtrToStringAnsi(tokenType);
+ token.Scope = scopes;
+ token.ExpiresIn = expiresIn;
+
+ response = new TokenResponse(responseHandle);
+ response.AccessToken = token;
+ response.State = (state == IntPtr.Zero) ? null : Marshal.PtrToStringAnsi(state);
+ response.RefreshToken = (refreshToken == IntPtr.Zero) ? null : new RefreshToken() { Token = Marshal.PtrToStringAnsi(refreshToken) };
+ }
+ };
+
+ ret = Interop.Manager.RequestAccessToken(_managerHandle, requestHandle, accessTokenCb, IntPtr.Zero);
+ Interop.Request.Destroy(requestHandle);
+ if (ret != (int)OAuth2Error.None || error != IntPtr.Zero)
+ {
+ if (error != IntPtr.Zero)
+ {
+ throw ErrorFactory.GetException(error);
+ }
+ else
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed : " + ret);
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+
+ return response;
+ }
+ }
+}
+
diff --git a/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/ClientCredentials.cs b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/ClientCredentials.cs
new file mode 100755
index 0000000..3b6f58b
--- /dev/null
+++ b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/ClientCredentials.cs
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Account.OAuth2
+{
+ /// <summary>
+ /// Contains client credentials required for authentication in request-body
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class ClientCredentials
+ {
+ /// <summary>
+ /// The constructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ClientCredentials()
+ {
+
+ }
+
+ /// <summary>
+ /// The client identifier
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Id { get; set; }
+
+ /// <summary>
+ /// The client secret
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Secret { get; set; }
+ }
+}
+
diff --git a/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/ClientCredentialsAuthorizer.cs b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/ClientCredentialsAuthorizer.cs
new file mode 100755
index 0000000..b9d8f1c
--- /dev/null
+++ b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/ClientCredentialsAuthorizer.cs
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Threading.Tasks;
+using System.Collections.Generic;
+
+namespace Tizen.Account.OAuth2
+{
+ /// <summary>
+ /// The ClientCredentialsAuthorizer is used to obtain access tokens using Client Credentials Grant flow as described at https://tools.ietf.org/html/rfc6749#section-4.4
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class ClientCredentialsAuthorizer : Authorizer
+ {
+ /// <summary>
+ /// The constructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ClientCredentialsAuthorizer()
+ {
+
+ }
+
+ /// <summary>
+ /// Authorization not supported through this API for this flow.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is not supported</exception>
+ public override Task<AuthorizationResponse> AuthorizeAsync(AuthorizationRequest request)
+ {
+ Log.Error(ErrorFactory.LogTag, "Authorization is not supported in this flow");
+ throw new InvalidOperationException();
+ }
+
+ /// <summary>
+ /// Refreshing access token is not supported in this flow.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is not supported</exception>
+ public override Task<TokenResponse> RefreshAccessTokenAsync(RefreshTokenRequest request)
+ {
+ Log.Error(ErrorFactory.LogTag, "Refreshing access token is not supported in this flow");
+ throw new InvalidOperationException();
+ }
+
+ /// <summary>
+ /// Retrieves access token using client credentials.
+ /// The authroization request parameters should be as defined in https://tools.ietf.org/html/rfc6749#section-4.4.2
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="request">The token request <see cref="ClientCredentialsTokenRequest"/></param>
+ /// <returns>The response containing access token.</returns>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ /// <exception cref="ArgumentException">Thrown when method failed due to invalid argumets</exception>
+ /// <exception cref="OAuth2Exception">Thrown when method fails due to server error</exception>
+ public override async Task<TokenResponse> GetAccessTokenAsync(TokenRequest request)
+ {
+ IntPtr requestHandle = GetRequestHandle(request as ClientCredentialsTokenRequest);
+ return await Task.Run(() => GetAccessToken(requestHandle));
+ }
+
+ // Fill device request handle for access token
+ private IntPtr GetRequestHandle(ClientCredentialsTokenRequest request)
+ {
+ if (request == null)
+ {
+ Log.Error(ErrorFactory.LogTag, "Invalid request or request is null");
+ throw ErrorFactory.GetException((int)OAuth2Error.InvalidParameter);
+ }
+
+ IntPtr requestHandle;
+ int ret = Interop.Request.Create(out requestHandle);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ ret = Interop.Request.SetTokenEndPointUrl(requestHandle, request.TokenEndpoint.ToString());
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ ret = Interop.Request.SetRedirectionUrl(requestHandle, request.RedirectionEndPoint.ToString());
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ ret = Interop.Request.SetGrantType(requestHandle, Interop.GrantType.ClientCredentials);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ if (request.ClientSecrets.Id != null)
+ {
+ ret = Interop.Request.SetClientId(requestHandle, request.ClientSecrets.Id);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+
+ if (request.ClientSecrets.Secret != null)
+ {
+ ret = Interop.Request.SetClientSecret(requestHandle, request.ClientSecrets.Secret);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+
+ if (request.Scopes != null)
+ {
+ string scope = string.Join(" ", request.Scopes);
+ ret = Interop.Request.SetScope(requestHandle, scope);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+
+ if (request.CustomData != null)
+ {
+ foreach (var item in request.CustomData)
+ {
+ ret = Interop.Request.AddCustomData(requestHandle, item.Key, item.Value);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+ }
+
+ ret = Interop.Request.SetClientAuthenticationType(requestHandle, (int) request.AuthenticationScheme);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ return requestHandle;
+ }
+ }
+}
diff --git a/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/ClientCredentialsTokenRequest.cs b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/ClientCredentialsTokenRequest.cs
new file mode 100755
index 0000000..a57225f
--- /dev/null
+++ b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/ClientCredentialsTokenRequest.cs
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Account.OAuth2
+{
+ /// <summary>
+ /// The class contains request parameters for retreiving access token in Client Credentials Grant flow.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class ClientCredentialsTokenRequest : TokenRequest
+ {
+ /// <summary>
+ /// The constructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ClientCredentialsTokenRequest()
+ {
+
+ }
+
+ /// <summary>
+ /// The grant type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public override string GrantType { get; } = "client_credentials";
+ }
+}
diff --git a/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/CodeGrantAuthorizationRequest.cs b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/CodeGrantAuthorizationRequest.cs
new file mode 100755
index 0000000..385a798
--- /dev/null
+++ b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/CodeGrantAuthorizationRequest.cs
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Account.OAuth2
+{
+ /// <summary>
+ /// The class contains request parameters for retreiving authorization code in Authorization Code Grant flow.
+ /// Please refer https://tools.ietf.org/html/rfc6749#section-4.1.1 for more details
+ /// </summary>
+ public class CodeGrantAuthorizationRequest : AuthorizationRequest
+ {
+ /// <summary>
+ /// The constructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public CodeGrantAuthorizationRequest()
+ {
+
+ }
+
+ /// <summary>
+ /// The response type parameter to authorization server.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public override string ResponseType { get; } = "code";
+ }
+}
diff --git a/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/CodeGrantAuthorizer.cs b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/CodeGrantAuthorizer.cs
new file mode 100755
index 0000000..bb7f1b5
--- /dev/null
+++ b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/CodeGrantAuthorizer.cs
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Threading.Tasks;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+
+namespace Tizen.Account.OAuth2
+{
+ /// <summary>
+ /// The CodeGrantAuthorizer is used to obtain access tokens and refresh tokens using Authorization Code Grant flow as described at https://tools.ietf.org/html/rfc6749#section-4.1
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class CodeGrantAuthorizer : Authorizer
+ {
+ /// <summary>
+ /// The constructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public CodeGrantAuthorizer()
+ {
+
+ }
+
+ /// <summary>
+ /// Retrieves authorization code asynchronously. The authroization request parameters should be as defined in https://tools.ietf.org/html/rfc6749#section-4.1.1
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="request">The authorization request <see cref="CodeGrantAuthorizationRequest"/></param>
+ /// <returns>The response containing authorization code.</returns>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ /// <exception cref="ArgumentException">Thrown when method failed due to invalid argumets</exception>
+ /// <exception cref="OAuth2Exception">Thrown when method fails due to server error</exception>
+ public override async Task<AuthorizationResponse> AuthorizeAsync(AuthorizationRequest request)
+ {
+ IntPtr requestHandle = GetRequestHandle(request as CodeGrantAuthorizationRequest);
+ return await Task.Run(() => GetAuthorizationResponse(requestHandle));
+ }
+
+ /// <summary>
+ /// Retrieves access token by exchanging authorization code received using <see cref="AuthorizeAsync(AuthorizationRequest)"/>.
+ /// The authroization request parameters should be as defined in https://tools.ietf.org/html/rfc6749#section-4.1.3
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="request">The token request <see cref="CodeGrantTokenRequest"/></param>
+ /// <returns>The response containing access token.</returns>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ /// <exception cref="ArgumentException">Thrown when method failed due to invalid argumets</exception>
+ /// <exception cref="OAuth2Exception">Thrown when method fails due to server error</exception>
+ public override async Task<TokenResponse> GetAccessTokenAsync(TokenRequest request)
+ {
+ IntPtr requestHandle = GetRequestHandle(request as CodeGrantTokenRequest);
+ return await Task.Run(() => GetAccessTokenByCode(requestHandle) );
+ }
+
+ /// <summary>
+ /// Clears the cookies
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public void ClearCookies()
+ {
+ int ret = (int)OAuth2Error.None;
+ ret = Interop.Manager.ClearCookies(_managerHandle);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Clear the cache
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public void ClearCache()
+ {
+ int ret = (int)OAuth2Error.None;
+ ret = Interop.Manager.ClearCache(_managerHandle);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+
+ // Fill device request handle for Authorization code grant
+ private IntPtr GetRequestHandle(CodeGrantAuthorizationRequest request)
+ {
+ if (request == null)
+ {
+ Log.Error(ErrorFactory.LogTag, "Invalid request or request is null");
+ throw ErrorFactory.GetException((int)OAuth2Error.InvalidParameter);
+ }
+
+ IntPtr requestHandle;
+ int ret = Interop.Request.Create(out requestHandle);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ ret = Interop.Request.SetAuthEndPointUrl(requestHandle, request.AuthorizationEndpoint.ToString());
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ ret = Interop.Request.SetResponseType(requestHandle, Interop.ResponseType.Code);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ if (request.ClientSecrets.Id != null)
+ {
+ ret = Interop.Request.SetClientId(requestHandle, request.ClientSecrets.Id);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+
+ if (request.ClientSecrets.Secret != null)
+ {
+ ret = Interop.Request.SetClientSecret(requestHandle, request.ClientSecrets.Secret);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+
+ if (request.RedirectionEndPoint != null)
+ {
+ ret = Interop.Request.SetRedirectionUrl(requestHandle, request.RedirectionEndPoint.OriginalString);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+
+ if (request.Scopes != null)
+ {
+ string scope = string.Join(" ", request.Scopes);
+ ret = Interop.Request.SetScope(requestHandle, scope);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+
+ if (request.State != null)
+ {
+ ret = Interop.Request.SetState(requestHandle, request.State);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+
+ if (request.CustomData != null)
+ {
+ foreach( var item in request.CustomData)
+ {
+ ret = Interop.Request.AddCustomData(requestHandle, item.Key, item.Value);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+ }
+
+ return requestHandle;
+ }
+
+ // Fill device request handle for access token
+ private IntPtr GetRequestHandle(CodeGrantTokenRequest request)
+ {
+ if (request == null)
+ {
+ Log.Error(ErrorFactory.LogTag, "Invalid request or request is null");
+ throw ErrorFactory.GetException((int)OAuth2Error.InvalidParameter);
+ }
+
+ IntPtr requestHandle;
+ int ret = Interop.Request.Create(out requestHandle);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ ret = Interop.Request.SetGrantType(requestHandle, Interop.GrantType.AuthCode);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ ret = Interop.Request.SetAuthorizationCode(requestHandle, request.Code);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ ret = Interop.Request.SetTokenEndPointUrl(requestHandle, request.TokenEndpoint.ToString());
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ ret = Interop.Request.SetRedirectionUrl(requestHandle, request.RedirectionEndPoint.ToString());
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ ret = Interop.Request.SetClientId(requestHandle, request.ClientSecrets.Id);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ if (request.ClientSecrets.Secret != null)
+ {
+ ret = Interop.Request.SetClientSecret(requestHandle, request.ClientSecrets.Secret);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+
+ if (request.CustomData != null)
+ {
+ foreach (var item in request.CustomData)
+ {
+ ret = Interop.Request.AddCustomData(requestHandle, item.Key, item.Value);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+ }
+
+ ret = Interop.Request.SetClientAuthenticationType(requestHandle, (int)request.AuthenticationScheme);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ return requestHandle;
+ }
+
+ private AuthorizationResponse GetAuthorizationResponse(IntPtr requestHandle)
+ {
+ AuthorizationResponse response = null;
+ int ret = (int)OAuth2Error.None;
+ IntPtr error = IntPtr.Zero;
+
+ Interop.Manager.Oauth2AuthGrantCallback authGrantCb = (IntPtr responseHandle, IntPtr usrData) =>
+ {
+ if (responseHandle == IntPtr.Zero)
+ {
+ Log.Error(ErrorFactory.LogTag, "Error occured");
+ throw (new ArgumentNullException());
+ }
+
+ Interop.Response.GetError(responseHandle, out error);
+ if (error == IntPtr.Zero)
+ {
+ Log.Warn(ErrorFactory.LogTag, "Error occured");
+ throw ErrorFactory.GetException(error);
+ }
+ else
+ {
+ IntPtr authorizationCode;
+ ret = Interop.Response.GetAuthorizationCode(responseHandle, out authorizationCode);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ IntPtr state;
+ ret = Interop.Response.GetState(responseHandle, out state);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ response = new AuthorizationResponse(responseHandle) { Code = Marshal.PtrToStringAnsi(authorizationCode), State = Marshal.PtrToStringAnsi(state) };
+ }
+ };
+
+ ret = Interop.Manager.RequestAuthorizationGrant(_managerHandle, requestHandle, authGrantCb, IntPtr.Zero);
+ Interop.Request.Destroy(requestHandle);
+ if (ret != (int)OAuth2Error.None || error != IntPtr.Zero)
+ {
+ if (error != IntPtr.Zero)
+ {
+ throw ErrorFactory.GetException(error);
+ }
+ else
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+
+ return response;
+ }
+ }
+}
diff --git a/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/CodeGrantTokenRequest.cs b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/CodeGrantTokenRequest.cs
new file mode 100755
index 0000000..38d21f9
--- /dev/null
+++ b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/CodeGrantTokenRequest.cs
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Account.OAuth2
+{
+ /// <summary>
+ /// The class contains request parameters for retreiving access token in Authorization Code Grant flow.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class CodeGrantTokenRequest : TokenRequest
+ {
+ /// <summary>
+ /// The constructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public CodeGrantTokenRequest()
+ {
+
+ }
+
+ /// <summary>
+ /// The grant type
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public override string GrantType { get; } = "authorization_code";
+
+ /// <summary>
+ /// The authoriztion code received from the authorization server.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Code { get; set; }
+ }
+}
diff --git a/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/ImplicitGrantAuthorizationRequest.cs b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/ImplicitGrantAuthorizationRequest.cs
new file mode 100755
index 0000000..5b0c50a
--- /dev/null
+++ b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/ImplicitGrantAuthorizationRequest.cs
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Account.OAuth2
+{
+ /// <summary>
+ /// The class contains request parameters for retreiving access token in Implicit Grant flow.
+ /// </summary>
+ public class ImplicitGrantAuthorizationRequest : AuthorizationRequest
+ {
+ /// <summary>
+ /// The constructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ImplicitGrantAuthorizationRequest()
+ {
+
+ }
+
+ /// <summary>
+ /// The response type parameter to aturhoization server.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public override string ResponseType { get; } = "token";
+ }
+}
diff --git a/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/ImplicitGrantAuthorizer.cs b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/ImplicitGrantAuthorizer.cs
new file mode 100755
index 0000000..c59dbee
--- /dev/null
+++ b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/ImplicitGrantAuthorizer.cs
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+
+namespace Tizen.Account.OAuth2
+{
+ /// <summary>
+ /// The ImplicitGrantAuthorizer is used to obtain access tokens using Implicit Grant flow as described at https://tools.ietf.org/html/rfc6749#section-4.2
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class ImplicitGrantAuthorizer : Authorizer
+ {
+ /// <summary>
+ /// The constructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ImplicitGrantAuthorizer()
+ {
+
+ }
+
+ /// <summary>
+ /// Retrieves access token asynchronously. The authroization request parameters should be as defined in https://tools.ietf.org/html/rfc6749#section-4.2.1
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="request">The authorization request <see cref="ImplicitGrantAuthorizationRequest"/></param>
+ /// <returns>The response containing access token.</returns>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ /// <exception cref="ArgumentException">Thrown when method failed due to invalid argumets</exception>
+ /// <exception cref="OAuth2Exception">Thrown when method fails due to server error</exception>
+ public new virtual async Task<TokenResponse> AuthorizeAsync(AuthorizationRequest request)
+ {
+ IntPtr requestHandle = GetRequestHandle(request as ImplicitGrantAuthorizationRequest);
+ return await Task.Run(() => GetAuthorizationResponse(requestHandle));
+ }
+
+ /// <summary>
+ /// Access token can be retreived implicitly using <see cref="AuthorizeAsync"/> in this flow.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is not supported</exception>
+ public override Task<TokenResponse> GetAccessTokenAsync(TokenRequest request)
+ {
+ Log.Error(ErrorFactory.LogTag, "Obtain token directly from authorization grant ");
+ throw new InvalidOperationException();
+ }
+
+ /// <summary>
+ /// Refreshing access token is not supported in this flow.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is not supported</exception>
+ public override Task<TokenResponse> RefreshAccessTokenAsync(RefreshTokenRequest request)
+ {
+ Log.Error(ErrorFactory.LogTag, "Refesh token is not supported in Implicit Grant flow");
+ throw new InvalidOperationException();
+ }
+
+ private TokenResponse GetAuthorizationResponse(IntPtr requestHandle)
+ {
+ IntPtr error = IntPtr.Zero;
+ TokenResponse response = null;
+ int ret = (int)OAuth2Error.None;
+ Interop.Manager.Oauth2AuthGrantCallback authGrantCb = (IntPtr responseHandle, IntPtr usrData) =>
+ {
+ if (responseHandle == IntPtr.Zero)
+ {
+ Log.Error(ErrorFactory.LogTag, "Error occured");
+ throw (new ArgumentNullException());
+ }
+
+ Interop.Response.GetError(responseHandle, out error);
+ if (error != IntPtr.Zero)
+ {
+ Log.Error(ErrorFactory.LogTag, "Server Error occured");
+ }
+ else
+ {
+ IntPtr accessToken;
+ ret = Interop.Response.GetAccessToken(responseHandle, out accessToken);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ IntPtr tokenType;
+ ret = Interop.Response.GetTokenType(responseHandle, out tokenType);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ long expiresIn;
+ ret = Interop.Response.GetExpiresIn(responseHandle, out expiresIn);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ IntPtr scope;
+ ret = Interop.Response.GetScope(responseHandle, out scope);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ IntPtr state;
+ ret = Interop.Response.GetState(responseHandle, out state);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ IEnumerable<string> scopes = (scope == IntPtr.Zero) ? null : Marshal.PtrToStringAnsi(scope)?.Split(' ');
+
+ var token = new AccessToken() { Token = Marshal.PtrToStringAnsi(accessToken), ExpiresIn = expiresIn, Scope = scopes, TokenType = Marshal.PtrToStringAnsi(tokenType) };
+ response = new TokenResponse(responseHandle) { AccessToken = token, State = Marshal.PtrToStringAnsi(state), RefreshToken = null };
+ }
+ };
+
+ ret = Interop.Manager.RequestAuthorizationGrant(_managerHandle, requestHandle, authGrantCb, IntPtr.Zero);
+ Interop.Request.Destroy(requestHandle);
+ if (ret != (int)OAuth2Error.None || error != IntPtr.Zero)
+ {
+ if (error != IntPtr.Zero)
+ {
+ throw ErrorFactory.GetException(error);
+ }
+ else
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+
+ return response;
+ }
+
+ // Fill device request handle for Authorization code grant
+ private IntPtr GetRequestHandle(ImplicitGrantAuthorizationRequest request)
+ {
+ if (request == null)
+ {
+ Log.Error(ErrorFactory.LogTag, "Invalid request or request is null");
+ throw ErrorFactory.GetException((int)OAuth2Error.InvalidParameter);
+ }
+
+ IntPtr requestHandle;
+ int ret = Interop.Request.Create(out requestHandle);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ ret = Interop.Request.SetAuthEndPointUrl(requestHandle, request.AuthorizationEndpoint.ToString());
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ ret = Interop.Request.SetResponseType(requestHandle, Interop.ResponseType.Token);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ ret = Interop.Request.SetClientId(requestHandle, request.ClientSecrets.Id);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ if (request.RedirectionEndPoint != null)
+ {
+ ret = Interop.Request.SetRedirectionUrl(requestHandle, request.RedirectionEndPoint.ToString());
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+
+ if (request.Scopes != null)
+ {
+ string scope = string.Join(" ", request.Scopes);
+ ret = Interop.Request.SetScope(requestHandle, scope);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+
+ if (request.State != null)
+ {
+ ret = Interop.Request.SetState(requestHandle, request.State);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+
+ if (request.CustomData != null)
+ {
+ foreach (var item in request.CustomData)
+ {
+ ret = Interop.Request.AddCustomData(requestHandle, item.Key, item.Value);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+ }
+
+ return requestHandle;
+ }
+ }
+}
diff --git a/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/OAuth2ErrorFactory.cs b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/OAuth2ErrorFactory.cs
new file mode 100755
index 0000000..08569f6
--- /dev/null
+++ b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/OAuth2ErrorFactory.cs
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Account.OAuth2
+{
+ internal enum OAuth2Error
+ {
+ // Tizen Account Oauth Error
+ // TIZEN_ERROR_ACCOUNT_OAUTH -0x01010000
+
+ None = ErrorCode.None,
+ OutOfMemory = ErrorCode.OutOfMemory,
+ InvalidParameter = ErrorCode.InvalidParameter,
+ AlreadyInProgress = ErrorCode.AlreadyInProgress,
+ NotSupported = ErrorCode.NotSupported,
+ PermissionDenied = ErrorCode.PermissionDenied,
+ ParseFailed = -0x01010000 | 0X01,
+ NetworkError = -0x01010000 | 0X02,
+ Server = -0x01010000 | 0X03,
+ UserCancelled = -0x01010000 | 0X04,
+ ValueNotFound = -0x01010000 | 0X05,
+ Unknown = ErrorCode.Unknown
+ }
+
+ internal class ErrorFactory
+ {
+ internal static string LogTag = "Tizen.Account.OAuth2";
+
+ internal static Exception GetException(IntPtr error)
+ {
+ int serverErrorCode, platformErrorCode;
+ int ret = Interop.Error.GetCode(error, out serverErrorCode, out platformErrorCode);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Debug(ErrorFactory.LogTag, "error code can't be found");
+ }
+
+ string errorDescription;
+ ret = Interop.Error.GetDescription(error, out errorDescription);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Debug(ErrorFactory.LogTag, "error description can't be found");
+ }
+
+ string uri;
+ Interop.Error.GetUri(error, out uri);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Debug(ErrorFactory.LogTag, "error uri can't be found");
+ }
+
+ var errorResponse = new OAuth2ErrorResponse()
+ {
+ PlatformErrorCode = platformErrorCode,
+ ServerErrorCode = serverErrorCode,
+ ErrorUri = uri,
+ Error = errorDescription
+ };
+
+ return new OAuth2Exception() { Error = errorResponse };
+ }
+
+ internal static Exception GetException(int error)
+ {
+ if ((OAuth2Error)error == OAuth2Error.OutOfMemory)
+ {
+ return new OutOfMemoryException("Out of memory");
+ }
+ else if ((OAuth2Error)error == OAuth2Error.InvalidParameter)
+ {
+ return new ArgumentException("Invalid parameter");
+ }
+ else if ((OAuth2Error)error == OAuth2Error.AlreadyInProgress)
+ {
+ return new InvalidOperationException("Request already in progress");
+ }
+ else if ((OAuth2Error)error == OAuth2Error.NotSupported)
+ {
+ return new NotSupportedException("Not supported");
+ }
+ else if ((OAuth2Error)error == OAuth2Error.PermissionDenied)
+ {
+ return new UnauthorizedAccessException("Permission denied");
+ }
+ else if ((OAuth2Error)error == OAuth2Error.ParseFailed)
+ {
+ return new FormatException("Parsing failed");
+ }
+ else if ((OAuth2Error)error == OAuth2Error.NetworkError)
+ {
+ return new Exception("Networking error occured");
+ }
+ else if ((OAuth2Error)error == OAuth2Error.Server)
+ {
+ return new Exception("Server error");
+ }
+ else if ((OAuth2Error)error == OAuth2Error.UserCancelled)
+ {
+ return new Exception("User cancelled");
+ }
+ else if ((OAuth2Error)error == OAuth2Error.ValueNotFound)
+ {
+ return new ArgumentException("Value not found");
+ }
+ else
+ {
+ return new Exception("Unknown error");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/OAuth2ErrorResponse.cs b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/OAuth2ErrorResponse.cs
new file mode 100755
index 0000000..82f1024
--- /dev/null
+++ b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/OAuth2ErrorResponse.cs
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Account.OAuth2
+{
+ /// <summary>
+ /// Exception wrapper for OAuth2 related exception
+ /// </summary>
+ public class OAuth2Exception : Exception
+ {
+ internal OAuth2Exception()
+ {
+ }
+
+ /// <summary>
+ /// The error response.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public OAuth2ErrorResponse Error { get; internal set; }
+ }
+
+ /// <summary>
+ /// Wrapper class contaning OAuth2 related error information
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class OAuth2ErrorResponse
+ {
+ internal OAuth2ErrorResponse ()
+ {
+
+ }
+
+ /// <summary>
+ /// The server error code
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int ServerErrorCode { get; internal set; }
+
+ /// <summary>
+ /// The platform error cocde
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int PlatformErrorCode { get; internal set; }
+
+ /// <summary>
+ /// Error description
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Error { get; internal set; }
+
+ /// <summary>
+ /// URI of the error page.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string ErrorUri { get; internal set; }
+ }
+}
diff --git a/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/RefreshToken.cs b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/RefreshToken.cs
new file mode 100755
index 0000000..5050563
--- /dev/null
+++ b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/RefreshToken.cs
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Account.OAuth2
+{
+ /// <summary>
+ /// The refresh token which can be used to obtain new access token.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class RefreshToken
+ {
+ internal RefreshToken ()
+ {
+
+ }
+
+ /// <summary>
+ /// The refresh token issued to the client.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Token { get; internal set; }
+ }
+}
diff --git a/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/RefreshTokenRequest.cs b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/RefreshTokenRequest.cs
new file mode 100755
index 0000000..0928ab6
--- /dev/null
+++ b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/RefreshTokenRequest.cs
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Account.OAuth2
+{
+ /// <summary>
+ /// The class contains request parameters for refreshing an access token.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class RefreshTokenRequest : TokenRequest
+ {
+ /// <summary>
+ /// The constructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public RefreshTokenRequest()
+ {
+
+ }
+
+ /// <summary>
+ /// The grant type to be used
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public override string GrantType { get; } = "refresh_token";
+
+ /// <summary>
+ /// The refresh token issued by authorization server.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string RefreshToken { get; set; }
+ }
+}
diff --git a/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/ResourceOwnerPwdCredentialsAuthorizer.cs b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/ResourceOwnerPwdCredentialsAuthorizer.cs
new file mode 100755
index 0000000..27ae244
--- /dev/null
+++ b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/ResourceOwnerPwdCredentialsAuthorizer.cs
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+
+namespace Tizen.Account.OAuth2
+{
+ /// <summary>
+ /// The ResourceOwnerPwdCredentialsAuthorizer is used to obtain access tokens using Resource Owner Password Credentials Grant flow as described at https://tools.ietf.org/html/rfc6749#section-4.3
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class ResourceOwnerPwdCredentialsAuthorizer : Authorizer
+ {
+ /// <summary>
+ /// The constructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ResourceOwnerPwdCredentialsAuthorizer()
+ {
+
+ }
+
+ /// <summary>
+ /// Authorization not supported through this API for this flow.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is not supported</exception>
+ public override Task<AuthorizationResponse> AuthorizeAsync(AuthorizationRequest request)
+ {
+ Log.Error(ErrorFactory.LogTag, "Authorization is not supported in this flow");
+ throw new InvalidOperationException();
+ }
+
+ /// <summary>
+ /// Retrieves access token by sending resource owner's password credentials.
+ /// The authroization request parameters should be as defined in https://tools.ietf.org/html/rfc6749#section-4.3.2
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="request">The token request <see cref="ResourceOwnerPwdCredentialsTokenRequest"/></param>
+ /// <returns>The response containing access token.</returns>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ /// <exception cref="ArgumentException">Thrown when method failed due to invalid argumets</exception>
+ /// <exception cref="OAuth2Exception">Thrown when method fails due to server error</exception>
+ public override async Task<TokenResponse> GetAccessTokenAsync(TokenRequest request)
+ {
+ IntPtr requestHandle = GetRequestHandle(request as ResourceOwnerPwdCredentialsTokenRequest);
+ return await Task.Run(() => GetAccessToken(requestHandle));
+ }
+
+ // Fill device request handle for access token
+ private IntPtr GetRequestHandle(ResourceOwnerPwdCredentialsTokenRequest request)
+ {
+ if (request == null)
+ {
+ Log.Error(ErrorFactory.LogTag, "Invalid request or request is null");
+ throw ErrorFactory.GetException((int)OAuth2Error.InvalidParameter);
+ }
+
+ IntPtr requestHandle;
+ int ret = Interop.Request.Create(out requestHandle);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ ret = Interop.Request.SetTokenEndPointUrl(requestHandle, request.TokenEndpoint.ToString());
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ ret = Interop.Request.SetRedirectionUrl(requestHandle, request.RedirectionEndPoint.ToString());
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ ret = Interop.Request.SetGrantType(requestHandle, Interop.GrantType.Password);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ ret = Interop.Request.SetUserName(requestHandle, request.Username);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ ret = Interop.Request.SetPassword(requestHandle, request.Password);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ if (request.ClientSecrets.Id != null)
+ {
+ ret = Interop.Request.SetClientId(requestHandle, request.ClientSecrets.Id);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+
+ if (request.ClientSecrets.Secret != null)
+ {
+ ret = Interop.Request.SetClientSecret(requestHandle, request.ClientSecrets.Secret);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+
+ if (request.Scopes != null)
+ {
+ string scope = string.Join(" ", request.Scopes);
+ ret = Interop.Request.SetScope(requestHandle, scope);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+
+ if (request.CustomData != null)
+ {
+ foreach (var item in request.CustomData)
+ {
+ ret = Interop.Request.AddCustomData(requestHandle, item.Key, item.Value);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+ }
+
+ if (request.State != null)
+ {
+ ret = Interop.Request.SetState(requestHandle, request.State);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ }
+
+ ret = Interop.Request.SetClientAuthenticationType(requestHandle, (int)request.AuthenticationScheme);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+
+ return requestHandle;
+ }
+ }
+}
diff --git a/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/ResourceOwnerPwdCredentialsTokenRequest.cs b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/ResourceOwnerPwdCredentialsTokenRequest.cs
new file mode 100755
index 0000000..a0cf7fa
--- /dev/null
+++ b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/ResourceOwnerPwdCredentialsTokenRequest.cs
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Account.OAuth2
+{
+ /// <summary>
+ /// The class contains request parameters for retreiving access token in Resource Owner Password Credentials Grant flow.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class ResourceOwnerPwdCredentialsTokenRequest : TokenRequest
+ {
+ /// <summary>
+ /// The constructor
+ /// </summary>
+ public ResourceOwnerPwdCredentialsTokenRequest()
+ {
+
+ }
+
+ /// <summary>
+ /// The grant type
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public override string GrantType { get; } = "password";
+
+ /// <summary>
+ /// The resource owner username
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Username { get; set; }
+
+ /// <summary>
+ /// The resource owner password
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Password { get; set; }
+ }
+}
diff --git a/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/TokenRequest.cs b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/TokenRequest.cs
new file mode 100755
index 0000000..1575c22
--- /dev/null
+++ b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/TokenRequest.cs
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Account.OAuth2
+{
+ /// <summary>
+ /// Abstract wrapper class containing OAuth 2.0 request parameters for requesting an access token.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public abstract class TokenRequest
+ {
+ /// <summary>
+ /// The Grant type
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public abstract string GrantType { get; }
+
+ /// <summary>
+ /// The client credentials
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ClientCredentials ClientSecrets { get; set; }
+
+ /// <summary>
+ /// The access token end point URL.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public Uri TokenEndpoint { get; set; }
+
+ /// <summary>
+ /// The redirection endpoint of the auhorization flow.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public Uri RedirectionEndPoint { get; set; }
+
+ /// <summary>
+ /// The scope of the access request as described by https://tools.ietf.org/html/rfc6749#section-3.3
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public IEnumerable<string> Scopes { get; set; }
+
+ /// <summary>
+ /// Custom key-value parameters to be sent to the server
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public IEnumerable<KeyValuePair<string, string>> CustomData { get; set; }
+
+ /// <summary>
+ /// Client authentication scheme. Default is Basic
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public AuthenticationScheme AuthenticationScheme { get; set; } = AuthenticationScheme.Basic;
+
+ /// <summary>
+ /// The client's state which is maintained between request and response.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string State { get; set; }
+ }
+}
diff --git a/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/TokenResponse.cs b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/TokenResponse.cs
new file mode 100755
index 0000000..0783268
--- /dev/null
+++ b/src/Tizen.Account.OAuth2/Tizen.Account.OAuth2/TokenResponse.cs
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Account.OAuth2
+{
+ /// <summary>
+ /// The response from authroization server containing access token and an optional refresh token.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class TokenResponse
+ {
+ private bool _disposed = false;
+ private IntPtr _responseHandle;
+
+ internal TokenResponse(IntPtr handle)
+ {
+ _responseHandle = handle;
+ }
+
+ /// <summary>
+ /// Destructor of the AuthorizationResponse class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ ~TokenResponse()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// The access token
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public AccessToken AccessToken { get; internal set; }
+
+ /// <summary>
+ /// The state parameter present in authorization request.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// The value can be null depending on the server specifications.
+ /// </remarks>
+ public string State { get; internal set; }
+
+ /// <summary>
+ /// The refresh token. The value will be null if authorization server doesn't return a refresh token.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// Issuing a refresh token is optional at the discretion of the authorization server.
+ /// </remarks>
+ public RefreshToken RefreshToken { get; internal set; }
+
+ /// <summary>
+ /// Gets the value of the key received from service provider
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>The value of respecitve key </returns>
+ /// <exception cref="System.ArgumentException">Thrown when the key does not exist or when there is an invalid parameter.</exception>
+ public string GetCustomValue(string key)
+ {
+ IntPtr value;
+ int ret = Interop.Response.GetCustomData(_responseHandle, key, out value);
+ if (ret != (int)OAuth2Error.None)
+ {
+ Log.Error(ErrorFactory.LogTag, "Interop failed");
+ throw ErrorFactory.GetException(ret);
+ }
+ return Marshal.PtrToStringAnsi(value);
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects
+ }
+
+ Interop.Response.Destroy(_responseHandle);
+ _disposed = true;
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Alarm/Interop/Interop.Alarm.cs b/src/Tizen.Applications.Alarm/Interop/Interop.Alarm.cs
new file mode 100755
index 0000000..bb4bbf9
--- /dev/null
+++ b/src/Tizen.Applications.Alarm/Interop/Interop.Alarm.cs
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+using Tizen.Internals.Errors;
+using Tizen.Applications;
+using Tizen.Applications.Notifications;
+
+internal static partial class Interop
+{
+ internal static partial class Alarm
+ {
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct DateTime
+ {
+ internal int sec;
+ internal int min;
+ internal int hour;
+ internal int mday; /* day of the month, range 1 to 31*/
+ internal int mon;
+ internal int year;
+ internal int wday; /* day of the week, range 0 to 6*/
+ internal int yday; /* day in the year, range 0 to 365*/
+ internal int isdst; /* daylight saving time*/
+ internal long tm_gmtoff;
+ internal IntPtr tm_zone;
+ };
+
+ [DllImport(Libraries.Alarm, EntryPoint = "alarm_schedule_after_delay")]
+ internal static extern int CreateAlarmAfterDelay(SafeAppControlHandle appControl, int delay, int period, out int alarmId);
+
+ [DllImport(Libraries.Alarm, EntryPoint = "alarm_schedule_once_after_delay")]
+ internal static extern int CreateAlarmOnceAfterDelay(SafeAppControlHandle appControl, int delay, out int alarmId);
+
+ [DllImport(Libraries.Alarm, EntryPoint = "alarm_schedule_once_at_date")]
+ internal static extern int CreateAlarmOnceAtDate(SafeAppControlHandle appControl, ref DateTime date, out int alarmId);
+
+ [DllImport(Libraries.Alarm, EntryPoint = "alarm_schedule_with_recurrence_week_flag")]
+ internal static extern int CreateAlarmRecurWeek(SafeAppControlHandle appControl, ref DateTime date, int week, out int alarmId);
+
+ [DllImport(Libraries.Alarm, EntryPoint = "alarm_get_scheduled_recurrence_week_flag")]
+ internal static extern int GetAlarmWeekFlag(int alarmId, out int weekFlag);
+
+ [DllImport(Libraries.Alarm, EntryPoint = "alarm_cancel")]
+ internal static extern int CancelAlarm(int alarmId);
+
+ [DllImport(Libraries.Alarm, EntryPoint = "alarm_cancel_all")]
+ internal static extern int CancelAllAlarms();
+
+ [DllImport(Libraries.Alarm, EntryPoint = "alarm_get_scheduled_date")]
+ internal static extern int GetAlarmScheduledDate(int alarmId, out DateTime date);
+
+ [DllImport(Libraries.Alarm, EntryPoint = "alarm_get_current_time")]
+ internal static extern int GetCurrentTime(out DateTime date);
+
+ [DllImport(Libraries.Alarm, EntryPoint = "alarm_get_app_control")]
+ internal static extern int GetAlarmAppControl(int alarmId, out SafeAppControlHandle control);
+
+ [DllImport(Libraries.Alarm, EntryPoint = "alarm_get_scheduled_period")]
+ internal static extern int GetAlarmScheduledPeriod(int alarmId, out int period);
+
+ [DllImport(Libraries.Alarm, EntryPoint = "alarm_set_global")]
+ internal static extern int SetAlarmGlobalFlag(int alarmId, bool global);
+
+ [DllImport(Libraries.Alarm, EntryPoint = "alarm_get_global")]
+ internal static extern int GetAlarmGlobalFlag(int alarmId, out bool global);
+
+ [DllImport(Libraries.Alarm, EntryPoint = "alarm_foreach_registered_alarm")]
+ internal static extern int GetAllRegisteredAlarms(RegisteredAlarmCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Alarm, EntryPoint = "alarm_schedule_noti_once_at_date")]
+ internal static extern AlarmError CreateAlarmNotiOnceAtDate(NotificationSafeHandle noti, ref DateTime date, out int alarmId);
+
+ [DllImport(Libraries.Alarm, EntryPoint = "alarm_schedule_noti_after_delay")]
+ internal static extern AlarmError CreateAlarmNotiAfterDelay(NotificationSafeHandle noti, int delay, int period, out int alarmId);
+
+ [DllImport(Libraries.Alarm, EntryPoint = "alarm_schedule_noti_once_after_delay")]
+ internal static extern AlarmError CreateAlarmNotiOnceAfterDelay(NotificationSafeHandle noti, int delay, out int alarmId);
+
+ [DllImport(Libraries.Alarm, EntryPoint = "alarm_schedule_noti_with_recurrence_week_flag")]
+ internal static extern AlarmError CreateAlarmNotiRecurWeek(NotificationSafeHandle noti, ref DateTime date, int week, out int alarmId);
+
+ //callback
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool RegisteredAlarmCallback(int alarmId, IntPtr userData);
+ }
+}
diff --git a/src/Tizen.Applications.Alarm/Interop/Interop.Libraries.cs b/src/Tizen.Applications.Alarm/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..63f4a29
--- /dev/null
+++ b/src/Tizen.Applications.Alarm/Interop/Interop.Libraries.cs
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string Alarm = "libcapi-appfw-alarm.so.0";
+ }
+}
diff --git a/src/Tizen.Applications.Alarm/Tizen.Applications.Alarm.csproj b/src/Tizen.Applications.Alarm/Tizen.Applications.Alarm.csproj
new file mode 100755
index 0000000..542b4f1
--- /dev/null
+++ b/src/Tizen.Applications.Alarm/Tizen.Applications.Alarm.csproj
@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen.Applications.Common\Tizen.Applications.Common.csproj" />
+ <ProjectReference Include="..\Tizen.Applications.Notification\Tizen.Applications.Notification.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project> \ No newline at end of file
diff --git a/src/Tizen.Applications.Alarm/Tizen.Applications/Alarm.cs b/src/Tizen.Applications.Alarm/Tizen.Applications/Alarm.cs
new file mode 100755
index 0000000..6f73c0f
--- /dev/null
+++ b/src/Tizen.Applications.Alarm/Tizen.Applications/Alarm.cs
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// The Alarm API allows setting an "alarm clock" for the delivery of a notification at some point in the future.
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// public class AlarmExample
+ /// {
+ /// /// ...
+ /// IEnumerable &lt; Alarm &gt; alarms = AlarmManager.GetAllSceduledAlarms();
+ /// alarms[0].Cancel();
+ /// }
+ /// </code>
+ /// </example>
+ public class Alarm
+ {
+ private const string _logTag = "Tizen.Applications.Alarm";
+
+ /// <summary>
+ /// Constructor created with new AlarmId.
+ /// </summary>
+ /// <param name="id"></param>
+ internal Alarm(int id)
+ {
+ AlarmId = id;
+ }
+
+ /// <summary>
+ /// The alarm ID uniquely identifies an alarm.
+ /// </summary>
+ public int AlarmId
+ {
+ get; private set;
+ }
+
+ /// <summary>
+ /// Gets the recurrence days of the week.
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/alarm.get</privilege>
+ /// <remarks>
+ /// week_flag may be a combination of days, like Tuesday | Friday
+ /// </remarks>
+ public AlarmWeekFlag WeekFlag
+ {
+ get
+ {
+ int week;
+ AlarmError ret = (AlarmError)Interop.Alarm.GetAlarmWeekFlag(AlarmId, out week);
+ if (ret != AlarmError.None)
+ {
+ Log.Error(_logTag, "Failed to get WeekFlag");
+ }
+
+ return (AlarmWeekFlag)week;
+ }
+ }
+
+ /// <summary>
+ /// Gets the scheduled time.
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/alarm.get</privilege>
+ public DateTime ScheduledDate
+ {
+ get
+ {
+ Interop.Alarm.DateTime value;
+ AlarmError ret = (AlarmError)Interop.Alarm.GetAlarmScheduledDate(AlarmId, out value);
+ if (ret != AlarmError.None)
+ {
+ Log.Error(_logTag, "Failed to get WeekFlag");
+ }
+
+ DateTime time = AlarmManager.ConvertIntPtrToDateTime(value);
+ return time;
+ }
+ }
+
+ /// <summary>
+ /// Gets the period of time between the recurrent alarms.
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/alarm.get</privilege>
+ public int Period
+ {
+ get
+ {
+ int period;
+ AlarmError ret = (AlarmError)Interop.Alarm.GetAlarmScheduledPeriod(AlarmId, out period);
+ if (ret != AlarmError.None)
+ {
+ Log.Error(_logTag, "Failed to get WeekFlag");
+ }
+
+ return period;
+ }
+ }
+
+ /// <summary>
+ /// Gets the AppControl to be invoked when the the alarm is triggered.
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/alarm.get</privilege>
+ public AppControl AlarmAppControl
+ {
+ get
+ {
+ SafeAppControlHandle handle;
+ AlarmError ret = (AlarmError)Interop.Alarm.GetAlarmAppControl(AlarmId, out handle);
+
+ if (ret != AlarmError.None)
+ {
+ Log.Error(_logTag, "Failed to get WeekFlag");
+ }
+
+ return new AppControl(handle);
+ }
+ }
+
+ /// <summary>
+ /// Gets whether the alarm will launch global application or not.
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/alarm.set</privilege>
+ /// <privilege>http://tizen.org/privilege/alarm.get</privilege>
+ public bool Global
+ {
+ get
+ {
+ bool global;
+ AlarmError ret = (AlarmError)Interop.Alarm.GetAlarmGlobalFlag(AlarmId, out global);
+ if (ret != AlarmError.None)
+ {
+ Log.Error(_logTag, "Failed to get WeekFlag");
+ }
+
+ return global;
+ }
+
+ set
+ {
+ AlarmError ret = (AlarmError)Interop.Alarm.SetAlarmGlobalFlag(AlarmId, value);
+ if (ret != AlarmError.None)
+ {
+ Log.Error(_logTag, "Failed to get WeekFlag");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Cancels the the specific alarm.
+ /// </summary>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied due to insufficient previlleges.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/alarm.set</privilege>
+ public void Cancel()
+ {
+ AlarmError ret = (AlarmError)Interop.Alarm.CancelAlarm(AlarmId);
+ if (ret != AlarmError.None)
+ {
+ throw AlarmErrorFactory.GetException(ret, "Failed to Cancel alarm");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Alarm/Tizen.Applications/AlarmErrorFactory.cs b/src/Tizen.Applications.Alarm/Tizen.Applications/AlarmErrorFactory.cs
new file mode 100755
index 0000000..4524882
--- /dev/null
+++ b/src/Tizen.Applications.Alarm/Tizen.Applications/AlarmErrorFactory.cs
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications
+{
+ internal enum AlarmError
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None,
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+ InvalidTime = -0x01100000 | 0x05,
+ InvalidDate = -0x01100000 | 0x06,
+ ConnectionFail = -0x01100000 | 0x07,
+ NotPermittedApp = -0x01100000 | 0x08,
+ OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
+ PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied
+ }
+ internal static class AlarmErrorFactory
+ {
+ private const string _logTag = "Tizen.Applications.Alarm";
+
+ internal static Exception GetException(AlarmError ret, string msg)
+ {
+ switch (ret)
+ {
+ case AlarmError.InvalidParameter:
+ //fall through
+ case AlarmError.InvalidTime:
+ //fall through
+ case AlarmError.InvalidDate:
+ Log.Error(_logTag, msg);
+ return new ArgumentException(ret + " error occurred.");
+ case AlarmError.NotPermittedApp:
+ //fall through
+ case AlarmError.PermissionDenied:
+ Log.Error(_logTag, msg);
+ return new UnauthorizedAccessException(ret + "error occured.");
+ default:
+ Log.Error(_logTag, msg);
+ return new InvalidOperationException(ret + " error occurred.");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Alarm/Tizen.Applications/AlarmManager.cs b/src/Tizen.Applications.Alarm/Tizen.Applications/AlarmManager.cs
new file mode 100755
index 0000000..68fc592
--- /dev/null
+++ b/src/Tizen.Applications.Alarm/Tizen.Applications/AlarmManager.cs
@@ -0,0 +1,412 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Runtime.InteropServices;
+ using Tizen.Applications.Notifications;
+
+ /// <summary>
+ /// Enumeration for Alarm Week Flag, the days of the week.
+ /// </summary>
+ [Flags]
+ public enum AlarmWeekFlag
+ {
+ /// <summary>
+ /// Identifier for Sunday.
+ /// </summary>
+ Sunday = 0x01,
+
+ /// <summary>
+ /// Identifier for Monday.
+ /// </summary>
+ Monday = 0x02,
+
+ /// <summary>
+ /// Identifier for Tuesday.
+ /// </summary>
+ Tuesday = 0x04,
+
+ /// <summary>
+ /// Identifier for Wednesday.
+ /// </summary>
+ Wednesday = 0x08,
+
+ /// <summary>
+ /// Identifier for Thursday.
+ /// </summary>
+ Thursday = 0x10,
+
+ /// <summary>
+ /// Identifier for Friday.
+ /// </summary>
+ Friday = 0x20,
+
+ /// <summary>
+ /// Identifier for Saturday.
+ /// </summary>
+ Saturday = 0x40,
+
+ /// <summary>
+ /// All Days of the Week.
+ /// </summary>
+ AllDays = Sunday |Monday|Tuesday|Wednesday|Thursday|Friday|Saturday,
+
+ /// <summary>
+ /// Only Weekdays
+ /// </summary>
+ WeekDays = Monday | Tuesday | Wednesday | Thursday | Friday
+ }
+
+ /// <summary>
+ /// Mobile devices typically give constant access to information from various sources.Some of this information is best delivered through alarms -
+ /// the most obvious case is a calendar scheduling application which lets you know when a meeting is about to start.Alarms are certainly better than actively waiting in a loop.
+ /// They are also better than putting an interface to sleep because they do not block your main UI thread.
+ /// Use of alarms helps build smooth user experiences and implements unattended data synchronization tasks.
+ /// If an application is installed after setting the alarm, your alarm is cancelled automatically.
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// public class AlarmManagerExample
+ /// {
+ /// /// ...
+ /// Alarm alarm = AlarmManager.CreateAlarm(24000,1000,null);
+ /// AlarmManager.CancelAll();
+ /// }
+ /// </code>
+ /// </example>
+
+ public static class AlarmManager
+ {
+ private const string LogTag = "Tizen.Applications.Alarm";
+
+ private static Interop.Alarm.DateTime ConvertDateTimeToStruct(DateTime value)
+ {
+ Interop.Alarm.DateTime time = new Interop.Alarm.DateTime();
+ time.sec = value.Second;
+ time.min = value.Minute;
+ time.hour = value.Hour;
+ time.mday = value.Day;
+ time.mon = value.Month - 1;
+ time.year = value.Year - 1900;
+ time.wday = (int)value.DayOfWeek;
+ time.yday = value.DayOfYear;
+ time.isdst = 0;
+ return time;
+ }
+
+ internal static DateTime ConvertIntPtrToDateTime(Interop.Alarm.DateTime time)
+ {
+ DateTime value = new DateTime(1900 + time.year, 1 + time.mon, time.mday, time.hour, time.min, time.sec, DateTimeKind.Utc);
+ return value;
+ }
+
+ /// <summary>
+ /// Sets an alarm to be triggered after a specific time.
+ /// The alarm will first go off delay seconds later and then will go off every certain amount of time defined using period seconds.
+ /// </summary>
+ /// <param name="delay">The amount of time before the first execution (in seconds).</param>
+ /// <param name="period"> The amount of time between subsequent alarms (in seconds). This value does not guarantee the accuracy.
+ /// The actual interval is calculated by the OS. The minimum value is 600sec</param>
+ /// <param name="appControl"> The destination AppControl to perform a specific task when the alarm is triggered </param>
+ /// <returns>Alarm Instance created with the set param values.</returns>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parameter.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/alarm.set</privilege>
+ public static Alarm CreateAlarm(int delay, int period, AppControl appControl)
+ {
+ Alarm alarm = null;
+ int alarmId;
+ SafeAppControlHandle handle = (appControl == null) ? null : appControl.SafeAppControlHandle;
+ AlarmError ret = (AlarmError)Interop.Alarm.CreateAlarmAfterDelay(handle, delay, period, out alarmId);
+ alarm = new Alarm(alarmId);
+ if (ret != AlarmError.None)
+ {
+ throw AlarmErrorFactory.GetException(ret, "Failed to create Alarm");
+ }
+
+ return alarm;
+ }
+
+ /// <summary>
+ /// Sets an alarm to be triggered after a specific time.
+ /// The alarm will go off delay seconds later.
+ /// </summary>
+ /// <param name="delay"> The amount of time before the execution (in seconds) </param>
+ /// <param name="appControl"> The destination AppControl to perform a specific task when the alarm is triggered </param>
+ /// <returns> Alarm Instance created with the set param values.</returns>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parameter.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/alarm.set</privilege>
+ public static Alarm CreateAlarm(int delay, AppControl appControl)
+ {
+ Alarm alarm = null;
+ int alarmId;
+ AlarmError ret = (AlarmError)Interop.Alarm.CreateAlarmOnceAfterDelay(appControl.SafeAppControlHandle, delay, out alarmId);
+ alarm = new Alarm(alarmId);
+ if (ret != AlarmError.None)
+ {
+ throw AlarmErrorFactory.GetException(ret, "Failed to create Alarm");
+ }
+
+ return alarm;
+ }
+
+ /// <summary>
+ /// Sets an alarm to be triggered at a specific time.
+ /// The date describes the time of the first occurrence.
+ /// </summary>
+ /// <param name="value"> The first active alarm time </param>
+ /// <param name="appControl"> The destination AppControl to perform specific work when the alarm is triggered </param>
+ /// <returns> Alarm Instance created with the set param values.</returns>
+ /// <remarks>This operation is permitted wit UI application appcontrol only.</remarks>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parameter.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/alarm.set</privilege>
+ public static Alarm CreateAlarm(DateTime value, AppControl appControl)
+ {
+ Alarm alarm = null;
+ int alarmId;
+ Interop.Alarm.DateTime time = ConvertDateTimeToStruct(value);
+ AlarmError ret = (AlarmError)Interop.Alarm.CreateAlarmOnceAtDate(appControl.SafeAppControlHandle, ref time, out alarmId);
+ alarm = new Alarm(alarmId);
+ if (ret != AlarmError.None)
+ {
+ throw AlarmErrorFactory.GetException(ret, "Failed to create Alarm");
+ }
+
+ return alarm;
+ }
+
+ /// <summary>
+ /// Sets an alarm to be triggered periodically, starting at a specific time.
+ /// The date describes the time of the first occurrence.
+ /// weekFlag is the repeat value of the days of the week.
+ /// If weekFlag is AlarmWeekFlag.Tuesday, the alarm will repeat every Tuesday at a specific time.
+ /// </summary>
+ /// <remarks>This operation is permitted wit UI application appcontrol only.</remarks>
+ /// <param name="value"> The first active alarm time </param>
+ /// <param name="weekFlag"> The day of the week, AlarmWeekFlag may be a combination of days, like AlarmWeekFlag.Sunday | AlarmWeekFlag.Monday</param>
+ /// <param name="appControl"> The destination AppControl to perform specific work when the alarm is triggered </param>
+ /// <returns> Alarm Instance created with the set param values.</returns>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parameter.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/alarm.set</privilege>
+ public static Alarm CreateAlarm(DateTime value, AlarmWeekFlag weekFlag, AppControl appControl)
+ {
+ Alarm alarm = null;
+ int alarmId;
+ Interop.Alarm.DateTime time = ConvertDateTimeToStruct(value);
+ AlarmError ret = (AlarmError)Interop.Alarm.CreateAlarmRecurWeek(appControl.SafeAppControlHandle, ref time, (int)weekFlag, out alarmId);
+ alarm = new Alarm(alarmId);
+ if (ret != AlarmError.None)
+ {
+ throw AlarmErrorFactory.GetException(ret, "Failed to create Alarm");
+ }
+
+ return alarm;
+ }
+
+ /// <summary>
+ /// Sets a notification alarm to be triggered at a specific time.
+ /// The date describes the time of the first occurrence.
+ /// </summary>
+ /// <param name="dateTime"> The first active alarm time </param>
+ /// <param name="notification"> The notification to be posted when the alarm is triggered </param>
+ /// <returns> Alarm Instance created with the set param values.</returns>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parameter.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/alarm.set</privilege>
+ /// <privilege>http://tizen.org/privilege/notification</privilege>
+ public static Alarm CreateAlarm(DateTime dateTime, Notification notification)
+ {
+ Alarm alarm = null;
+ int alarmId;
+ NotificationSafeHandle safeHandle = NotificationManager.MakeNotificationSafeHandle(notification);
+ Interop.Alarm.DateTime time = ConvertDateTimeToStruct(dateTime);
+ AlarmError ret = Interop.Alarm.CreateAlarmNotiOnceAtDate(safeHandle, ref time, out alarmId);
+ if (ret != AlarmError.None)
+ {
+ throw AlarmErrorFactory.GetException(ret, "Failed to create Alarm");
+ }
+
+ alarm = new Alarm(alarmId);
+
+ return alarm;
+ }
+
+ /// <summary>
+ /// Sets a notification alarm to be triggered after a specific time.
+ /// The alarm will first go off delay seconds later and then will go off every certain amount of time defined using period seconds.
+ /// </summary>
+ /// <param name="delay">The amount of time before the first execution (in seconds). </param>
+ /// <param name="period"> The amount of time between subsequent alarms (in seconds). This value does not guarantee the accuracy. </param>
+ /// <param name="notification"> The notification to be posted when the alarm is triggered </param>
+ /// <returns> Alarm Instance created with the set param values.</returns>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parameter.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/alarm.set</privilege>
+ /// <privilege>http://tizen.org/privilege/notification</privilege>
+ public static Alarm CreateAlarm(int delay, int period, Notification notification)
+ {
+ Alarm alarm = null;
+ int alarmId;
+ NotificationSafeHandle safeHandle = NotificationManager.MakeNotificationSafeHandle(notification);
+ AlarmError ret = Interop.Alarm.CreateAlarmNotiAfterDelay(safeHandle, delay, period, out alarmId);
+ if (ret != AlarmError.None)
+ {
+ throw AlarmErrorFactory.GetException(ret, "Failed to create Alarm");
+ }
+
+ alarm = new Alarm(alarmId);
+
+ return alarm;
+ }
+
+ /// <summary>
+ /// Sets a notification alarm to be triggered periodically, starting at a specific time.
+ /// The date describes the time of the first occurrence.
+ /// weekFlag is the repeat value of the days of the week.
+ /// If weekFlag is AlarmWeekFlag.Tuesday, the alarm will repeat every Tuesday at a specific time.
+ /// </summary>
+ /// <param name="dateTime"> The first active alarm time </param>
+ /// <param name="weekFlag"> The day of the week, AlarmWeekFlag may be a combination of days,
+ /// like AlarmWeekFlag.Sunday | AlarmWeekFlag.Monday</param>
+ /// <param name="notification"> The notification to be posted when the alarm is triggered </param>
+ /// <returns> Alarm Instance created with the set param values.</returns>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parameter.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/alarm.set</privilege>
+ /// <privilege>http://tizen.org/privilege/notification</privilege>
+ public static Alarm CreateAlarm(DateTime dateTime, AlarmWeekFlag weekFlag, Notification notification)
+ {
+ Alarm alarm = null;
+ int alarmId;
+ NotificationSafeHandle safeHandle = NotificationManager.MakeNotificationSafeHandle(notification);
+ Interop.Alarm.DateTime time = ConvertDateTimeToStruct(dateTime);
+ AlarmError ret = Interop.Alarm.CreateAlarmNotiRecurWeek(safeHandle, ref time, (int)weekFlag, out alarmId);
+ if (ret != AlarmError.None)
+ {
+ throw AlarmErrorFactory.GetException(ret, "Failed to create Alarm");
+ }
+
+ alarm = new Alarm(alarmId);
+
+ return alarm;
+ }
+
+ /// <summary>
+ /// Sets a notification alarm to be triggered after a specific time.
+ /// The alarm will go off delay seconds later.
+ /// </summary>
+ /// <param name="delay">The amount of time before the first execution (in seconds).</param>
+ /// <param name="notification"> The notification to be posted when the alarm is triggered </param>
+ /// <returns> Alarm Instance created with the set param values.</returns>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parameter.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/alarm.set</privilege>
+ /// <privilege>http://tizen.org/privilege/notification</privilege>
+ public static Alarm CreateAlarm(int delay, Notification notification)
+ {
+ Alarm alarm = null;
+ int alarmId;
+ NotificationSafeHandle safeHandle = NotificationManager.MakeNotificationSafeHandle(notification);
+ AlarmError ret = Interop.Alarm.CreateAlarmNotiOnceAfterDelay(safeHandle, delay, out alarmId);
+ if (ret != AlarmError.None)
+ {
+ throw AlarmErrorFactory.GetException(ret, "Failed to create Alarm");
+ }
+
+ alarm = new Alarm(alarmId);
+
+ return alarm;
+ }
+
+ /// <summary>
+ /// Cancels all scheduled alarms that are registered by the application that calls this API.
+ /// </summary>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/alarm.set</privilege>
+ public static void CancelAll()
+ {
+ AlarmError ret = (AlarmError)Interop.Alarm.CancelAllAlarms();
+ if (ret != AlarmError.None)
+ {
+ throw AlarmErrorFactory.GetException(ret, "Failed to cancel Alarms");
+ }
+ }
+
+ /// <summary>
+ /// Retrieves all registered alarms.
+ /// </summary>
+ /// <returns>List of all Alarm instances.</returns>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/alarm.get</privilege>
+ public static IEnumerable<Alarm> GetAllSceduledAlarms()
+ {
+ List<Alarm> alarms = new List<Alarm>();
+ Interop.Alarm.RegisteredAlarmCallback callback = (int alarmId, IntPtr userData) =>
+ {
+ alarms.Add(new Alarm(alarmId));
+ return true;
+ };
+
+ AlarmError ret = (AlarmError)Interop.Alarm.GetAllRegisteredAlarms(callback, IntPtr.Zero);
+ if (ret != AlarmError.None)
+ {
+ throw AlarmErrorFactory.GetException(ret, "Failed to get Alarms");
+ }
+
+ return alarms;
+ }
+
+ /// <summary>
+ /// Gets the current system time.
+ /// </summary>
+ /// <returns>The current system time</returns>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ public static DateTime GetCurrentTime()
+ {
+ DateTime time;
+ Interop.Alarm.DateTime value;
+ AlarmError ret = (AlarmError)Interop.Alarm.GetCurrentTime(out value);
+ if (ret != AlarmError.None)
+ {
+ throw AlarmErrorFactory.GetException(ret, "Failed to get Currenttime");
+ }
+ else
+ {
+
+ time = ConvertIntPtrToDateTime(value);
+ }
+
+ return time;
+ }
+
+ }
+}
diff --git a/src/Tizen.Applications.Badge/Interop/Interop.Badge.cs b/src/Tizen.Applications.Badge/Interop/Interop.Badge.cs
new file mode 100755
index 0000000..53b1b1a
--- /dev/null
+++ b/src/Tizen.Applications.Badge/Interop/Interop.Badge.cs
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Applications;
+
+internal static partial class Interop
+{
+ internal static partial class Badge
+ {
+ internal enum Action : uint
+ {
+ Create = 0,
+ Remove,
+ Update,
+ ChangedDisplay,
+ ServiceReady
+ }
+
+ internal delegate void ForeachCallback(string appId, uint count, IntPtr userData);
+
+ internal delegate void ChangedCallback(Action action, string appId, uint count, IntPtr userData);
+
+ [DllImport(Libraries.Badge, EntryPoint = "badge_add")]
+ internal static extern BadgeError Add(string appId);
+
+ [DllImport(Libraries.Badge, EntryPoint = "badge_remove")]
+ internal static extern BadgeError Remove(string appId);
+
+ [DllImport(Libraries.Badge, EntryPoint = "badge_set_count")]
+ internal static extern BadgeError SetCount(string appId, uint count);
+
+ [DllImport(Libraries.Badge, EntryPoint = "badge_get_count")]
+ internal static extern BadgeError GetCount(string appId, out uint count);
+
+ [DllImport(Libraries.Badge, EntryPoint = "badge_set_display")]
+ internal static extern BadgeError SetDisplay(string appId, uint isDisplay);
+
+ [DllImport(Libraries.Badge, EntryPoint = "badge_get_display")]
+ internal static extern BadgeError GetDisplay(string appId, out uint isDisplay);
+
+ [DllImport(Libraries.Badge, EntryPoint = "badge_foreach")]
+ internal static extern BadgeError Foreach(ForeachCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Badge, EntryPoint = "badge_register_changed_cb")]
+ internal static extern BadgeError SetChangedCallback(ChangedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Badge, EntryPoint = "badge_unregister_changed_cb")]
+ internal static extern BadgeError UnsetChangedCallback(ChangedCallback callback);
+ }
+}
diff --git a/src/Tizen.Applications.Badge/Interop/Interop.Libraries.cs b/src/Tizen.Applications.Badge/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..01ccffd
--- /dev/null
+++ b/src/Tizen.Applications.Badge/Interop/Interop.Libraries.cs
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string Badge = "libbadge.so.0";
+ }
+}
diff --git a/src/Tizen.Applications.Badge/Tizen.Applications.Badge.csproj b/src/Tizen.Applications.Badge/Tizen.Applications.Badge.csproj
new file mode 100755
index 0000000..8f0f722
--- /dev/null
+++ b/src/Tizen.Applications.Badge/Tizen.Applications.Badge.csproj
@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="../Tizen/Tizen.csproj" />
+ <ProjectReference Include="../Tizen.Log/Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Applications.Badge/Tizen.Applications/Badge.cs b/src/Tizen.Applications.Badge/Tizen.Applications/Badge.cs
new file mode 100755
index 0000000..d5e6fff
--- /dev/null
+++ b/src/Tizen.Applications.Badge/Tizen.Applications/Badge.cs
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Immutable class for getting information of the badge.
+ /// </summary>
+ public class Badge
+ {
+ private readonly string _appId;
+ private readonly int _count;
+ private readonly bool _isDisplay;
+
+ internal Badge(string appid, int count, bool isDisplay)
+ {
+ _appId = appid;
+ _count = count;
+ _isDisplay = isDisplay;
+ }
+
+ /// <summary>
+ /// Property for the count value of the badge.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public int Count
+ {
+ get
+ {
+ return _count;
+ }
+ }
+
+ /// <summary>
+ /// Property for the application ID of the badge.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string AppId
+ {
+ get
+ {
+ return _appId;
+ }
+ }
+
+ /// <summary>
+ /// Property for the flag of 'display'.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public bool IsDisplay
+ {
+ get
+ {
+ return _isDisplay;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Badge/Tizen.Applications/BadgeControl.cs b/src/Tizen.Applications.Badge/Tizen.Applications/BadgeControl.cs
new file mode 100755
index 0000000..4956efc
--- /dev/null
+++ b/src/Tizen.Applications.Badge/Tizen.Applications/BadgeControl.cs
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications
+{
+ using System;
+ using System.Collections.Generic;
+ /// <summary>
+ /// Class for badge operation.
+ /// </summary>
+ public static class BadgeControl
+ {
+ private static event EventHandler<BadgeEventArgs> s_changed;
+ private static bool s_registered = false;
+ private static Interop.Badge.ChangedCallback s_callback;
+
+ /// <summary>
+ /// Event handler for receiving badge events.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="InvalidOperationException">Thrown in case of failed conditions</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
+ /// <privilege>http://tizen.org/privilege/notification</privilege>
+ public static event EventHandler<BadgeEventArgs> Changed
+ {
+ add
+ {
+ if (s_changed == null && !s_registered)
+ {
+ if (s_callback == null)
+ {
+ s_callback = new Interop.Badge.ChangedCallback(OnChangedEvent);
+ }
+
+ BadgeError err = Interop.Badge.SetChangedCallback(s_callback, IntPtr.Zero);
+ if (err != BadgeError.None)
+ {
+ throw BadgeErrorFactory.GetException(err, "Failed to add event handler");
+ }
+
+ s_registered = true;
+ }
+
+ s_changed += value;
+ }
+ remove
+ {
+ s_changed -= value;
+ if (s_changed == null && s_registered)
+ {
+ BadgeError err = Interop.Badge.UnsetChangedCallback(s_callback);
+ if (err != BadgeError.None)
+ {
+ throw BadgeErrorFactory.GetException(err, "Failed to remove event handler");
+ }
+
+ s_callback = null;
+ s_registered = false;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the badge information from application ID.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="appId">Application ID</param>
+ /// <exception cref="ArgumentException">Thrown when failed because of invalid argument</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of failed conditions</exception>
+ /// <privilege>http://tizen.org/privilege/notification</privilege>
+ public static Badge Find(string appId)
+ {
+ uint count;
+ uint display;
+
+ BadgeError err = Interop.Badge.GetCount(appId, out count);
+ if (err != BadgeError.None)
+ {
+ throw BadgeErrorFactory.GetException(err, "Failed to find badge count of " + appId);
+ }
+
+ err = Interop.Badge.GetDisplay(appId, out display);
+ if (err != BadgeError.None)
+ {
+ throw BadgeErrorFactory.GetException(err, "Failed to find badge display of " + appId);
+ }
+
+ return new Badge(appId, (int)count, display == 0 ? false : true);
+ }
+
+ /// <summary>
+ /// Removes the badge information.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="appId">Application ID</param>
+ /// <exception cref="ArgumentException">Thrown when failed because of invalid argument</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of failed conditions</exception>
+ /// <privilege>http://tizen.org/privilege/notification</privilege>
+ public static void Remove(string appId)
+ {
+ BadgeError err = Interop.Badge.Remove(appId);
+ if (err != BadgeError.None)
+ {
+ throw BadgeErrorFactory.GetException(err, "Failed to Remove badge of " + appId);
+ }
+ }
+
+ /// <summary>
+ /// Adds the badge information.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="appId">Application ID</param>
+ /// <param name="count">Count value</param>
+ /// <param name="isDisplay">True if it should be displayed</param>
+ /// <exception cref="ArgumentException">Thrown when failed because of invalid argument</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of failed conditions</exception>
+ /// <privilege>http://tizen.org/privilege/notification</privilege>
+ public static void Add(string appId, int count = 1, bool isDisplay = true)
+ {
+ BadgeError err = Interop.Badge.Add(appId);
+ if (err != BadgeError.None)
+ {
+ throw BadgeErrorFactory.GetException(err, "Failed to add badge of " + appId);
+ }
+
+ try
+ {
+ Update(appId, count, isDisplay);
+ }
+ catch (Exception e)
+ {
+ Remove(appId);
+ throw e;
+ }
+ }
+
+ /// <summary>
+ /// Updates the badge information.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="appId">Application ID</param>
+ /// <param name="count">Count value</param>
+ /// <exception cref="ArgumentException">Thrown when failed because of invalid argument</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of failed conditions</exception>
+ /// <privilege>http://tizen.org/privilege/notification</privilege>
+ public static void Update(string appId, int count)
+ {
+ BadgeError err = Interop.Badge.SetCount(appId, (uint)count);
+ if (err != BadgeError.None)
+ {
+ throw BadgeErrorFactory.GetException(err, "Failed to update badge of " + appId);
+ }
+ }
+
+ /// <summary>
+ /// Updates the badge information.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="appId">Application ID</param>
+ /// <param name="isDisplay">True if it should be displayed</param>
+ /// <exception cref="ArgumentException">Thrown when failed because of invalid argument</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of failed conditions</exception>
+ /// <privilege>http://tizen.org/privilege/notification</privilege>
+ public static void Update(string appId, bool isDisplay)
+ {
+ BadgeError err = Interop.Badge.SetDisplay(appId, isDisplay ? 1U : 0U);
+ if (err != BadgeError.None)
+ {
+ throw BadgeErrorFactory.GetException(err, "Failed to update badge of " + appId);
+ }
+ }
+
+ /// <summary>
+ /// Updates the badge information.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="appId">Application ID</param>
+ /// <param name="count">Count value</param>
+ /// <param name="isDisplay">True if it should be displayed</param>
+ /// <exception cref="ArgumentException">Thrown when failed because of invalid argument</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of failed conditions</exception>
+ /// <privilege>http://tizen.org/privilege/notification</privilege>
+ public static void Update(string appId, int count, bool isDisplay)
+ {
+ Update(appId, count);
+ Update(appId, isDisplay);
+ }
+
+ /// <summary>
+ /// Gets all badge information.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of failed conditions</exception>
+ /// <privilege>http://tizen.org/privilege/notification</privilege>
+ public static IEnumerable<Badge> GetBadges()
+ {
+ IList<Badge> list = new List<Badge>();
+
+ BadgeError err = Interop.Badge.Foreach((appId, count, userData) =>
+ {
+ uint display = 0;
+ BadgeError errGetDisplay = Interop.Badge.GetDisplay(appId, out display);
+ if (errGetDisplay != BadgeError.None)
+ {
+ throw BadgeErrorFactory.GetException(errGetDisplay, "Failed to get badges ");
+ }
+
+ list.Add(new Badge(appId, (int)count, display == 0 ? false : true));
+ }, IntPtr.Zero);
+
+ if (err != BadgeError.None)
+ {
+ throw BadgeErrorFactory.GetException(err, "Failed to get badges");
+ }
+
+ return list;
+ }
+
+ private static void OnChangedEvent(Interop.Badge.Action action, string appId, uint count, IntPtr userData)
+ {
+ uint display = 0;
+ uint countLocal = 0;
+
+ switch (action)
+ {
+ case Interop.Badge.Action.Create:
+ s_changed?.Invoke(null, new BadgeEventArgs()
+ {
+ Reason = BadgeEventArgs.Action.Add,
+ Badge = new Badge(appId, 0, false)
+ });
+ break;
+
+ case Interop.Badge.Action.Remove:
+ s_changed?.Invoke(null, new BadgeEventArgs()
+ {
+ Reason = BadgeEventArgs.Action.Remove,
+ Badge = new Badge(appId, 0, false)
+ });
+ break;
+
+ case Interop.Badge.Action.Update:
+ Interop.Badge.GetDisplay(appId, out display);
+ s_changed?.Invoke(null, new BadgeEventArgs()
+ {
+ Reason = BadgeEventArgs.Action.Update,
+ Badge = new Badge(appId, (int)count, display == 0 ? false : true)
+ });
+ break;
+
+ case Interop.Badge.Action.ChangedDisplay:
+ Interop.Badge.GetCount(appId, out countLocal);
+ s_changed?.Invoke(null, new BadgeEventArgs()
+ {
+ Reason = BadgeEventArgs.Action.Update,
+ Badge = new Badge(appId, (int)countLocal, count == 0 ? false : true)
+ });
+ break;
+
+ case Interop.Badge.Action.ServiceReady:
+ // Ignore
+ break;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Badge/Tizen.Applications/BadgeErrorFactory.cs b/src/Tizen.Applications.Badge/Tizen.Applications/BadgeErrorFactory.cs
new file mode 100755
index 0000000..9443298
--- /dev/null
+++ b/src/Tizen.Applications.Badge/Tizen.Applications/BadgeErrorFactory.cs
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications
+{
+ using System;
+ using System.Runtime.CompilerServices;
+
+ internal enum BadgeError
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None,
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+ OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
+ PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied,
+ IoError = Tizen.Internals.Errors.ErrorCode.IoError,
+ DbError = -0x01120000 | 0x01,
+ AlreadyExists = -0x01120000 | 0x02,
+ DBusError = -0x01120000 | 0x03,
+ DoesnotExist = -0x01120000 | 0x04,
+ ServiceError = -0x01120000 | 0x05,
+ InvalidPackage = -0x01120000 | 0x06
+ }
+
+ /// <summary>
+ /// Immutable class for getting information of the badge.
+ /// </summary>
+ internal static class BadgeErrorFactory
+ {
+ private static readonly string LogTag = "Tizen.Applications.Badge";
+
+ internal static Exception GetException(BadgeError ret, string msg, [CallerMemberName] string memberName = "", [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNumber = 0)
+ {
+ Log.Error(LogTag, memberName + " : " + lineNumber);
+
+ switch (ret)
+ {
+ case BadgeError.InvalidParameter:
+ Log.Error(LogTag, msg);
+ return new ArgumentException(ret + " error occurred.");
+ case BadgeError.PermissionDenied:
+ throw new UnauthorizedAccessException("Permission denied (http://tizen.org/privilege/notification)");
+ default:
+ Log.Error(LogTag, msg);
+ return new InvalidOperationException(ret + " error occurred.");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Badge/Tizen.Applications/BadgeEventArgs.cs b/src/Tizen.Applications.Badge/Tizen.Applications/BadgeEventArgs.cs
new file mode 100755
index 0000000..2977289
--- /dev/null
+++ b/src/Tizen.Applications.Badge/Tizen.Applications/BadgeEventArgs.cs
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications
+{
+ using System;
+
+ /// <summary>
+ /// Class for event arguments of the badge event
+ /// </summary>
+ public class BadgeEventArgs : EventArgs
+ {
+ internal BadgeEventArgs()
+ {
+ }
+
+ /// <summary>
+ /// Enumeration for badge action.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum Action : int
+ {
+ /// <summary>
+ /// Badge was added.
+ /// </summary>
+ Add = 0,
+
+ /// <summary>
+ /// Badge was removed.
+ /// </summary>
+ Remove,
+
+ /// <summary>
+ /// Badge was updated.
+ /// </summary>
+ Update,
+ }
+
+ /// <summary>
+ /// Property for Badge object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public Badge Badge { get; internal set; }
+
+ /// <summary>
+ /// Property for Action value.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public Action Reason { get; internal set; }
+ }
+}
diff --git a/src/Tizen.Applications.Common/Interop/Interop.AppCommon.cs b/src/Tizen.Applications.Common/Interop/Interop.AppCommon.cs
new file mode 100755
index 0000000..5ad41f5
--- /dev/null
+++ b/src/Tizen.Applications.Common/Interop/Interop.AppCommon.cs
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+using Tizen.Internals.Errors;
+using Tizen.Applications;
+
+internal static partial class Interop
+{
+ internal static partial class AppCommon
+ {
+ internal enum ResourceCategory : int
+ {
+ Image = 0,
+ Layout,
+ Sound,
+ Binary
+ }
+
+ [DllImport(Libraries.AppCommon, EntryPoint = "app_get_id")]
+ internal static extern ErrorCode AppGetId(out string appId);
+
+ [DllImport(Libraries.AppCommon, EntryPoint = "app_get_name")]
+ internal static extern ErrorCode AppGetName(out string name);
+
+ [DllImport(Libraries.AppCommon, EntryPoint = "app_get_resource_path")]
+ internal static extern string AppGetResourcePath();
+
+ [DllImport(Libraries.AppCommon, EntryPoint = "app_get_data_path")]
+ internal static extern string AppGetDataPath();
+
+ [DllImport(Libraries.AppCommon, EntryPoint = "app_get_cache_path")]
+ internal static extern string AppGetCachePath();
+
+ [DllImport(Libraries.AppCommon, EntryPoint = "app_get_shared_data_path")]
+ internal static extern string AppGetSharedDataPath();
+
+ [DllImport(Libraries.AppCommon, EntryPoint = "app_get_shared_resource_path")]
+ internal static extern string AppGetSharedResourcePath();
+
+ [DllImport(Libraries.AppCommon, EntryPoint = "app_get_shared_trusted_path")]
+ internal static extern string AppGetSharedTrustedPath();
+
+ [DllImport(Libraries.AppCommon, EntryPoint = "app_get_tep_resource_path")]
+ internal static extern string AppGetTepResourcePath();
+
+ [DllImport(Libraries.AppCommon, EntryPoint = "app_get_external_cache_path")]
+ internal static extern string AppGetExternalCachePath();
+
+ [DllImport(Libraries.AppCommon, EntryPoint = "app_get_external_data_path")]
+ internal static extern string AppGetExternalDataPath();
+
+ [DllImport(Libraries.AppCommon, EntryPoint = "app_get_external_shared_data_path")]
+ internal static extern string AppGetExternalSharedDataPath();
+
+ [DllImport(Libraries.AppCommon, EntryPoint = "app_get_version")]
+ internal static extern ErrorCode AppGetVersion(out string version);
+
+ [DllImport(Libraries.AppCommon, EntryPoint = "app_event_get_low_memory_status")]
+ internal static extern ErrorCode AppEventGetLowMemoryStatus(IntPtr handle, out LowMemoryStatus status);
+
+ [DllImport(Libraries.AppCommon, EntryPoint = "app_event_get_low_battery_status")]
+ internal static extern ErrorCode AppEventGetLowBatteryStatus(IntPtr handle, out LowBatteryStatus status);
+
+ [DllImport(Libraries.AppCommon, EntryPoint = "app_event_get_language")]
+ internal static extern ErrorCode AppEventGetLanguage(IntPtr handle, out string lang);
+
+ [DllImport(Libraries.AppCommon, EntryPoint = "app_event_get_region_format")]
+ internal static extern ErrorCode AppEventGetRegionFormat(IntPtr handle, out string region);
+
+ [DllImport(Libraries.AppCommon, EntryPoint = "app_resource_manager_get")]
+ internal static extern ErrorCode AppResourceManagerGet(ResourceCategory category, string id, out string path);
+
+ [DllImport(Libraries.Application, EntryPoint = "app_resource_manager_get")]
+ internal static extern ErrorCode LegacyAppResourceManagerGet(ResourceCategory category, string id, out string path);
+
+ [DllImport(Libraries.AppCommon, EntryPoint = "app_event_get_device_orientation")]
+ internal static extern ErrorCode AppEventGetDeviceOrientation(IntPtr handle, out DeviceOrientation orientation);
+ }
+}
+
diff --git a/src/Tizen.Applications.Common/Interop/Interop.AppControl.cs b/src/Tizen.Applications.Common/Interop/Interop.AppControl.cs
new file mode 100755
index 0000000..c379698
--- /dev/null
+++ b/src/Tizen.Applications.Common/Interop/Interop.AppControl.cs
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+using Tizen.Applications;
+
+internal static partial class Interop
+{
+ internal static partial class AppControl
+ {
+ internal const int AppStartedStatus = 1;
+
+ internal delegate bool ExtraDataCallback(IntPtr handle, string key, IntPtr userData);
+ internal delegate bool AppMatchedCallback(IntPtr handle, string applicationId, IntPtr userData);
+ internal delegate void ReplyCallback(IntPtr request, IntPtr reply, int result, IntPtr userData);
+
+ internal enum ErrorCode
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None,
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+ OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
+ AppNotFound = -0x01100000 | 0x21,
+ KeyNotFound = Tizen.Internals.Errors.ErrorCode.KeyNotAvailable,
+ KeyRejected = Tizen.Internals.Errors.ErrorCode.KeyRejected,
+ InvalidDataType = -0x01100000 | 0x22,
+ LaunchRejected = -0x01100000 | 0x23,
+ PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied,
+ LaunchFailed = -0x01100000 | 0x24,
+ IoError = Tizen.Internals.Errors.ErrorCode.IoError,
+ TimedOut = Tizen.Internals.Errors.ErrorCode.TimedOut,
+ }
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_create")]
+ internal static extern ErrorCode Create(out SafeAppControlHandle handle);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_clone")]
+ internal static extern ErrorCode DangerousClone(out SafeAppControlHandle clone, IntPtr handle);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_get_app_id")]
+ internal static extern ErrorCode GetAppId(IntPtr app_control, out IntPtr app_id);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_get_operation")]
+ internal static extern ErrorCode GetOperation(SafeAppControlHandle handle, out string operation);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_set_operation")]
+ internal static extern ErrorCode SetOperation(SafeAppControlHandle handle, string operation);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_get_uri")]
+ internal static extern ErrorCode GetUri(SafeAppControlHandle handle, out string uri);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_set_uri")]
+ internal static extern ErrorCode SetUri(SafeAppControlHandle handle, string uri);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_get_mime")]
+ internal static extern ErrorCode GetMime(SafeAppControlHandle handle, out string mime);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_set_mime")]
+ internal static extern ErrorCode SetMime(SafeAppControlHandle handle, string mime);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_get_category")]
+ internal static extern ErrorCode GetCategory(SafeAppControlHandle handle, out string category);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_set_category")]
+ internal static extern ErrorCode SetCategory(SafeAppControlHandle handle, string category);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_get_app_id")]
+ internal static extern ErrorCode GetAppId(SafeAppControlHandle handle, out string appId);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_set_app_id")]
+ internal static extern ErrorCode SetAppId(SafeAppControlHandle handle, string appId);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_set_launch_mode")]
+ internal static extern ErrorCode SetLaunchMode(SafeAppControlHandle handle, int mode);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_get_launch_mode")]
+ internal static extern ErrorCode GetLaunchMode(SafeAppControlHandle handle, out int mode);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_get_caller")]
+ internal static extern ErrorCode GetCaller(SafeAppControlHandle handle, out string caller);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_is_reply_requested")]
+ internal static extern ErrorCode IsReplyRequested(SafeAppControlHandle handle, out bool requested);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_add_extra_data")]
+ internal static extern ErrorCode AddExtraData(SafeAppControlHandle handle, string key, string value);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_remove_extra_data")]
+ internal static extern ErrorCode RemoveExtraData(SafeAppControlHandle handle, string key);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_get_extra_data")]
+ internal static extern ErrorCode GetExtraData(SafeAppControlHandle handle, string key, out string value);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_add_extra_data_array")]
+ internal static extern ErrorCode AddExtraDataArray(SafeAppControlHandle handle, string key, string[] value, int length);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_get_extra_data_array")]
+ internal static extern ErrorCode GetExtraDataArray(SafeAppControlHandle handle, string key, out IntPtr value, out int length);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_is_extra_data_array")]
+ internal static extern ErrorCode IsExtraDataArray(SafeAppControlHandle handle, string key, out bool array);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_destroy")]
+ internal static extern ErrorCode DangerousDestroy(IntPtr handle);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_foreach_extra_data")]
+ internal static extern ErrorCode ForeachExtraData(SafeAppControlHandle handle, ExtraDataCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_foreach_app_matched")]
+ internal static extern ErrorCode ForeachAppMatched(SafeAppControlHandle handle, AppMatchedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_send_launch_request")]
+ internal static extern ErrorCode SendLaunchRequest(SafeAppControlHandle handle, ReplyCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_send_terminate_request")]
+ internal static extern ErrorCode SendTerminateRequest(SafeAppControlHandle handle);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_reply_to_launch_request")]
+ internal static extern ErrorCode ReplyToLaunchRequest(SafeAppControlHandle reply, SafeAppControlHandle request, int result);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_enable_app_started_result_event")]
+ internal static extern ErrorCode EnableAppStartedResultEvent(SafeAppControlHandle handle);
+ }
+}
diff --git a/src/Tizen.Applications.Common/Interop/Interop.ApplicationManager.cs b/src/Tizen.Applications.Common/Interop/Interop.ApplicationManager.cs
new file mode 100755
index 0000000..2b52a32
--- /dev/null
+++ b/src/Tizen.Applications.Common/Interop/Interop.ApplicationManager.cs
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class ApplicationManager
+ {
+ internal enum ErrorCode
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None,
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+ OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
+ IoError = Tizen.Internals.Errors.ErrorCode.IoError,
+ NoSuchApp = -0x01110000 | 0x01,
+ DbFailed = -0x01110000 | 0x03,
+ InvalidPackage = -0x01110000 | 0x04,
+ AppNoRunning = -0x01110000 | 0x05,
+ RequestFailed = -0x01110000 | 0x06,
+ PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied
+ }
+
+ internal enum AppContextEvent
+ {
+ Launched = 0,
+ Terminated = 1
+ }
+
+ internal enum AppManagerEventStatusType
+ {
+ All = 0x00,
+ Enable = 0x01,
+ Disable = 0x02
+ }
+
+ internal enum AppManagerEventType
+ {
+ Enable = 0,
+ Disable = 1
+ }
+
+ internal enum AppManagerEventState
+ {
+ Started = 0,
+ Completed = 1,
+ Failed = 2
+ }
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void AppManagerEventCallback(string appType, string appId, AppManagerEventType eventType, AppManagerEventState eventState, IntPtr eventHandle, IntPtr userData);
+ //void(* app_manager_event_cb)(const char *type, const char *app_id, app_manager_event_type_e event_type, app_manager_event_state_e event_state, app_manager_event_h handle, void *user_data)
+
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void AppManagerAppContextEventCallback(IntPtr handle, AppContextEvent state, IntPtr userData);
+ //void(* app_manager_app_context_event_cb)(app_context_h app_context, app_context_event_e event, void *user_data)
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool AppManagerAppInfoCallback(IntPtr handle, IntPtr userData);
+ //bool(* app_manager_app_info_cb )(app_info_h app_info, void *user_data)
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool AppManagerAppContextCallback(IntPtr handle, IntPtr userData);
+ //bool(* app_manager_app_context_cb)(app_context_h app_context, void *user_data)
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool AppInfoFilterCallback(IntPtr handle, IntPtr userData);
+ //bool(* app_info_filter_cb )(app_info_h app_info, void *user_data)
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool AppInfoMetadataCallback(string key, string value, IntPtr userData);
+ //bool(* app_info_metadata_cb )(const char *metadata_key, const char *metadata_value, void *user_data)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_manager_set_app_context_event_cb")]
+ internal static extern ErrorCode AppManagerSetAppContextEvent(AppManagerAppContextEventCallback callback, IntPtr userData);
+ //int app_manager_set_app_context_event_cb( app_manager_app_context_event_cb callback, void * user_data)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_manager_unset_app_context_event_cb")]
+ internal static extern void AppManagerUnSetAppContextEvent();
+ //void app_manager_unset_app_context_event_cb (void);
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_manager_foreach_running_app_context")]
+ internal static extern ErrorCode AppManagerForeachRunningAppContext(AppManagerAppContextCallback callback, IntPtr userData);
+ //int app_manager_foreach_running_app_context(app_manager_app_context_cb callback, void *user_data)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_manager_foreach_app_context")]
+ internal static extern ErrorCode AppManagerForeachAppContext(AppManagerAppContextCallback callback, IntPtr userData);
+ //int app_manager_foreach_app_context(app_manager_app_context_cb callback, void *user_data)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_manager_get_app_context")]
+ internal static extern ErrorCode AppManagerGetAppContext(string applicationId, out IntPtr handle);
+ //int app_manager_get_app_context(const char* app_id, app_context_h *app_context);
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_manager_get_app_id")]
+ internal static extern ErrorCode AppManagerGetAppId(int processId, out string applicationId);
+ //int app_manager_get_app_id (pid_t pid, char **appid);
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_manager_is_running")]
+ internal static extern ErrorCode AppManagerIsRunning(string applicationId, out bool running);
+ //int app_manager_is_running (const char *appid, bool *running);
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_manager_resume_app")]
+ internal static extern ErrorCode AppManagerResumeApp(IntPtr handle);
+ //int app_manager_resume_app (app_context_h handle);
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_manager_request_terminate_bg_app")]
+ internal static extern ErrorCode AppManagerRequestTerminateBgApp(IntPtr handle);
+ //int app_manager_request_terminate_bg_app (app_context_h handle);
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_manager_foreach_app_info")]
+ internal static extern ErrorCode AppManagerForeachAppInfo(AppManagerAppInfoCallback callback, IntPtr userData);
+ //int app_manager_foreach_app_info(app_manager_app_info_cb callback, void *user_data)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_manager_get_app_info")]
+ internal static extern ErrorCode AppManagerGetAppInfo(string applicationId, out IntPtr handle);
+ //int app_manager_get_app_info(const char * app_id, app_info_h * app_info)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_manager_get_shared_data_path")]
+ internal static extern ErrorCode AppManagerGetSharedDataPath(string applicationId, out string path);
+ //int app_manager_get_shared_data_path (const char *appid, char **path);
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_manager_get_shared_resource_path")]
+ internal static extern ErrorCode AppManagerGetSharedResourcePath(string applicationId, out string path);
+ //int app_manager_get_shared_resource_path (const char *appid, char **path);
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_manager_get_shared_trusted_path")]
+ internal static extern ErrorCode AppManagerGetSharedTrustedPath(string applicationId, out string path);
+ //int app_manager_get_shared_trusted_path (const char *appid, char **path);
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_manager_get_external_shared_data_path")]
+ internal static extern ErrorCode AppManagerGetExternalSharedDataPath(string applicationId, out string path);
+ //int app_manager_get_external_shared_data_path (const char *appid, char **path);
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_manager_event_create")]
+ internal static extern ErrorCode AppManagerEventCreate(out IntPtr handle);
+ //int app_manager_event_create (app_manager_event_h *handle);
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_manager_event_set_status")]
+ internal static extern ErrorCode AppManagerEventSetStatus(IntPtr handle, AppManagerEventStatusType statusType);
+ //int app_manager_event_set_status (app_manager_event_h handle, int status_type);
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_manager_set_event_cb")]
+ internal static extern ErrorCode AppManagerSetEventCallback(IntPtr handle, AppManagerEventCallback callback, IntPtr userData);
+ //int app_manager_set_event_cb (app_manager_event_h handle, app_manager_event_cb callback, void *user_data);
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_manager_unset_event_cb")]
+ internal static extern ErrorCode AppManagerUnSetEventCallback(IntPtr handle);
+ //int app_manager_unset_event_cb (app_manager_event_h handle);
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_manager_event_destroy")]
+ internal static extern ErrorCode AppManagerEventDestroy(IntPtr handle);
+ //int app_manager_event_destroy (app_manager_event_h handle);
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_context_destroy")]
+ internal static extern ErrorCode AppContextDestroy(IntPtr handle);
+ //int app_context_destroy(app_context_h app_context)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_context_get_app_id")]
+ internal static extern ErrorCode AppContextGetAppId(IntPtr handle, out string applicationId);
+ //int app_context_get_app_id(app_context_h app_context, char **app_id)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_context_get_package_id")]
+ internal static extern ErrorCode AppContextGetPackageId(IntPtr handle, out string packageId);
+ //int app_context_get_package_id(app_context_h app_context, char **package_id)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_context_get_pid")]
+ internal static extern ErrorCode AppContextGetPid(IntPtr handle, out int processId);
+ //int app_context_get_pid (app_context_h app_context, pid_t *pid)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_context_get_app_state")]
+ internal static extern ErrorCode AppContextGetAppState(IntPtr handle, out int state);
+ //int app_context_get_app_state (app_context_h app_context, app_state_e *state)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_context_is_terminated")]
+ internal static extern ErrorCode AppContextIsTerminated(IntPtr handle, out bool terminated);
+ //int app_context_is_terminated (app_context_h app_context, bool *terminated);
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_context_is_equal")]
+ internal static extern ErrorCode AppContextIsEqual(IntPtr first, IntPtr second, out bool equal);
+ //int app_context_is_equal (app_context_h lhs, app_context_h rhs, bool *equal);
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_context_is_sub_app")]
+ internal static extern ErrorCode AppContextIsSubApp(IntPtr handle, out bool is_sub_app);
+ //int app_context_is_sub_app (app_context_h app_context, bool *is_sub_app);
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_context_clone")]
+ internal static extern ErrorCode AppContextClone(out IntPtr destination, IntPtr source);
+ //int app_context_clone (app_context_h *clone, app_context_h app_context);
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_info_create")]
+ internal static extern ErrorCode AppInfoCreate(string applicationId, out IntPtr handle);
+ //int app_info_create (const char *app_id, app_info_h *app_info);
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_info_destroy")]
+ internal static extern ErrorCode AppInfoDestroy(IntPtr handle);
+ //int app_info_destroy (app_info_h app_info);
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_info_get_app_id")]
+ internal static extern ErrorCode AppInfoGetAppId(IntPtr handle, out string applicationId);
+ //int app_info_get_app_id (app_info_h app_info, char **app_id);
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_info_get_exec")]
+ internal static extern ErrorCode AppInfoGetExec(IntPtr handle, out string exec);
+ //int app_info_get_exec (app_info_h app_info, char **exec);
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_info_get_label")]
+ internal static extern ErrorCode AppInfoGetLabel(IntPtr handle, out string label);
+ //int app_info_get_label (app_info_h app_info, char **label);
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_info_get_localed_label")]
+ internal static extern ErrorCode AppInfoGetLocaledLabel(string applicationId, string locale, out string label);
+ //int app_info_get_localed_label (const char *app_id, const char *locale, char **label);
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_info_get_icon")]
+ internal static extern ErrorCode AppInfoGetIcon(IntPtr handle, out string path);
+ //int app_info_get_icon (app_info_h app_info, char **path)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_info_get_package")]
+ internal static extern ErrorCode AppInfoGetPackage(IntPtr handle, out string package);
+ //int app_info_get_package (app_info_h app_info, char **package)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_info_get_type")]
+ internal static extern ErrorCode AppInfoGetType(IntPtr handle, out string type);
+ //int app_info_get_type (app_info_h app_info, char **type)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_info_foreach_metadata")]
+ internal static extern ErrorCode AppInfoForeachMetadata(IntPtr handle, AppInfoMetadataCallback callback, IntPtr userData);
+ //int app_info_foreach_metadata(app_info_h app_info, app_info_metadata_cb callback, void *user_data)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_info_is_nodisplay")]
+ internal static extern ErrorCode AppInfoIsNodisplay(IntPtr handle, out bool noDisplay);
+ //int app_info_is_nodisplay (app_info_h app_info, bool *nodisplay)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_info_is_equal")]
+ internal static extern ErrorCode AppInfoIsEqual(IntPtr first, IntPtr second, out bool equal);
+ //int app_info_is_equal (app_info_h lhs, app_info_h rhs, bool *equal)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_info_is_enabled")]
+ internal static extern ErrorCode AppInfoIsEnabled(IntPtr handle, out bool enabled);
+ //int app_info_is_enabled (app_info_h app_info, bool *enabled)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_info_is_onboot")]
+ internal static extern ErrorCode AppInfoIsOnBoot(IntPtr handle, out bool onBoot);
+ //int app_info_is_onboot (app_info_h app_info, bool *onboot)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_info_is_preload")]
+ internal static extern ErrorCode AppInfoIsPreLoad(IntPtr handle, out bool preLoaded);
+ //int app_info_is_preload (app_info_h app_info, bool *preload)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_info_clone")]
+ internal static extern ErrorCode AppInfoClone(out IntPtr destination, IntPtr source);
+ //int app_info_clone(app_info_h * clone, app_info_h app_info)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_info_filter_create")]
+ internal static extern ErrorCode AppInfoFilterCreate(out IntPtr handle);
+ //int app_info_filter_create(app_info_filter_h * handle)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_info_filter_destroy")]
+ internal static extern ErrorCode AppInfoFilterDestroy(IntPtr handle);
+ //int app_info_filter_destroy(app_info_filter_h handle)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_info_filter_add_bool")]
+ internal static extern ErrorCode AppInfoFilterAddBool(IntPtr handle, string property, bool value);
+ //int app_info_filter_add_bool(app_info_filter_h handle, const char *property, const bool value)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_info_filter_add_string")]
+ internal static extern ErrorCode AppInfoFilterAddString(IntPtr handle, string property, string value);
+ //int app_info_filter_add_string(app_info_filter_h handle, const char *property, const char *value)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_info_filter_count_appinfo")]
+ internal static extern ErrorCode AppInfoFilterCountAppinfo(IntPtr handle, out int count);
+ //int app_info_filter_count_appinfo(app_info_filter_h handle, int *count)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_info_filter_foreach_appinfo")]
+ internal static extern ErrorCode AppInfoFilterForeachAppinfo(IntPtr handle, AppInfoFilterCallback callback, IntPtr userData);
+ //int app_info_filter_foreach_appinfo(app_info_filter_h handle, app_info_filter_cb callback, void * user_data)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_info_metadata_filter_create")]
+ internal static extern ErrorCode AppInfoMetadataFilterCreate(out IntPtr handle);
+ //int app_info_metadata_filter_create (app_info_metadata_filter_h *handle)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_info_metadata_filter_destroy")]
+ internal static extern ErrorCode AppInfoMetadataFilterDestroy(IntPtr handle);
+ //int app_info_metadata_filter_destroy (app_info_metadata_filter_h handle)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_info_metadata_filter_add")]
+ internal static extern ErrorCode AppInfoMetadataFilterAdd(IntPtr handle, string key, string value);
+ //int app_info_metadata_filter_add (app_info_metadata_filter_h handle, const char *key, const char *value)
+
+ [DllImport(Libraries.AppManager, EntryPoint = "app_info_metadata_filter_foreach")]
+ internal static extern ErrorCode AppInfoMetadataFilterForeach(IntPtr handle, AppInfoFilterCallback callback, IntPtr userData);
+ //int app_info_metadata_filter_foreach (app_info_metadata_filter_h handle, app_info_filter_cb callback, void *user_data)
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct RuaRec
+ {
+ internal int id;
+ internal IntPtr pkgName;
+ internal IntPtr appPath;
+ internal IntPtr arg;
+ internal IntPtr launchTime;
+ internal IntPtr instanceId;
+ internal IntPtr instanceName;
+ internal IntPtr icon;
+ internal IntPtr uri;
+ };
+
+ [DllImport(Libraries.Rua, EntryPoint = "rua_history_get_rec")]
+ internal static extern ErrorCode RuaHistoryGetRecord(out RuaRec record, IntPtr table, int nRows, int nCols, int row);
+ //int rua_history_get_rec(struct rua_rec *rec, char** table, int nrows, int ncols, int row);
+
+ [DllImport(Libraries.Rua, EntryPoint = "rua_history_load_db")]
+ internal static extern ErrorCode RuaHistoryLoadDb(out IntPtr table, out int nRows, out int nCols);
+ //int rua_history_load_db(char*** table, int *nrows, int *ncols);
+
+ [DllImport(Libraries.Rua, EntryPoint = "rua_history_unload_db")]
+ internal static extern ErrorCode RuaHistoryUnLoadDb(ref IntPtr table);
+ //int rua_history_unload_db(char*** table);
+
+ [DllImport(Libraries.Rua, EntryPoint = "rua_delete_history_with_pkgname")]
+ internal static extern ErrorCode RuaDeleteHistoryWithPkgname(string pkgName);
+ //int rua_delete_history_with_pkgname(char* pkg_name);
+
+ [DllImport(Libraries.Rua, EntryPoint = "rua_delete_history_with_apppath")]
+ internal static extern ErrorCode RuaDeleteHistoryWithApppath(string appPath);
+ //int rua_delete_history_with_apppath(char* app_path);
+
+ [DllImport(Libraries.Rua, EntryPoint = "rua_clear_history")]
+ internal static extern ErrorCode RuaClearHistory();
+ //int rua_clear_history(void);
+ }
+}
diff --git a/src/Tizen.Applications.Common/Interop/Interop.Bundle.cs b/src/Tizen.Applications.Common/Interop/Interop.Bundle.cs
new file mode 100755
index 0000000..65c314a
--- /dev/null
+++ b/src/Tizen.Applications.Common/Interop/Interop.Bundle.cs
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+using Tizen.Applications;
+
+internal static partial class Interop
+{
+ internal static partial class Bundle
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void Iterator(string key, int type, IntPtr keyval, IntPtr userData);
+
+ [DllImport(Libraries.Bundle, EntryPoint = "bundle_create")]
+ internal static extern SafeBundleHandle Create();
+
+ [DllImport(Libraries.Bundle, EntryPoint = "bundle_free")]
+ internal static extern int DangerousFree(IntPtr handle);
+
+ [DllImport(Libraries.Bundle, EntryPoint = "bundle_del")]
+ internal static extern int RemoveItem(SafeBundleHandle handle, string key);
+
+ [DllImport(Libraries.Bundle, EntryPoint = "bundle_add_str")]
+ internal static extern int AddString(SafeBundleHandle handle, string key, string value);
+
+ [DllImport(Libraries.Bundle, EntryPoint = "bundle_get_type")]
+ internal static extern int GetType(SafeBundleHandle handle, string key);
+
+ [DllImport(Libraries.Bundle, EntryPoint = "bundle_get_str")]
+ internal static extern int GetString(SafeBundleHandle handle, string key, out IntPtr value);
+
+ [DllImport(Libraries.Bundle, EntryPoint = "bundle_add_byte")]
+ internal static extern unsafe int AddByte(SafeBundleHandle handle, string key, byte* value, int size);
+
+ [DllImport(Libraries.Bundle, EntryPoint = "bundle_get_byte")]
+ internal static extern int GetByte(SafeBundleHandle handle, string key, out IntPtr value, out int size);
+
+ [DllImport(Libraries.Bundle, EntryPoint = "bundle_add_str_array")]
+ internal static extern int AddStringArray(SafeBundleHandle handle, string key, string[] value, int size);
+
+ [DllImport(Libraries.Bundle, EntryPoint = "bundle_get_str_array")]
+ internal static extern IntPtr GetStringArray(SafeBundleHandle handle, string key, out int size);
+
+ [DllImport(Libraries.Bundle, EntryPoint = "bundle_foreach")]
+ internal static extern void Foreach(SafeBundleHandle handle, Iterator iterator, IntPtr userData);
+
+ [DllImport(Libraries.Bundle, EntryPoint = "bundle_encode")]
+ internal static extern void BundleEncode(SafeBundleHandle handle, out string str, out int len);
+
+ [DllImport(Libraries.Bundle, EntryPoint = "bundle_decode")]
+ internal static extern SafeBundleHandle BundleDecode(string bundleRaw, int len);
+
+ [DllImport(Libraries.Bundle, EntryPoint = "bundle_dup")]
+ internal static extern SafeBundleHandle DangerousClone(IntPtr handle);
+
+ internal static class UnsafeCode
+ {
+ internal static unsafe int AddItem(SafeBundleHandle handle, string key, byte[] value, int offset, int count)
+ {
+ fixed (byte* pointer = value)
+ {
+ return AddByte(handle, key, pointer + offset, count);
+ }
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Common/Interop/Interop.Glib.cs b/src/Tizen.Applications.Common/Interop/Interop.Glib.cs
new file mode 100755
index 0000000..576a6e2
--- /dev/null
+++ b/src/Tizen.Applications.Common/Interop/Interop.Glib.cs
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Glib
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool GSourceFunc(IntPtr userData);
+
+ [DllImport(Libraries.Glib, EntryPoint = "g_idle_add", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern uint IdleAdd(GSourceFunc d, IntPtr data);
+ }
+}
diff --git a/src/Tizen.Applications.Common/Interop/Interop.Libc.cs b/src/Tizen.Applications.Common/Interop/Interop.Libc.cs
new file mode 100755
index 0000000..825599e
--- /dev/null
+++ b/src/Tizen.Applications.Common/Interop/Interop.Libc.cs
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Libc
+ {
+ [DllImport(Libraries.Libc, EntryPoint = "free", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int Free(IntPtr ptr);
+ }
+}
diff --git a/src/Tizen.Applications.Common/Interop/Interop.Libraries.cs b/src/Tizen.Applications.Common/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..8a417c6
--- /dev/null
+++ b/src/Tizen.Applications.Common/Interop/Interop.Libraries.cs
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string AppCommon = "libcapi-appfw-app-common.so.0";
+ public const string AppControl = "libcapi-appfw-app-control.so.0";
+ public const string AppEvent = "libcapi-appfw-event.so.0";
+ public const string AppManager = "libcapi-appfw-app-manager.so.0";
+ public const string Bundle = "libbundle.so.0";
+ public const string Rua = "librua.so.0";
+ public const string Glib = "libglib-2.0.so.0";
+ public const string Libc = "libc.so.6";
+ public const string Application = "libcapi-appfw-application.so.0";
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications.Common.csproj b/src/Tizen.Applications.Common/Tizen.Applications.Common.csproj
new file mode 100644
index 0000000..8f0f722
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications.Common.csproj
@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="../Tizen/Tizen.csproj" />
+ <ProjectReference Include="../Tizen.Log/Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Applications.Common/Tizen.Applications.CoreBackend/DefaultCoreBackend.cs b/src/Tizen.Applications.Common/Tizen.Applications.CoreBackend/DefaultCoreBackend.cs
new file mode 100755
index 0000000..aabbbeb
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications.CoreBackend/DefaultCoreBackend.cs
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+using Tizen.Internals.Errors;
+
+namespace Tizen.Applications.CoreBackend
+{
+ /// <summary>
+ /// Abstract class to provide default event handlers for apps.
+ /// </summary>
+ public abstract class DefaultCoreBackend : ICoreBackend
+ {
+ /// <summary>
+ /// Low level event types
+ /// </summary>
+ public enum AppEventType
+ {
+ LowMemory = 0,
+ LowBattery,
+ LanguageChanged,
+ DeviceOrientationChanged,
+ RegionFormatChanged,
+ SuspendedStateChanged
+ }
+
+ protected static readonly string LogTag = typeof(DefaultCoreBackend).Namespace;
+
+ protected IDictionary<EventType, object> Handlers = new Dictionary<EventType, object>();
+
+ public DefaultCoreBackend()
+ {
+ }
+
+ ~DefaultCoreBackend()
+ {
+ Dispose(false);
+ }
+
+ public void AddEventHandler(EventType evType, Action handler)
+ {
+ Handlers.Add(evType, handler);
+ }
+
+ public void AddEventHandler<TEventArgs>(EventType evType, Action<TEventArgs> handler) where TEventArgs : EventArgs
+ {
+ Handlers.Add(evType, handler);
+ }
+
+ public virtual void Run(string[] args)
+ {
+ TizenSynchronizationContext.Initialize();
+ }
+
+ public abstract void Exit();
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected abstract void Dispose(bool disposing);
+
+ protected virtual void OnLowMemoryNative(IntPtr infoHandle, IntPtr data)
+ {
+ LowMemoryStatus status = LowMemoryStatus.None;
+ ErrorCode err = Interop.AppCommon.AppEventGetLowMemoryStatus(infoHandle, out status);
+ if (err != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get memory status. Err = " + err);
+ }
+ if (Handlers.ContainsKey(EventType.LowMemory))
+ {
+ var handler = Handlers[EventType.LowMemory] as Action<LowMemoryEventArgs>;
+ handler?.Invoke(new LowMemoryEventArgs(status));
+ }
+ }
+
+ protected virtual void OnLowBatteryNative(IntPtr infoHandle, IntPtr data)
+ {
+ LowBatteryStatus status = LowBatteryStatus.None;
+ ErrorCode err = Interop.AppCommon.AppEventGetLowBatteryStatus(infoHandle, out status);
+ if (err != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get battery status. Err = " + err);
+ }
+ if (Handlers.ContainsKey(EventType.LowBattery))
+ {
+ var handler = Handlers[EventType.LowBattery] as Action<LowBatteryEventArgs>;
+ handler?.Invoke(new LowBatteryEventArgs(status));
+ }
+ }
+
+ protected virtual void OnLocaleChangedNative(IntPtr infoHandle, IntPtr data)
+ {
+ string lang;
+ ErrorCode err = Interop.AppCommon.AppEventGetLanguage(infoHandle, out lang);
+ if (err != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get changed language. Err = " + err);
+ }
+ if (Handlers.ContainsKey(EventType.LocaleChanged))
+ {
+ var handler = Handlers[EventType.LocaleChanged] as Action<LocaleChangedEventArgs>;
+ handler?.Invoke(new LocaleChangedEventArgs(lang));
+ }
+ }
+
+ protected virtual void OnRegionChangedNative(IntPtr infoHandle, IntPtr data)
+ {
+ string region;
+ ErrorCode err = Interop.AppCommon.AppEventGetRegionFormat(infoHandle, out region);
+ if (err != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get changed region format. Err = " + err);
+ }
+ if (Handlers.ContainsKey(EventType.RegionFormatChanged))
+ {
+ var handler = Handlers[EventType.RegionFormatChanged] as Action<RegionFormatChangedEventArgs>;
+ handler?.Invoke(new RegionFormatChangedEventArgs(region));
+ }
+ }
+
+ protected virtual void OnDeviceOrientationChangedNative(IntPtr infoHandle, IntPtr data)
+ {
+ DeviceOrientation orientation;
+ ErrorCode err = Interop.AppCommon.AppEventGetDeviceOrientation(infoHandle, out orientation);
+ if (err != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get deivce orientation. Err = " + err);
+ }
+ if (Handlers.ContainsKey(EventType.DeviceOrientationChanged))
+ {
+ var handler = Handlers[EventType.DeviceOrientationChanged] as Action<DeviceOrientationEventArgs>;
+ handler?.Invoke(new DeviceOrientationEventArgs(orientation));
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications.CoreBackend/EventType.cs b/src/Tizen.Applications.Common/Tizen.Applications.CoreBackend/EventType.cs
new file mode 100755
index 0000000..e24cddf
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications.CoreBackend/EventType.cs
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+namespace Tizen.Applications.CoreBackend
+{
+ /// <summary>
+ /// Class that represents the type of event for backends. This class can be converted from string type.
+ /// </summary>
+ public class EventType
+ {
+ /// <summary>
+ /// Pre-defined event type. "PreCreated"
+ /// </summary>
+ public static readonly EventType PreCreated = "PreCreated";
+
+ /// <summary>
+ /// Pre-defined event type. "Created"
+ /// </summary>
+ public static readonly EventType Created = "Created";
+
+ /// <summary>
+ /// Pre-defined event type. "Terminated"
+ /// </summary>
+ public static readonly EventType Terminated = "Terminated";
+
+ /// <summary>
+ /// Pre-defined event type. "AppControlReceived"
+ /// </summary>
+ public static readonly EventType AppControlReceived = "AppControlReceived";
+
+ /// <summary>
+ /// Pre-defined event type. "Resumed"
+ /// </summary>
+ public static readonly EventType Resumed = "Resumed";
+
+ /// <summary>
+ /// Pre-defined event type. "Paused"
+ /// </summary>
+ public static readonly EventType Paused = "Paused";
+
+ /// <summary>
+ /// Pre-defined event type. "LowMemory"
+ /// </summary>
+ public static readonly EventType LowMemory = "LowMemory";
+
+ /// <summary>
+ /// Pre-defined event type. "LowBattery"
+ /// </summary>
+ public static readonly EventType LowBattery = "LowBattery";
+
+ /// <summary>
+ /// Pre-defined event type. "LocaleChanged"
+ /// </summary>
+ public static readonly EventType LocaleChanged = "LocaleChanged";
+
+ /// <summary>
+ /// Pre-defined event type. "RegionFormatChanged"
+ /// </summary>
+ public static readonly EventType RegionFormatChanged = "RegionFormatChanged";
+
+ /// <summary>
+ /// Pre-defined event type. "DeviceOrientationChanged"
+ /// </summary>
+ public static readonly EventType DeviceOrientationChanged = "DeviceOrientationChanged";
+
+ private string _typeName;
+
+ /// <summary>
+ /// Initializes the EventType class.
+ /// </summary>
+ /// <param name="name">The name of event type.</param>
+ public EventType(string name)
+ {
+ _typeName = name;
+ }
+
+ /// <summary>
+ /// Returns the name of event type.
+ /// </summary>
+ public override string ToString()
+ {
+ return _typeName;
+ }
+
+ /// <summary>
+ /// Returns the hash code for event type string.
+ /// </summary>
+ public override int GetHashCode()
+ {
+ if (_typeName == null) return 0;
+ return _typeName.GetHashCode();
+ }
+
+ /// <summary>
+ /// Determines whether this instance and a specified object.
+ /// </summary>
+ public override bool Equals(object obj)
+ {
+ EventType other = obj as EventType;
+ return other != null && other._typeName == this._typeName;
+ }
+
+ /// <summary>
+ /// Converts a string to EventType instance.
+ /// </summary>
+ public static implicit operator EventType(string value)
+ {
+ return new EventType(value);
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications.CoreBackend/ICoreBackend.cs b/src/Tizen.Applications.Common/Tizen.Applications.CoreBackend/ICoreBackend.cs
new file mode 100755
index 0000000..0ba8be5
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications.CoreBackend/ICoreBackend.cs
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications.CoreBackend
+{
+ /// <summary>
+ /// Interface that represents the backend lifecycles.
+ /// </summary>
+ public interface ICoreBackend : IDisposable
+ {
+ /// <summary>
+ /// Adds an event handler.
+ /// </summary>
+ /// <param name="evType">The type of event.</param>
+ /// <param name="handler">The handler method without arguments.</param>
+ void AddEventHandler(EventType evType, Action handler);
+
+ /// <summary>
+ /// Adds an event handler.
+ /// </summary>
+ /// <typeparam name="TEventArgs">The EventArgs type used in arguments of the handler method.</typeparam>
+ /// <param name="evType">The type of event.</param>
+ /// <param name="handler">The handler method with a TEventArgs type argument.</param>
+ void AddEventHandler<TEventArgs>(EventType evType, Action<TEventArgs> handler) where TEventArgs : EventArgs;
+
+ /// <summary>
+ /// Runs the mainloop of backend.
+ /// </summary>
+ /// <param name="args"></param>
+ void Run(string[] args);
+
+ /// <summary>
+ /// Exits the mainloop of backend.
+ /// </summary>
+ void Exit();
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/AppControl.cs b/src/Tizen.Applications.Common/Tizen.Applications/AppControl.cs
new file mode 100755
index 0000000..1128f02
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/AppControl.cs
@@ -0,0 +1,1038 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Represents the control message to exchange between applications.
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// public class AppControlExample : UIApplication
+ /// {
+ /// /// ...
+ /// protected override void OnAppControlReceived(AppControlReceivedEventArgs e)
+ /// {
+ /// AppControl appControl = new AppControl();
+ /// appControl.ApplicationId = "org.tizen.calculator";
+ /// AppControl.SendLaunchRequest(appControl, (launchRequest, replyRequest, result) => {
+ /// // ...
+ /// });
+ /// }
+ /// }
+ /// </code>
+ /// </example>
+ public class AppControl
+ {
+ private const string LogTag = "Tizen.Applications";
+
+ private static Dictionary<int, Interop.AppControl.ReplyCallback> s_replyNativeCallbackMaps = new Dictionary<int, Interop.AppControl.ReplyCallback>();
+ private static int s_replyNativeCallbackId = 0;
+
+ private readonly SafeAppControlHandle _handle;
+
+ private string _operation = null;
+ private string _mime = null;
+ private string _uri = null;
+ private string _category = null;
+ private string _applicationId = null;
+ private ExtraDataCollection _extraData = null;
+
+ /// <summary>
+ /// Initializes the instance of the AppControl class.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">Thrown when failed to create AppControl handle.</exception>
+ public AppControl()
+ {
+ Interop.AppControl.ErrorCode err = Interop.AppControl.Create(out _handle);
+ if (err != Interop.AppControl.ErrorCode.None)
+ {
+ throw new InvalidOperationException("Failed to create the appcontrol handle. Err = " + err);
+ }
+ }
+
+ /// <summary>
+ /// Initializes the instance of the AppControl class with parameter.
+ /// </summary>
+ /// <param name="enableAppStartedResultEvent">The flag value to receive an additional launch result event on launch request.</param>
+ /// <exception cref="InvalidOperationException">Thrown when failed to create AppControl handle.</exception>
+ public AppControl(bool enableAppStartedResultEvent)
+ {
+ Interop.AppControl.ErrorCode err = Interop.AppControl.Create(out _handle);
+ if (err != Interop.AppControl.ErrorCode.None)
+ {
+ throw new InvalidOperationException("Failed to create the appcontrol handle. Err = " + err);
+ }
+
+ if (enableAppStartedResultEvent)
+ {
+ err = Interop.AppControl.EnableAppStartedResultEvent(_handle);
+ if (err != Interop.AppControl.ErrorCode.None)
+ {
+ throw new InvalidOperationException("Failed to set EnableAppStartedResultEvent");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Initializes the instance of the AppControl class with the SafeAppControlHandle.
+ /// </summary>
+ /// <param name="handle"></param>
+ public AppControl(SafeAppControlHandle handle)
+ {
+ if (handle == null)
+ {
+ throw new ArgumentNullException("handle");
+ }
+
+ Interop.AppControl.ErrorCode err = Interop.AppControl.DangerousClone(out _handle, handle.DangerousGetHandle());
+ if (err != Interop.AppControl.ErrorCode.None)
+ {
+ throw new InvalidOperationException("Failed to clone the appcontrol handle. Err = " + err);
+ }
+ }
+
+ private AppControl(IntPtr handle)
+ {
+ Interop.AppControl.ErrorCode err = Interop.AppControl.DangerousClone(out _handle, handle);
+ if (err != Interop.AppControl.ErrorCode.None)
+ {
+ throw new InvalidOperationException("Failed to clone the appcontrol handle. Err = " + err);
+ }
+ }
+
+ #region Public Properties
+
+ /// <summary>
+ /// Gets the SafeAppControlHandle instance.
+ /// </summary>
+ public SafeAppControlHandle SafeAppControlHandle
+ {
+ get
+ {
+ return _handle;
+ }
+ }
+
+ /// <summary>
+ /// Gets and sets the operation to be performed.
+ /// </summary>
+ /// <value>
+ /// The operation is the mandatory information for the launch request. If the operation is not specified,
+ /// AppControlOperations.Default is used for the launch request. If the operation is AppControlOperations.Default,
+ /// the package information is mandatory to explicitly launch the application.
+ /// (if the operation is null for setter, it clears the previous value.)
+ /// </value>
+ /// <example>
+ /// <code>
+ /// AppControl appControl = new AppControl();
+ /// appControl.Operation = AppControlOperations.Default;
+ /// Log.Debug(LogTag, "Operation: " + appControl.Operation);
+ /// </code>
+ /// </example>
+ public string Operation
+ {
+ get
+ {
+ if (String.IsNullOrEmpty(_operation))
+ {
+ Interop.AppControl.ErrorCode err = Interop.AppControl.GetOperation(_handle, out _operation);
+ if (err != Interop.AppControl.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get the operation from the appcontrol. Err = " + err);
+ }
+ }
+ return _operation;
+ }
+ set
+ {
+ Interop.AppControl.ErrorCode err = Interop.AppControl.SetOperation(_handle, value);
+ if (err == Interop.AppControl.ErrorCode.None)
+ {
+ _operation = value;
+ }
+ else
+ {
+ Log.Warn(LogTag, "Failed to set the operation to the appcontrol. Err = " + err);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets and sets the explicit MIME type of the data.
+ /// </summary>
+ /// <value>
+ /// (if the mime is null for setter, it clears the previous value.)
+ /// </value>
+ /// <example>
+ /// <code>
+ /// AppControl appControl = new AppControl();
+ /// appControl.Mime = "image/jpg";
+ /// Log.Debug(LogTag, "Mime: " + appControl.Mime);
+ /// </code>
+ /// </example>
+ public string Mime
+ {
+ get
+ {
+ if (String.IsNullOrEmpty(_mime))
+ {
+ Interop.AppControl.ErrorCode err = Interop.AppControl.GetMime(_handle, out _mime);
+ if (err != Interop.AppControl.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get the mime from the appcontrol. Err = " + err);
+ }
+ }
+ return _mime;
+ }
+ set
+ {
+ Interop.AppControl.ErrorCode err = Interop.AppControl.SetMime(_handle, value);
+ if (err == Interop.AppControl.ErrorCode.None)
+ {
+ _mime = value;
+ }
+ else
+ {
+ Log.Warn(LogTag, "Failed to set the mime to the appcontrol. Err = " + err);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets and sets the URI of the data.
+ /// </summary>
+ /// <value>
+ /// Since Tizen 2.4, if the parameter 'uri' is started with 'file://' and
+ /// it is a regular file in this application's data path which can be obtained
+ /// by property DataPath in ApplicationInfo class,
+ /// it will be shared to the callee application.
+ /// Framework will grant a temporary permission to the callee application for this file and
+ /// revoke it when the callee application is terminated.
+ /// The callee application can just read it.
+ /// (if the uri is null for setter, it clears the previous value.)
+ /// </value>
+ /// <example>
+ /// <code>
+ /// public class AppControlExample : UIApplication
+ /// {
+ /// ...
+ /// protected override void OnAppControlReceived(AppControlReceivedEventArgs e)
+ /// {
+ /// ...
+ /// AppControl appControl = new AppControl();
+ /// appContrl.Uri = this.ApplicationInfo.DataPath + "image.jpg";
+ /// Log.Debug(LogTag, "Set Uri: " + appControl.Uri);
+ /// }
+ /// }
+ /// </code>
+ /// </example>
+ public string Uri
+ {
+ get
+ {
+ if (String.IsNullOrEmpty(_uri))
+ {
+ Interop.AppControl.ErrorCode err = Interop.AppControl.GetUri(_handle, out _uri);
+ if (err != Interop.AppControl.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get the uri from the appcontrol. Err = " + err);
+ }
+ }
+ return _uri;
+ }
+ set
+ {
+ Interop.AppControl.ErrorCode err = Interop.AppControl.SetUri(_handle, value);
+ if (err == Interop.AppControl.ErrorCode.None)
+ {
+ _uri = value;
+ }
+ else
+ {
+ Log.Warn(LogTag, "Failed to set the uri to the appcontrol. Err = " + err);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets and sets the explicit category.
+ /// </summary>
+ /// <value>
+ /// (if the category is null for setter, it clears the previous value.)
+ /// </value>
+ public string Category
+ {
+ get
+ {
+ if (String.IsNullOrEmpty(_category))
+ {
+ Interop.AppControl.ErrorCode err = Interop.AppControl.GetCategory(_handle, out _category);
+ if (err != Interop.AppControl.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get the category from the appcontrol. Err = " + err);
+ }
+ }
+ return _category;
+ }
+ set
+ {
+ Interop.AppControl.ErrorCode err = Interop.AppControl.SetCategory(_handle, value);
+ if (err == Interop.AppControl.ErrorCode.None)
+ {
+ _category = value;
+ }
+ else
+ {
+ Log.Warn(LogTag, "Failed to set the category to the appcontrol. Err = " + err);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets and sets the application id to explicitly launch.
+ /// </summary>
+ /// <value>
+ /// (if the application id is null for setter, it clears the previous value.)
+ /// </value>
+ /// <example>
+ /// <code>
+ /// AppControl appControl = new AppControl();
+ /// appControl.ApplicationId = "org.tizen.calculator";
+ /// Log.Debug(LogTag, "ApplicationId: " + appControl.ApplicationId);
+ /// </code>
+ /// </example>
+ public string ApplicationId
+ {
+ get
+ {
+ if (String.IsNullOrEmpty(_applicationId))
+ {
+ Interop.AppControl.ErrorCode err = Interop.AppControl.GetAppId(_handle, out _applicationId);
+ if (err != Interop.AppControl.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get the application id from the AppControl. Err = " + err);
+ }
+ }
+ return _applicationId;
+ }
+ set
+ {
+ Interop.AppControl.ErrorCode err = Interop.AppControl.SetAppId(_handle, value);
+ if (err == Interop.AppControl.ErrorCode.None)
+ {
+ _applicationId = value;
+ }
+ else
+ {
+ Log.Warn(LogTag, "Failed to set the application id to the AppControl. Err = " + err);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets and sets the launch mode of the application.
+ /// </summary>
+ /// <value>
+ /// Although LaunchMode were set as AppControlLaunchMode.Group,
+ /// callee application would be launched as single mode
+ /// if the manifest file of callee application defined the launch mode as "single".
+ /// This property can just set the preference of caller application to launch an application.
+ /// Sub-applications which were launched as group mode always have own process.
+ /// Since Tizen 3.0, if launch mode not set in the caller app control,
+ /// this property returns AppControlLaunchMode.Single launch mode.
+ /// </value>
+ /// <example>
+ /// <code>
+ /// AppControl appControl = new AppControl();
+ /// appControl.LaunchMode = AppControlLaunchMode.Group;
+ /// </code>
+ /// </example>
+ public AppControlLaunchMode LaunchMode
+ {
+ get
+ {
+ int value = 0;
+ Interop.AppControl.ErrorCode err = Interop.AppControl.GetLaunchMode(_handle, out value);
+ if (err != Interop.AppControl.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get the LaunchMode from the AppControl. Err = " + err);
+ }
+ return (AppControlLaunchMode)value;
+ }
+ set
+ {
+ Interop.AppControl.ErrorCode err = Interop.AppControl.SetLaunchMode(_handle, (int)value);
+ if (err != Interop.AppControl.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to set the LaunchMode to the AppControl. Err = " + err);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the collection of the extra data.
+ /// </summary>
+ /// <value>
+ /// Extra data for communication between AppControls.
+ /// </value>
+ /// <example>
+ /// <code>
+ /// AppControl appControl = new AppControl();
+ /// appControl.ExtraData.Add("key", "value");
+ /// ...
+ /// </code>
+ /// </example>
+ public ExtraDataCollection ExtraData
+ {
+ get
+ {
+ if (_extraData == null)
+ _extraData = new ExtraDataCollection(_handle);
+ return _extraData;
+ }
+ }
+
+ #endregion // Public Properties
+
+ /// <summary>
+ /// Retrieves all applications that can be launched to handle the given app_control request.
+ /// </summary>
+ /// <param name="control">The AppControl</param>
+ /// <returns>ApplicationIds</returns>
+ /// <exception cref="InvalidOperationException">Thrown when failed because of invalid parameter</exception>
+ /// <example>
+ /// <code>
+ /// IEnumerable<string> applicationIds = AppControl.GetMatchedApplicationIds(control);
+ /// if (applicationIds != null)
+ /// {
+ /// foreach (string id in applicationIds)
+ /// {
+ /// // ...
+ /// }
+ /// }
+ /// </code>
+ /// </example>
+ public static IEnumerable<string> GetMatchedApplicationIds(AppControl control)
+ {
+ if (control == null)
+ {
+ throw new ArgumentNullException("control");
+ }
+
+ List<string> ids = new List<string>();
+ Interop.AppControl.AppMatchedCallback callback = (handle, applicationId, userData) =>
+ {
+ if (applicationId == null)
+ {
+ return false;
+ }
+
+ ids.Add(applicationId);
+ return true;
+ };
+
+ Interop.AppControl.ErrorCode err = Interop.AppControl.ForeachAppMatched(control._handle, callback, IntPtr.Zero);
+ if (err != Interop.AppControl.ErrorCode.None)
+ {
+ throw new InvalidOperationException("Failed to get matched application ids. err = " + err);
+ }
+
+ return ids;
+ }
+
+ /// <summary>
+ /// Sends the launch request.
+ /// </summary>
+ /// <remarks>
+ /// The operation is mandatory information for the launch request.
+ /// If the operation is not specified, AppControlOperations.Default is used by default.
+ /// If the operation is AppControlOperations.Default, the application ID is mandatory to explicitly launch the application. \n
+ /// Since Tizen 2.4, the launch request of the service application over out of packages is restricted by the platform.
+ /// Also, implicit launch requests are NOT delivered to service applications since 2.4.
+ /// To launch a service application, an explicit launch request with application ID given by property ApplicationId MUST be sent.
+ /// </remarks>
+ /// <param name="launchRequest">The AppControl</param>
+ /// <exception cref="ArgumentNullException">Thrown when failed because of a null arguament</exception>
+ /// <exception cref="InvalidOperationException">Thrown when failed because of invalid operation</exception>
+ /// <exception cref="TimeoutException">Thrown when failed because of timeout</exception>
+ /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ /// <example>
+ /// <code>
+ /// AppControl appControl = new AppControl();
+ /// appControl.ApplicationId = "org.tizen.calculator";
+ /// AppControl.SendLaunchRequest(appControl);
+ /// </code>
+ /// </example>
+ public static void SendLaunchRequest(AppControl launchRequest)
+ {
+ SendLaunchRequest(launchRequest, null);
+ }
+
+ /// <summary>
+ /// Sends the launch request.
+ /// </summary>
+ /// <remarks>
+ /// The operation is mandatory information for the launch request.
+ /// If the operation is not specified, AppControlOperations.Default is used by default.
+ /// If the operation is AppControlOperations.Default, the application ID is mandatory to explicitly launch the application. \n
+ /// Since Tizen 2.4, the launch request of the service application over out of packages is restricted by the platform.
+ /// Also, implicit launch requests are NOT delivered to service applications since 2.4.
+ /// To launch a service application, an explicit launch request with application ID given by property ApplicationId MUST be sent.
+ /// </remarks>
+ /// <param name="launchRequest">The AppControl</param>
+ /// <param name="replyAfterLaunching">The callback function to be called when the reply is delivered</param>
+ /// <exception cref="ArgumentException">Thrown when failed because of arguament is invalid</exception>
+ /// <exception cref="InvalidOperationException">Thrown when failed because of invalid operation</exception>
+ /// <exception cref="TimeoutException">Thrown when failed because of timeout</exception>
+ /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ /// <example>
+ /// <code>
+ /// AppControl appControl = new AppControl();
+ /// appControl.ApplicationId = "org.tizen.calculator";
+ /// AppControl.SendLaunchRequest(appControl, (launchRequest, replyRequest, result) => {
+ /// // ...
+ /// });
+ /// </code>
+ /// </example>
+ public static void SendLaunchRequest(AppControl launchRequest, AppControlReplyCallback replyAfterLaunching)
+ {
+ if (launchRequest == null)
+ {
+ throw new ArgumentNullException("launchRequest");
+ }
+
+ Interop.AppControl.ErrorCode err;
+
+ if (replyAfterLaunching != null)
+ {
+ int id = 0;
+ lock (s_replyNativeCallbackMaps)
+ {
+ id = s_replyNativeCallbackId++;
+ s_replyNativeCallbackMaps[id] = (launchRequestHandle, replyRequestHandle, result, userData) =>
+ {
+ if (replyAfterLaunching != null)
+ {
+ Log.Debug(LogTag, "Reply Callback is launched");
+ replyAfterLaunching(new AppControl(launchRequestHandle), new AppControl(replyRequestHandle), (AppControlReplyResult)result);
+ if (result != Interop.AppControl.AppStartedStatus)
+ {
+ lock (s_replyNativeCallbackMaps)
+ {
+ s_replyNativeCallbackMaps.Remove(id);
+ }
+ }
+ }
+ };
+ }
+ err = Interop.AppControl.SendLaunchRequest(launchRequest._handle, s_replyNativeCallbackMaps[id], IntPtr.Zero);
+ }
+ else
+ {
+ err = Interop.AppControl.SendLaunchRequest(launchRequest._handle, null, IntPtr.Zero);
+ }
+
+ if (err != Interop.AppControl.ErrorCode.None)
+ {
+ switch (err)
+ {
+ case Interop.AppControl.ErrorCode.InvalidParameter:
+ throw new ArgumentException("Invalid Arguments");
+ case Interop.AppControl.ErrorCode.TimedOut:
+ throw new TimeoutException("Timed out");
+ default:
+ throw new InvalidOperationException("Error = " + err);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Sends the terminate request to the application that is launched by AppControl.
+ /// </summary>
+ /// <remarks>
+ /// You are not allowed to terminate other general applications using this API.
+ /// This API can be used to terminate sub-applications which were launched as group mode by caller application.
+ /// Once callee application is being terminated by this API,
+ /// other applications which were launched by callee application as group mode will be terminated as well
+ /// </remarks>
+ /// <param name="terminateRequest">The AppControl</param>
+ /// <exception cref="ArgumentException">Thrown when failed because of arguament is invalid</exception>
+ /// <exception cref="InvalidOperationException">Thrown when failed because of invalid operation</exception>
+ /// <exception cref="TimeoutException">Thrown when failed because of timeout</exception>
+ /// <example>
+ /// <code>
+ /// AppControl terminateRequest = new AppControl();
+ /// terminateRequest.ApplicationId = "org.tizen.calculator";
+ /// AppControl.SendTerminateRequest(terminateRequest);
+ /// </code>
+ /// </example>
+ public static void SendTerminateRequest(AppControl terminateRequest)
+ {
+ if (terminateRequest == null)
+ {
+ throw new ArgumentNullException("terminateRequest");
+ }
+ Interop.AppControl.ErrorCode err;
+
+ err = Interop.AppControl.SendTerminateRequest(terminateRequest._handle);
+
+ if (err != Interop.AppControl.ErrorCode.None)
+ {
+ switch (err)
+ {
+ case Interop.AppControl.ErrorCode.InvalidParameter:
+ throw new ArgumentException("Invalid Arguments");
+ case Interop.AppControl.ErrorCode.TimedOut:
+ throw new TimeoutException("Timed out");
+ default:
+ throw new InvalidOperationException("Error = " + err);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Class for Extra Data
+ /// </summary>
+ public class ExtraDataCollection
+ {
+ private readonly SafeAppControlHandle _handle;
+
+ internal ExtraDataCollection(SafeAppControlHandle handle)
+ {
+ _handle = handle;
+ }
+
+ /// <summary>
+ /// Adds extra data.
+ /// </summary>
+ /// <remarks>
+ /// The function replaces any existing value for the given key.
+ /// </remarks>
+ /// <param name="key">The name of the extra data</param>
+ /// <param name="value">The value associated with the given key</param>
+ /// <exception cref="ArgumentNullException">Thrown when key or value is a zero-length string</exception>
+ /// <exception cref="ArgumentException">Thrown when the application tries to use the same key with system-defined key</exception>
+ /// <example>
+ /// <code>
+ /// AppControl appControl = new AppControl();
+ /// appControl.ExtraData.Add("myKey", "myValue");
+ /// </code>
+ /// </example>
+ public void Add(string key, string value)
+ {
+ if (string.IsNullOrEmpty(key))
+ {
+ throw new ArgumentNullException("key");
+ }
+ if (string.IsNullOrEmpty(value))
+ {
+ throw new ArgumentNullException("value");
+ }
+ Interop.AppControl.ErrorCode err = Interop.AppControl.AddExtraData(_handle, key, value);
+ if (err != Interop.AppControl.ErrorCode.None)
+ {
+ switch (err)
+ {
+ case Interop.AppControl.ErrorCode.InvalidParameter:
+ throw new ArgumentException("Invalid parameter: key or value is a zero-length string");
+ case Interop.AppControl.ErrorCode.KeyRejected:
+ throw new ArgumentException("Key is rejected: the key is system-defined key.");
+ default:
+ throw new InvalidOperationException("Error = " + err);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Adds extra data.
+ /// </summary>
+ /// <remarks>
+ /// The function replaces any existing value for the given key.
+ /// </remarks>
+ /// <param name="key">The name of the extra data</param>
+ /// <param name="value">The value associated with the given key</param>
+ /// <exception cref="ArgumentNullException">Thrown when key or value is a zero-length string</exception>
+ /// <exception cref="ArgumentException">Thrown when the application tries to use the same key with system-defined key</exception>
+ /// <example>
+ /// <code>
+ /// AppControl appControl = new AppControl();
+ /// string[] myValues = new string[] { "first", "second", "third" };
+ /// appControl.ExtraData.Add("myKey", myValues);
+ /// </code>
+ /// </example>
+ public void Add(string key, IEnumerable<string> value)
+ {
+ if (string.IsNullOrEmpty(key))
+ {
+ throw new ArgumentNullException("key");
+ }
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+ string[] valueArray = value.ToArray();
+ Interop.AppControl.ErrorCode err = Interop.AppControl.AddExtraDataArray(_handle, key, valueArray, valueArray.Length);
+ if (err != Interop.AppControl.ErrorCode.None)
+ {
+ switch (err)
+ {
+ case Interop.AppControl.ErrorCode.InvalidParameter:
+ throw new ArgumentException("Invalid parameter: key or value is a zero-length string");
+ case Interop.AppControl.ErrorCode.KeyRejected:
+ throw new ArgumentException("Key is rejected: the key is system-defined key.");
+ default:
+ throw new InvalidOperationException("Error = " + err);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the extra data.
+ /// </summary>
+ /// <typeparam name="T">Only string and IEnumerable&lt;string&gt;</typeparam>
+ /// <param name="key">The name of extra data</param>
+ /// <returns>The value associated with the given key</returns>
+ /// <exception cref="ArgumentNullException">Thrown when the key is invalid parameter</exception>
+ /// <exception cref="KeyNotFoundException">Thrown when the key is not found</exception>
+ /// <exception cref="ArgumentException">Thrown when the key is rejected</exception>
+ /// <example>
+ /// <code>
+ /// AppControl appControl = new AppControl();
+ /// string myValue = appControl.ExtraData.Get<string>("myKey");
+ /// </code>
+ /// </example>
+ public T Get<T>(string key)
+ {
+ object ret = Get(key);
+ return (T)ret;
+ }
+
+ /// <summary>
+ /// Gets the extra data.
+ /// </summary>
+ /// <param name="key">The name of extra data</param>
+ /// <returns>The value associated with the given key</returns>
+ /// <exception cref="ArgumentNullException">Thrown when the key is invalid parameter</exception>
+ /// <exception cref="KeyNotFoundException">Thrown when the key is not found</exception>
+ /// <exception cref="ArgumentException">Thrown when the key is rejected</exception>
+ /// <example>
+ /// <code>
+ /// AppControl appControl = new AppControl();
+ /// string myValue = appControl.ExtraData.Get("myKey") as string;
+ /// if (myValue != null)
+ /// {
+ /// // ...
+ /// }
+ /// </code>
+ /// </example>
+ public object Get(string key)
+ {
+ if (IsCollection(key))
+ {
+ return GetDataCollection(key);
+ }
+ else
+ {
+ return GetData(key);
+ }
+ }
+
+ /// <summary>
+ /// Gets all keys in extra data.
+ /// </summary>
+ /// <returns>The keys in the AppControl</returns>
+ /// <exception cref="InvalidOperationException">Thrown when invalid parameter</exception>
+ /// <example>
+ /// <code>
+ /// AppControl appControl = new AppControl();
+ /// IEnumerable<string> keys = appControl.GetKeys();
+ /// if (keys != null)
+ /// {
+ /// foreach (string key in keys)
+ /// {
+ /// // ...
+ /// }
+ /// }
+ /// </code>
+ /// </example>
+ public IEnumerable<string> GetKeys()
+ {
+ List<string> keys = new List<string>();
+ Interop.AppControl.ExtraDataCallback callback = (handle, key, userData) =>
+ {
+ if (key == null)
+ {
+ return false;
+ }
+
+ keys.Add(key);
+ return true;
+ };
+
+ Interop.AppControl.ErrorCode err = Interop.AppControl.ForeachExtraData(_handle, callback, IntPtr.Zero);
+ if (err != Interop.AppControl.ErrorCode.None)
+ {
+ throw new InvalidOperationException("Failed to get keys. err = " + err);
+ }
+
+ return keys;
+ }
+
+ /// <summary>
+ /// Tries getting the extra data.
+ /// </summary>
+ /// <param name="key">The name of extra data</param>
+ /// <param name="value">The value associated with the given key</param>
+ /// <returns>The result whether getting the value is done</returns>
+ /// <exception cref="ArgumentNullException">Thrown when the key is invalid parameter</exception>
+ /// <exception cref="KeyNotFoundException">Thrown when the key is not found</exception>
+ /// <exception cref="ArgumentException">Thrown when the key is rejected</exception>
+ /// <example>
+ /// <code>
+ /// AppControl appControl = new AppControl();
+ /// string myValue = string.Empty;
+ /// bool result = appControl.ExtraData.TryGet("myKey", out myValue);
+ /// if (result != null)
+ /// {
+ /// // ...
+ /// }
+ /// </code>
+ /// </example>
+ public bool TryGet(string key, out string value)
+ {
+ if (string.IsNullOrEmpty(key))
+ {
+ throw new ArgumentNullException("key");
+ }
+ Interop.AppControl.GetExtraData(_handle, key, out value);
+ if (value != null)
+ {
+ return true;
+ }
+ else
+ {
+ value = default(string);
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Tries getting the extra data.
+ /// </summary>
+ /// <param name="key">The name of extra data</param>
+ /// <param name="value">The value associated with the given key</param>
+ /// <returns>The result whether getting the value is done</returns>
+ /// <exception cref="ArgumentNullException">Thrown when the key is invalid parameter</exception>
+ /// <exception cref="KeyNotFoundException">Thrown when the key is not found</exception>
+ /// <exception cref="ArgumentException">Thrown when the key is rejected</exception>
+ /// <example>
+ /// <code>
+ /// AppControl appControl = new AppControl();
+ /// IEnumerable<string> myValue = null;
+ /// bool result = appControl.ExtraData.TryGet("myKey", out myValue);
+ /// if (result)
+ /// {
+ /// foreach (string value in myValue)
+ /// {
+ /// // ...
+ /// }
+ /// }
+ /// </code>
+ /// </example>
+ public bool TryGet(string key, out IEnumerable<string> value)
+ {
+ if (string.IsNullOrEmpty(key))
+ {
+ throw new ArgumentNullException("key");
+ }
+ IntPtr valuePtr = IntPtr.Zero;
+ int len = -1;
+ Interop.AppControl.ErrorCode err = Interop.AppControl.GetExtraDataArray(_handle, key, out valuePtr, out len);
+ if (err == Interop.AppControl.ErrorCode.None && valuePtr != IntPtr.Zero)
+ {
+ List<string> stringList = new List<string>();
+ for (int i = 0; i < len; ++i)
+ {
+ IntPtr charArr = Marshal.ReadIntPtr(valuePtr, IntPtr.Size * i);
+ stringList.Add(Marshal.PtrToStringAnsi(charArr));
+ Interop.Libc.Free(charArr);
+ }
+ Interop.Libc.Free(valuePtr);
+ value = stringList;
+ return true;
+ }
+ else
+ {
+ value = default(IEnumerable<string>);
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Removes the extra data.
+ /// </summary>
+ /// <param name="key">The name of the extra data</param>
+ /// <exception cref="ArgumentNullException">Thrown when the key is a zero-length string</exception>
+ /// <exception cref="KeyNotFoundException">Thrown when the key is not found</exception>
+ /// <exception cref="ArgumentException">Thrown when the key is rejected</exception>
+ /// <example>
+ /// <code>
+ /// AppControl appControl = new AppControl();
+ /// appControl.ExtraData.Remove("myKey");
+ /// </code>
+ /// </example>
+ public void Remove(string key)
+ {
+ if (string.IsNullOrEmpty(key))
+ {
+ throw new ArgumentNullException("key");
+ }
+ Interop.AppControl.ErrorCode err = Interop.AppControl.RemoveExtraData(_handle, key);
+ if (err != Interop.AppControl.ErrorCode.None)
+ {
+ switch (err)
+ {
+ case Interop.AppControl.ErrorCode.InvalidParameter:
+ throw new ArgumentException("Invalid parameter: key is a zero-length string");
+ case Interop.AppControl.ErrorCode.KeyNotFound:
+ throw new KeyNotFoundException("Key is not found"); ;
+ case Interop.AppControl.ErrorCode.KeyRejected:
+ throw new ArgumentException("Key is rejected: the key is system-defined key.");
+ default:
+ throw new InvalidOperationException("Error = " + err);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Counts keys in the extra data.
+ /// </summary>
+ /// <returns>The number of counting keys</returns>
+ /// <exception cref="InvalidOperationException">Thrown when invalid parameter</exception>
+ /// <example>
+ /// <code>
+ /// AppControl appControl = new AppControl();
+ /// int numberOfKeys = appControl.ExtraData.Count();
+ /// </code>
+ /// </example>
+ public int Count()
+ {
+ return GetKeys().Count();
+ }
+
+ /// <summary>
+ /// Checks whether the extra data associated with the given key is of collection data type.
+ /// </summary>
+ /// <param name="key">The name of the extra data</param>
+ /// <returns>If true the extra data is of array data type, otherwise false</returns>
+ /// <exception cref="ArgumentNullException">Thrown when the key is a zero-length string</exception>
+ /// <exception cref="InvalidOperationException">Thrown when failed to check the key</exception>
+ /// <example>
+ /// <code>
+ /// AppControl appControl = new AppControl();
+ /// bool result = appControl.ExtraData.IsCollection("myKey");
+ /// </code>
+ /// </example>
+ public bool IsCollection(string key)
+ {
+ if (string.IsNullOrEmpty(key))
+ {
+ throw new ArgumentNullException("key");
+ }
+ bool isArray = false;
+ Interop.AppControl.ErrorCode err = Interop.AppControl.IsExtraDataArray(_handle, key, out isArray);
+ if (err != Interop.AppControl.ErrorCode.None)
+ {
+ throw new InvalidOperationException("Error = " + err);
+ }
+ return isArray;
+ }
+
+ private string GetData(string key)
+ {
+ if (string.IsNullOrEmpty(key))
+ {
+ throw new ArgumentNullException("key");
+ }
+ string value = string.Empty;
+ Interop.AppControl.ErrorCode err = Interop.AppControl.GetExtraData(_handle, key, out value);
+ if (err != Interop.AppControl.ErrorCode.None)
+ {
+ switch (err)
+ {
+ case Interop.AppControl.ErrorCode.InvalidParameter:
+ throw new ArgumentException("Invalid parameter: key is a zero-length string");
+ case Interop.AppControl.ErrorCode.KeyNotFound:
+ throw new KeyNotFoundException("Key is not found"); ;
+ case Interop.AppControl.ErrorCode.InvalidDataType:
+ throw new ArgumentException("Invalid data type: value is data collection type");
+ case Interop.AppControl.ErrorCode.KeyRejected:
+ throw new ArgumentException("Key is rejected: the key is system-defined key.");
+ default:
+ throw new InvalidOperationException("Error = " + err);
+ }
+ }
+ return value;
+ }
+
+ private IEnumerable<string> GetDataCollection(string key)
+ {
+ if (string.IsNullOrEmpty(key))
+ {
+ throw new ArgumentNullException("key");
+ }
+ IntPtr valuePtr = IntPtr.Zero;
+ int len = -1;
+ Interop.AppControl.ErrorCode err = Interop.AppControl.GetExtraDataArray(_handle, key, out valuePtr, out len);
+ if (err != Interop.AppControl.ErrorCode.None)
+ {
+ switch (err)
+ {
+ case Interop.AppControl.ErrorCode.InvalidParameter:
+ throw new ArgumentException("Invalid parameter: key is a zero-length string");
+ case Interop.AppControl.ErrorCode.KeyNotFound:
+ throw new KeyNotFoundException("Key is not found"); ;
+ case Interop.AppControl.ErrorCode.InvalidDataType:
+ throw new ArgumentException("Invalid data type: value is data collection type");
+ case Interop.AppControl.ErrorCode.KeyRejected:
+ throw new ArgumentException("Key is rejected: the key is system-defined key.");
+ default:
+ throw new InvalidOperationException("Error = " + err);
+ }
+ }
+
+ List<string> valueArray = new List<string>();
+ if (valuePtr != IntPtr.Zero)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ IntPtr charArr = Marshal.ReadIntPtr(valuePtr, IntPtr.Size * i);
+ valueArray.Add(Marshal.PtrToStringAnsi(charArr));
+ Interop.Libc.Free(charArr);
+ }
+ Interop.Libc.Free(valuePtr);
+ }
+ return valueArray;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/AppControlData.cs b/src/Tizen.Applications.Common/Tizen.Applications/AppControlData.cs
new file mode 100755
index 0000000..fddfd09
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/AppControlData.cs
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Data of the AppControl.
+ /// </summary>
+ public static class AppControlData
+ {
+ /// <summary>
+ /// Subject
+ /// </summary>
+ public const string Subject = "http://tizen.org/appcontrol/data/subject";
+
+ /// <summary>
+ /// Recipients
+ /// </summary>
+ public const string To = "http://tizen.org/appcontrol/data/to";
+
+ /// <summary>
+ /// E-mail addresses that should be carbon copied
+ /// </summary>
+ public const string Cc = "http://tizen.org/appcontrol/data/cc";
+
+ /// <summary>
+ /// E-mail addresses that should be blind carbon copied
+ /// </summary>
+ public const string Bcc = "http://tizen.org/appcontrol/data/bcc";
+
+ /// <summary>
+ /// Text
+ /// </summary>
+ public const string Text = "http://tizen.org/appcontrol/data/text";
+
+ /// <summary>
+ /// Title
+ /// </summary>
+ public const string Title = "http://tizen.org/appcontrol/data/title";
+
+ /// <summary>
+ /// Selected items
+ /// </summary>
+ public const string Selected = "http://tizen.org/appcontrol/data/selected";
+
+ /// <summary>
+ /// Paths of items
+ /// </summary>
+ public const string Path = "http://tizen.org/appcontrol/data/path";
+
+ /// <summary>
+ /// Selection mode. ("single" or "multiple")
+ /// </summary>
+ public const string SectionMode = "http://tizen.org/appcontrol/data/selection_mode";
+
+ /// <summary>
+ /// All-day mode of event ("true" or "false")
+ /// </summary>
+ public const string AllDay = "http://tizen.org/appcontrol/data/calendar/all_day";
+
+ /// <summary>
+ /// Start time of event (format: YYYY-MM-DD HH:MM:SS)
+ /// </summary>
+ public const string StartTime = "http://tizen.org/appcontrol/data/calendar/start_time";
+
+ /// <summary>
+ /// End time of event (format: YYYY-MM-DD HH:MM:SS)
+ /// </summary>
+ public const string Endtime = "http://tizen.org/appcontrol/data/calendar/end_time";
+
+ /// <summary>
+ /// E-mail addressed
+ /// </summary>
+ public const string Email = "http://tizen.org/appcontrol/data/email";
+
+ /// <summary>
+ /// Phone numbers
+ /// </summary>
+ public const string Phone = "http://tizen.org/appcontrol/data/phone";
+
+ /// <summary>
+ /// URLs
+ /// </summary>
+ public const string Url = "http://tizen.org/appcontrol/data/url";
+
+ /// <summary>
+ /// IDs
+ /// </summary>
+ public const string Ids = "http://tizen.org/appcontrol/data/id";
+
+ /// <summary>
+ /// Type
+ /// </summary>
+ public const string Type = "http://tizen.org/appcontrol/data/type";
+
+ /// <summary>
+ /// Total count
+ /// </summary>
+ public const string TotalCount = "http://tizen.org/appcontrol/data/total_count";
+
+ /// <summary>
+ /// Total size (unit : bytes)
+ /// </summary>
+ public const string TotalSize = "http://tizen.org/appcontrol/data/total_size";
+
+ /// <summary>
+ /// Name
+ /// </summary>
+ public const string Name = "http://tizen.org/appcontrol/data/name";
+
+ /// <summary>
+ /// Location
+ /// </summary>
+ public const string Location = "http://tizen.org/appcontrol/data/location";
+
+ /// <summary>
+ /// Select the type of input method
+ /// </summary>
+ public const string InputType = "http://tizen.org/appcontrol/data/input_type";
+
+ /// <summary>
+ /// Send the pre inputted text such as "http://" in web
+ /// </summary>
+ public const string InputDefaultText = "http://tizen.org/appcontrol/data/input_default_text";
+
+ /// <summary>
+ /// Send guide text to show to user such as "Input user name"
+ /// </summary>
+ public const string InputGuideText = "http://tizen.org/appcontrol/data/input_guide_text";
+
+ /// <summary>
+ /// Send text to receive answer result from smart reply
+ /// </summary>
+ public const string InputPredictionHint = "http://tizen.org/appcontrol/data/input_prediction_hint";
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/AppControlLaunchMode.cs b/src/Tizen.Applications.Common/Tizen.Applications/AppControlLaunchMode.cs
new file mode 100755
index 0000000..728612c
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/AppControlLaunchMode.cs
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Enumeration for App Control Launch Mode.
+ /// </summary>
+ public enum AppControlLaunchMode
+ {
+ /// <summary>
+ /// Prefer to launch an application as single mode
+ /// </summary>
+ Single = 0,
+
+ /// <summary>
+ /// Prefer to launch an application as group mode
+ /// </summary>
+ Group,
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/AppControlOperations.cs b/src/Tizen.Applications.Common/Tizen.Applications/AppControlOperations.cs
new file mode 100755
index 0000000..c045651
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/AppControlOperations.cs
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Operations of the AppControl.
+ /// </summary>
+ public static class AppControlOperations
+ {
+ /// <summary>
+ /// An explicit launch for a homescreen application.
+ /// </summary>
+ public const string Main = "http://tizen.org/appcontrol/operation/main";
+
+ /// <summary>
+ /// An explicit launch for an application that excludes a homescreen application.
+ /// </summary>
+ public const string Default = "http://tizen.org/appcontrol/operation/default";
+
+ /// <summary>
+ /// Provides an editable access to the given data.
+ /// </summary>
+ public const string Edit = "http://tizen.org/appcontrol/operation/edit";
+
+ /// <summary>
+ /// Displays the data.
+ /// </summary>
+ public const string View = "http://tizen.org/appcontrol/operation/view";
+
+ /// <summary>
+ /// Picks items.
+ /// </summary>
+ public const string Pick = "http://tizen.org/appcontrol/operation/pick";
+
+ /// <summary>
+ /// Creates contents.
+ /// </summary>
+ public const string CreateContent = "http://tizen.org/appcontrol/operation/create_content";
+
+ /// <summary>
+ /// Performs a call to someone.
+ /// </summary>
+ public const string Call = "http://tizen.org/appcontrol/operation/call";
+
+ /// <summary>
+ /// Delivers some data to someone else.
+ /// </summary>
+ public const string Send = "http://tizen.org/appcontrol/operation/send";
+
+ /// <summary>
+ /// Delivers text data to someone else.
+ /// </summary>
+ public const string SendText = "http://tizen.org/appcontrol/operation/send_text";
+
+ /// <summary>
+ /// Shares an item with someone else.
+ /// </summary>
+ public const string Share = "http://tizen.org/appcontrol/operation/share";
+
+ /// <summary>
+ /// Shares multiple items with someone else.
+ /// </summary>
+ public const string MultiShare = "http://tizen.org/appcontrol/operation/multi_share";
+
+ /// <summary>
+ /// Shares text data with someone else.
+ /// </summary>
+ public const string ShareText = "http://tizen.org/appcontrol/operation/share_text";
+
+ /// <summary>
+ /// Dials a number. This shows a UI with the number to be dialed, allowing the user to explicitly initiate the call.
+ /// </summary>
+ public const string Dial = "http://tizen.org/appcontrol/operation/dial";
+
+ /// <summary>
+ /// Performs a search.
+ /// </summary>
+ public const string Search = "http://tizen.org/appcontrol/operation/search";
+
+ /// <summary>
+ /// Downloads items.
+ /// </summary>
+ public const string Download = "http://tizen.org/appcontrol/operation/download";
+
+ /// <summary>
+ /// Prints contents.
+ /// </summary>
+ public const string Print = "http://tizen.org/appcontrol/operation/print";
+
+ /// <summary>
+ /// Composes a message.
+ /// </summary>
+ public const string Compose = "http://tizen.org/appcontrol/operation/compose";
+
+ /// <summary>
+ /// Can be launched by interested System-Event.
+ /// </summary>
+ public const string LaunchOnEvent = "http://tizen.org/appcontrol/operation/launch_on_event";
+
+ /// <summary>
+ /// Adds an item.
+ /// </summary>
+ public const string Add = "http://tizen.org/appcontrol/operation/add";
+
+ /// <summary>
+ /// Captures images by camera applications.
+ /// </summary>
+ public const string ImageCapture = "http://tizen.org/appcontrol/operation/image_capture";
+
+ /// <summary>
+ /// Captures videos by camera applications.
+ /// </summary>
+ public const string VideoCapture = "http://tizen.org/appcontrol/operation/video_capture";
+
+ /// <summary>
+ /// Shows system settings.
+ /// </summary>
+ public const string Setting = "http://tizen.org/appcontrol/operation/setting";
+
+ /// <summary>
+ /// Shows settings to enable Bluetooth.
+ /// </summary>
+ public const string SettingBluetoothEnable = "http://tizen.org/appcontrol/operation/setting/bt_enable";
+
+ /// <summary>
+ /// Shows settings to configure Bluetooth visibility.
+ /// </summary>
+ public const string SettingBluetoothVisibility = "http://tizen.org/appcontrol/operation/setting/bt_visibility";
+
+ /// <summary>
+ /// Shows settings to allow configuration of current location sources.
+ /// </summary>
+ public const string SettingLocation = "http://tizen.org/appcontrol/operation/setting/location";
+
+ /// <summary>
+ /// Shows NFC settings.
+ /// </summary>
+ public const string SettingNfc = "http://tizen.org/appcontrol/operation/setting/nfc";
+
+ /// <summary>
+ /// Shows settings to allow configuration of Wi-Fi.
+ /// </summary>
+ public const string SettingWifi = "http://tizen.org/appcontrol/operation/setting/wifi";
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/AppControlReceivedEventArgs.cs b/src/Tizen.Applications.Common/Tizen.Applications/AppControlReceivedEventArgs.cs
new file mode 100755
index 0000000..7318466
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/AppControlReceivedEventArgs.cs
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Arguments for the event that raised when the application receives the AppControl.
+ /// </summary>
+ public class AppControlReceivedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Initializes AppControlReceivedEventArgs class.
+ /// </summary>
+ /// <param name="appControl"></param>
+ public AppControlReceivedEventArgs(ReceivedAppControl appControl)
+ {
+ ReceivedAppControl = appControl;
+ }
+
+ /// <summary>
+ /// The received AppControl.
+ /// </summary>
+ public ReceivedAppControl ReceivedAppControl { get; private set; }
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/AppControlReplyCallback.cs b/src/Tizen.Applications.Common/Tizen.Applications/AppControlReplyCallback.cs
new file mode 100755
index 0000000..501be67
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/AppControlReplyCallback.cs
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="launchRequest"></param>
+ /// <param name="replyRequest"></param>
+ /// <param name="result"></param>
+ public delegate void AppControlReplyCallback(AppControl launchRequest, AppControl replyRequest, AppControlReplyResult result);
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/AppControlReplyResult.cs b/src/Tizen.Applications.Common/Tizen.Applications/AppControlReplyResult.cs
new file mode 100755
index 0000000..7fed628
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/AppControlReplyResult.cs
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Enumeration for App Control Result.
+ /// </summary>
+ public enum AppControlReplyResult
+ {
+ /// <summary>
+ /// Callee application launched actually
+ /// </summary>
+ AppStarted = 1,
+
+ /// <summary>
+ /// Operation is succeeded
+ /// </summary>
+ Succeeded = 0,
+
+ /// <summary>
+ /// Operation is failed by the callee
+ /// </summary>
+ Failed = -1,
+
+ /// <summary>
+ /// Operation is canceled by the platform
+ /// </summary>
+ Canceled = -2,
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/Application.cs b/src/Tizen.Applications.Common/Tizen.Applications/Application.cs
new file mode 100755
index 0000000..2049f57
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/Application.cs
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Class that represents a Tizen application.
+ /// </summary>
+ public abstract class Application : IDisposable
+ {
+ internal const string LogTag = "Tizen.Applications";
+
+ private static Application s_CurrentApplication = null;
+
+ private object _lock = new object();
+
+ private DirectoryInfo _directoryInfo;
+ private ApplicationInfo _applicationInfo;
+
+ /// <summary>
+ /// Gets the instance of current application.
+ /// </summary>
+ public static Application Current { get { return s_CurrentApplication; } }
+
+ /// <summary>
+ /// Gets the class representing directory information of current application.
+ /// </summary>
+ public DirectoryInfo DirectoryInfo
+ {
+ get
+ {
+ lock (_lock)
+ {
+ if (_directoryInfo == null)
+ {
+ _directoryInfo = new DirectoryInfo();
+ }
+ }
+ return _directoryInfo;
+ }
+ }
+
+ /// <summary>
+ /// Gets the class representing information of current application.
+ /// </summary>
+ public ApplicationInfo ApplicationInfo
+ {
+ get
+ {
+ lock (_lock)
+ {
+ if (_applicationInfo == null)
+ {
+ string appId = string.Empty;
+ Interop.AppCommon.AppGetId(out appId);
+ if (!string.IsNullOrEmpty(appId))
+ {
+ _applicationInfo = new ApplicationInfo(appId);
+ }
+ }
+ }
+ return _applicationInfo;
+ }
+ }
+
+ /// <summary>
+ /// Runs the application's main loop.
+ /// </summary>
+ /// <param name="args">Arguments from commandline.</param>
+ public virtual void Run(string[] args)
+ {
+ if (args == null)
+ {
+ throw new ArgumentNullException("args");
+ }
+ s_CurrentApplication = this;
+ }
+
+ /// <summary>
+ /// Exits the main loop of application.
+ /// </summary>
+ public abstract void Exit();
+
+ #region IDisposable Support
+ private bool _disposedValue = false; // To detect redundant calls
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+ /// </summary>
+ /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ if (disposing)
+ {
+ if (_applicationInfo != null)
+ {
+ _applicationInfo.Dispose();
+ }
+ }
+
+ _disposedValue = true;
+ }
+ }
+
+ /// <summary>
+ /// Finalizer of the Application class.
+ /// </summary>
+ ~Application()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Releases all resources used by the Application class.
+ /// </summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/ApplicationDisabledEventArgs.cs b/src/Tizen.Applications.Common/Tizen.Applications/ApplicationDisabledEventArgs.cs
new file mode 100644
index 0000000..5b185d3
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/ApplicationDisabledEventArgs.cs
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Arguments for the event that is raised when the application is disabled.
+ /// </summary>
+ public class ApplicationDisabledEventArgs : EventArgs
+ {
+ private readonly ApplicationEventState _eventState;
+ private readonly string _applicationId;
+
+ internal ApplicationDisabledEventArgs(string appId, ApplicationEventState eventState)
+ {
+ _applicationId = appId;
+ _eventState = eventState;
+ }
+
+ /// <summary>
+ /// The Id of the application
+ /// </summary>
+ public string ApplicationId { get { return _applicationId; } }
+
+ /// <summary>
+ /// The Event state of the application
+ /// </summary>
+ public ApplicationEventState EventState { get { return _eventState; } }
+ }
+}
+
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/ApplicationEnabledEventArgs.cs b/src/Tizen.Applications.Common/Tizen.Applications/ApplicationEnabledEventArgs.cs
new file mode 100644
index 0000000..fa72e8a
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/ApplicationEnabledEventArgs.cs
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Arguments for the event that is raised when the application is enabled.
+ /// </summary>
+ public class ApplicationEnabledEventArgs : EventArgs
+ {
+ private readonly ApplicationEventState _eventState;
+ private readonly string _applicationId;
+
+ internal ApplicationEnabledEventArgs(string appId, ApplicationEventState eventState)
+ {
+ _applicationId = appId;
+ _eventState = eventState;
+ }
+
+ /// <summary>
+ /// The Id of the application
+ /// </summary>
+ public string ApplicationId { get { return _applicationId; } }
+
+ /// <summary>
+ /// The Event state of the application
+ /// </summary>
+ public ApplicationEventState EventState { get { return _eventState; } }
+ }
+}
+
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/ApplicationEventState.cs b/src/Tizen.Applications.Common/Tizen.Applications/ApplicationEventState.cs
new file mode 100644
index 0000000..8ef9597
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/ApplicationEventState.cs
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Enumeration of the application event state
+ /// </summary>
+ public enum ApplicationEventState
+ {
+ /// <summary>
+ /// Processing Started.
+ /// </summary>
+ Started = Interop.ApplicationManager.AppManagerEventState.Started,
+ /// <summary>
+ /// Processing Completed.
+ /// </summary>
+ Completed = Interop.ApplicationManager.AppManagerEventState.Completed,
+ /// <summary>
+ /// Processing Failed.
+ /// </summary>
+ Failed = Interop.ApplicationManager.AppManagerEventState.Failed
+ }
+}
+
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/ApplicationInfo.cs b/src/Tizen.Applications.Common/Tizen.Applications/ApplicationInfo.cs
new file mode 100755
index 0000000..34d7b19
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/ApplicationInfo.cs
@@ -0,0 +1,406 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// This class provides methods and properties to get information of the application.
+ /// </summary>
+ public class ApplicationInfo : IDisposable
+ {
+ private const string LogTag = "Tizen.Applications";
+ private bool _disposed = false;
+ private IntPtr _infoHandle = IntPtr.Zero;
+ private string _applicationId = string.Empty;
+ private Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.ErrorCode.None;
+
+ internal ApplicationInfo(IntPtr infoHandle)
+ {
+ err = Interop.ApplicationManager.AppInfoGetAppId(infoHandle, out _applicationId);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ throw new ArgumentException("Invalid native handle.");
+ }
+ _infoHandle = infoHandle;
+ }
+
+ /// <summary>
+ /// A constructor of ApplicationInfo that takes the application id.
+ /// </summary>
+ /// <param name="applicationId">application id.</param>
+ public ApplicationInfo(string applicationId)
+ {
+ _applicationId = applicationId;
+ }
+
+ /// <summary>
+ /// Destructor of the class
+ /// </summary>
+ ~ApplicationInfo()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Gets the application id.
+ /// </summary>
+ public string ApplicationId
+ {
+ get
+ {
+ if (!string.IsNullOrEmpty(_applicationId))
+ return _applicationId;
+ IntPtr infoHandle = GetInfoHandle();
+ string appid = string.Empty;
+ if (infoHandle != IntPtr.Zero)
+ {
+ err = Interop.ApplicationManager.AppInfoGetAppId(infoHandle, out appid);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get the application id. err = " + err);
+ }
+ }
+ return appid;
+ }
+ }
+
+ /// <summary>
+ /// Gets the package id of the application.
+ /// </summary>
+ public string PackageId
+ {
+ get
+ {
+ IntPtr infoHandle = GetInfoHandle();
+ string packageid = string.Empty;
+ if (infoHandle != IntPtr.Zero)
+ {
+ err = Interop.ApplicationManager.AppInfoGetPackage(infoHandle, out packageid);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get the package id of " + _applicationId + ". err = " + err);
+ }
+ }
+ return packageid;
+ }
+ }
+
+ /// <summary>
+ /// Gets the label of the application.
+ /// </summary>
+ public string Label
+ {
+ get
+ {
+ IntPtr infoHandle = GetInfoHandle();
+ string label = string.Empty;
+ if (infoHandle != IntPtr.Zero)
+ {
+ err = Interop.ApplicationManager.AppInfoGetLabel(infoHandle, out label);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get the app label of " + _applicationId + ". err = " + err);
+ }
+ }
+ return label;
+ }
+ }
+
+ /// <summary>
+ /// Gets the executable path of the application.
+ /// </summary>
+ public string ExecutablePath
+ {
+ get
+ {
+ IntPtr infoHandle = GetInfoHandle();
+ string exec = string.Empty;
+ if (infoHandle != IntPtr.Zero)
+ {
+ err = Interop.ApplicationManager.AppInfoGetExec(infoHandle, out exec);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get the executable file path of " + _applicationId + ". err = " + err);
+ }
+ }
+ return exec;
+ }
+ }
+
+ /// <summary>
+ /// Gets the absolute path to the icon image.
+ /// </summary>
+ public string IconPath
+ {
+ get
+ {
+ IntPtr infoHandle = GetInfoHandle();
+ string path = string.Empty;
+ if (infoHandle != IntPtr.Zero)
+ {
+ err = Interop.ApplicationManager.AppInfoGetIcon(infoHandle, out path);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get the app icon path of " + _applicationId + ". err = " + err);
+ }
+ }
+ return path;
+ }
+ }
+
+ /// <summary>
+ /// Gets the application type name.
+ /// </summary>
+ public string ApplicationType
+ {
+ get
+ {
+ IntPtr infoHandle = GetInfoHandle();
+ string type = string.Empty;
+ if (infoHandle != IntPtr.Zero)
+ {
+ err = Interop.ApplicationManager.AppInfoGetType(infoHandle, out type);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get the application type of " + _applicationId + ". err = " + err);
+ }
+ }
+ return type;
+ }
+ }
+
+ /// <summary>
+ /// Gets the application's metadata.
+ /// </summary>
+ public IDictionary<String, String> Metadata
+ {
+ get
+ {
+ IDictionary<string, string> metadata = new Dictionary<String, String>();
+
+ Interop.ApplicationManager.AppInfoMetadataCallback cb = (string key, string value, IntPtr userData) =>
+ {
+ if (key.Length != 0)
+ {
+ metadata.Add(key, value);
+ }
+ return true;
+ };
+
+ IntPtr infoHandle = GetInfoHandle();
+ if (infoHandle != IntPtr.Zero)
+ {
+ err = Interop.ApplicationManager.AppInfoForeachMetadata(infoHandle, cb, IntPtr.Zero);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get application metadata of " + _applicationId + ". err = " + err);
+ }
+ }
+ return metadata;
+ }
+ }
+
+ /// <summary>
+ /// Checks whether application information is nodisplay. If the application icon is not displayed on the menu screen, true; otherwise, false.
+ /// </summary>
+ public bool IsNoDisplay
+ {
+ get
+ {
+ IntPtr infoHandle = GetInfoHandle();
+ bool nodisplay = false;
+ if (infoHandle != IntPtr.Zero)
+ {
+ err = Interop.ApplicationManager.AppInfoIsNodisplay(infoHandle, out nodisplay);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get the IsNoDisplay value of " + _applicationId + ". err = " + err);
+
+ }
+ }
+ return nodisplay;
+ }
+ }
+
+ /// <summary>
+ /// Checks whether application is launched on booting time. If the application will be automatically start on boot, true; otherwise, false.
+ /// </summary>
+ public bool IsOnBoot
+ {
+ get
+ {
+ IntPtr infoHandle = GetInfoHandle();
+ bool onboot = false;
+ if (infoHandle != IntPtr.Zero)
+ {
+ err = Interop.ApplicationManager.AppInfoIsOnBoot(infoHandle, out onboot);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get the IsOnBoot value of " + _applicationId + ". err = " + err);
+ }
+ }
+ return onboot;
+ }
+ }
+
+ /// <summary>
+ /// Checks whether application is preloaded. If the application is preloaded, true; otherwise, false.
+ /// </summary>
+ public bool IsPreload
+ {
+ get
+ {
+ IntPtr infoHandle = GetInfoHandle();
+ bool preloaded = false;
+ if (infoHandle != IntPtr.Zero)
+ {
+ err = Interop.ApplicationManager.AppInfoIsPreLoad(infoHandle, out preloaded);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get the IsPreload value of " + _applicationId + ". err = " + err);
+ }
+ }
+ return preloaded;
+ }
+ }
+
+ /// <summary>
+ /// Gets the shared data path.
+ /// </summary>
+ public string SharedDataPath
+ {
+ get
+ {
+ string path = string.Empty;
+ err = Interop.ApplicationManager.AppManagerGetSharedDataPath(ApplicationId, out path);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get the SharedDataPath of " + _applicationId + ". err = " + err);
+ }
+ return path;
+ }
+ }
+
+ /// <summary>
+ /// Gets the shared resource path.
+ /// </summary>
+ public string SharedResourcePath
+ {
+ get
+ {
+ string path = string.Empty;
+ err = Interop.ApplicationManager.AppManagerGetSharedResourcePath(ApplicationId, out path);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get the SharedResourcePath of " + _applicationId + ". err = " + err);
+ }
+ return path;
+ }
+ }
+
+ /// <summary>
+ /// Gets the shared trust path.
+ /// </summary>
+ public string SharedTrustedPath
+ {
+ get
+ {
+ string path = string.Empty;
+ err = Interop.ApplicationManager.AppManagerGetSharedTrustedPath(ApplicationId, out path);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get the SharedTrustedPath of " + _applicationId + ". err = " + err);
+ }
+ return path;
+ }
+ }
+
+ /// <summary>
+ /// Gets the external shared data path.
+ /// </summary>
+ public string ExternalSharedDataPath
+ {
+ get
+ {
+ string path = string.Empty;
+ err = Interop.ApplicationManager.AppManagerGetExternalSharedDataPath(ApplicationId, out path);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get the ExternalSharedDataPath of " + _applicationId + ". err = " + err);
+ }
+ return path;
+ }
+ }
+
+ /// <summary>
+ /// Gets the localized label of application for the given locale.
+ /// </summary>
+ /// <param name="locale">locale.</param>
+ public string GetLocalizedLabel(string locale)
+ {
+ string label = string.Empty;
+ err = Interop.ApplicationManager.AppInfoGetLocaledLabel(ApplicationId, locale, out label);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get the GetLocalizedLabel of " + _applicationId + ". err = " + err);
+ label = Label;
+ }
+ return label;
+ }
+
+ private IntPtr GetInfoHandle()
+ {
+ if (_infoHandle == IntPtr.Zero)
+ {
+ IntPtr infoHandle = IntPtr.Zero;
+ err = Interop.ApplicationManager.AppManagerGetAppInfo(_applicationId, out infoHandle);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get the handle of the ApplicationInfo. err = " + err);
+ }
+ _infoHandle = infoHandle;
+ }
+ return _infoHandle;
+ }
+
+ /// <summary>
+ /// Releases all resources used by the ApplicationInfo class.
+ /// </summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (_disposed)
+ return;
+ if (disposing)
+ {
+ }
+ if (_infoHandle != IntPtr.Zero)
+ {
+ Interop.ApplicationManager.AppInfoDestroy(_infoHandle);
+ _infoHandle = IntPtr.Zero;
+ }
+ _disposed = true;
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/ApplicationInfoFilter.cs b/src/Tizen.Applications.Common/Tizen.Applications/ApplicationInfoFilter.cs
new file mode 100755
index 0000000..bba97b3
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/ApplicationInfoFilter.cs
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// This class is a parameter of GetInstalledApplicationsAsync method.
+ /// </summary>
+ public class ApplicationInfoFilter
+ {
+ /// <summary>
+ ///
+ /// </summary>
+ public ApplicationInfoFilter()
+ {
+ Filter = new Dictionary<string, string>();
+ }
+
+ /// <summary>
+ /// This class is a possible key to use in the InstalledApplicationFilter.
+ /// </summary>
+ public static class Keys
+ {
+ /// <summary>
+ ///
+ /// </summary>
+ public const string Id = "PACKAGE_INFO_PROP_APP_ID";
+ /// <summary>
+ ///
+ /// </summary>
+ public const string Type = "PACKAGE_INFO_PROP_APP_TYPE";
+ /// <summary>
+ ///
+ /// </summary>
+ public const string Category = "PACKAGE_INFO_PROP_APP_CATEGORY";
+ /// <summary>
+ ///
+ /// </summary>
+ public const string NoDisplay = "PACKAGE_INFO_PROP_APP_NODISPLAY";
+ /// <summary>
+ ///
+ /// </summary>
+ public const string TaskManage = "PACKAGE_INFO_PROP_APP_TASKMANAGE";
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public IDictionary<string, string> Filter
+ {
+ get; private set;
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/ApplicationInfoMetadataFilter.cs b/src/Tizen.Applications.Common/Tizen.Applications/ApplicationInfoMetadataFilter.cs
new file mode 100755
index 0000000..b4bc005
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/ApplicationInfoMetadataFilter.cs
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// This class is a parameter of GetInstalledApplicationsAsync method.
+ /// </summary>
+ public class ApplicationInfoMetadataFilter : ApplicationInfoFilter
+ {
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/ApplicationLaunchedEventArgs.cs b/src/Tizen.Applications.Common/Tizen.Applications/ApplicationLaunchedEventArgs.cs
new file mode 100755
index 0000000..7f9c4b7
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/ApplicationLaunchedEventArgs.cs
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Arguments for the event that is raised when the application is launched.
+ /// </summary>
+ public class ApplicationLaunchedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// The information of the application.
+ /// </summary>
+ public ApplicationRunningContext ApplicationRunningContext { get; internal set; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/ApplicationManager.cs b/src/Tizen.Applications.Common/Tizen.Applications/ApplicationManager.cs
new file mode 100755
index 0000000..adc70c3
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/ApplicationManager.cs
@@ -0,0 +1,608 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// This class has the methods and events of the ApplicationManager.
+ /// </summary>
+ public static class ApplicationManager
+ {
+ private const string LogTag = "Tizen.Applications";
+ private static EventHandler<ApplicationLaunchedEventArgs> s_launchedHandler;
+ private static EventHandler<ApplicationTerminatedEventArgs> s_terminatedHandler;
+ private static Interop.ApplicationManager.AppManagerAppContextEventCallback s_applicationChangedEventCallback;
+ private static EventHandler<ApplicationEnabledEventArgs> _enabledHandler;
+ private static EventHandler<ApplicationDisabledEventArgs> _disabledHandler;
+ private static Interop.ApplicationManager.AppManagerEventCallback _eventCallback;
+ private static IntPtr _eventHandle = IntPtr.Zero;
+
+ /// <summary>
+ /// Occurs whenever the installed application is enabled.
+ /// </summary>
+ public static event EventHandler<ApplicationEnabledEventArgs> ApplicationEnabled
+ {
+ add
+ {
+ if (_enabledHandler == null && _disabledHandler == null)
+ {
+ RegisterApplicationEvent();
+ }
+ _enabledHandler += value;
+ }
+ remove
+ {
+ _enabledHandler -= value;
+ if (_enabledHandler == null && _disabledHandler == null)
+ {
+ UnRegisterApplicationEvent();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Occurs whenever the installed application is disabled.
+ /// </summary>
+ public static event EventHandler<ApplicationDisabledEventArgs> ApplicationDisabled
+ {
+ add
+ {
+ if (_disabledHandler == null && _enabledHandler == null)
+ {
+ RegisterApplicationEvent();
+ }
+ _disabledHandler += value;
+ }
+ remove
+ {
+ _disabledHandler -= value;
+ if (_disabledHandler == null && _enabledHandler == null)
+ {
+ UnRegisterApplicationEvent();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Occurs whenever the installed applications get launched.
+ /// </summary>
+ public static event EventHandler<ApplicationLaunchedEventArgs> ApplicationLaunched
+ {
+ add
+ {
+ if (s_launchedHandler == null && s_terminatedHandler == null)
+ {
+ RegisterApplicationChangedEvent();
+ }
+ s_launchedHandler += value;
+ }
+ remove
+ {
+ s_launchedHandler -= value;
+ if (s_launchedHandler == null && s_terminatedHandler == null)
+ {
+ UnRegisterApplicationChangedEvent();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Occurs whenever the installed applications get terminated.
+ /// </summary>
+ public static event EventHandler<ApplicationTerminatedEventArgs> ApplicationTerminated
+ {
+ add
+ {
+ if (s_launchedHandler == null && s_terminatedHandler == null)
+ {
+ RegisterApplicationChangedEvent();
+ }
+ s_terminatedHandler += value;
+ }
+ remove
+ {
+ s_terminatedHandler -= value;
+ if (s_launchedHandler == null && s_terminatedHandler == null)
+ {
+ UnRegisterApplicationChangedEvent();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the information of the installed applications asynchronously.
+ /// </summary>
+ public static async Task<IEnumerable<ApplicationInfo>> GetInstalledApplicationsAsync()
+ {
+ return await Task.Run(() =>
+ {
+ Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.ErrorCode.None;
+ List<ApplicationInfo> result = new List<ApplicationInfo>();
+
+ Interop.ApplicationManager.AppManagerAppInfoCallback cb = (IntPtr infoHandle, IntPtr userData) =>
+ {
+ if (infoHandle != IntPtr.Zero)
+ {
+ IntPtr clonedHandle = IntPtr.Zero;
+ err = Interop.ApplicationManager.AppInfoClone(out clonedHandle, infoHandle);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to clone the appinfo. err = " + err);
+ return false;
+ }
+ ApplicationInfo app = new ApplicationInfo(clonedHandle);
+ result.Add(app);
+ return true;
+ }
+ return false;
+ };
+ err = Interop.ApplicationManager.AppManagerForeachAppInfo(cb, IntPtr.Zero);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ throw ApplicationManagerErrorFactory.GetException(err, "Failed to foreach the appinfo.");
+ }
+ return result;
+ });
+ }
+
+ /// <summary>
+ /// Gets the information of the installed applications with the ApplicationInfoFilter asynchronously.
+ /// </summary>
+ /// <param name="filter">Key-value pairs for filtering.</param>
+ public static async Task<IEnumerable<ApplicationInfo>> GetInstalledApplicationsAsync(ApplicationInfoFilter filter)
+ {
+ return await Task.Run(() =>
+ {
+ List<ApplicationInfo> result = new List<ApplicationInfo>();
+
+ Interop.ApplicationManager.AppInfoFilterCallback cb = (IntPtr infoHandle, IntPtr userData) =>
+ {
+ if (infoHandle != IntPtr.Zero)
+ {
+ IntPtr clonedHandle = IntPtr.Zero;
+ Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppInfoClone(out clonedHandle, infoHandle);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to clone the appinfo. err = " + err);
+ return false;
+ }
+ ApplicationInfo app = new ApplicationInfo(clonedHandle);
+ result.Add(app);
+ return true;
+ }
+ return false;
+ };
+ filter.Fetch(cb);
+ return result;
+ });
+ }
+
+ /// <summary>
+ /// Gets the information of the installed applications with the ApplicationInfoMetadataFilter asynchronously.
+ /// </summary>
+ /// <param name="filter">Key-value pairs for filtering.</param>
+ public static async Task<IEnumerable<ApplicationInfo>> GetInstalledApplicationsAsync(ApplicationInfoMetadataFilter filter)
+ {
+ return await Task.Run(() =>
+ {
+ List<ApplicationInfo> result = new List<ApplicationInfo>();
+
+ Interop.ApplicationManager.AppInfoFilterCallback cb = (IntPtr infoHandle, IntPtr userData) =>
+ {
+ if (infoHandle != IntPtr.Zero)
+ {
+ IntPtr clonedHandle = IntPtr.Zero;
+ Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppInfoClone(out clonedHandle, infoHandle);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to clone the appinfo. err = " + err);
+ return false;
+ }
+ ApplicationInfo app = new ApplicationInfo(clonedHandle);
+ result.Add(app);
+ return true;
+ }
+ return false;
+ };
+ filter.Fetch(cb);
+ return result;
+ });
+ }
+
+ /// <summary>
+ /// Gets the information of the running applications asynchronously.
+ /// </summary>
+ public static async Task<IEnumerable<ApplicationRunningContext>> GetRunningApplicationsAsync()
+ {
+ return await Task.Run(() =>
+ {
+ Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.ErrorCode.None;
+ List<ApplicationRunningContext> result = new List<ApplicationRunningContext>();
+
+ Interop.ApplicationManager.AppManagerAppContextCallback cb = (IntPtr contextHandle, IntPtr userData) =>
+ {
+ if (contextHandle != IntPtr.Zero)
+ {
+ IntPtr clonedHandle = IntPtr.Zero;
+ err = Interop.ApplicationManager.AppContextClone(out clonedHandle, contextHandle);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to clone the app context. err = " + err);
+ return false;
+ }
+ ApplicationRunningContext context = new ApplicationRunningContext(clonedHandle);
+ result.Add(context);
+ return true;
+ }
+ return false;
+ };
+
+ err = Interop.ApplicationManager.AppManagerForeachAppContext(cb, IntPtr.Zero);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ throw ApplicationManagerErrorFactory.GetException(err, "Failed to foreach appcontext.");
+ }
+ return result;
+ });
+ }
+
+ /// <summary>
+ /// Gets the information of the running applications including subapp asynchronously.
+ /// </summary>
+ public static async Task<IEnumerable<ApplicationRunningContext>> GetAllRunningApplicationsAsync()
+ {
+ return await Task.Run(() =>
+ {
+ Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.ErrorCode.None;
+ List<ApplicationRunningContext> result = new List<ApplicationRunningContext>();
+
+ Interop.ApplicationManager.AppManagerAppContextCallback cb = (IntPtr contextHandle, IntPtr userData) =>
+ {
+ if (contextHandle != IntPtr.Zero)
+ {
+ IntPtr clonedHandle = IntPtr.Zero;
+ err = Interop.ApplicationManager.AppContextClone(out clonedHandle, contextHandle);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to clone the app context. err = " + err);
+ return false;
+ }
+ ApplicationRunningContext context = new ApplicationRunningContext(clonedHandle);
+ result.Add(context);
+ return true;
+ }
+ return false;
+ };
+
+ err = Interop.ApplicationManager.AppManagerForeachRunningAppContext(cb, IntPtr.Zero);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ throw ApplicationManagerErrorFactory.GetException(err, "Failed to foreach appcontext.");
+ }
+ return result;
+ });
+ }
+
+ /// <summary>
+ /// Gets the information of the specified application with the application id.
+ /// </summary>
+ /// <param name="applicationId">Application id.</param>
+ public static ApplicationInfo GetInstalledApplication(string applicationId)
+ {
+ IntPtr infoHandle = IntPtr.Zero;
+ Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppManagerGetAppInfo(applicationId, out infoHandle);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ throw ApplicationManagerErrorFactory.GetException(err, "Failed to get the installed application information of " + applicationId + ".");
+ }
+ ApplicationInfo app = new ApplicationInfo(infoHandle);
+ return app;
+ }
+
+ /// <summary>
+ /// Returns if the specified application is running or not.
+ /// </summary>
+ /// <param name="applicationId">The application Id.</param>
+ /// <returns>Returns true if the given application is running, otherwise false.</returns>
+ /// <exception cref="ArgumentException">Thrown when the given parameter is invalid.</exception>
+ public static bool IsRunning(string applicationId)
+ {
+ bool isRunning = false;
+ Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppManagerIsRunning(applicationId, out isRunning);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ throw ApplicationManagerErrorFactory.GetException(Interop.ApplicationManager.ErrorCode.InvalidParameter, "Invalid parameter");
+ }
+ return isRunning;
+ }
+
+ private static void RegisterApplicationChangedEvent()
+ {
+ Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.ErrorCode.None;
+ s_applicationChangedEventCallback = (IntPtr contextHandle, Interop.ApplicationManager.AppContextEvent state, IntPtr userData) =>
+ {
+ if (contextHandle == IntPtr.Zero) return;
+
+ IntPtr clonedHandle = IntPtr.Zero;
+ err = Interop.ApplicationManager.AppContextClone(out clonedHandle, contextHandle);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ throw ApplicationManagerErrorFactory.GetException(err, "Failed to register the application context event.");
+ }
+ using (ApplicationRunningContext context = new ApplicationRunningContext(clonedHandle))
+ {
+ if (state == Interop.ApplicationManager.AppContextEvent.Launched)
+ {
+ s_launchedHandler?.Invoke(null, new ApplicationLaunchedEventArgs { ApplicationRunningContext = context });
+ }
+ else if (state == Interop.ApplicationManager.AppContextEvent.Terminated)
+ {
+ s_terminatedHandler?.Invoke(null, new ApplicationTerminatedEventArgs { ApplicationRunningContext = context });
+ }
+ }
+ };
+ err = Interop.ApplicationManager.AppManagerSetAppContextEvent(s_applicationChangedEventCallback, IntPtr.Zero);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ throw ApplicationManagerErrorFactory.GetException(err, "Failed to register the application context event.");
+ }
+ }
+
+ private static void UnRegisterApplicationChangedEvent()
+ {
+ Interop.ApplicationManager.AppManagerUnSetAppContextEvent();
+ }
+
+ private static void RegisterApplicationEvent()
+ {
+ Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.ErrorCode.None;
+ err = Interop.ApplicationManager.AppManagerEventCreate(out _eventHandle);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ throw ApplicationManagerErrorFactory.GetException(err, "Failed to create the application event handle");
+ }
+
+ err = Interop.ApplicationManager.AppManagerEventSetStatus(_eventHandle, Interop.ApplicationManager.AppManagerEventStatusType.All);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Interop.ApplicationManager.AppManagerEventDestroy(_eventHandle);
+ _eventHandle = IntPtr.Zero;
+ throw ApplicationManagerErrorFactory.GetException(err, "Failed to set the application event");
+ }
+
+ _eventCallback = (string appType, string appId, Interop.ApplicationManager.AppManagerEventType eventType, Interop.ApplicationManager.AppManagerEventState eventState, IntPtr eventHandle, IntPtr UserData) =>
+ {
+ if (eventType == Interop.ApplicationManager.AppManagerEventType.Enable)
+ {
+ _enabledHandler?.Invoke(null, new ApplicationEnabledEventArgs(appId, (ApplicationEventState)eventState));
+ }
+ else if (eventType == Interop.ApplicationManager.AppManagerEventType.Disable)
+ {
+ _disabledHandler?.Invoke(null, new ApplicationDisabledEventArgs(appId, (ApplicationEventState)eventState));
+ }
+ };
+ err = Interop.ApplicationManager.AppManagerSetEventCallback(_eventHandle, _eventCallback, IntPtr.Zero);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Interop.ApplicationManager.AppManagerEventDestroy(_eventHandle);
+ _eventHandle = IntPtr.Zero;
+ throw ApplicationManagerErrorFactory.GetException(err, "Failed to set the application event callback");
+ }
+ }
+
+ private static void UnRegisterApplicationEvent()
+ {
+ if (_eventHandle != IntPtr.Zero)
+ {
+ Interop.ApplicationManager.AppManagerUnSetEventCallback(_eventHandle);
+ Interop.ApplicationManager.AppManagerEventDestroy(_eventHandle);
+ _eventHandle = IntPtr.Zero;
+ }
+ }
+
+ /// <summary>
+ /// Gets the information of the recent applications.
+ /// </summary>
+ /// <returns>Returns a dictionary containing all recent application info.</returns>
+ /// <exception cref="InvalidOperationException">Thrown when failed because of invalid operation</exception>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static IEnumerable<RecentApplicationInfo> GetRecentApplications()
+ {
+ Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.ErrorCode.None;
+
+ List<RecentApplicationInfo> result = new List<RecentApplicationInfo>();
+ IntPtr table;
+ int nrows, ncols;
+
+ err = Interop.ApplicationManager.RuaHistoryLoadDb(out table, out nrows, out ncols);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ throw ApplicationManagerErrorFactory.GetException(err, "Failed to load a table for the recent application list.");
+ }
+
+ for (int row = 0; row < nrows; ++row)
+ {
+ Interop.ApplicationManager.RuaRec record;
+
+ err = Interop.ApplicationManager.RuaHistoryGetRecord(out record, table, nrows, ncols, row);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ throw ApplicationManagerErrorFactory.GetException(err, "Failed to get record.");
+ }
+
+ RecentApplicationInfo info = new RecentApplicationInfo(record);
+ result.Add(info);
+ }
+
+ err = Interop.ApplicationManager.RuaHistoryUnLoadDb(ref table);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ throw ApplicationManagerErrorFactory.GetException(err, "Failed to unload a table for the recent application list.");
+ }
+
+ return result;
+ }
+ }
+
+ internal static class FilterExtension
+ {
+ private const string LogTag = "Tizen.Applications";
+ internal static void Fetch(this ApplicationInfoFilter filter, Interop.ApplicationManager.AppInfoFilterCallback callback)
+ {
+ if (filter is ApplicationInfoMetadataFilter)
+ {
+ ApplicationInfoMetadataFilter metaFilter = (ApplicationInfoMetadataFilter)filter;
+ metaFilter.Fetch(callback);
+ return;
+ }
+
+ IntPtr nativeHandle = MakeNativeAppInfoFilter(filter.Filter);
+ if (nativeHandle == IntPtr.Zero)
+ {
+ throw ApplicationManagerErrorFactory.NativeFilterHandleIsInvalid();
+ }
+ try
+ {
+ Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppInfoFilterForeachAppinfo(nativeHandle, callback, IntPtr.Zero);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ throw ApplicationManagerErrorFactory.GetException(err, "Failed to get application information list with filter.");
+ }
+ }
+ finally
+ {
+ Interop.ApplicationManager.AppInfoFilterDestroy(nativeHandle);
+ }
+ }
+
+ internal static void Fetch(this ApplicationInfoMetadataFilter filter, Interop.ApplicationManager.AppInfoFilterCallback callback)
+ {
+ IntPtr nativeHandle = MakeNativeAppMetadataFilter(filter.Filter);
+ if (nativeHandle == IntPtr.Zero)
+ {
+ throw ApplicationManagerErrorFactory.NativeFilterHandleIsInvalid();
+ }
+ try
+ {
+ Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppInfoMetadataFilterForeach(nativeHandle, callback, IntPtr.Zero);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ throw ApplicationManagerErrorFactory.GetException(err, "Failed to get metadata list with filter.");
+ }
+ }
+ finally
+ {
+ Interop.ApplicationManager.AppInfoMetadataFilterDestroy(nativeHandle);
+ }
+ }
+
+ private static IntPtr MakeNativeAppInfoFilter(IDictionary<string, string> filter)
+ {
+ if (filter == null || filter.Count == 0)
+ {
+ throw ApplicationManagerErrorFactory.FilterIsInvalid();
+ }
+
+ IntPtr infoHandle = IntPtr.Zero;
+ Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppInfoFilterCreate(out infoHandle);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ throw ApplicationManagerErrorFactory.GetException(err, "Failed to create the filter handle.");
+ }
+
+ foreach (var item in filter)
+ {
+ if ((item.Key == ApplicationInfoFilter.Keys.Id) ||
+ (item.Key == ApplicationInfoFilter.Keys.Type) ||
+ (item.Key == ApplicationInfoFilter.Keys.Category))
+ {
+ err = Interop.ApplicationManager.AppInfoFilterAddString(infoHandle, item.Key, item.Value);
+ }
+ else if ((item.Key == ApplicationInfoFilter.Keys.NoDisplay) ||
+ (item.Key == ApplicationInfoFilter.Keys.TaskManage))
+ {
+ err = Interop.ApplicationManager.AppInfoFilterAddBool(infoHandle, item.Key, Convert.ToBoolean(item.Value));
+ }
+ else
+ {
+ Log.Warn(LogTag, string.Format("'{0}' is not supported key for the filter.", item.Key));
+ }
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Interop.ApplicationManager.AppInfoFilterDestroy(infoHandle);
+ throw ApplicationManagerErrorFactory.GetException(err, "Failed to add item to the filter.");
+ }
+ }
+ return infoHandle;
+ }
+
+ private static IntPtr MakeNativeAppMetadataFilter(IDictionary<string, string> filter)
+ {
+ if (filter == null || filter.Count == 0)
+ {
+ throw ApplicationManagerErrorFactory.FilterIsInvalid();
+ }
+
+ IntPtr infoHandle = IntPtr.Zero;
+ Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppInfoMetadataFilterCreate(out infoHandle);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ throw ApplicationManagerErrorFactory.GetException(err, "Failed to create the filter for searching with metadata.");
+ }
+ foreach (var item in filter)
+ {
+ err = Interop.ApplicationManager.AppInfoMetadataFilterAdd(infoHandle, item.Key, item.Value);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Interop.ApplicationManager.AppInfoMetadataFilterDestroy(infoHandle);
+ throw ApplicationManagerErrorFactory.GetException(err, "Failed to add the item to the filter.");
+ }
+ }
+ return infoHandle;
+ }
+ }
+
+ internal static class ApplicationManagerErrorFactory
+ {
+ internal static Exception NativeFilterHandleIsInvalid()
+ {
+ return new InvalidOperationException("The native handle for filtering is invalid.");
+ }
+
+ internal static Exception FilterIsInvalid()
+ {
+ return new ArgumentException("The filter is invalid.");
+ }
+
+ internal static Exception GetException(Interop.ApplicationManager.ErrorCode err, string message)
+ {
+ string errMessage = String.Format("{0} err = {1}", message, err);
+ switch (err)
+ {
+ case Interop.ApplicationManager.ErrorCode.InvalidParameter:
+ return new ArgumentException(errMessage);
+ default:
+ return new InvalidOperationException(errMessage);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/ApplicationRunningContext.cs b/src/Tizen.Applications.Common/Tizen.Applications/ApplicationRunningContext.cs
new file mode 100644
index 0000000..35d9223
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/ApplicationRunningContext.cs
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// This class provides methods and properties to get information of the application.
+ /// </summary>
+ public class ApplicationRunningContext : IDisposable
+ {
+ private const string LogTag = "Tizen.Applications";
+ private bool _disposed = false;
+ private IntPtr _contextHandle = IntPtr.Zero;
+ private Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.ErrorCode.None;
+
+ internal ApplicationRunningContext(IntPtr contextHandle)
+ {
+ _contextHandle = contextHandle;
+ }
+
+ /// <summary>
+ /// A constructor of ApplicationRunningContext that takes the application id.
+ /// </summary>
+ /// <param name="applicationId">application id.</param>
+ /// <exception cref="ArgumentException">Thrown when failed of invalid argument.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when failed because of application not exist error or system error.</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when failed because of out of memory.</exception>
+ public ApplicationRunningContext(string applicationId)
+ {
+ IntPtr contextHandle = IntPtr.Zero;
+ err = Interop.ApplicationManager.AppManagerGetAppContext(applicationId, out contextHandle);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get the handle of the ApplicationRunningContext. err = " + err);
+ switch (err)
+ {
+ case Interop.ApplicationManager.ErrorCode.InvalidParameter:
+ throw new ArgumentException("Invalid Parameter.");
+ case Interop.ApplicationManager.ErrorCode.NoSuchApp:
+ throw new InvalidOperationException("No such application.");
+ case Interop.ApplicationManager.ErrorCode.OutOfMemory:
+ throw new OutOfMemoryException("Out of memory");
+ default:
+ throw new InvalidOperationException("Invalid Operation.");
+ }
+ }
+ _contextHandle = contextHandle;
+ }
+
+ /// <summary>
+ /// Destructor of the class
+ /// </summary>
+ ~ApplicationRunningContext()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Enumeration for the Application State.
+ /// </summary>
+ public enum AppState
+ {
+ /// <summary>
+ /// The undefined state
+ /// </summary>
+ Undefined = 0,
+
+ /// <summary>
+ /// The UI application is running in the foreground.
+ /// </summary>
+ Foreground,
+
+ /// <summary>
+ /// The UI application is running in the background.
+ /// </summary>
+ Background,
+
+ /// <summary>
+ /// The Service application is running.
+ /// </summary>
+ Service,
+
+ /// <summary>
+ /// The application is terminated.
+ /// </summary>
+ Terminated,
+ }
+
+ /// <summary>
+ /// Gets the application id.
+ /// </summary>
+ public string ApplicationId
+ {
+ get
+ {
+ string appid = string.Empty;
+ err = Interop.ApplicationManager.AppContextGetAppId(_contextHandle, out appid);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get the application id. err = " + err);
+ }
+ return appid;
+ }
+ }
+
+ /// <summary>
+ /// Gets the package id of the application.
+ /// </summary>
+ public string PackageId
+ {
+ get
+ {
+ string packageid = string.Empty;
+ err = Interop.ApplicationManager.AppContextGetPackageId(_contextHandle, out packageid);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get the package id. err = " + err);
+ }
+ return packageid;
+ }
+ }
+
+ /// <summary>
+ /// Gets the application's process id.
+ /// </summary>
+ public int ProcessId
+ {
+ get
+ {
+ int pid = 0;
+ err = Interop.ApplicationManager.AppContextGetPid(_contextHandle, out pid);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get the process id. err = " + err);
+ }
+ return pid;
+ }
+ }
+
+ /// <summary>
+ /// Gets the state of the application.
+ /// </summary>
+ public AppState State
+ {
+ get
+ {
+ int state = 0;
+
+ err = Interop.ApplicationManager.AppContextGetAppState(_contextHandle, out state);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get the application state. err = " + err);
+ }
+ return (AppState)state;
+ }
+ }
+
+ /// <summary>
+ /// Gets whether the application is sub application of the application group.
+ /// </summary>
+ public bool IsSubApp
+ {
+ get
+ {
+ bool subapp = false;
+ err = Interop.ApplicationManager.AppContextIsSubApp(_contextHandle, out subapp);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get the IsSubApp value. err = " + err);
+ }
+ return subapp;
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by the ApplicationRunningContext class.
+ /// </summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (_disposed)
+ return;
+
+ if (_contextHandle != IntPtr.Zero)
+ {
+ Interop.ApplicationManager.AppContextDestroy(_contextHandle);
+ _contextHandle = IntPtr.Zero;
+ }
+ _disposed = true;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/ApplicationTerminatedEventArgs.cs b/src/Tizen.Applications.Common/Tizen.Applications/ApplicationTerminatedEventArgs.cs
new file mode 100755
index 0000000..622dc91
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/ApplicationTerminatedEventArgs.cs
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Arguments for the event that is raised when the application is terminated.
+ /// </summary>
+ public class ApplicationTerminatedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// The information of the application.
+ /// </summary>
+ public ApplicationRunningContext ApplicationRunningContext { get; internal set; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/ApplicationType.cs b/src/Tizen.Applications.Common/Tizen.Applications/ApplicationType.cs
new file mode 100755
index 0000000..857c3a7
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/ApplicationType.cs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Enumeration for applications type.
+ /// </summary>
+ public enum ApplicationType
+ {
+ /// <summary>
+ /// All applications.
+ /// </summary>
+ All = 0,
+ /// <summary>
+ /// UI applications.
+ /// </summary>
+ Ui = 1,
+ /// <summary>
+ /// Service applications.
+ /// </summary>
+ Service = 2
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/Bundle.cs b/src/Tizen.Applications.Common/Tizen.Applications/Bundle.cs
new file mode 100755
index 0000000..1b56e8e
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/Bundle.cs
@@ -0,0 +1,714 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Reflection;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// A Bundle object represents a bundle.
+ /// A bundle holds items (key-value pairs) and can be used with other Tizen APIs.
+ /// Keys can be used to access values.
+ /// This class is accessed by using a constructor to create a new instance of this object.
+ /// A bundle instance is not guaranteed to be thread safe if the instance is modified by multiple threads.
+ /// </summary>
+ public class Bundle : IDisposable
+ {
+ private SafeBundleHandle _handle;
+ private bool _disposed = false;
+ private readonly HashSet<string> _keys;
+
+ /// <summary>
+ /// The Bundle constructor.
+ /// </summary>
+ /// <exception cref="System.InvalidOperationException">Thrown when out of memory</exception>
+ /// <code>
+ /// Tizen.Applications.Bundle bundle = new Tizen.Applications.Bundle();
+ /// </code>
+ public Bundle()
+ {
+ _handle = Interop.Bundle.Create();
+ BundleErrorFactory.CheckAndThrowException(ErrorFacts.GetLastResult(), _handle);
+ _keys = new HashSet<string>();
+ }
+
+ /// <summary>
+ /// The Bundle constructor.
+ /// </summary>
+ /// <param name="handle">The SafeBundleHandle instance.</param>
+ /// <exception cref="System.ArgumentNullException">Thrown when the handle is null or invalid.</exception>
+ public Bundle(SafeBundleHandle handle)
+ {
+ if (handle == null || handle.IsInvalid)
+ {
+ throw new ArgumentNullException("handle");
+ }
+
+ _handle = Interop.Bundle.DangerousClone(handle.DangerousGetHandle());
+ _keys = new HashSet<string>();
+ Interop.Bundle.Iterator iterator = (string key, int type, IntPtr keyval, IntPtr userData) =>
+ {
+ _keys.Add(key);
+ };
+
+ Interop.Bundle.Foreach(_handle, iterator, IntPtr.Zero);
+ if ((BundleErrorFactory.BundleError)ErrorFacts.GetLastResult() == BundleErrorFactory.BundleError.InvalidParameter)
+ {
+ throw new ArgumentException("Invalid parameter - cannot create bundle instance");
+ }
+ }
+
+ private enum BundleTypeProperty
+ {
+ Array = 0x0100,
+ Primitive = 0x0200,
+ Measurable = 0x0400
+ }
+
+ private enum BundleType
+ {
+ None = -1,
+ Any = 0,
+ String = 1 | BundleTypeProperty.Measurable,
+ StringArray = String | BundleTypeProperty.Array | BundleTypeProperty.Measurable,
+ Byte = 2,
+ ByteArray = Byte | BundleTypeProperty.Array
+ }
+
+ /// <summary>
+ /// The number of items in a Bundle object.
+ /// </summary>
+ /// <code>
+ /// Tizen.Applications.Bundle bundle = new Tizen.Applications.Bundle();
+ /// bundle.AddItem("string", "a_string");
+ /// Console.WriteLine("There are {0} items in the bundle", bundle.Count);
+ /// </code>
+ public int Count
+ {
+ get
+ {
+ return _keys.Count;
+ }
+ }
+
+ /// <summary>
+ /// The keys in a Bundle object.
+ /// </summary>
+ /// <code>
+ /// Tizen.Applications.Bundle bundle = new Tizen.Applications.Bundle();
+ /// bundle.AddItem("string1", "a_string1");
+ /// bundle.AddItem("string2", "a_string2");
+ /// bundle.AddItem("string3", "a_string3");
+ /// Console.WriteLine("The bundle contains the following keys:");
+ /// foreach(string key in bundle.Keys)
+ /// {
+ /// Console.WriteLine(key);
+ /// }
+ /// </code>
+ public IEnumerable<string> Keys
+ {
+ get
+ {
+ return _keys;
+ }
+ }
+
+ /// <summary>
+ /// Gets the SafeBundleHandle instance.
+ /// </summary>
+ public SafeBundleHandle SafeBundleHandle
+ {
+ get { return _handle; }
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object.
+ /// </summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Checks whether the bundle contains an item with a specified key.
+ /// </summary>
+ /// <param name="key">The key to check for.</param>
+ /// <returns>true if the bundle contains the key. false otherwise.</returns>
+ /// <code>
+ /// Tizen.Applications.Bundle bundle = new Tizen.Applications.Bundle();
+ /// bundle.AddItem("string", "a_string");
+ /// if (bundle.Contains("string"))
+ /// {
+ /// string aValue = bundle.GetItem<string>("string");
+ /// Console.WriteLine(aValue);
+ /// }
+ /// </code>
+ public bool Contains(string key)
+ {
+ return _keys.Contains(key);
+ }
+
+ /// <summary>
+ /// Adds an item into the bundle.
+ /// </summary>
+ /// <param name="key">The key to identify the item with. If an item with the key already exists in the Bundle, this method will not succeed.</param>
+ /// <param name="value">The value of the item.</param>
+ /// <exception cref="System.ArgumentException">Thrown when the key already exists or when there is an invalid parameter.</exception>
+ /// <exception cref="System.ArgumentNullException">Thrown when value is null.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when out of memory or when the Bundle instance has been disposed.</exception>
+ /// <code>
+ /// Tizen.Applications.Bundle bundle = new Tizen.Applications.Bundle();
+ /// byte[] byteArray = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+ /// bundle.AddItem("byte_array", byteArray);
+ /// </code>
+ public void AddItem(string key, byte[] value)
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+ AddItem(key, value, 0, value.Length);
+ }
+
+ /// <summary>
+ /// Adds an item into the bundle.
+ /// </summary>
+ /// <param name="key">The key to identify the item with. If an item with the key already exists in the Bundle, this method will not succeed.</param>
+ /// <param name="value">The value of the item.</param>
+ /// <param name="offset">The zero-based byte offset in value from which to add to the bundle.</param>
+ /// <param name="count">The maximum number of bytes to add to the bundle starting with offset.</param>
+ /// <exception cref="System.ArgumentOutOfRangeException">Thrown when the offset or count is out of range.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when the key already exists or when there is an invalid parameter.</exception>
+ /// <exception cref="System.ArgumentNullException">Thrown when value is null.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when out of memory or when the Bundle instance has been disposed.</exception>
+ /// <code>
+ /// Tizen.Applications.Bundle bundle = new Tizen.Applications.Bundle();
+ /// byte[] byteArray = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+ /// bundle.AddItem("byte_array", byteArray, 2, 3);
+ /// </code>
+ public void AddItem(string key, byte[] value, int offset, int count)
+ {
+ if (!_keys.Contains(key))
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+ if (offset < 0)
+ {
+ throw new ArgumentOutOfRangeException("offset", offset, "Cannot be less than 0");
+ }
+ if (offset > value.Length - 1)
+ {
+ throw new ArgumentOutOfRangeException("offset", offset, "Greater than last index of array");
+ }
+ if (count < 1)
+ {
+ throw new ArgumentOutOfRangeException("count", count, "Must be at least 1");
+ }
+ if (offset + count > value.Length)
+ {
+ throw new ArgumentException("The count is too large for the specified offset");
+ }
+ // Code is in Interop file because it is unsafe
+ int ret = Interop.Bundle.UnsafeCode.AddItem(_handle, key, value, offset, count);
+ BundleErrorFactory.CheckAndThrowException(ret, _handle);
+ _keys.Add(key);
+ }
+ else
+ {
+ throw new ArgumentException("Key already exists", "key");
+ }
+ }
+
+ /// <summary>
+ /// Adds an item into the bundle.
+ /// </summary>
+ /// <param name="key">The key to identify the item with. If an item with the key already exists in the Bundle, this method will not succeed.</param>
+ /// <param name="value">The value of the item.</param>
+ /// <exception cref="System.ArgumentException">Thrown when the key already exists or when there is an invalid parameter.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when out of memory or when the Bundle instance has been disposed.</exception>
+ /// <code>
+ /// Tizen.Applications.Bundle bundle = new Tizen.Applications.Bundle();
+ /// bundle.AddItem("string", "a_string");
+ /// </code>
+ public void AddItem(string key, string value)
+ {
+ if (!_keys.Contains(key))
+ {
+ int ret = Interop.Bundle.AddString(_handle, key, value);
+ BundleErrorFactory.CheckAndThrowException(ret, _handle);
+ _keys.Add(key);
+ }
+ else
+ {
+ throw new ArgumentException("Key already exists", "key");
+ }
+ }
+
+ /// <summary>
+ /// Adds an item into the bundle.
+ /// </summary>
+ /// <param name="key">The key to identify the item with. If an item with the key already exists in the Bundle, this method will not succeed.</param>
+ /// <param name="value">The value of the item.</param>
+ /// <exception cref="System.ArgumentException">Thrown when the key already exists or when there is an invalid parameter.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when out of memory or when the Bundle instance has been disposed.</exception>
+ /// <code>
+ /// Tizen.Applications.Bundle bundle = new Tizen.Applications.Bundle();
+ /// string[] stringArray = { "a", "b", "c" };
+ /// bundle.AddItem("string_array", stringArray);
+ /// </code>
+ public void AddItem(string key, IEnumerable<string> value)
+ {
+ if (!_keys.Contains(key))
+ {
+ string[] valueArray = value.Select(v => v == null ? string.Empty : v).ToArray();
+ int ret = Interop.Bundle.AddStringArray(_handle, key, valueArray, valueArray.Count());
+ BundleErrorFactory.CheckAndThrowException(ret, _handle);
+ _keys.Add(key);
+ }
+ else
+ {
+ throw new ArgumentException("Key already exists", "key");
+ }
+ }
+
+ /// <summary>
+ /// Gets the value of a bundle item with a specified key.
+ /// </summary>
+ /// <param name="key">The key of the bundle item whose value is desired.</param>
+ /// <returns>The value of the bundle item.</returns>
+ /// <exception cref="System.ArgumentException">Thrown when the key does not exist or when there is an invalid parameter.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when the Bundle instance has been disposed.</exception>
+ /// <code>
+ /// Tizen.Applications.Bundle bundle = new Tizen.Applications.Bundle();
+ /// bundle.AddItem("string", "a_string");
+ /// if (bundle.Contains("string"))
+ /// {
+ /// object aValue = bundle.GetItem("string");
+ /// if (bundle.Is<string>("string");)
+ /// {
+ /// string aString = (string)aValue;
+ /// Console.WriteLine(aString);
+ /// }
+ /// }
+ /// </code>
+ public object GetItem(string key)
+ {
+ if (_keys.Contains(key))
+ {
+ int type = Interop.Bundle.GetType(_handle, key);
+ BundleErrorFactory.CheckAndThrowException(ErrorFacts.GetLastResult(), _handle);
+ switch (type)
+ {
+ case (int)BundleType.String:
+ // get string
+ IntPtr stringPtr;
+ int retString = Interop.Bundle.GetString(_handle, key, out stringPtr);
+ BundleErrorFactory.CheckAndThrowException(retString, _handle);
+ string stringValue = Marshal.PtrToStringAnsi(stringPtr);
+ if (stringValue == null)
+ return string.Empty;
+ return stringValue;
+
+ case (int)BundleType.StringArray:
+ // get string array
+ int stringArraySize;
+ IntPtr stringArrayPtr = Interop.Bundle.GetStringArray(_handle, key, out stringArraySize);
+ BundleErrorFactory.CheckAndThrowException(ErrorFacts.GetLastResult(), _handle);
+ string[] stringArray;
+ IntPtrToStringArray(stringArrayPtr, stringArraySize, out stringArray);
+ return stringArray;
+
+ case (int)BundleType.Byte:
+ // get byte array
+ IntPtr byteArrayPtr;
+ int byteArraySize;
+ int retByte = Interop.Bundle.GetByte(_handle, key, out byteArrayPtr, out byteArraySize);
+ BundleErrorFactory.CheckAndThrowException(retByte, _handle);
+ byte[] byteArray = new byte[byteArraySize];
+ Marshal.Copy(byteArrayPtr, byteArray, 0, byteArraySize);
+ return byteArray;
+
+ default:
+ throw new ArgumentException("Key does not exist in the bundle", "key");
+ }
+ }
+ else
+ {
+ throw new ArgumentException("Key does not exist in the bundle (may be null or empty string)", "key");
+ }
+ }
+
+ /// <summary>
+ /// Gets the value of a bundle item with a specified key.
+ /// Note that this is a generic method.
+ /// </summary>
+ /// <typeparam name="T">The generic type to return.</typeparam>
+ /// <param name="key">The key of the bundle item whose value is desired.</param>
+ /// <returns>The value of the bundle item if it is of the specified generic type.</returns>
+ /// <exception cref="System.ArgumentException">Thrown when the key does not exist or when there is an invalid parameter.</exception>
+ /// <exception cref="System.InvalidCastException">Thrown when the value of the bundle item cannot be converted to the specified generic type.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when the Bundle instance has been disposed.</exception>
+ /// <code>
+ /// Tizen.Applications.Bundle bundle = new Tizen.Applications.Bundle();
+ /// string[] stringArray = { "a", "b", "c" };
+ /// bundle.AddItem("string_array", stringArray);
+ /// if (bundle.Is<string>("string_array"))
+ /// {
+ /// Console.WriteLine("It is a string");
+ /// Console.WriteLine(bundle.GetItem<string>("string_array"));
+ /// }
+ /// else if (bundle.Is<string[]>("string_array"))
+ /// {
+ /// Console.WriteLine("It is a string[]");
+ /// string[] anArray = bundle.GetItem<string[]>("string_array");
+ /// foreach (string value in anArray)
+ /// {
+ /// Console.WriteLine(value);
+ /// }
+ /// }
+ /// </code>
+ public T GetItem<T>(string key)
+ {
+ return (T)GetItem(key);
+ }
+
+ /// <summary>
+ /// Gets the value of a bundle item with a specified key.
+ /// </summary>
+ /// <param name="key">The key of the bundle item whose value is desired.</param>
+ /// <param name="value">The value of the bundle item. If the key does not exist or the type of this parameter is incorrect, it is the default value for the value parameter type.</param>
+ /// <returns>true if an item with the key exists and if the value is the same type as the output value parameter. false otherwise.</returns>
+ /// <exception cref="System.InvalidOperationException">Thrown when the Bundle instance has been disposed.</exception>
+ /// <code>
+ /// Tizen.Applications.Bundle bundle = new Tizen.Applications.Bundle();
+ /// byte[] byteArray = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+ /// bundle.AddItem("byte_array", byteArray);
+ /// byte[] aByteArray;
+ /// if (bundle.TryGetItem("byte_array", out aByteArray))
+ /// {
+ /// Console.WriteLine("First item in the byte array: {0}", aByteArray[0]);
+ /// }
+ /// </code>
+ public bool TryGetItem(string key, out byte[] value)
+ {
+ if (_keys.Contains(key) && Interop.Bundle.GetType(_handle, key) == (int)BundleType.Byte)
+ {
+ value = GetItem<byte[]>(key);
+ return true;
+ }
+ else
+ {
+ if (_keys.Contains(key) && ErrorFacts.GetLastResult() == (int)BundleErrorFactory.BundleError.InvalidParameter)
+ {
+ throw new InvalidOperationException("Invalid bundle instance (object may have been disposed or released)");
+ }
+ value = default(byte[]);
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Gets the value of a bundle item with a specified key.
+ /// </summary>
+ /// <param name="key">The key of the bundle item whose value is desired.</param>
+ /// <param name="value">The value of the bundle item. If the key does not exist or the type of this parameter is incorrect, it is the default value for the value parameter type.</param>
+ /// <returns>true if an item with the key exists and if the value is the same type as the output value parameter. false otherwise.</returns>
+ /// <exception cref="System.InvalidOperationException">Thrown when the Bundle instance has been disposed.</exception>
+ /// <code>
+ /// Tizen.Applications.Bundle bundle = new Tizen.Applications.Bundle();
+ /// bundle.AddItem("string", "a_string");
+ /// string aString;
+ /// if (bundle.TryGetItem("string", out aString))
+ /// {
+ /// Console.WriteLine(aString);
+ /// }
+ /// </code>
+ public bool TryGetItem(string key, out string value)
+ {
+ if (_keys.Contains(key) && Interop.Bundle.GetType(_handle, key) == (int)BundleType.String)
+ {
+ value = GetItem<string>(key);
+ return true;
+ }
+ else
+ {
+ if (_keys.Contains(key) && ErrorFacts.GetLastResult() == (int)BundleErrorFactory.BundleError.InvalidParameter)
+ {
+ throw new InvalidOperationException("Invalid bundle instance (object may have been disposed or released)");
+ }
+ value = default(string);
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Gets the value of a bundle item with a specified key.
+ /// </summary>
+ /// <param name="key">The key of the bundle item whose value is desired.</param>
+ /// <param name="value">The value of the bundle item. If the key does not exist or the type of this parameter is incorrect, it is the default value for the value parameter type.</param>
+ /// <returns>true if an item with the key exists and if the value is the same type as the output value parameter. false otherwise.</returns>
+ /// <exception cref="System.InvalidOperationException">Thrown when the Bundle instance has been disposed.</exception>
+ /// <code>
+ /// Tizen.Applications.Bundle bundle = new Tizen.Applications.Bundle();
+ /// string[] stringArray = { "a", "b", "c" };
+ /// bundle.AddItem("string_array", stringArray);
+ /// System.Collections.Generic.IEnumerable<string> aStringEnumerable;
+ /// if (bundle.TryGetItem("string", out aStringEnumerable))
+ /// {
+ /// foreach (string value in aStringEnumerable)
+ /// {
+ /// Console.WriteLine(value);
+ /// }
+ /// }
+ /// </code>
+ public bool TryGetItem(string key, out IEnumerable<string> value)
+ {
+ if (_keys.Contains(key) && Interop.Bundle.GetType(_handle, key) == (int)BundleType.StringArray)
+ {
+ value = GetItem<IEnumerable<string>>(key);
+ return true;
+ }
+ else
+ {
+ if (_keys.Contains(key) && ErrorFacts.GetLastResult() == (int)BundleErrorFactory.BundleError.InvalidParameter)
+ {
+ throw new InvalidOperationException("Invalid bundle instance (object may have been disposed or released)");
+ }
+ value = default(IEnumerable<string>);
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Checks whether an item is of a specific type.
+ /// </summary>
+ /// <typeparam name="T">The generic type to check for.</typeparam>
+ /// <param name="key">The key whose type wants to be checked.</param>
+ /// <returns>true if the item is of the specified type. false otherwise.</returns>
+ /// <exception cref="System.ArgumentException">Thrown when the key does not exist or when there is an invalid parameter.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when the Bundle instance has been disposed.</exception>
+ /// <code>
+ /// Tizen.Applications.Bundle bundle = new Tizen.Applications.Bundle();
+ /// string[] stringArray = { "a", "b", "c" };
+ /// bundle.AddItem("string_array", stringArray);
+ /// if (bundle.Is<string[]>("string_array"))
+ /// {
+ /// Console.WriteLine("It is a string[]");
+ /// string[] anArray = bundle.GetItem<string[]>("string_array");
+ /// foreach (string value in anArray)
+ /// {
+ /// Console.WriteLine(value);
+ /// }
+ /// }
+ /// </code>
+ public bool Is<T>(string key)
+ {
+ if (_keys.Contains(key))
+ {
+ int type = Interop.Bundle.GetType(_handle, key);
+ switch (type)
+ {
+ case (int)BundleType.String:
+ return typeof(string) == typeof(T);
+
+ case (int)BundleType.StringArray:
+ return typeof(T).GetTypeInfo().IsAssignableFrom(typeof(string[]).GetTypeInfo());
+
+ case (int)BundleType.Byte:
+ return typeof(byte[]) == typeof(T);
+
+ default:
+ throw new ArgumentException("Key does not exist in the bundle", "key");
+ }
+ }
+ else
+ {
+ throw new ArgumentException("Key does not exist in the bundle (may be null or empty string)", "key");
+ }
+ }
+
+ /// <summary>
+ /// Removes a a bundle item with a specific key from a Bundle.
+ /// </summary>
+ /// <param name="key">The key of the item to delete.</param>
+ /// <returns>true if the item is successfully found and removed. false otherwise (even if the item is not found).</returns>
+ /// <exception cref="System.ArgumentException">Thrown when there is an invalid parameter.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when the Bundle instance has been disposed.</exception>
+ /// <code>
+ /// Tizen.Applications.Bundle bundle = new Tizen.Applications.Bundle();
+ /// bundle.AddItem("string", "a_string");
+ /// if (bundle.Contains("string"))
+ /// {
+ /// if (bundle.RemoveItem("string"))
+ /// {
+ /// Console.WriteLine("Removed");
+ /// }
+ /// }
+ /// </code>
+ public bool RemoveItem(string key)
+ {
+ if (_keys.Contains(key))
+ {
+ int ret = Interop.Bundle.RemoveItem(_handle, key);
+ if (ret == (int)BundleErrorFactory.BundleError.KeyNotAvailable)
+ {
+ return false;
+ }
+ BundleErrorFactory.CheckAndThrowException(ret, _handle);
+ _keys.Remove(key);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Decodes an encoded bundle data.
+ /// </summary>
+ /// <param name="bundleRaw">The encoded bundle data. bundleRaw should be return value of Tizen.Applications.Bundle.Encode, otherwise this method will not succeed</param>
+ /// <returns>Decoded Bundle object.</returns>
+ /// <exception cref="System.ArgumentException">Thrown when there is an invalid parameter.</exception>
+ /// <code>
+ /// Tizen.Applications.Bundle bundle = new Tizen.Applications.Bundle();
+ /// string bundleRaw = bundle.Encode();
+ /// Bundle data = bundle.Decode(bundleRaw);
+ /// </code>
+ public static Bundle Decode(string bundleRaw)
+ {
+ SafeBundleHandle handle;
+
+ handle = Interop.Bundle.BundleDecode(bundleRaw, bundleRaw.Length);
+ if (ErrorFacts.GetLastResult() == (int)BundleErrorFactory.BundleError.InvalidParameter)
+ {
+ throw new ArgumentException("Invalid bundle raw");
+ }
+
+ return new Bundle(handle);
+ }
+
+ /// <summary>
+ /// Encodes bundle to string.
+ /// </summary>
+ /// <returns>Encoded Bundle data in string.</returns>
+ /// <exception cref="System.InvalidOperationException">Thrown when out of memory or when the Bundle instance has been disposed.</exception>
+ /// <code>
+ /// Tizen.Applications.Bundle bundle = new Tizen.Applications.Bundle();
+ /// string bundleRaw = bundle.Encode();
+ /// </code>
+ public string Encode()
+ {
+ string bundleRaw;
+ int len;
+
+ Interop.Bundle.BundleEncode(_handle, out bundleRaw, out len);
+ if (ErrorFacts.GetLastResult() == (int)BundleErrorFactory.BundleError.InvalidParameter)
+ {
+ throw new InvalidOperationException("Invalid bundle");
+ }
+
+ return bundleRaw;
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+ /// </summary>
+ /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (disposing)
+ {
+ if (_handle != null && !_handle.IsInvalid)
+ _handle.Dispose();
+ }
+
+ _disposed = true;
+ }
+ }
+
+ /// <summary>
+ /// Destructor of the Bundle class.
+ /// </summary>
+ ~Bundle()
+ {
+ Dispose(false);
+ }
+
+ static private void IntPtrToStringArray(IntPtr unmanagedArray, int size, out string[] managedArray)
+ {
+ managedArray = new string[size];
+ IntPtr[] IntPtrArray = new IntPtr[size];
+
+ Marshal.Copy(unmanagedArray, IntPtrArray, 0, size);
+
+ for (int iterator = 0; iterator < size; iterator++)
+ {
+ managedArray[iterator] = Marshal.PtrToStringAnsi(IntPtrArray[iterator]);
+ }
+ }
+ }
+
+ internal static class BundleErrorFactory
+ {
+ internal enum BundleError
+ {
+ None = ErrorCode.None,
+ OutOfMemory = ErrorCode.OutOfMemory,
+ InvalidParameter = ErrorCode.InvalidParameter,
+ KeyNotAvailable = ErrorCode.KeyNotAvailable,
+ KeyExists = -0x01180000 | 0x01
+ }
+
+ static internal void CheckAndThrowException(int error, SafeBundleHandle handle)
+ {
+ if ((BundleError)error == BundleError.None)
+ {
+ return;
+ }
+ else if ((BundleError)error == BundleError.OutOfMemory)
+ {
+ throw new InvalidOperationException("Out of memory");
+ }
+ else if ((BundleError)error == BundleError.InvalidParameter)
+ {
+ if (handle.IsInvalid)
+ {
+ throw new InvalidOperationException("Invalid bundle instance (object may have been disposed or released)");
+ }
+ throw new ArgumentException("Invalid parameter");
+ }
+ else if ((BundleError)error == BundleError.KeyNotAvailable)
+ {
+ throw new ArgumentException("Key does not exist in the bundle");
+ }
+ else if ((BundleError)error == BundleError.KeyExists)
+ {
+ throw new ArgumentException("Key already exists");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/CoreApplication.cs b/src/Tizen.Applications.Common/Tizen.Applications/CoreApplication.cs
new file mode 100755
index 0000000..5bf6e39
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/CoreApplication.cs
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+using Tizen.Applications.CoreBackend;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Class that represents an application controlled lifecycles by the backend system.
+ /// </summary>
+ public class CoreApplication : Application
+ {
+ private readonly ICoreBackend _backend;
+ private bool _disposedValue = false;
+
+ /// <summary>
+ /// Initializes the CoreApplication class.
+ /// </summary>
+ /// <param name="backend">The backend instance implementing ICoreBacked interface.</param>
+ public CoreApplication(ICoreBackend backend)
+ {
+ _backend = backend;
+ }
+
+ /// <summary>
+ /// Occurs when the application is launched.
+ /// </summary>
+ public event EventHandler Created;
+
+ /// <summary>
+ /// Occurs when the application is about to shutdown.
+ /// </summary>
+ public event EventHandler Terminated;
+
+ /// <summary>
+ /// Occurs whenever the application receives the appcontrol message.
+ /// </summary>
+ public event EventHandler<AppControlReceivedEventArgs> AppControlReceived;
+
+ /// <summary>
+ /// Occurs when the system memory is low.
+ /// </summary>
+ public event EventHandler<LowMemoryEventArgs> LowMemory;
+
+ /// <summary>
+ /// Occurs when the system battery is low.
+ /// </summary>
+ public event EventHandler<LowBatteryEventArgs> LowBattery;
+
+ /// <summary>
+ /// Occurs when the system language is chagned.
+ /// </summary>
+ public event EventHandler<LocaleChangedEventArgs> LocaleChanged;
+
+ /// <summary>
+ /// Occurs when the region format is changed.
+ /// </summary>
+ public event EventHandler<RegionFormatChangedEventArgs> RegionFormatChanged;
+
+ /// <summary>
+ /// Occurs when the device orientation is changed.
+ /// </summary>
+ public event EventHandler<DeviceOrientationEventArgs> DeviceOrientationChanged;
+
+ /// <summary>
+ /// The backend instance.
+ /// </summary>
+ protected ICoreBackend Backend { get { return _backend; } }
+
+ /// <summary>
+ /// Runs the application's main loop.
+ /// </summary>
+ /// <param name="args">Arguments from commandline.</param>
+ public override void Run(string[] args)
+ {
+ base.Run(args);
+
+ _backend.AddEventHandler(EventType.Created, OnCreate);
+ _backend.AddEventHandler(EventType.Terminated, OnTerminate);
+ _backend.AddEventHandler<AppControlReceivedEventArgs>(EventType.AppControlReceived, OnAppControlReceived);
+ _backend.AddEventHandler<LowMemoryEventArgs>(EventType.LowMemory, OnLowMemory);
+ _backend.AddEventHandler<LowBatteryEventArgs>(EventType.LowBattery, OnLowBattery);
+ _backend.AddEventHandler<LocaleChangedEventArgs>(EventType.LocaleChanged, OnLocaleChanged);
+ _backend.AddEventHandler<RegionFormatChangedEventArgs>(EventType.RegionFormatChanged, OnRegionFormatChanged);
+ _backend.AddEventHandler<DeviceOrientationEventArgs>(EventType.DeviceOrientationChanged, OnDeviceOrientationChanged);
+
+ string[] argsClone = null;
+
+ if (args == null)
+ {
+ argsClone = new string[1];
+ }
+ else
+ {
+ argsClone = new string[args.Length + 1];
+ args.CopyTo(argsClone, 1);
+ }
+ argsClone[0] = string.Empty;
+ _backend.Run(argsClone);
+ }
+
+ /// <summary>
+ /// Exits the main loop of the application.
+ /// </summary>
+ public override void Exit()
+ {
+ _backend.Exit();
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the application is launched.
+ /// If base.OnCreated() is not called, the event 'Created' will not be emitted.
+ /// </summary>
+ protected virtual void OnCreate()
+ {
+ Created?.Invoke(this, EventArgs.Empty);
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the application is terminated.
+ /// If base.OnTerminate() is not called, the event 'Terminated' will not be emitted.
+ /// </summary>
+ protected virtual void OnTerminate()
+ {
+ Terminated?.Invoke(this, EventArgs.Empty);
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the application receives the appcontrol message.
+ /// If base.OnAppControlReceived() is not called, the event 'AppControlReceived' will not be emitted.
+ /// </summary>
+ /// <param name="e"></param>
+ protected virtual void OnAppControlReceived(AppControlReceivedEventArgs e)
+ {
+ AppControlReceived?.Invoke(this, e);
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the system memory is low.
+ /// If base.OnLowMemory() is not called, the event 'LowMemory' will not be emitted.
+ /// </summary>
+ protected virtual void OnLowMemory(LowMemoryEventArgs e)
+ {
+ LowMemory?.Invoke(this, e);
+ System.GC.Collect();
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the system battery is low.
+ /// If base.OnLowBattery() is not called, the event 'LowBattery' will not be emitted.
+ /// </summary>
+ protected virtual void OnLowBattery(LowBatteryEventArgs e)
+ {
+ LowBattery?.Invoke(this, e);
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the system language is changed.
+ /// If base.OnLocaleChanged() is not called, the event 'LocaleChanged' will not be emitted.
+ /// </summary>
+ protected virtual void OnLocaleChanged(LocaleChangedEventArgs e)
+ {
+ LocaleChanged?.Invoke(this, e);
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the region format is changed.
+ /// If base.OnRegionFormatChanged() is not called, the event 'RegionFormatChanged' will not be emitted.
+ /// </summary>
+ protected virtual void OnRegionFormatChanged(RegionFormatChangedEventArgs e)
+ {
+ RegionFormatChanged?.Invoke(this, e);
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the device orientation is changed.
+ /// If base.OnRegionFormatChanged() is not called, the event 'RegionFormatChanged' will not be emitted.
+ /// </summary>
+ protected virtual void OnDeviceOrientationChanged(DeviceOrientationEventArgs e)
+ {
+ DeviceOrientationChanged?.Invoke(this, e);
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+ /// </summary>
+ /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
+ protected override void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ if (disposing)
+ {
+ _backend.Dispose();
+ }
+
+ _disposedValue = true;
+ }
+ base.Dispose(disposing);
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/DeviceOrientation.cs b/src/Tizen.Applications.Common/Tizen.Applications/DeviceOrientation.cs
new file mode 100755
index 0000000..5b41aea
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/DeviceOrientation.cs
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Enumeration for device orientation.
+ /// </summary>
+ public enum DeviceOrientation
+ {
+ /// <summary>
+ /// The device orientation is 0
+ /// </summary>
+ Orientation_0 = 0,
+
+ /// <summary>
+ /// The device orientation is 90
+ /// </summary>
+ Orientation_90 = 90,
+
+ /// <summary>
+ /// The device orientation is 180
+ /// </summary>
+ Orientation_180 = 180,
+
+ /// <summary>
+ /// The device orientation is 270
+ /// </summary>
+ Orientation_270 = 270,
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/DeviceOrientationEventArgs.cs b/src/Tizen.Applications.Common/Tizen.Applications/DeviceOrientationEventArgs.cs
new file mode 100755
index 0000000..e042e32
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/DeviceOrientationEventArgs.cs
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// The class for event arguments of the DeviceOrientationChanged
+ /// </summary>
+ public class DeviceOrientationEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Initializes DeviceOrientationEventArgs class
+ /// </summary>
+ /// <param name="orientation"></param>
+ public DeviceOrientationEventArgs(DeviceOrientation orientation)
+ {
+ DeviceOrientation = orientation;
+ }
+
+ /// <summary>
+ /// The received DeviceOrientation
+ /// </summary>
+ public DeviceOrientation DeviceOrientation { get; private set; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/DirectoryInfo.cs b/src/Tizen.Applications.Common/Tizen.Applications/DirectoryInfo.cs
new file mode 100755
index 0000000..4b7f06b
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/DirectoryInfo.cs
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Represents directory information of the application.
+ /// </summary>
+ public class DirectoryInfo
+ {
+ private string _dataPath;
+ private string _cachePath;
+ private string _resourcePath;
+
+ private string _sharedDataPath;
+ private string _sharedResourcePath;
+ private string _sharedTrustedPath;
+
+ private string _externalDataPath;
+ private string _externalCachePath;
+ private string _externalSharedDataPath;
+
+ private string _expansionPackageResourcePath;
+
+ internal DirectoryInfo()
+ {
+ }
+
+ /// <summary>
+ /// Gets the absolute path to the application's data directory which is used to store private data of the application.
+ /// </summary>
+ public string Data
+ {
+ get
+ {
+ if (_dataPath == null)
+ _dataPath = Interop.AppCommon.AppGetDataPath();
+ return _dataPath;
+ }
+ }
+
+ /// <summary>
+ /// Gets the absolute path to the application's cache directory which is used to store temporary data of the application.
+ /// </summary>
+ public string Cache
+ {
+ get
+ {
+ if (_cachePath == null)
+ _cachePath = Interop.AppCommon.AppGetCachePath();
+ return _cachePath;
+ }
+ }
+
+ /// <summary>
+ /// Gets the absolute path to the application resource directory. The resource files are delivered with the application package.
+ /// </summary>
+ public string Resource
+ {
+ get
+ {
+ if (_resourcePath == null)
+ _resourcePath = Interop.AppCommon.AppGetResourcePath();
+ return _resourcePath;
+ }
+ }
+
+ /// <summary>
+ /// Gets the absolute path to the application's shared data directory which is used to share data with other applications.
+ /// </summary>
+ public string SharedData
+ {
+ get
+ {
+ if (_sharedDataPath == null)
+ _sharedDataPath = Interop.AppCommon.AppGetSharedDataPath();
+ return _sharedDataPath;
+ }
+ }
+
+ /// <summary>
+ /// Gets the absolute path to the application's shared resource directory which is used to share resources with other applications.
+ /// </summary>
+ public string SharedResource
+ {
+ get
+ {
+ if (_sharedResourcePath == null)
+ _sharedResourcePath = Interop.AppCommon.AppGetSharedResourcePath();
+ return _sharedResourcePath;
+ }
+ }
+
+
+ /// <summary>
+ /// Gets the absolute path to the application's shared trusted directory which is used to share data with a family of trusted applications.
+ /// </summary>
+ public string SharedTrusted
+ {
+ get
+ {
+ if (_sharedTrustedPath == null)
+ _sharedTrustedPath = Interop.AppCommon.AppGetSharedTrustedPath();
+ return _sharedTrustedPath;
+ }
+ }
+
+ /// <summary>
+ /// Gets the absolute path to the application's external data directory which is used to store data of the application.
+ /// </summary>
+ public string ExternalData
+ {
+ get
+ {
+ if (_externalDataPath == null)
+ _externalDataPath = Interop.AppCommon.AppGetExternalDataPath();
+ return _externalDataPath;
+ }
+ }
+
+ /// <summary>
+ /// Gets the absolute path to the application's external cache directory which is used to store temporary data of the application.
+ /// </summary>
+ public string ExternalCache
+ {
+ get
+ {
+ if (_externalCachePath == null)
+ _externalCachePath = Interop.AppCommon.AppGetExternalCachePath();
+ return _externalCachePath;
+ }
+ }
+
+ /// <summary>
+ /// Gets the absolute path to the application's external shared data directory which is used to share data with other applications.
+ /// </summary>
+ public string ExternalSharedData
+ {
+ get
+ {
+ if (_externalSharedDataPath == null)
+ _externalSharedDataPath = Interop.AppCommon.AppGetExternalSharedDataPath();
+ return _externalSharedDataPath;
+ }
+ }
+
+ /// <summary>
+ /// Gets the absolute path to the application's TEP(Tizen Expansion Package) directory. The resource files are delivered with the expansion package.
+ /// </summary>
+ public string ExpansionPackageResource
+ {
+ get
+ {
+ if (_expansionPackageResourcePath == null)
+ _expansionPackageResourcePath = Interop.AppCommon.AppGetTepResourcePath();
+ return _expansionPackageResourcePath;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/LocaleChangedEventArgs.cs b/src/Tizen.Applications.Common/Tizen.Applications/LocaleChangedEventArgs.cs
new file mode 100755
index 0000000..314495d
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/LocaleChangedEventArgs.cs
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ ///
+ /// </summary>
+ public class LocaleChangedEventArgs : EventArgs
+ {
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="locale"></param>
+ public LocaleChangedEventArgs(string locale)
+ {
+ Locale = locale;
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public string Locale { get; private set; }
+
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/LowBatteryEventArgs.cs b/src/Tizen.Applications.Common/Tizen.Applications/LowBatteryEventArgs.cs
new file mode 100755
index 0000000..e3c45a1
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/LowBatteryEventArgs.cs
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ ///
+ /// </summary>
+ public class LowBatteryEventArgs : EventArgs
+ {
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="status"></param>
+ public LowBatteryEventArgs(LowBatteryStatus status)
+ {
+ LowBatteryStatus = status;
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public LowBatteryStatus LowBatteryStatus { get; private set; }
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/LowBatteryStatus.cs b/src/Tizen.Applications.Common/Tizen.Applications/LowBatteryStatus.cs
new file mode 100755
index 0000000..a835521
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/LowBatteryStatus.cs
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Enumeration for low battery status.
+ /// </summary>
+ public enum LowBatteryStatus
+ {
+ /// <summary>
+ ///
+ /// </summary>
+ None = 0,
+
+ /// <summary>
+ /// The battery status is under 1%
+ /// </summary>
+ PowerOff = 1,
+
+ /// <summary>
+ /// The battery status is under 5%
+ /// </summary>
+ CriticalLow
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/LowMemoryEventArgs.cs b/src/Tizen.Applications.Common/Tizen.Applications/LowMemoryEventArgs.cs
new file mode 100755
index 0000000..062a4b9
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/LowMemoryEventArgs.cs
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ ///
+ /// </summary>
+ public class LowMemoryEventArgs : EventArgs
+ {
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="status"></param>
+ public LowMemoryEventArgs(LowMemoryStatus status)
+ {
+ LowMemoryStatus = status;
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public LowMemoryStatus LowMemoryStatus { get; private set; }
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/LowMemoryStatus.cs b/src/Tizen.Applications.Common/Tizen.Applications/LowMemoryStatus.cs
new file mode 100755
index 0000000..e704de3
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/LowMemoryStatus.cs
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Enumeration for low memory status.
+ /// </summary>
+ public enum LowMemoryStatus
+ {
+ /// <summary>
+ /// Not initialized status
+ /// </summary>
+ None = 0x00,
+
+ /// <summary>
+ /// Normal status
+ /// </summary>
+ Normal = 0x01,
+
+ /// <summary>
+ /// Soft warning status
+ /// </summary>
+ SoftWarning = 0x02,
+
+ /// <summary>
+ /// Hard warning status
+ /// </summary>
+ HardWarning = 0x04,
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/ReceivedAppControl.cs b/src/Tizen.Applications.Common/Tizen.Applications/ReceivedAppControl.cs
new file mode 100755
index 0000000..638ee7a
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/ReceivedAppControl.cs
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Represents the received AppControl.
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// public class ReceivedAppControlExample : UIApplication
+ /// {
+ /// // ...
+ /// protected override void OnAppControlReceived(AppControlReceivedEventArgs e)
+ /// {
+ /// ReceivedAppControl control = e.ReceivedAppControl;
+ /// if (control.Operation == AppControlOperations.Pick)
+ /// {
+ /// Log.Debug(LogTag, "Received AppControl is Pick");
+ /// }
+ /// if (control.IsReplyRequest)
+ /// {
+ /// AppControl replyRequest = new AppControl();
+ /// replyRequest.ExtraData.Add("myKey", "I'm replying");
+ /// control.ReplyToLaunchRequest(replyRequest, AppControlReplyResult.Succeeded);
+ /// }
+ /// }
+ /// }
+ /// </code>
+ /// </example>
+ public class ReceivedAppControl : AppControl
+ {
+ private const string LogTag = "Tizen.Applications";
+
+ /// <summary>
+ /// Initializes a ReceivedAppControl class.
+ /// </summary>
+ public ReceivedAppControl(SafeAppControlHandle handle) : base(handle)
+ {
+ }
+
+ /// <summary>
+ /// Gets the application ID of the caller from the launch request.
+ /// </summary>
+ /// <value>
+ /// The application ID of the caller
+ /// </value>
+ /// <example>
+ /// <code>
+ /// protected override void OnAppControlReceived(AppControlReceivedEventArgs e)
+ /// {
+ /// ReceivedAppControl control = e.ReceivedAppControl;
+ /// string caller = control.CallerApplicationId;
+ /// }
+ /// </code>
+ /// </example>
+ public string CallerApplicationId
+ {
+ get
+ {
+ string value = String.Empty;
+ Interop.AppControl.ErrorCode err = Interop.AppControl.GetCaller(SafeAppControlHandle, out value);
+ if (err != Interop.AppControl.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get the caller application id from the AppControl. Err = " + err);
+ }
+ return value;
+ }
+ }
+
+ /// <summary>
+ /// Checks whether the caller is requesting a reply from the launch request.
+ /// </summary>
+ /// <value>
+ /// If true this ReceivedAppControl is requested by the caller, otherwise false
+ /// </value>
+ /// <example>
+ /// <code>
+ /// protected override void OnAppControlReceived(AppControlReceivedEventArgs e)
+ /// {
+ /// ReceivedAppControl control = e.ReceivedAppControl;
+ /// bool isReply = control.IsReplyRequest;
+ /// }
+ /// </code>
+ /// </example>
+ public bool IsReplyRequest
+ {
+ get
+ {
+ bool value = false;
+ Interop.AppControl.ErrorCode err = Interop.AppControl.IsReplyRequested(SafeAppControlHandle, out value);
+ if (err != Interop.AppControl.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to check the reply of the AppControl is requested. Err = " + err);
+ }
+ return value;
+ }
+ }
+
+ /// <summary>
+ /// Replies to the launch request sent by the caller.
+ /// If the caller application sent the launch request to receive the result, the callee application can return the result back to the caller.
+ /// </summary>
+ /// <param name="replyRequest">The AppControl in which the results of the callee are contained</param>
+ /// <param name="result">The result code of the launch request</param>
+ /// <example>
+ /// <code>
+ /// protected override void OnAppControlReceived(AppControlReceivedEventArgs e)
+ /// {
+ /// ReceivedAppControl control = e.ReceivedAppControl;
+ /// if (control.IsReplyRequest)
+ /// {
+ /// AppControl replyRequest = new AppControl();
+ /// replyRequest.ExtraData.Add("myKey", "I'm replying");
+ /// control.ReplyToLaunchRequest(replyRequest, AppControlReplyResult.Succeeded);
+ /// }
+ /// }
+ /// </code>
+ /// </example>
+ public void ReplyToLaunchRequest(AppControl replyRequest, AppControlReplyResult result)
+ {
+ if (replyRequest == null)
+ {
+ throw new ArgumentNullException("replyRequest");
+ }
+ Interop.AppControl.ErrorCode err = Interop.AppControl.ReplyToLaunchRequest(replyRequest.SafeAppControlHandle, this.SafeAppControlHandle, (int)result);
+ if (err != Interop.AppControl.ErrorCode.None)
+ throw new InvalidOperationException("Failed to reply. Err = " + err);
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/RecentApplicationControl.cs b/src/Tizen.Applications.Common/Tizen.Applications/RecentApplicationControl.cs
new file mode 100755
index 0000000..3ff7bb8
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/RecentApplicationControl.cs
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// This class provides methods and properties to get information of recent application.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public class RecentApplicationControl
+ {
+ private const string LogTag = "Tizen.Applications";
+
+ private readonly string _pkgId;
+
+ internal RecentApplicationControl(String pkgId)
+ {
+ _pkgId = pkgId;
+ }
+
+ /// <summary>
+ /// Deletes the application from recent application list.
+ /// </summary>
+ public void Delete()
+ {
+ Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.ErrorCode.None;
+ err = Interop.ApplicationManager.RuaDeleteHistoryWithPkgname(_pkgId);
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ throw ApplicationManagerErrorFactory.GetException(err, "Failed to delete application from recent application list.");
+ }
+ }
+
+ /// <summary>
+ /// Delete all recent applicationsfrom recent application list.
+ /// </summary>
+ public static void DeleteAll()
+ {
+ Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.ErrorCode.None;
+ err = Interop.ApplicationManager.RuaClearHistory();
+ if (err != Interop.ApplicationManager.ErrorCode.None)
+ {
+ throw ApplicationManagerErrorFactory.GetException(err, "Failed to clear the recent application list.");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/RecentApplicationInfo.cs b/src/Tizen.Applications.Common/Tizen.Applications/RecentApplicationInfo.cs
new file mode 100755
index 0000000..613e7d6
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/RecentApplicationInfo.cs
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// This class provides methods and properties to get information of recent application.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public class RecentApplicationInfo : ApplicationInfo
+ {
+ private const string LogTag = "Tizen.Applications";
+
+ /// <summary>
+ /// Gets the instance id.
+ /// </summary>
+ public string InstanceId { get; private set; }
+
+ /// <summary>
+ /// Gets the instance Name.
+ /// </summary>
+ public string InstanceName { get; private set; }
+
+ /// <summary>
+ /// Gets the arguements.
+ /// </summary>
+ public string Arg { get; private set; }
+
+ /// <summary>
+ /// Gets the uri.
+ /// </summary>
+ public string Uri { get; private set; }
+
+ /// <summary>
+ /// Gets the launchTime.
+ /// </summary>
+ public DateTime LaunchTime { get; private set; }
+
+ /// <summary>
+ /// Gets the recent application controller.
+ /// </summary>
+ public RecentApplicationControl Controller { get; private set; }
+
+ internal RecentApplicationInfo(Interop.ApplicationManager.RuaRec record) : base(Marshal.PtrToStringAnsi(record.pkgName))
+ {
+ InstanceId = Marshal.PtrToStringAnsi(record.instanceId);
+ InstanceName = Marshal.PtrToStringAnsi(record.instanceName);
+ Arg = Marshal.PtrToStringAnsi(record.arg);
+ Uri = Marshal.PtrToStringAnsi(record.uri);
+ long seconds = record.launchTime.ToInt64();
+ LaunchTime = new DateTime(1970, 1, 1).AddSeconds(seconds);
+ Controller = new RecentApplicationControl(Marshal.PtrToStringAnsi(record.pkgName));
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/RegionFormatChangedEventArgs.cs b/src/Tizen.Applications.Common/Tizen.Applications/RegionFormatChangedEventArgs.cs
new file mode 100755
index 0000000..531a8dd
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/RegionFormatChangedEventArgs.cs
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ ///
+ /// </summary>
+ public class RegionFormatChangedEventArgs : EventArgs
+ {
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="region"></param>
+ public RegionFormatChangedEventArgs(string region)
+ {
+ Region = region;
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public string Region { get; private set; }
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/ResourceManager.cs b/src/Tizen.Applications.Common/Tizen.Applications/ResourceManager.cs
new file mode 100755
index 0000000..c20840a
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/ResourceManager.cs
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Class for getting resource path.
+ /// </summary>
+ public static class ResourceManager
+ {
+ /// <summary>
+ /// Enumeration for Resource category.
+ /// </summary>
+ public enum Category : int
+ {
+ /// <summary>
+ /// Image format.
+ /// </summary>
+ Image = 0,
+
+ /// <summary>
+ /// Layout format.
+ /// </summary>
+ Layout,
+
+ /// <summary>
+ /// Sound format.
+ /// </summary>
+ Sound,
+
+ /// <summary>
+ /// Binary format.
+ /// </summary>
+ Binary
+ }
+
+ private static ErrorCode AppResourceManagerGet(Category category, string id, out string path)
+ {
+ ErrorCode err;
+
+ try
+ {
+ err = Interop.AppCommon.AppResourceManagerGet(
+ (Interop.AppCommon.ResourceCategory)category, id, out path);
+ }
+ catch (System.TypeLoadException)
+ {
+ err = Interop.AppCommon.LegacyAppResourceManagerGet(
+ (Interop.AppCommon.ResourceCategory)category, id, out path);
+ }
+
+ return err;
+ }
+
+ /// <summary>
+ /// Converts resource ID to path name.
+ /// </summary>
+ /// <param name="category">Category to search</param>
+ /// <param name="id">ID to search</param>
+ /// <returns>Found resource path</returns>
+ /// <exception cref="InvalidOperationException">Thrown in case of failed conditions</exception>
+ public static string GetPath(Category category, string id)
+ {
+ string path;
+ ErrorCode err = AppResourceManagerGet(category, id, out path);
+
+ switch (err)
+ {
+ case ErrorCode.InvalidParameter:
+ throw new InvalidOperationException("Invalid parameter");
+
+ case ErrorCode.OutOfMemory:
+ throw new InvalidOperationException("Out-of-memory at unmanaged code");
+
+ case ErrorCode.IoError:
+ throw new InvalidOperationException("IO error at unmanaged code");
+ }
+
+ return path;
+ }
+
+ /// <summary>
+ /// Converts resource ID to path name.
+ /// </summary>
+ /// <param name="category">Category to search</param>
+ /// <param name="id">ID to search</param>
+ /// <returns>Found resource path or null when the resource doesn't exist</returns>
+ /// <exception cref="InvalidOperationException">Thrown in case of failed conditions</exception>
+ public static string TryGetPath(Category category, string id)
+ {
+ string path;
+ ErrorCode err = AppResourceManagerGet(category, id, out path);
+
+ switch (err)
+ {
+ case ErrorCode.InvalidParameter:
+ throw new InvalidOperationException("Invalid parameter");
+
+ case ErrorCode.OutOfMemory:
+ throw new InvalidOperationException("Out-of-memory at unmanaged code");
+
+ case ErrorCode.IoError:
+ return null;
+ }
+
+ return path;
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/SafeAppControlHandle.cs b/src/Tizen.Applications.Common/Tizen.Applications/SafeAppControlHandle.cs
new file mode 100755
index 0000000..5bbdf60
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/SafeAppControlHandle.cs
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Represents a wrapper class for a unmanaged AppControl handle.
+ /// </summary>
+ public sealed class SafeAppControlHandle : SafeHandle
+ {
+ /// <summary>
+ /// Initializes a new instance of the SafeAppControlHandle class.
+ /// </summary>
+ public SafeAppControlHandle() : base(IntPtr.Zero, true)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the SafeAppControlHandle class.
+ /// </summary>
+ /// <param name="existingHandle">An IntPtr object that represents the pre-existing handle to use.</param>
+ /// <param name="ownsHandle">true to reliably release the handle during the finalization phase; false to prevent reliable release.</param>
+ public SafeAppControlHandle(IntPtr existingHandle, bool ownsHandle) : base(IntPtr.Zero, ownsHandle)
+ {
+ SetHandle(existingHandle);
+ }
+
+ /// <summary>
+ /// Gets a value that indicates whether the handle is invalid.
+ /// </summary>
+ public override bool IsInvalid
+ {
+ get { return this.handle == IntPtr.Zero; }
+ }
+
+ /// <summary>
+ /// When overridden in a derived class, executes the code required to free the handle.
+ /// </summary>
+ /// <returns>true if the handle is released successfully</returns>
+ protected override bool ReleaseHandle()
+ {
+ Interop.AppControl.DangerousDestroy(this.handle);
+ this.SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/SafeBundleHandle.cs b/src/Tizen.Applications.Common/Tizen.Applications/SafeBundleHandle.cs
new file mode 100755
index 0000000..c3bab4b
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/SafeBundleHandle.cs
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Represents a wrapper class for a unmanaged Bundle handle.
+ /// </summary>
+ public sealed class SafeBundleHandle : SafeHandle
+ {
+ /// <summary>
+ /// Initializes a new instance of the SafeBundleHandle class.
+ /// </summary>
+ public SafeBundleHandle() : base(IntPtr.Zero, true)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the SafeBundleHandle class.
+ /// </summary>
+ /// <param name="existingHandle">An IntPtr object that represents the pre-existing handle to use.</param>
+ /// <param name="ownsHandle">true to reliably release the handle during the finalization phase; false to prevent reliable release.</param>
+ public SafeBundleHandle(IntPtr existingHandle, bool ownsHandle) : base(IntPtr.Zero, ownsHandle)
+ {
+ SetHandle(existingHandle);
+ }
+
+ /// <summary>
+ /// Gets a value that indicates whether the handle is invalid.
+ /// </summary>
+ public override bool IsInvalid
+ {
+ get { return this.handle == IntPtr.Zero; }
+ }
+
+ /// <summary>
+ /// When overridden in a derived class, executes the code required to free the handle.
+ /// </summary>
+ /// <returns>true if the handle is released successfully</returns>
+ protected override bool ReleaseHandle()
+ {
+ Interop.Bundle.DangerousFree(this.handle);
+ this.SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/TizenSynchronizationContext.cs b/src/Tizen.Applications.Common/Tizen.Applications/TizenSynchronizationContext.cs
new file mode 100644
index 0000000..dcfb4c8
--- /dev/null
+++ b/src/Tizen.Applications.Common/Tizen.Applications/TizenSynchronizationContext.cs
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Concurrent;
+using System.Threading;
+
+namespace Tizen.Applications
+{
+
+ /// <summary>
+ /// Provides a synchronization context for the Tizen application model.
+ /// </summary>
+ public class TizenSynchronizationContext : SynchronizationContext
+ {
+ private readonly Interop.Glib.GSourceFunc _wrapperHandler;
+ private readonly Object _transactionLock = new Object();
+ private readonly ConcurrentDictionary<int, Action> _handlerMap = new ConcurrentDictionary<int, Action>();
+ private int _transactionId = 0;
+
+ /// <summary>
+ /// Initializes a new instance of the TizenSynchronizationContext class.
+ /// </summary>
+ public TizenSynchronizationContext()
+ {
+ _wrapperHandler = new Interop.Glib.GSourceFunc(Handler);
+ }
+
+ /// <summary>
+ /// Initilizes a new TizenSynchronizationContext and install into current thread
+ /// </summary>
+ /// <remarks>
+ /// It is equivalent
+ /// <code>
+ /// SetSynchronizationContext(new TizenSynchronizationContext());
+ /// </code>
+ /// </remarks>
+ public static void Initialize()
+ {
+ SetSynchronizationContext(new TizenSynchronizationContext());
+ }
+
+
+ /// <summary>
+ /// Dispatches an asynchronous message to a Tizen main loop.
+ /// </summary>
+ /// <param name="d"><see cref="System.Threading.SendOrPostCallback"/>The SendOrPostCallback delegate to call.</param>
+ /// <param name="state"><see cref="System.Object"/>The object passed to the delegate.</param>
+ /// <remarks>
+ /// The Post method starts an asynchronous request to post a message.</remarks>
+ public override void Post(SendOrPostCallback d, object state)
+ {
+ Post(() =>
+ {
+ d(state);
+ });
+ }
+
+ /// <summary>
+ /// Dispatches a synchronous message to a Tizen main loop
+ /// </summary>
+ /// <param name="d"><see cref="System.Threading.SendOrPostCallback"/>The SendOrPostCallback delegate to call.</param>
+ /// <param name="state"><see cref="System.Object"/>The object passed to the delegate.</param>
+ /// <remarks>
+ /// The Send method starts a synchronous request to send a message.</remarks>
+ public override void Send(SendOrPostCallback d, object state)
+ {
+ var mre = new ManualResetEvent(false);
+ Exception err = null;
+ Post(() =>
+ {
+ try
+ {
+ d(state);
+ }
+ catch (Exception ex)
+ {
+ err = ex;
+ }
+ finally
+ {
+ mre.Set();
+ }
+ });
+ mre.WaitOne();
+ if (err != null)
+ {
+ throw err;
+ }
+ }
+
+ private void Post(Action action)
+ {
+ int id = 0;
+ lock (_transactionLock)
+ {
+ id = _transactionId++;
+ }
+ _handlerMap.TryAdd(id, action);
+ Interop.Glib.IdleAdd(_wrapperHandler, (IntPtr)id);
+ }
+
+ private bool Handler(IntPtr userData)
+ {
+ int key = (int)userData;
+ if (_handlerMap.ContainsKey(key))
+ {
+ Action action;
+ _handlerMap.TryRemove(key, out action);
+ action?.Invoke();
+ }
+ return false;
+ }
+ }
+}
diff --git a/src/Tizen.Applications.DataControl/Interop/Interop.DataControl.cs b/src/Tizen.Applications.DataControl/Interop/Interop.DataControl.cs
new file mode 100755
index 0000000..b19f6ee
--- /dev/null
+++ b/src/Tizen.Applications.DataControl/Interop/Interop.DataControl.cs
@@ -0,0 +1,466 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+using Tizen.Applications;
+using Tizen;
+using Tizen.Applications.DataControl;
+
+internal static partial class Interop
+{
+ internal static partial class DataControl
+ {
+
+ internal enum NativeResultType : int
+ {
+ Success = Tizen.Internals.Errors.ErrorCode.None,
+ OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
+ IoError = Tizen.Internals.Errors.ErrorCode.IoError,
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+ PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied,
+ MaxExceed = -0x01190000 | 0x01,
+ }
+
+ internal sealed class SafeBulkDataHandle : SafeHandle
+ {
+ internal SafeBulkDataHandle()
+ : base(IntPtr.Zero, true)
+ {
+ }
+
+ internal SafeBulkDataHandle(IntPtr existingHandle, bool ownsHandle) : base(IntPtr.Zero, ownsHandle)
+ {
+ SetHandle(existingHandle);
+ }
+
+ public override bool IsInvalid
+ {
+ get { return this.handle == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ DataControl.BulkFree(this.handle);
+ this.SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+
+ internal sealed class SafeBulkResultDataHandle : SafeHandle
+ {
+ internal SafeBulkResultDataHandle()
+ : base(IntPtr.Zero, true)
+ {
+ }
+
+ internal SafeBulkResultDataHandle(IntPtr existingHandle, bool ownsHandle) : base(IntPtr.Zero, ownsHandle)
+ {
+ SetHandle(existingHandle);
+ }
+
+ public override bool IsInvalid
+ {
+ get { return this.handle == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ DataControl.BulkResultFree(this.handle);
+ this.SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+
+ internal sealed class SafeCursorHandle : SafeHandle
+ {
+ internal SafeCursorHandle()
+ : base(IntPtr.Zero, true)
+ {
+ }
+
+ internal SafeCursorHandle(IntPtr existingHandle, bool ownsHandle) : base(IntPtr.Zero, ownsHandle)
+ {
+ SetHandle(existingHandle);
+ }
+
+ public override bool IsInvalid
+ {
+ get { return this.handle == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ this.SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+
+ internal sealed class SafeDataControlHandle : SafeHandle
+ {
+ internal SafeDataControlHandle()
+ : base(IntPtr.Zero, true)
+ {
+ }
+
+ internal SafeDataControlHandle(IntPtr existingHandle, bool ownsHandle) : base(IntPtr.Zero, ownsHandle)
+ {
+ SetHandle(existingHandle);
+ }
+
+ public override bool IsInvalid
+ {
+ get { return this.handle == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ DataControl.Destroy(this.handle);
+ this.SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_create")]
+ internal static extern ResultType DataControlCreate(out SafeDataControlHandle handle);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_destroy")]
+ internal static extern ResultType Destroy(IntPtr handle);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_get_provider_id")]
+ internal static extern ResultType DataControlGetProviderId(SafeDataControlHandle handle, out string providerId);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_set_provider_id")]
+ internal static extern ResultType DataControlSetProviderId(SafeDataControlHandle handle, string providerId);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_set_data_id")]
+ internal static extern ResultType DataControlSetDataId(SafeDataControlHandle handle, string dataId);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_get_data_id")]
+ internal static extern ResultType DataControlGetDataId(SafeDataControlHandle handle, out string dataId);
+
+ internal delegate void MapGetResponseCallback(int requestID,
+ IntPtr provider, string[] resultValueList, int resultValueCount, bool providerResult, string error, IntPtr userData);
+ internal delegate void MapSetResponseCallback(int requestID,
+ IntPtr provider, bool providerResult, string error, IntPtr userData);
+ internal delegate void MapAddResponseCallback(int requestID,
+ IntPtr provider, bool providerResult, string error, IntPtr userData);
+ internal delegate void MapRemoveResponseCallback(int requestID,
+ IntPtr provider, bool providerResult, string error, IntPtr userData);
+ internal delegate void MapBulkAddResponseCallback(int requestID,
+ IntPtr provider, IntPtr bulkResults, bool providerResult, string error, IntPtr userData);
+
+ [StructLayoutAttribute(LayoutKind.Sequential)]
+ internal struct MapResponseCallbacks
+ {
+ public MapGetResponseCallback Get;
+ public MapSetResponseCallback Set;
+ public MapAddResponseCallback Add;
+ public MapRemoveResponseCallback Remove;
+ }
+
+ internal delegate void SqlSelectResponseCallback(int requestID,
+ IntPtr provider, IntPtr cursor, bool providerResult, string error, IntPtr userData);
+ internal delegate void SqlInsertResponseCallback(int requestID,
+ IntPtr provider, long inserted_row_id, bool providerResult, string error, IntPtr userData);
+ internal delegate void SqlUpdateResponseCallback(int requestID,
+ IntPtr provider, bool providerResult, string error, IntPtr userData);
+ internal delegate void SqlDeleteResponseCallback(int requestID,
+ IntPtr provider, bool providerResult, string error, IntPtr userData);
+ internal delegate void SqlBulkInsertResponseCallback(int requestID,
+ IntPtr provider, IntPtr bulk_results, bool providerResult, string error, IntPtr userData);
+
+ [StructLayoutAttribute(LayoutKind.Sequential)]
+ internal struct SqlResponseCallbacks
+ {
+ public SqlSelectResponseCallback Select;
+ public SqlInsertResponseCallback Insert;
+ public SqlUpdateResponseCallback Update;
+ public SqlDeleteResponseCallback Delete;
+ }
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_map_register_response_cb")]
+ internal static extern ResultType RegisterMapResponse(SafeDataControlHandle provider, ref MapResponseCallbacks callback, IntPtr userData);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_map_unregister_response_cb")]
+ internal static extern ResultType UnregisterMapResponse(SafeDataControlHandle provider);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_map_register_add_bulk_data_response_cb")]
+ internal static extern ResultType RegisterMapBulkResponseCallback(SafeDataControlHandle provider, MapBulkAddResponseCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_map_unregister_add_bulk_data_response_cb")]
+ internal static extern ResultType UnregisterMapBulkResponseCallback(SafeDataControlHandle provider);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_register_response_cb")]
+ internal static extern ResultType RegisterSqlResponseCallback(SafeDataControlHandle provider, ref SqlResponseCallbacks callback, IntPtr userData);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_unregister_response_cb")]
+ internal static extern ResultType UnregisterSqlResponseCallback(SafeDataControlHandle provider);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_register_insert_bulk_data_response_cb")]
+ internal static extern ResultType RegisterSqlBulkResponseCallback(SafeDataControlHandle provider, SqlBulkInsertResponseCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_unregister_insert_bulk_data_response_cb")]
+ internal static extern ResultType UnregisterSqlBulkResponseCallback(SafeDataControlHandle provider);
+
+ internal delegate void MapGetRequestCallback(int requestID,
+ IntPtr provider, string key, IntPtr userData);
+ internal delegate void MapSetRequestCallback(int requestID,
+ IntPtr provider, string key, string oldValue, string newValue, IntPtr userData);
+ internal delegate void MapAddRequestCallback(int requestID,
+ IntPtr provider, string key, string value, IntPtr userData);
+ internal delegate void MapRemoveRequestCallback(int requestID,
+ IntPtr provider, string key, string value, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MapBulkAddRequestCallback(int requestID,
+ IntPtr provider, IntPtr bulkData, IntPtr userData);
+
+ [StructLayoutAttribute(LayoutKind.Sequential)]
+ internal struct MapRequestCallbacks
+ {
+ public MapGetRequestCallback Get;
+ public MapSetRequestCallback Set;
+ public MapAddRequestCallback Add;
+ public MapRemoveRequestCallback Remove;
+ }
+
+ internal delegate void SqlInsertRequestCallback(int requestID,
+ IntPtr provider, IntPtr insertData, IntPtr userData);
+ internal delegate void SqlSelectRequestCallback(int requestID,
+ IntPtr provider, IntPtr columnList, int columnCount, string where, string order, IntPtr userData);
+ internal delegate void SqlUpdateRequestCallback(int requestID,
+ IntPtr provider, IntPtr updateData, string where, IntPtr userData);
+ internal delegate void SqlDeleteRequestCallback(int requestID,
+ IntPtr provider, string where, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void SqlBulkInsertRequestCallback(int requestID,
+ IntPtr provider, IntPtr bulk_data, IntPtr userData);
+
+ [StructLayoutAttribute(LayoutKind.Sequential)]
+ internal struct SqlRequestCallbacks
+ {
+ public SqlInsertRequestCallback Insert;
+ public SqlSelectRequestCallback Select;
+ public SqlUpdateRequestCallback Update;
+ public SqlDeleteRequestCallback Delete;
+ }
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_map_register_cb")]
+ internal static extern ResultType RegisterMapRequest(ref MapRequestCallbacks callback, IntPtr userData);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_sql_register_cb")]
+ internal static extern ResultType RegisterSqlRequest(ref SqlRequestCallbacks callback, IntPtr userData);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_sql_register_insert_bulk_data_request_cb")]
+ internal static extern ResultType RegisterSqlBulkRequest(SqlBulkInsertRequestCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_sql_unregister_insert_bulk_data_request_cb")]
+ internal static extern ResultType UnregisterSqlBulkRequest();
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_map_register_add_bulk_data_request_cb")]
+ internal static extern ResultType RegisterMapBulkRequest(MapBulkAddRequestCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_map_unregister_add_bulk_data_request_cb")]
+ internal static extern ResultType UnregisterMapBulkRequest();
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_send_map_result")]
+ internal static extern ResultType SendMapResult(int requestID);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_send_map_get_value_result")]
+ internal static extern ResultType SendMapGetResult(int requestID, string[] valueList, int valueCount);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_send_insert_result")]
+ internal static extern ResultType SendInsertResult(int requestID, long rowId);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_send_update_result")]
+ internal static extern ResultType SendUpdateResult(int requestID);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_send_delete_result")]
+ internal static extern ResultType SendDeleteResult(int requestID);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "datacontrol_provider_send_select_result_without_data")]
+ internal static extern ResultType SendSelectResult(int requestID, out int fd);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_send_error")]
+ internal static extern ResultType SendError(int requestID, string error);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_insert")]
+ internal static extern ResultType Insert(SafeDataControlHandle provider, SafeBundleHandle insertData, out int requestId);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_select_with_page")]
+ internal static extern ResultType Select(SafeDataControlHandle provider, string[] columnList, int columnCount, string where, string order, int pageNumber,
+ int countPerPage, out int requestID);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_delete")]
+ internal static extern ResultType Delete(SafeDataControlHandle provider, string where, out int requestID);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_update")]
+ internal static extern ResultType Update(SafeDataControlHandle provider, SafeBundleHandle updatetData, string where, out int requestID);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_insert_bulk_data")]
+ internal static extern ResultType BulkInsert(SafeDataControlHandle provider, SafeBulkDataHandle insertData, out int requestID);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_map_add")]
+ internal static extern ResultType MapAdd(SafeDataControlHandle provider, string key, string value, out int requestId);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_map_set")]
+ internal static extern ResultType MapSet(SafeDataControlHandle provider, string key, string oldValue, string newValue, out int requestId);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_map_remove")]
+ internal static extern ResultType MapRemove(SafeDataControlHandle provider, string key, string value, out int requestId);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_map_get_with_page")]
+ internal static extern ResultType MapGet(SafeDataControlHandle provider, string key, out int requestId, int pageNumber,
+ int countPerPage);
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_map_add_bulk_data")]
+ internal static extern ResultType BulkAdd(SafeDataControlHandle provider, SafeBulkDataHandle insertData, out int requestID);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_create_insert_statement")]
+ internal static extern string CreateInsertStatement(SafeDataControlHandle provider, SafeBundleHandle insertData);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_create_delete_statement")]
+ internal static extern string CreateDeleteStatement(SafeDataControlHandle provider, string where);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_create_update_statement")]
+ internal static extern string CreateUpdateStatement(SafeDataControlHandle provider, SafeBundleHandle updateData, string where);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "datacontrol_provider_get_select_page_info")]
+ internal static extern ResultType GetSelectPageInfo(int requestId, out int pageNum, out int countPerPage);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "datacontrol_provider_write_socket")]
+ internal static extern unsafe ResultType WriteSelectResult(int socketFd, byte* buffer, uint nbytes, out uint bytesWrite);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_send_data_change_noti")]
+ internal static extern ResultType SendDataChange(IntPtr handle, ChangeType type, SafeBundleHandle data);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_step_next")]
+ internal static extern ResultType Next(SafeCursorHandle cursor);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_step_last")]
+ internal static extern ResultType Last(SafeCursorHandle cursor);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_step_first")]
+ internal static extern ResultType First(SafeCursorHandle cursor);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_step_previous")]
+ internal static extern ResultType Prev(SafeCursorHandle cursor);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_get_column_count")]
+ internal static extern int GetColumnCount(SafeCursorHandle cursor);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_get_column_name")]
+ internal static extern ResultType GetColumnName(SafeCursorHandle cursor, int idx, StringBuilder name);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_get_column_item_size")]
+ internal static extern int GetItemSize(SafeCursorHandle cursor, int idx);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_get_column_item_type")]
+ internal static extern ResultType GetItemType(SafeCursorHandle cursor, int idx, out int type);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_get_blob_data")]
+ internal static extern ResultType GetBlob(SafeCursorHandle cursor, int idx, byte[] buffer, int size);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_get_int_data")]
+ internal static extern ResultType GetInt(SafeCursorHandle cursor, int idx, out int data);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_get_int64_data")]
+ internal static extern ResultType GetInt64(SafeCursorHandle cursor, int idx, out long data);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_get_double_data")]
+ internal static extern ResultType Getdouble(SafeCursorHandle cursor, int idx, out double data);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_get_text_data")]
+ internal static extern unsafe ResultType GetText(SafeCursorHandle cursor, int idx, byte[] data);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_bulk_data_create")]
+ internal static extern ResultType BulkCreate(out SafeBulkDataHandle handle);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_bulk_data_add")]
+ internal static extern ResultType BulkAdd(SafeBulkDataHandle handle, SafeBundleHandle data);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_bulk_data_get_count")]
+ internal static extern ResultType BulkGetCount(SafeBulkDataHandle handle, out int count);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_bulk_data_destroy")]
+ internal static extern ResultType BulkFree(IntPtr handle);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_bulk_data_get_data")]
+ internal static extern ResultType BulkGetData(SafeBulkDataHandle handle, int idx, out IntPtr data);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_bulk_result_data_create")]
+ internal static extern ResultType BulkResultCreate(out SafeBulkResultDataHandle handle);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_bulk_result_data_add")]
+ internal static extern ResultType BulkResultAdd(SafeBulkResultDataHandle handle, SafeBundleHandle data, int result);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_bulk_result_data_get_count")]
+ internal static extern ResultType BulkResultGetCount(SafeBulkResultDataHandle handle, out int count);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_bulk_result_data_get_result_data")]
+ internal static extern ResultType BulkResultGetData(SafeBulkResultDataHandle handle, int idx, out IntPtr data, out int result);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_bulk_result_data_get_result_data")]
+ internal static extern ResultType BulkResultGetResult(SafeBulkResultDataHandle handle, int idx, out IntPtr data, out int result);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_bulk_result_data_destroy")]
+ internal static extern ResultType BulkResultFree(IntPtr handle);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void AddCallbackResultCallback(IntPtr handle, ResultType type, int callbackID, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void DataChangeCallback(IntPtr handle, ChangeType type, IntPtr data, IntPtr userData);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_add_data_change_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern ResultType AddDataChangeCallback(SafeDataControlHandle provider, DataChangeCallback callback,
+ IntPtr userData, AddCallbackResultCallback resultCallback, IntPtr resultCbUserData, out int callbackID);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_remove_data_change_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern ResultType RemoveDataChangeCallback(SafeDataControlHandle provider, int callbackID);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool DataChangeConsumerFilterCb(IntPtr handle, string consumerAppid, IntPtr userData);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_add_data_change_consumer_filter_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern ResultType AddDataChangeConsumerFilterCallback(DataChangeConsumerFilterCb callback,
+ IntPtr userData,
+ out int callbackID);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_remove_data_change_consumer_filter_cb")]
+ internal static extern int RemoveDataChangeConsumerFilterCallback(int callbackID);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_send_bulk_insert_result")]
+ internal static extern ResultType SendBulkInsertResult(int requestId, SafeBulkResultDataHandle result);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_send_map_bulk_add_result")]
+ internal static extern ResultType SendMapBulkAddResult(int requestId, SafeBulkResultDataHandle result);
+
+ internal static class UnsafeCode
+ {
+ internal static unsafe ResultType WriteResult(int socketFd, byte[] value, int nbytes, out uint bytesWrite)
+ {
+ fixed (byte* pointer = value)
+ {
+ return WriteSelectResult(socketFd, pointer, (uint)nbytes, out bytesWrite);
+ }
+ }
+ }
+
+ }
+}
diff --git a/src/Tizen.Applications.DataControl/Interop/Interop.Libraries.cs b/src/Tizen.Applications.DataControl/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..1658ec6
--- /dev/null
+++ b/src/Tizen.Applications.DataControl/Interop/Interop.Libraries.cs
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string DataControl = "libdata-control.so.0";
+ }
+}
diff --git a/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl.Core/CloneCursorCore.cs b/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl.Core/CloneCursorCore.cs
new file mode 100755
index 0000000..1e066ee
--- /dev/null
+++ b/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl.Core/CloneCursorCore.cs
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+using System.IO;
+using System.Text;
+using System.Collections.Generic;
+using System.Threading;
+
+namespace Tizen.Applications.DataControl.Core
+{
+ internal class CloneCursorCore : ICursor
+ {
+ internal const int MaxColumnNameSize = 1024;
+ private const string LogTag = "Tizen.Applications.DataControl";
+ private long _rowCount;
+ private int _columnCount;
+ private const int ResultNoData = -1;
+ private Interop.DataControl.SafeCursorHandle _cursor;
+ internal CloneCursorCore(Interop.DataControl.SafeCursorHandle cursor)
+ {
+ _cursor = cursor;
+ _columnCount = Interop.DataControl.GetColumnCount(cursor);
+
+ if (_columnCount == ResultNoData)
+ {
+ _rowCount = 0;
+ return;
+ }
+
+ Interop.DataControl.First(cursor);
+
+ do
+ {
+ _rowCount++;
+ }
+ while (Interop.DataControl.Next(cursor) == (int)ResultType.Success);
+ Interop.DataControl.First(cursor);
+ }
+
+ public int GetColumnCount()
+ {
+ return Interop.DataControl.GetColumnCount(_cursor);
+ }
+
+ public ColumnType GetColumnType(int index)
+ {
+ int type;
+ ResultType ret;
+
+ if (index < 0 || index >= _columnCount)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ ret = Interop.DataControl.GetItemType(_cursor, index, out type);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "Column Index " + index.ToString());
+ }
+
+ return (ColumnType)type;
+ }
+
+ public string GetColumnName(int index)
+ {
+ string retStr;
+ ResultType ret;
+ StringBuilder columnName = new StringBuilder();
+
+ if (index < 0 || index >= _columnCount)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ columnName.Length = MaxColumnNameSize;
+ ret = Interop.DataControl.GetColumnName(_cursor, index, columnName);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "Column Index " + index.ToString());
+ }
+
+ retStr = columnName.ToString();
+ columnName.Clear();
+ columnName = null;
+
+ return retStr;
+ }
+
+ public long GetRowCount()
+ {
+ return _rowCount;
+ }
+
+ public bool Next()
+ {
+ ResultType type = Interop.DataControl.Next(_cursor);
+
+ if (type != ResultType.Success)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public bool Prev()
+ {
+ ResultType type = Interop.DataControl.Prev(_cursor);
+
+ if (type != ResultType.Success)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public bool Reset()
+ {
+ ResultType type = Interop.DataControl.First(_cursor);
+
+ if (type != ResultType.Success)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public int GetIntValue(int index)
+ {
+ ResultType ret;
+ int value;
+
+ if (index < 0 || index >= _columnCount)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ ret = Interop.DataControl.GetInt(_cursor, index, out value);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "Column Index " + index.ToString());
+ }
+
+ return value;
+ }
+
+ public Int64 GetInt64Value(int index)
+ {
+ ResultType ret;
+ Int64 value;
+
+ if (index < 0 || index >= _columnCount)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ ret = Interop.DataControl.GetInt64(_cursor, index, out value);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "Column Index " + index.ToString());
+ }
+
+ return value;
+ }
+
+ public double GetDoubleValue(int index)
+ {
+ ResultType ret;
+ double value;
+
+ if (index < 0 || index >= _columnCount)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ ret = Interop.DataControl.Getdouble(_cursor, index, out value);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "Column Index " + index.ToString());
+ }
+
+ return value;
+ }
+
+ public string GetStringValue(int index)
+ {
+ ResultType ret;
+ int size;
+ byte[] value;
+ string text;
+
+ if (index < 0 || index >= _columnCount)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ size = Interop.DataControl.GetItemSize(_cursor, index);
+ if (size < 0)
+ {
+ ErrorFactory.ThrowException(ResultType.IoError, false, "Invalid size");
+ }
+
+ value = new byte[size + 1];
+ ret = Interop.DataControl.GetText(_cursor, index, value);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false);
+ }
+
+ text = Encoding.UTF8.GetString(value);
+
+ return text;
+ }
+
+ public byte[] GetBlobValue(int index)
+ {
+ ResultType ret;
+ int size;
+ byte[] byte_array;
+
+ if (index < 0 || index >= _columnCount)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ size = Interop.DataControl.GetItemSize(_cursor, index);
+ if (size < 0)
+ {
+ ErrorFactory.ThrowException(ResultType.IoError, false, "Invalid size");
+ }
+
+ byte_array = new byte[size];
+ ret = Interop.DataControl.GetBlob(_cursor, index, byte_array, size);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false);
+ }
+
+ return byte_array;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl.csproj b/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl.csproj
new file mode 100644
index 0000000..0e326ef
--- /dev/null
+++ b/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl.csproj
@@ -0,0 +1,18 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen.Applications.Common\Tizen.Applications.Common.csproj" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <PackageReference Include="System.Diagnostics.Process" Version="$(SystemPackageVersion)" PrivateAssets="All" />
+ <PackageReference Include="System.Threading.Thread" Version="$(SystemPackageVersion)" PrivateAssets="All" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl/BulkData.cs b/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl/BulkData.cs
new file mode 100755
index 0000000..a3aa164
--- /dev/null
+++ b/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl/BulkData.cs
@@ -0,0 +1,361 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Applications.DataControl
+{
+ /// <summary>
+ /// Represents BulkData class for DataControl bulk request.
+ /// </summary>
+ public class BulkData : IDisposable
+ {
+ private bool _disposed = false;
+ private Interop.DataControl.SafeBulkDataHandle _handle;
+
+ /// <summary>
+ /// Initializes BulkData class.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ public BulkData()
+ {
+ ResultType ret;
+
+ ret = Interop.DataControl.BulkCreate(out _handle);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true, "BulkCreate");
+ }
+
+ }
+
+ internal BulkData(Interop.DataControl.SafeBulkDataHandle handle)
+ {
+ ResultType ret;
+ int count, i;
+
+ ret = Interop.DataControl.BulkCreate(out _handle);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true, "BulkCreate");
+ }
+
+ ret = Interop.DataControl.BulkGetCount(handle, out count);
+ for ( i = 0; i < count; i++)
+ {
+ IntPtr bundleHandle;
+ Bundle bundle;
+
+ ret = Interop.DataControl.BulkGetData(handle, i, out bundleHandle);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true, "BulkGetData");
+ }
+
+ bundle = new Bundle(new SafeBundleHandle(bundleHandle, false));
+ ret = Interop.DataControl.BulkAdd(_handle, bundle.SafeBundleHandle);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true, "BulkAdd");
+ }
+ }
+ }
+
+ internal Interop.DataControl.SafeBulkDataHandle SafeBulkDataHandle
+ {
+ get { return _handle; }
+ }
+
+ /// <summary>
+ /// Adds bulk data.
+ /// </summary>
+ /// <param name="data">Bulk data</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public void Add(Bundle data)
+ {
+ ResultType ret;
+
+ if (data == null || data.SafeBundleHandle.IsInvalid)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "data");
+ }
+
+ ret = Interop.DataControl.BulkAdd(_handle, data.SafeBundleHandle);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true, "BulkAdd");
+ }
+ }
+
+ /// <summary>
+ /// Gets current data count.
+ /// </summary>
+ public int GetCount()
+ {
+ int count;
+ ResultType ret;
+
+ ret = Interop.DataControl.BulkGetCount(_handle, out count);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true, "BulkGetCount");
+ }
+
+ return count;
+ }
+
+ /// <summary>
+ /// Returns the data at the given zero-based data index.
+ /// </summary>
+ /// <param name="index">Target data index</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public Bundle GetData(int index)
+ {
+ IntPtr bundlePtr;
+ Bundle bundle;
+ ResultType ret;
+
+ if (index < 0)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "index");
+ }
+
+ ret = Interop.DataControl.BulkGetData(_handle, index, out bundlePtr);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true, "BulkGetData");
+ }
+
+ bundle = new Bundle(new SafeBundleHandle(bundlePtr, false));
+ return bundle;
+ }
+
+ /// <summary>
+ /// Releases all resources used by the BulkData class.
+ /// </summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+ /// </summary>
+ /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (_handle != null && !_handle.IsInvalid)
+ {
+ _handle.Dispose();
+ }
+
+ _disposed = true;
+ }
+ }
+
+ ~BulkData()
+ {
+ Dispose(false);
+ }
+ }
+
+ /// <summary>
+ /// Represents BulkResultData class for DataControl bulk request.
+ /// </summary>
+ public class BulkResultData : IDisposable
+ {
+ private const string LogTag = "Tizen.Applications.DataControl";
+ private bool _disposed = false;
+ private Interop.DataControl.SafeBulkResultDataHandle _handle;
+ /// <summary>
+ /// Initializes BulkResultData class.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ public BulkResultData()
+ {
+ ResultType ret;
+
+ ret = Interop.DataControl.BulkResultCreate(out _handle);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true,"BulkResultCreate");
+ }
+ }
+
+ internal BulkResultData(Interop.DataControl.SafeBulkResultDataHandle handle)
+ {
+ ResultType ret;
+
+ ret = Interop.DataControl.BulkResultCreate(out _handle);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true,"BulkResultCreate");
+ }
+
+ int count;
+ ret = Interop.DataControl.BulkResultGetCount(handle, out count);
+ for (int i = 0; i < count; i++)
+ {
+ IntPtr bundleHandle;
+ Bundle bundle;
+ int result;
+
+ ret = Interop.DataControl.BulkResultGetData(handle, i, out bundleHandle, out result);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true, "BulkResultGetData");
+ }
+
+ bundle = new Bundle(new SafeBundleHandle(bundleHandle, false));
+ ret = Interop.DataControl.BulkResultAdd(_handle, bundle.SafeBundleHandle, result);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true, "BulkResultAdd");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Adds bulk operation result data.
+ /// </summary>
+ /// <param name="data">Result data</param>
+ /// <param name="result">Result</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public void Add(Bundle data, int result)
+ {
+ ResultType ret;
+
+ if (data == null || data.SafeBundleHandle.IsInvalid)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "data");
+ }
+
+ ret = Interop.DataControl.BulkResultAdd(_handle, data.SafeBundleHandle, result);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true, "BulkResultAdd");
+ }
+ }
+
+ internal Interop.DataControl.SafeBulkResultDataHandle SafeBulkDataHandle
+ {
+ get { return _handle; }
+ }
+
+ /// <summary>
+ /// Gets current result data count.
+ /// </summary>
+ public int GetCount()
+ {
+ int count;
+ ResultType ret;
+
+ ret = Interop.DataControl.BulkResultGetCount(_handle, out count);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true,"BulkResultGetCount");
+ }
+
+ return count;
+ }
+
+ /// <summary>
+ /// Returns the result data at the given zero-based data index.
+ /// </summary>
+ /// <param name="index">Target result data index</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public Bundle GetData(int index)
+ {
+ IntPtr bundlePtr;
+ Bundle bundle;
+ ResultType ret;
+ int result;
+
+ if (index < 0)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "index");
+ }
+
+ ret = Interop.DataControl.BulkResultGetData(_handle, index, out bundlePtr, out result);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true, "BulkResultGetData");
+ }
+
+ bundle = new Bundle(new SafeBundleHandle(bundlePtr, false));
+ return bundle;
+ }
+
+ /// <summary>
+ /// Returns the result at the given zero-based data index.
+ /// </summary>
+ /// <param name="index">Target result index</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public int GetResult(int index)
+ {
+ IntPtr bundlePtr;
+ ResultType ret;
+ int result;
+
+ if (index < 0)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "index");
+ }
+
+ ret = Interop.DataControl.BulkResultGetData(_handle, index, out bundlePtr, out result);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true, "BulkResultGetData");
+ }
+
+ return result;
+ }
+
+ /// <summary>
+ /// Releases all resources used by the BulkResultData class.
+ /// </summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+ /// </summary>
+ /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (_handle != null && !_handle.IsInvalid)
+ {
+ _handle.Dispose();
+ }
+
+ _disposed = true;
+ }
+ }
+
+ ~BulkResultData()
+ {
+ Dispose(false);
+ }
+ }
+}
diff --git a/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl/Consumer.cs b/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl/Consumer.cs
new file mode 100755
index 0000000..ddbf6a8
--- /dev/null
+++ b/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl/Consumer.cs
@@ -0,0 +1,973 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.Collections.Generic;
+using Tizen.Applications.DataControl.Core;
+using System.Threading;
+
+namespace Tizen.Applications.DataControl
+{
+ /// <summary>
+ /// Represents Consumer class for DataControl consumer application.
+ /// </summary>
+ public abstract class Consumer : IDisposable
+ {
+
+ private Interop.DataControl.SafeDataControlHandle _handle;
+ private string _dataID, _providerID;
+ private int _changeCallbackID = 0;
+ private const string LogTag = "Tizen.Applications.DataControl";
+ private bool _disposed = false;
+ private static Mutex _lock = new Mutex();
+ private Interop.DataControl.DataChangeCallback _dataChangeCallback;
+ private Interop.DataControl.AddCallbackResultCallback _addCallbackResultCallback;
+
+ private static class CallbackManager
+ {
+ private static IDictionary<string, Interop.DataControl.MapResponseCallbacks> _mapResponseCallbacks = new Dictionary<string, Interop.DataControl.MapResponseCallbacks>();
+ private static IDictionary<string, Interop.DataControl.MapBulkAddResponseCallback> _mapBulkResponseCallback = new Dictionary<string, Interop.DataControl.MapBulkAddResponseCallback>();
+ private static IDictionary<string, Interop.DataControl.SqlResponseCallbacks> _sqlResponseCallbacks = new Dictionary<string, Interop.DataControl.SqlResponseCallbacks>();
+ private static IDictionary<string, Interop.DataControl.SqlBulkInsertResponseCallback> _sqlBulkResponseCallback = new Dictionary<string, Interop.DataControl.SqlBulkInsertResponseCallback>();
+ private static IDictionary<int, Consumer> _reqConsumerDictionary = new Dictionary<int, Consumer>();
+ private static IDictionary<string, int> _reqProviderList = new Dictionary<string, int>();
+ private static void InsertResponse(int reqId, IntPtr provider, long insertedRowId, bool providerResult, string error, IntPtr userData)
+ {
+ Log.Debug(LogTag, $"InsertResponse {reqId.ToString()}");
+ if (!_reqConsumerDictionary.ContainsKey(reqId))
+ {
+ Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
+ return;
+ }
+
+ if (!providerResult)
+ {
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}, rowID : {insertedRowId.ToString()}");
+ }
+
+ Consumer consumer = _reqConsumerDictionary[reqId];
+ consumer.OnInsertResult(new InsertResult(insertedRowId, providerResult));
+ _reqConsumerDictionary.Remove(reqId);
+ }
+
+ private static void BulkInsertResponse(int reqId, IntPtr provider, IntPtr bulkResults, bool providerResult, string error, IntPtr userData)
+ {
+ BulkResultData brd;
+ Log.Debug(LogTag, $"BulkInsertResponse {reqId.ToString()}");
+ if (!_reqConsumerDictionary.ContainsKey(reqId))
+ {
+ Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
+ return;
+ }
+
+ if (!providerResult)
+ {
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}");
+ }
+
+ if (bulkResults != IntPtr.Zero)
+ {
+ brd = new BulkResultData(new Interop.DataControl.SafeBulkResultDataHandle(bulkResults, false));
+ }
+ else
+ {
+ brd = new BulkResultData();
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, bulkResults is null");
+ }
+
+ Consumer consumer = _reqConsumerDictionary[reqId];
+ consumer.OnBulkInsertResult(new BulkInsertResult(brd, providerResult));
+ _reqConsumerDictionary.Remove(reqId);
+ }
+
+ private static void SelectResponse(int reqId, IntPtr provider, IntPtr cursor, bool providerResult, string error, IntPtr userData)
+ {
+ MatrixCursor dmc;
+ Log.Debug(LogTag, $"SelectResponse {reqId.ToString()}");
+ if (!_reqConsumerDictionary.ContainsKey(reqId))
+ {
+ Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
+ return;
+ }
+
+ if (!providerResult)
+ {
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}");
+ }
+
+ if (cursor != IntPtr.Zero)
+ {
+ try
+ {
+ dmc = CloneCursor(new CloneCursorCore(new Interop.DataControl.SafeCursorHandle(cursor, true)));
+ }
+ catch (Exception ex)
+ {
+ dmc = new MatrixCursor();
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, {ex.ToString()}");
+ }
+ }
+ else
+ {
+ dmc = new MatrixCursor();
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, cursor is null");
+ }
+ Consumer consumer = _reqConsumerDictionary[reqId];
+ consumer.OnSelectResult(new SelectResult(dmc, providerResult));
+ _reqConsumerDictionary.Remove(reqId);
+ }
+
+ private static void UpdateResponse(int reqId, IntPtr provider, bool providerResult, string error, IntPtr userData)
+ {
+ if (!_reqConsumerDictionary.ContainsKey(reqId))
+ {
+ Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
+ return;
+ }
+
+ if (!providerResult)
+ {
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}");
+ }
+
+ Consumer consumer = _reqConsumerDictionary[reqId];
+ consumer.OnUpdateResult(new UpdateResult(providerResult));
+ _reqConsumerDictionary.Remove(reqId);
+ }
+
+ private static void DeleteResponse(int reqId, IntPtr provider, bool providerResult, string error, IntPtr userData)
+ {
+ if (!_reqConsumerDictionary.ContainsKey(reqId))
+ {
+ Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
+ return;
+ }
+
+ if (!providerResult)
+ {
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}");
+ }
+
+ Consumer consumer = _reqConsumerDictionary[reqId];
+ consumer.OnDeleteResult(new DeleteResult(providerResult));
+ _reqConsumerDictionary.Remove(reqId);
+ }
+
+ private static void MapGetResponse(int reqId, IntPtr provider, string[] valueList, int valueCount, bool providerResult, string error, IntPtr userData)
+ {
+ MapGetResult mgr;
+ Log.Debug(LogTag, $"MapGetResponse {reqId.ToString()}");
+ if (!_reqConsumerDictionary.ContainsKey(reqId))
+ {
+ Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
+ return;
+ }
+
+ if (!providerResult)
+ {
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}");
+ }
+
+ if (valueList !=null)
+ {
+ mgr = new MapGetResult(valueList, providerResult);
+ }
+ else
+ {
+ mgr = new MapGetResult(new string[0], providerResult);
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, valueList is null");
+ }
+
+ Consumer consumer = _reqConsumerDictionary[reqId];
+ consumer.OnMapGetResult(mgr);
+ _reqConsumerDictionary.Remove(reqId);
+ }
+
+ private static void MapBulkAddResponse(int reqId, IntPtr provider, IntPtr bulkResults, bool providerResult, string error, IntPtr userData)
+ {
+ BulkResultData brd;
+ Log.Debug(LogTag, $"MapBulkAddResponse {reqId.ToString()}");
+ if (!_reqConsumerDictionary.ContainsKey(reqId))
+ {
+ Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
+ return;
+ }
+
+ if (!providerResult)
+ {
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}");
+ }
+
+ if (bulkResults != IntPtr.Zero)
+ {
+ brd = new BulkResultData(new Interop.DataControl.SafeBulkResultDataHandle(bulkResults, false));
+ }
+ else
+ {
+ brd = new BulkResultData();
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, bulkResults is null");
+ }
+
+ Consumer consumer = _reqConsumerDictionary[reqId];
+ consumer.OnMapBulkAddResult(new MapBulkAddResult(brd, providerResult));
+ _reqConsumerDictionary.Remove(reqId);
+ }
+
+ private static void MapAddResponse(int reqId, IntPtr provider, bool providerResult, string error, IntPtr userData)
+ {
+ Log.Debug(LogTag, $"MapAddResponse {reqId.ToString()}");
+ if (!_reqConsumerDictionary.ContainsKey(reqId))
+ {
+ Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
+ return;
+ }
+
+ if (!providerResult)
+ {
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}");
+ }
+
+ Consumer consumer = _reqConsumerDictionary[reqId];
+ consumer.OnMapAddResult(new MapAddResult(providerResult));
+ _reqConsumerDictionary.Remove(reqId);
+ }
+
+ private static void MapSetResponse(int reqId, IntPtr provider, bool providerResult, string error, IntPtr userData)
+ {
+ Log.Debug(LogTag, $"MapSetResponse {reqId.ToString()}");
+ if (!_reqConsumerDictionary.ContainsKey(reqId))
+ {
+ Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
+ return;
+ }
+
+ if (!providerResult)
+ {
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}");
+ }
+
+ Consumer consumer = _reqConsumerDictionary[reqId];
+ consumer.OnMapSetResult(new MapSetResult(providerResult));
+ _reqConsumerDictionary.Remove(reqId);
+ }
+
+ private static void MapRemoveResponse(int reqId, IntPtr provider, bool providerResult, string error, IntPtr userData)
+ {
+ if (!_reqConsumerDictionary.ContainsKey(reqId))
+ {
+ Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
+ return;
+ }
+
+ if (!providerResult)
+ {
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}");
+ }
+
+ Consumer consumer = _reqConsumerDictionary[reqId];
+ consumer.OnMapRemoveResult(new MapRemoveResult(providerResult));
+ _reqConsumerDictionary.Remove(reqId);
+ }
+
+ private static MatrixCursor CloneCursor(CloneCursorCore coreCursor)
+ {
+ int size = coreCursor.GetColumnCount();
+ int i;
+ string[] name = new string[size];
+ object[] newRow = new object[size];
+ ColumnType[] type = new ColumnType[size];
+
+ for (i = 0; i < size; i++)
+ {
+ name[i] = coreCursor.GetColumnName(i);
+ type[i] = coreCursor.GetColumnType(i);
+ }
+
+ MatrixCursor dmc = new MatrixCursor(name, type);
+
+ if (coreCursor.GetRowCount() <= 0)
+ {
+ return dmc;
+ }
+
+ coreCursor.Reset();
+ do
+ {
+ for (i = 0; i < size; i++)
+ {
+ switch (type[i])
+ {
+ case ColumnType.ColumnTypeInt:
+ newRow[i] = coreCursor.GetInt64Value(i);
+ break;
+ case ColumnType.ColumnTypeDouble:
+ newRow[i] = coreCursor.GetDoubleValue(i);
+ break;
+ case ColumnType.ColumnTypeBlob:
+ newRow[i] = coreCursor.GetBlobValue(i);
+ break;
+ case ColumnType.ColumnTypeString:
+ newRow[i] = coreCursor.GetStringValue(i);
+ break;
+ }
+ }
+
+ dmc.AddRow(newRow);
+ }
+ while (coreCursor.Next());
+
+ return dmc;
+ }
+
+ internal static void RegisterReqId(int reqId, Consumer consumer)
+ {
+ _lock.WaitOne();
+ _reqConsumerDictionary.Add(reqId, consumer);
+ _lock.ReleaseMutex();
+ }
+
+ internal static void RegisterCallback(Interop.DataControl.SafeDataControlHandle handle, string providerId)
+ {
+ ResultType ret;
+ Interop.DataControl.SqlResponseCallbacks sqlCallbacks;
+ Interop.DataControl.SqlBulkInsertResponseCallback sqlBulkCallbacks;
+ Interop.DataControl.MapResponseCallbacks mapCallbacks;
+ Interop.DataControl.MapBulkAddResponseCallback mapBulkCallbacks;
+ bool sqlRegistered = false;
+ bool mapRegistered = false;
+
+ if (_reqProviderList.ContainsKey(providerId))
+ {
+ _reqProviderList[providerId]++;
+ Log.Error(LogTag, "The data control is already set");
+ return;
+ }
+
+ sqlCallbacks.Insert = new Interop.DataControl.SqlInsertResponseCallback(InsertResponse);
+ sqlCallbacks.Select = new Interop.DataControl.SqlSelectResponseCallback(SelectResponse);
+ sqlCallbacks.Update = new Interop.DataControl.SqlUpdateResponseCallback(UpdateResponse);
+ sqlCallbacks.Delete = new Interop.DataControl.SqlDeleteResponseCallback(DeleteResponse);
+ ret = Interop.DataControl.RegisterSqlResponseCallback(handle, ref sqlCallbacks, IntPtr.Zero);
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "Registering the sql callback function is failed : " + ret);
+ }
+ else
+ {
+ _sqlResponseCallbacks.Add(providerId, sqlCallbacks);
+ sqlRegistered = true;
+ }
+
+ sqlBulkCallbacks = new Interop.DataControl.SqlBulkInsertResponseCallback(BulkInsertResponse);
+ ret = Interop.DataControl.RegisterSqlBulkResponseCallback(handle, sqlBulkCallbacks, IntPtr.Zero);
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "Registering the sql bulk callback function is failed : " + ret);
+ }
+ else
+ {
+ _sqlBulkResponseCallback.Add(providerId, sqlBulkCallbacks);
+ }
+
+ mapCallbacks.Add = new Interop.DataControl.MapAddResponseCallback(MapAddResponse);
+ mapCallbacks.Set = new Interop.DataControl.MapSetResponseCallback(MapSetResponse);
+ mapCallbacks.Get = new Interop.DataControl.MapGetResponseCallback(MapGetResponse);
+ mapCallbacks.Remove = new Interop.DataControl.MapRemoveResponseCallback(MapRemoveResponse);
+ ret = Interop.DataControl.RegisterMapResponse(handle, ref mapCallbacks, IntPtr.Zero);
+
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "Registering the map callback function is failed : " + ret);
+ }
+ else
+ {
+ _mapResponseCallbacks.Add(providerId, mapCallbacks);
+ mapRegistered = true;
+ }
+
+ mapBulkCallbacks = new Interop.DataControl.MapBulkAddResponseCallback(MapBulkAddResponse);
+ ret = Interop.DataControl.RegisterMapBulkResponseCallback(handle, mapBulkCallbacks, IntPtr.Zero);
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "Registering the map bulk callback function is failed : " + ret);
+ }
+ else
+ {
+ _mapBulkResponseCallback.Add(providerId, mapBulkCallbacks);
+ }
+
+ if (!mapRegistered && !sqlRegistered)
+ {
+ ErrorFactory.ThrowException(ret, true, "Registering the response callback function is failed");
+ }
+
+ _reqProviderList.Add(providerId, 1);
+ }
+
+ internal static void UnregisterCallback(Interop.DataControl.SafeDataControlHandle handle, string providerId)
+ {
+ int count;
+
+ _reqProviderList[providerId]--;
+ count = _reqProviderList[providerId];
+ if (count <= 0)
+ {
+ _reqProviderList.Remove(providerId);
+
+ _mapResponseCallbacks.Remove(providerId);
+ Interop.DataControl.UnregisterMapResponse(handle);
+
+ _mapBulkResponseCallback.Remove(providerId);
+ Interop.DataControl.UnregisterMapBulkResponseCallback(handle);
+
+ _sqlResponseCallbacks.Remove(providerId);
+ Interop.DataControl.UnregisterSqlResponseCallback(handle);
+
+ _sqlBulkResponseCallback.Remove(providerId);
+ Interop.DataControl.UnregisterSqlBulkResponseCallback(handle);
+ }
+
+ }
+ }
+
+ /// <summary>
+ /// Sends insert request to provider application.
+ /// </summary>
+ /// <remarks>OnInsertResult will recieve result of this API</remarks>
+ /// <param name="insertData">Insert data</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">Thrown when message has exceeded the maximum limit(1MB)</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ public void Insert(Bundle insertData)
+ {
+ int reqId;
+ ResultType ret;
+
+ if (insertData == null || insertData.SafeBundleHandle.IsInvalid)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "insertData");
+ }
+
+ _lock.WaitOne();
+ ret = Interop.DataControl.Insert(_handle, insertData.SafeBundleHandle, out reqId);
+ _lock.ReleaseMutex();
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "Insert");
+ }
+
+ CallbackManager.RegisterReqId(reqId, this);
+ }
+
+ /// <summary>
+ /// Sends select request to provider application.
+ /// </summary>
+ /// <remarks>OnSelectResult will recieve result of this API</remarks>
+ /// <param name="columnList">Select target column list</param>
+ /// <param name="where">Where statement for select query</param>
+ /// <param name="order">Order statement for select query</param>
+ /// <param name="pageNumber">Select target page number</param>
+ /// <param name="countPerPage">Select row count per page</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ public void Select(string[] columnList, string where, string order, int pageNumber = 1, int countPerPage = 20)
+ {
+ int reqId, i;
+ ResultType ret;
+ if (columnList == null || columnList.Length == 0)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "column_list");
+ }
+
+ for (i = 0; i < columnList.Length; i++)
+ {
+ if (string.IsNullOrEmpty(columnList[i]))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "column_list index " + i.ToString());
+ }
+ }
+
+ _lock.WaitOne();
+ ret = Interop.DataControl.Select(_handle, columnList, columnList.Length, where, order, pageNumber, countPerPage, out reqId);
+ _lock.ReleaseMutex();
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "Select");
+ }
+ Log.Info(LogTag, "select end. " + reqId.ToString());
+
+ CallbackManager.RegisterReqId(reqId, this);
+ }
+
+ /// <summary>
+ /// Sends delete request to provider application.
+ /// </summary>
+ /// <remarks>OnDeleteResult will recieve result of this API</remarks>
+ /// <param name="where">Where statement for delete query</param>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ public void Delete(string where)
+ {
+ int reqId;
+ ResultType ret;
+
+ _lock.WaitOne();
+ ret = Interop.DataControl.Delete(_handle, where, out reqId);
+ _lock.ReleaseMutex();
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "Delete");
+ }
+
+ CallbackManager.RegisterReqId(reqId, this);
+ }
+
+ /// <summary>
+ /// Sends update request to provider application.
+ /// </summary>
+ /// <remarks>OnUpdateResult will recieve result of this API</remarks>
+ /// <param name="updateData">Update data</param>
+ /// <param name="where">Where statement for query</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">Thrown when message has exceeded the maximum limit(1MB)</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ public void Update(Bundle updateData, string where)
+ {
+ int reqId;
+ ResultType ret;
+
+ if (updateData == null || updateData.SafeBundleHandle.IsInvalid)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "insertData");
+ }
+
+ if (string.IsNullOrEmpty(where))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "where");
+ }
+
+ _lock.WaitOne();
+ ret = Interop.DataControl.Update(_handle, updateData.SafeBundleHandle, where, out reqId);
+ _lock.ReleaseMutex();
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "Update");
+ }
+
+ CallbackManager.RegisterReqId(reqId, this);
+ }
+
+ /// <summary>
+ /// Sends bulk insert request to provider application.
+ /// </summary>
+ /// <remarks>OnBulkInsertResult will recieve result of this API</remarks>
+ /// <param name="insertData">Bulk insert data</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">Thrown when message has exceeded the maximum limit(1MB)</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ public void BulkInsert(BulkData insertData)
+ {
+ int reqId;
+ ResultType ret;
+
+ if (insertData == null || insertData.SafeBulkDataHandle.IsInvalid)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "insertData");
+ }
+
+ _lock.WaitOne();
+ ret = Interop.DataControl.BulkInsert(_handle, insertData.SafeBulkDataHandle, out reqId);
+ _lock.ReleaseMutex();
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "BulkInsert");
+ }
+
+ CallbackManager.RegisterReqId(reqId, this);
+ }
+
+ /// <summary>
+ /// Sends map add request to provider application.
+ /// </summary>
+ /// <remarks>OnMapAddResult will recieve result of this API</remarks>
+ /// <param name="key">The key of the value to add</param>
+ /// <param name="value">The value to add</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">Thrown when message has exceeded the maximum limit(1MB)</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ public void MapAdd(string key, string value)
+ {
+ int reqId;
+ ResultType ret;
+
+ if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(value))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ _lock.WaitOne();
+ ret = Interop.DataControl.MapAdd(_handle, key, value, out reqId);
+ _lock.ReleaseMutex();
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "MapAdd");
+ }
+
+ CallbackManager.RegisterReqId(reqId, this);
+ }
+
+ /// <summary>
+ /// Sends map get request to provider application.
+ /// </summary>
+ /// <remarks>OnMapGetResult will recieve result of this API</remarks>
+ /// <param name="key">The key of the value list to obtain</param>
+ /// <param name="pageNumber">The page number of the value set</param>
+ /// <param name="countPerPage">The desired maximum count of the data items per page</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ public void MapGet(string key, int pageNumber = 1, int countPerPage = 20)
+ {
+ int reqId;
+ ResultType ret;
+
+ if (string.IsNullOrEmpty(key) || pageNumber <= 0 || countPerPage <= 0)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ _lock.WaitOne();
+ ret = Interop.DataControl.MapGet(_handle, key, out reqId, pageNumber, countPerPage);
+ _lock.ReleaseMutex();
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "MapGet");
+ }
+
+ CallbackManager.RegisterReqId(reqId, this);
+ }
+
+ /// <summary>
+ /// Sends map remove request to provider application.
+ /// </summary>
+ /// <remarks>OnMapRemoveResult will recieve result of this API</remarks>
+ /// <param name="key">The key of the value to remove</param>
+ /// <param name="value">The value to remove</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ public void MapRemove(string key, string value)
+ {
+ int reqId;
+ ResultType ret;
+
+ if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(value))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ _lock.WaitOne();
+ ret = Interop.DataControl.MapRemove(_handle, key, value, out reqId);
+ _lock.ReleaseMutex();
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "MapRemove");
+ }
+
+ CallbackManager.RegisterReqId(reqId, this);
+ }
+
+ /// <summary>
+ /// Sends map set request to provider application.
+ /// </summary>
+ /// <remarks>OnMapSetResult will recieve result of this API</remarks>
+ /// <param name="key">The key of the value to replace</param>
+ /// <param name="oldValue">The value to be replaced</param>
+ /// <param name="newValue"> The new value that replaces the existing value</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">Thrown when message has exceeded the maximum limit(1MB)</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ public void MapSet(string key, string oldValue, string newValue)
+ {
+ int reqId;
+ ResultType ret;
+
+ if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(oldValue) || string.IsNullOrEmpty(newValue))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ _lock.WaitOne();
+ ret = Interop.DataControl.MapSet(_handle, key, oldValue, newValue, out reqId);
+ _lock.ReleaseMutex();
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "MapSet");
+ }
+
+ CallbackManager.RegisterReqId(reqId, this);
+ }
+
+ /// <summary>
+ /// Sends map bulk add request to provider application.
+ /// </summary>
+ /// <remarks>OnMapBulkAddResult will recieve result of this API</remarks>
+ /// <param name="addData">Map bulk add data</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">Thrown when message has exceeded the maximum limit(1MB)</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ public void MapBulkAdd(BulkData addData)
+ {
+ int reqId;
+ ResultType ret;
+
+ if (addData == null || addData.SafeBulkDataHandle.IsInvalid)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "addData");
+ }
+
+ _lock.WaitOne();
+ ret = Interop.DataControl.BulkAdd(_handle, addData.SafeBulkDataHandle, out reqId);
+ _lock.ReleaseMutex();
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "BulkAdd");
+ }
+
+ CallbackManager.RegisterReqId(reqId, this);
+ }
+
+ private void DataChange(IntPtr handle, ChangeType type, IntPtr data, IntPtr userData)
+ {
+ OnDataChange(type, new Bundle(new SafeBundleHandle(data, false)));
+ }
+
+ private void DataChangeListenResult(IntPtr handle, ResultType type, int callbackId, IntPtr userData)
+ {
+ OnDataChangeListenResult(new DataChangeListenResult(type));
+ }
+
+ /// <summary>
+ /// Listen DataChange event
+ /// </summary>
+ /// <remarks>OnDataChangeListenResult will recieve result of this API</remarks>
+ /// <remarks>If success, OnDataChange will recieve DataChange event</remarks>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ public void DataChangeListen()
+ {
+ ResultType ret;
+ _lock.WaitOne();
+ /* Only one callback is allowed for every obejct */
+ if (_changeCallbackID > 0)
+ {
+ _lock.ReleaseMutex();
+ return;
+ }
+ _dataChangeCallback = new Interop.DataControl.DataChangeCallback(DataChange);
+ _addCallbackResultCallback = new Interop.DataControl.AddCallbackResultCallback(DataChangeListenResult);
+ ret = Interop.DataControl.AddDataChangeCallback(_handle, _dataChangeCallback, IntPtr.Zero,
+ _addCallbackResultCallback , IntPtr.Zero, out _changeCallbackID);
+ _lock.ReleaseMutex();
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "DataChangeListen");
+ }
+ }
+
+ /// <summary>
+ /// Initializes Consumer class with providerId and dataId.
+ /// </summary>
+ /// <param name="providerId">DataControl Provider ID</param>
+ /// <param name="dataId">DataControl Data ID</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ public Consumer(string providerId, string dataId)
+ {
+ ResultType ret;
+
+ if (string.IsNullOrEmpty(providerId))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "providerId");
+ }
+
+ if (string.IsNullOrEmpty(dataId))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "dataId");
+ }
+
+ ret = Interop.DataControl.DataControlCreate(out _handle);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "Creating data control handle is failed");
+ }
+
+ Interop.DataControl.DataControlSetProviderId(_handle, providerId);
+ Interop.DataControl.DataControlSetDataId(_handle, dataId);
+ CallbackManager.RegisterCallback(_handle, providerId);
+ _dataID = dataId;
+ _providerID = providerId;
+ }
+
+ ~Consumer()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the DataChangeListen result is received.
+ /// </summary>
+ protected virtual void OnDataChangeListenResult(DataChangeListenResult result)
+ {
+ Log.Info(LogTag, "The OnDataChangeListenResult is not implemented.");
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the data change event is received.
+ /// </summary>
+ protected virtual void OnDataChange(ChangeType type, Bundle data)
+ {
+ Log.Info(LogTag, "The OnDataChange is not implemented.");
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the select response is received.
+ /// </summary>
+ protected abstract void OnSelectResult(SelectResult result);
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the insert response is received.
+ /// </summary>
+ protected abstract void OnInsertResult(InsertResult result);
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the update response is received.
+ /// </summary>
+ protected abstract void OnUpdateResult(UpdateResult result);
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the delete response is received.
+ /// </summary>
+ protected abstract void OnDeleteResult(DeleteResult result);
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the BulkInsert response is received.
+ /// </summary>
+ protected virtual void OnBulkInsertResult(BulkInsertResult result)
+ {
+ Log.Info(LogTag, "The OnBulkInsertResult is not implemented.");
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the map get response is received.
+ /// </summary>
+ protected virtual void OnMapGetResult(MapGetResult result)
+ {
+ Log.Info(LogTag, "The OnMapGetResult is not implemented.");
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the map add response is received.
+ /// </summary>
+ protected virtual void OnMapAddResult(MapAddResult result)
+ {
+ Log.Info(LogTag, "The OnMapAddResult is not implemented.");
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the map set response is received.
+ /// </summary>
+ protected virtual void OnMapSetResult(MapSetResult result)
+ {
+ Log.Info(LogTag, "The OnMapSetResult is not implemented.");
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the map remove response is received.
+ /// </summary>
+ protected virtual void OnMapRemoveResult(MapRemoveResult result)
+ {
+ Log.Info(LogTag, "The OnMapRemoveResult is not implemented.");
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the BulkAdd response is received.
+ /// </summary>
+ protected virtual void OnMapBulkAddResult(MapBulkAddResult result)
+ {
+ Log.Info(LogTag, "The OnMapBulkAddResult is not implemented.");
+ }
+
+ /// <summary>
+ /// Releases the unmanaged resourced used by the Consumer class specifying whether to perform a normal dispose operation.
+ /// </summary>
+ /// <param name="disposing">true for a normal dispose operation; false to finalize the handle.</param>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (_changeCallbackID > 0)
+ {
+ Interop.DataControl.RemoveDataChangeCallback(_handle, _changeCallbackID);
+ }
+
+ CallbackManager.UnregisterCallback(_handle, _providerID);
+ _handle.Dispose();
+ _disposed = true;
+ }
+
+ if (disposing)
+ {
+ GC.SuppressFinalize(this);
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by the Consumer class.
+ /// </summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+ }
+}
diff --git a/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl/ErrorFactory.cs b/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl/ErrorFactory.cs
new file mode 100755
index 0000000..a5712c9
--- /dev/null
+++ b/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl/ErrorFactory.cs
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.CompilerServices;
+
+namespace Tizen.Applications.DataControl
+{
+ internal static class ErrorFactory
+ {
+ private const string LogTag = "Tizen.Applications.DataControl";
+
+ internal static void ThrowException(ResultType errorCode, bool ignoreType, string errorMessage = null,
+ [CallerMemberName] string memberName = "", [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNumber = 0)
+ {
+ Log.Error(LogTag, $"{memberName}({lineNumber.ToString()}) : {filePath}");
+ if (ignoreType)
+ {
+ throw new InvalidOperationException(string.IsNullOrEmpty(errorMessage) ? "error code : " + errorCode.ToString() :
+ $"{errorMessage} - {errorCode}");
+ }
+
+ switch (errorCode)
+ {
+ case ResultType.Success:
+ return;
+ case ResultType.OutOfMemory:
+ case ResultType.IoError:
+ throw new InvalidOperationException(string.IsNullOrEmpty(errorMessage) ? "error code : " + errorCode.ToString() :
+ $"{errorMessage} - {errorCode}");
+ case ResultType.InvalidParameter:
+ Log.Error(LogTag, "Invalid parameter : " + errorMessage);
+ throw new ArgumentException(string.IsNullOrEmpty(errorMessage) ? "Invalid parameter" : "Invalid parameter : " + errorMessage);
+ case ResultType.PermissionDenied:
+ Log.Error(LogTag, "Permission denied : " + errorMessage);
+ throw new UnauthorizedAccessException(string.IsNullOrEmpty(errorMessage) ? "Permission denied" : "Permission denied : " + errorMessage);
+ case ResultType.MaxExceed:
+ Log.Error(LogTag, "Too long argument : " + errorMessage);
+ throw new ArgumentOutOfRangeException(string.IsNullOrEmpty(errorMessage) ? "Too long argument" : "Too long argument : " + errorMessage);
+ default:
+ Log.Error(LogTag, $"Unknown error : {errorMessage} - {errorCode}");
+ throw new InvalidOperationException(string.IsNullOrEmpty(errorMessage) ? "Unknown error : " + errorCode.ToString() :
+ $"Unknown error : {errorMessage} - {errorCode}");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl/ICursor.cs b/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl/ICursor.cs
new file mode 100755
index 0000000..4136358
--- /dev/null
+++ b/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl/ICursor.cs
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+
+namespace Tizen.Applications.DataControl
+{
+ /// <summary>
+ /// This interface is for DataControl cursor.
+ /// </summary>
+ public interface ICursor
+ {
+ /// <summary>
+ /// Gets a column count.
+ /// </summary>
+ int GetColumnCount();
+ /// <summary>
+ /// Gets a column type.
+ /// </summary>
+ /// <param name="index">The index of column.</param>
+ ColumnType GetColumnType(int index);
+ /// <summary>
+ /// Gets a column name.
+ /// </summary>
+ /// <param name="index">The index of column.</param>
+ string GetColumnName(int index);
+ /// <summary>
+ /// Gets the numbers of rows in the cursor.
+ /// </summary>
+ long GetRowCount();
+ /// <summary>
+ /// Gets a next row.
+ /// </summary>
+ bool Next();
+ /// <summary>
+ /// Gets a prev row.
+ /// </summary>
+ bool Prev();
+ /// <summary>
+ /// Gets a first row.
+ /// </summary>
+ bool Reset();
+ /// <summary>
+ /// / Gets an int value.
+ /// </summary>
+ /// <param name="index">The index of row.</param>
+ int GetIntValue(int index);
+ /// <summary>
+ /// / Gets an int64 value.
+ /// </summary>
+ /// <param name="index">The index of row.</param>
+ Int64 GetInt64Value(int index);
+ /// <summary>
+ /// Gets an double value.
+ /// </summary>
+ /// <param name="index">The index of row.</param>
+ double GetDoubleValue(int index);
+ /// <summary>
+ /// Gets an string value.
+ /// </summary>
+ /// <param name="index">The index of row.</param>
+ string GetStringValue(int index);
+ /// <summary>
+ /// Gets a blob value.
+ /// </summary>
+ /// <param name="index">The index of row.</param>
+ byte[] GetBlobValue(int index);
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl/MatrixCursor.cs b/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl/MatrixCursor.cs
new file mode 100755
index 0000000..426416e
--- /dev/null
+++ b/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl/MatrixCursor.cs
@@ -0,0 +1,629 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.IO;
+using System.Text;
+using System.Collections.Generic;
+using System.Threading;
+using System.Diagnostics;
+
+namespace Tizen.Applications.DataControl
+{
+ /// <summary>
+ /// Represents MatrixCursor class for DataControl provider's matrix cursor.
+ /// </summary>
+ public class MatrixCursor : IDisposable, ICursor
+ {
+ private const string LogTag = "Tizen.Applications.DataControl";
+ private FileStream _fs;
+ private bool _disposed = false;
+ private string _cursorPath;
+ private long _rowCount = 0;
+ private long _rowCountPosition = 0;
+ private int _currentRowIndex = 0;
+ private IList<long> _rowFieldOffset = new List<long>();
+ private string[] _columnNames;
+ private ColumnType[] _columnTypes;
+ private const int ColumnTypeNull = 5;
+
+ private byte[] GetValue(int index)
+ {
+ byte[] int_tmp = new byte[sizeof(int)];
+ byte[] ret_array;
+ ColumnType type;
+ int size, read_len;
+
+ MoveToColumn(index);
+
+ read_len = _fs.Read(int_tmp, 0, int_tmp.Length);
+ if (read_len != int_tmp.Length)
+ {
+ ErrorFactory.ThrowException(ResultType.IoError, true, "Column Type " + index.ToString());
+ }
+
+ type = (ColumnType)BitConverter.ToInt32(int_tmp, 0);
+
+ if (type != _columnTypes[index])
+ {
+ if ((int)type == ColumnTypeNull &&
+ (_columnTypes[index] == ColumnType.ColumnTypeBlob || _columnTypes[index] == ColumnType.ColumnTypeString))
+ {
+ return null; /* null type */
+ }
+
+ ErrorFactory.ThrowException(ResultType.IoError, true, "Type mismatch " + index.ToString());
+ }
+
+ read_len = _fs.Read(int_tmp, 0, int_tmp.Length);
+ if (read_len != int_tmp.Length)
+ {
+ ErrorFactory.ThrowException(ResultType.IoError, true, "Column size " + index.ToString());
+ }
+
+ size = BitConverter.ToInt32(int_tmp, 0);
+
+ if (size < 0)
+ {
+ ErrorFactory.ThrowException(ResultType.IoError, true, "Invalid data size " + index.ToString());
+ }
+
+ ret_array = new byte[size];
+ read_len = _fs.Read(ret_array, 0, ret_array.Length);
+ if (read_len != ret_array.Length)
+ {
+ ErrorFactory.ThrowException(ResultType.IoError, true, "Column value size " + index.ToString());
+ return null;
+ }
+
+ return ret_array;
+ }
+
+ private void MoveToColumn(int ColumnIndex)
+ {
+ int i, tmp_position;
+ byte[] int_tmp = new byte[sizeof(int)];
+ int read_len;
+ long seek_len;
+
+ seek_len = _fs.Seek(_rowFieldOffset[_currentRowIndex], SeekOrigin.Begin);
+ if (seek_len != _rowFieldOffset[_currentRowIndex])
+ {
+ ErrorFactory.ThrowException(ResultType.IoError, true, "Row index " + _currentRowIndex.ToString());
+ }
+
+ for (i = 0; i < ColumnIndex; i++)
+ {
+ /* type(int) size(int) value */
+ switch (_columnTypes[i])
+ {
+ case ColumnType.ColumnTypeInt:
+ tmp_position = sizeof(int) * 2 + sizeof(Int64);
+ _fs.Seek(tmp_position, SeekOrigin.Current);
+ break;
+ case ColumnType.ColumnTypeDouble:
+ tmp_position = sizeof(int) * 2 + sizeof(double);
+ _fs.Seek(tmp_position, SeekOrigin.Current);
+ break;
+ case ColumnType.ColumnTypeString:
+ tmp_position = sizeof(int);
+ _fs.Seek(tmp_position, SeekOrigin.Current);
+ read_len = _fs.Read(int_tmp, 0, int_tmp.Length);
+ if (read_len != int_tmp.Length)
+ {
+ ErrorFactory.ThrowException(ResultType.IoError, true, "Column Index " + ColumnIndex.ToString());
+ }
+
+ tmp_position = BitConverter.ToInt32(int_tmp, 0);
+
+ if (tmp_position > 0)
+ {
+ _fs.Seek(tmp_position, SeekOrigin.Current);
+ }
+
+ break;
+ case ColumnType.ColumnTypeBlob:
+ tmp_position = sizeof(int);
+ _fs.Seek(tmp_position, SeekOrigin.Current);
+
+ read_len = _fs.Read(int_tmp, 0, int_tmp.Length);
+ if (read_len != int_tmp.Length)
+ {
+ ErrorFactory.ThrowException(ResultType.IoError, true, "Column Index " + ColumnIndex.ToString());
+ }
+
+ tmp_position = BitConverter.ToInt32(int_tmp, 0);
+
+ if (tmp_position > 0)
+ {
+ _fs.Seek(tmp_position, SeekOrigin.Current);
+ }
+
+ break;
+ }
+ }
+
+ }
+
+ internal FileStream GetFileStream()
+ {
+ return _fs;
+ }
+
+ /// <summary>
+ /// Gets column count of MatrixCursor.
+ /// </summary>
+ public int GetColumnCount()
+ {
+ return _columnTypes.Length;
+ }
+
+ /// <summary>
+ /// Returns the column type at the given zero-based column index.
+ /// </summary>
+ /// <param name="index">Target column index</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public ColumnType GetColumnType(int index)
+ {
+ if (index < 0 || index >= _columnTypes.Length)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ return _columnTypes[index];
+ }
+
+ /// <summary>
+ /// Returns the column name at the given zero-based column index.
+ /// </summary>
+ /// <param name="index">Target column index</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public string GetColumnName(int index)
+ {
+ if (index < 0 || index >= _columnTypes.Length)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ return _columnNames[index];
+ }
+
+ /// <summary>
+ /// Gets MatrixCursor's row count.
+ /// </summary>
+ public long GetRowCount()
+ {
+ return _rowCount;
+ }
+
+ /// <summary>
+ /// Move the MatrixCursor to the next row.
+ /// </summary>
+ public bool Next()
+ {
+ if (_currentRowIndex >= _rowCount - 1)
+ {
+ return false;
+ }
+
+ _currentRowIndex++;
+ return true;
+ }
+
+ /// <summary>
+ /// Move the MatrixCursor to the previous row.
+ /// </summary>
+ public bool Prev()
+ {
+ if (_currentRowIndex <= 0)
+ {
+ return false;
+ }
+
+ _currentRowIndex--;
+ return true;
+ }
+
+ /// <summary>
+ /// Move the MatrixCursor to the first row.
+ /// </summary>
+ public bool Reset()
+ {
+ _currentRowIndex = 0;
+ return true;
+ }
+
+ /// <summary>
+ /// Returns the value of the requested column as a int.
+ /// </summary>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public int GetIntValue(int index)
+ {
+ int ret;
+ byte[] byte_array;
+
+ if (index < 0 || index >= _columnTypes.Length)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ byte_array = GetValue(index);
+ if (byte_array == null)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+ ret = BitConverter.ToInt32(byte_array, 0);
+
+ return ret;
+ }
+
+ /// <summary>
+ /// Returns the value of the requested column as a int64.
+ /// </summary>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public Int64 GetInt64Value(int index)
+ {
+ Int64 ret;
+ byte[] byte_array;
+
+ if (index < 0 || index >= _columnTypes.Length)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ byte_array = GetValue(index);
+ if (byte_array == null)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+ ret = BitConverter.ToInt64(byte_array, 0);
+
+ return ret;
+ }
+
+ /// <summary>
+ /// Returns the value of the requested column as a double.
+ /// </summary>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public double GetDoubleValue(int index)
+ {
+ double ret;
+ byte[] byte_array;
+
+ if (index < 0 || index >= _columnTypes.Length)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ byte_array = GetValue(index);
+ if (byte_array == null)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+ ret = BitConverter.ToDouble(byte_array, 0);
+
+ return ret;
+ }
+
+ /// <summary>
+ /// Returns the value of the requested column as a string.
+ /// </summary>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public string GetStringValue(int index)
+ {
+ string ret;
+ byte[] byte_array;
+
+ if (index < 0 || index >= _columnTypes.Length)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ byte_array = GetValue(index);
+
+ if (byte_array == null)
+ {
+ return null;
+ }
+
+ ret = Encoding.UTF8.GetString(byte_array).TrimEnd('\0');
+ return ret;
+
+ }
+
+ /// <summary>
+ /// Returns the value of the requested column as a blob.
+ /// </summary>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public byte[] GetBlobValue(int index)
+ {
+ byte[] byte_array;
+
+ if (index < 0 || index >= _columnTypes.Length)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ byte_array = GetValue(index);
+ return byte_array;
+ }
+
+ private static class FileManager
+ {
+ private static readonly string DATACONTROL_DIRECTORY = "/tmp/";
+ private static Dictionary<int, int> fileTable = new Dictionary<int, int>();
+ public static string OpenFileStream(int threadID)
+ {
+ string path;
+ int index;
+
+ if (threadID < 0)
+ {
+ Log.Error(LogTag, "threadID is " + threadID.ToString());
+ return null;
+ }
+
+ if (fileTable.ContainsKey(threadID) == false)
+ {
+ fileTable.Add(threadID, 0);
+ }
+
+ index = fileTable[threadID];
+ index++;
+ fileTable[threadID] = index;
+
+ path = DATACONTROL_DIRECTORY + Application.Current.ApplicationInfo.ApplicationId + "_" + Process.GetCurrentProcess().Id.ToString() + "_" + threadID.ToString() + "_" + index.ToString();
+
+ return path;
+ }
+ }
+
+ /// <summary>
+ /// Initializes MatrixCursor class with columnNames and columnTypes.
+ /// </summary>
+ /// <param name="columnNames">MatrixCursor's column name list</param>
+ /// <param name="columnTypes">MatrixCursor's column type list</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ public MatrixCursor(string[] columnNames, ColumnType[] columnTypes)
+ {
+ byte[] byte_tmp, length_tmp, string_tmp;
+ int i, total_len_of_column_names = 0;
+
+ if (columnNames == null || columnTypes == null ||
+ (columnNames.Length != columnTypes.Length) || columnNames.Length < 1)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ for (i = 0; i < columnNames.Length; i++)
+ {
+ if (string.IsNullOrEmpty(columnNames[i]))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "columnNames index " + i.ToString());
+ }
+ }
+
+ for (i = 0; i < columnTypes.Length; i++)
+ {
+ if ( columnTypes[i] < ColumnType.ColumnTypeInt || columnTypes[i] > ColumnType.ColumnTypeBlob)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "columnTypes index" + i.ToString());
+ }
+ }
+
+ _columnNames = columnNames;
+ _columnTypes = columnTypes;
+
+ _cursorPath = FileManager.OpenFileStream(Thread.CurrentThread.ManagedThreadId);
+ if (_cursorPath == null)
+ {
+ Log.Error(LogTag, "Unable to create a cursor file : " + _cursorPath);
+ ErrorFactory.ThrowException(ResultType.IoError, true);
+ }
+
+ _fs = new FileStream(_cursorPath, FileMode.Create);
+ /* column count */
+ byte_tmp = BitConverter.GetBytes(columnNames.Length);
+ _fs.Write(byte_tmp, 0, byte_tmp.Length);
+
+ /* column type */
+ for (i = 0; i < columnTypes.Length; i++)
+ {
+ byte_tmp = BitConverter.GetBytes((int)_columnTypes[i]);
+ _fs.Write(byte_tmp, 0, byte_tmp.Length);
+ }
+
+ /* column name */
+ for (i = 0; i < columnTypes.Length; i++)
+ {
+ string_tmp = Encoding.UTF8.GetBytes(columnNames[i]);
+ byte_tmp = new byte[string_tmp.Length + 1];/*insert null */
+
+ string_tmp.CopyTo(byte_tmp, 0);
+
+ length_tmp = BitConverter.GetBytes(byte_tmp.Length);
+ total_len_of_column_names += length_tmp.Length;
+
+ _fs.Write(length_tmp, 0, length_tmp.Length);
+ _fs.Write(byte_tmp, 0, byte_tmp.Length);
+ }
+
+ /* total length of column names */
+ byte_tmp = BitConverter.GetBytes(total_len_of_column_names);
+ _fs.Write(byte_tmp, 0, byte_tmp.Length);
+
+ _rowCountPosition = _fs.Position;
+ /* row count */
+ byte_tmp = BitConverter.GetBytes(_rowCount);
+ _fs.Write(byte_tmp, 0, byte_tmp.Length);
+ _fs.Flush();
+ }
+
+ internal MatrixCursor()
+ {
+ _columnNames = new string[0];
+ _columnTypes = new ColumnType[0];
+ _fs = null;
+ _cursorPath = null;
+ }
+
+ /// <summary>
+ /// Adds a new row to the end with the given column values.
+ /// </summary>
+ /// <param name="columnValues">New column values</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public void AddRow(object[] columnValues)
+ {
+ int i, size = 0;
+ byte[] type_array, length_array, value_array = null, string_array, byte_tmp;
+
+ if (columnValues == null || columnValues.Length <= 0 || columnValues.Length != _columnTypes.Length)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ using (MemoryStream ms = new MemoryStream())
+ {
+ for (i = 0; i < _columnTypes.Length; i++)
+ {
+ type_array = BitConverter.GetBytes((int)_columnTypes[i]);
+ switch (_columnTypes[i])
+ {
+ case ColumnType.ColumnTypeInt:
+ if (!(columnValues[i] is Int64) && !(columnValues[i] is Int32))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "Type mismatch :Index " + i.ToString());
+ }
+
+ value_array = BitConverter.GetBytes(Convert.ToUInt64(columnValues[i]));
+ size = value_array.Length;
+ break;
+ case ColumnType.ColumnTypeDouble:
+ if (!(columnValues[i] is Double))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "Type mismatch :Index " + i.ToString());
+ }
+
+ value_array = BitConverter.GetBytes(Convert.ToDouble(columnValues[i]));
+ size = value_array.Length;
+ break;
+ case ColumnType.ColumnTypeString:
+ if (columnValues[i] == null)
+ {
+ type_array = BitConverter.GetBytes(ColumnTypeNull);
+ size = 0;
+ break;
+ }
+
+ if (!(columnValues[i] is string))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "Type mismatch :Index " + i.ToString());
+ }
+
+ string_array = Encoding.UTF8.GetBytes(Convert.ToString(columnValues[i]));
+ value_array = new byte[string_array.Length + 1];/*insert null */
+ string_array.CopyTo(value_array, 0);
+ size = value_array.Length;
+ break;
+
+ case ColumnType.ColumnTypeBlob:
+ if (columnValues[i] == null)
+ {
+ type_array = BitConverter.GetBytes(ColumnTypeNull);
+ size = 0;
+ break;
+ }
+
+ if (!(columnValues[i] is byte[]))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "Type mismatch :Index " + i.ToString());
+ }
+
+ value_array = (byte[])columnValues[i];
+ size = value_array.Length;
+ break;
+ }
+
+ ms.Write(type_array, 0, type_array.Length);
+
+ length_array = BitConverter.GetBytes(size);
+ ms.Write(length_array, 0, length_array.Length);
+ if (size > 0)
+ {
+ ms.Write(value_array, 0, value_array.Length);
+ }
+ }
+
+ /* update row count */
+ _rowCount++;
+ byte_tmp = BitConverter.GetBytes(_rowCount);
+ _fs.Seek(_rowCountPosition, SeekOrigin.Begin);
+ _fs.Write(byte_tmp, 0, byte_tmp.Length);
+
+ _fs.Seek(0, SeekOrigin.End);
+
+ _rowFieldOffset.Add(_fs.Position);
+ ms.WriteTo(_fs);/* row data */
+ _fs.Flush();
+
+ Log.Debug(LogTag, "_fs pos = " + _fs.Position.ToString());
+ Log.Debug(LogTag, "_fs len = " + _fs.Length.ToString());
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by the MatrixCursor class.
+ /// </summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (!string.IsNullOrEmpty(_cursorPath))
+ {
+ FileInfo fi = new FileInfo(_cursorPath);
+
+ if (_fs != null)
+ {
+ _fs.Dispose();
+ }
+
+ if (fi.Exists)
+ {
+ fi.Delete();
+ }
+ }
+
+ _disposed = true;
+ }
+
+ if (disposing)
+ {
+ GC.SuppressFinalize(this);
+ }
+ }
+
+ ~MatrixCursor()
+ {
+ Dispose(false);
+ }
+ }
+}
diff --git a/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl/Provider.cs b/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl/Provider.cs
new file mode 100755
index 0000000..72a1142
--- /dev/null
+++ b/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl/Provider.cs
@@ -0,0 +1,1091 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.IO;
+using System.Text;
+using System.Collections.Generic;
+using Tizen.Applications.DataControl;
+using System.Runtime.InteropServices;
+using System.Threading;
+
+namespace Tizen.Applications.DataControl
+{
+ /// <summary>
+ /// Represents Provider class for DataControl provider application.
+ /// </summary>
+ public abstract class Provider : IDisposable
+ {
+ private const string LogTag = "Tizen.Applications.DataControl";
+ private static IDictionary<string, Provider> _providerDict = new Dictionary<string, Provider>();
+ private static Interop.DataControl.SqlRequestCallbacks _sqlRequestCallbacks;
+ private static Interop.DataControl.MapRequestCallbacks _mapRequestCallbacks;
+ private IntPtr _nativeHandle;
+ private static Interop.DataControl.DataChangeConsumerFilterCb _filterCallback;
+ private static int _filterCallbackID;
+ private static bool _filterRegistered;
+ private static Interop.DataControl.SqlBulkInsertRequestCallback _sqlBulkCallback;
+ private static Interop.DataControl.MapBulkAddRequestCallback _mapBulkCallback;
+ private static Mutex _lock = new Mutex();
+ private bool _disposed = false;
+ private bool _isRunning = false;
+
+ /// <summary>
+ /// Gets the data ID
+ /// </summary>
+ public string DataID
+ {
+ get;
+ private set;
+ }
+
+ private static bool DataChangeListenFilter(IntPtr handlePtr, string consumerAppid, IntPtr userData)
+ {
+ Provider provider;
+ DataChangeListenResult result;
+
+ provider = GetProvider(handlePtr);
+ if (provider == null)
+ {
+ Log.Error(LogTag, "Provider not exist ");
+ return false;
+ }
+
+ result = provider.OnDataChangeListenRequest(consumerAppid);
+ if (result == null || result.Result != ResultType.Success)
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+ }
+
+ private enum OperationType : short
+ {
+ Select,
+ Update,
+ Insert,
+ Delete
+ }
+
+ private static string CreateSelectQuery(IntPtr handlePtr, string[] columnList, int columnCount, string where, string order, int pageNum, int countPerPage)
+ {
+ Interop.DataControl.SafeDataControlHandle handle = new Interop.DataControl.SafeDataControlHandle(handlePtr, false);
+ string query = "SELECT";
+ string dataId;
+ if (columnList == null)
+ {
+ query += " * ";
+ }
+ else
+ {
+ for (int i = 0; i < columnCount; i++)
+ {
+ if (i != 0)
+ {
+ query += ",";
+ }
+
+ query += " " + columnList[i];
+ }
+ }
+
+ Interop.DataControl.DataControlGetDataId(handle, out dataId);
+ query += " FROM " + dataId;
+ if (where != null)
+ {
+ query += " WHERE " + where;
+ }
+
+ if (order != null)
+ {
+ query += " ORDER BY " + order;
+ }
+
+ if (pageNum != 0)
+ {
+ query += " LIMIT " + countPerPage + " OFFSET " + (countPerPage * (pageNum - 1));
+ }
+ handle.Dispose();
+ return query;
+ }
+
+ private static void InsertRequest(int requestId, IntPtr handlePtr, IntPtr insertData, IntPtr userData)
+ {
+ Provider provider;
+ InsertResult result;
+ SafeBundleHandle sbh = new SafeBundleHandle(insertData, false);
+ string query = GetQuery(handlePtr, sbh, null, OperationType.Update);
+ ResultType ret;
+
+ provider = GetProvider(handlePtr);
+ if (provider == null)
+ {
+ Log.Error(LogTag, "Provider not exist ");
+ return;
+ }
+
+ result = provider.OnInsert(query, new Bundle(sbh));
+ if (result != null)
+ {
+ if (result.Result)
+ {
+ ret = Interop.DataControl.SendInsertResult(requestId, result.RowID);
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendInsertResult fail " + ret.ToString());
+ }
+ }
+ else
+ {
+ ret = Interop.DataControl.SendError(requestId, result.Result.ToString());
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendError fail " + ret.ToString());
+ }
+ }
+ }
+ else
+ {
+ Log.Info(LogTag, $"InsertResult is null : {requestId.ToString()}");
+ }
+ }
+
+ private static void BulkInsertRequest(int requestId, IntPtr handlePtr, IntPtr bulk_data, IntPtr userData)
+ {
+ Provider provider;
+ BulkInsertResult result;
+ BulkData bulkData = new BulkData(new Interop.DataControl.SafeBulkDataHandle(bulk_data, false));
+ Interop.DataControl.SafeBulkDataHandle sbdh = bulkData.SafeBulkDataHandle;
+ IntPtr bundleHandel;
+ ResultType ret;
+
+ int count = bulkData.GetCount();
+ List<string> queryList = new List<string>();
+
+ for (int i = 0; i < count; i++)
+ {
+ Interop.DataControl.BulkGetData(sbdh, i, out bundleHandel);
+ queryList.Add(GetQuery(handlePtr, new SafeBundleHandle(bundleHandel, false), null, OperationType.Insert));
+ }
+
+ provider = GetProvider(handlePtr);
+ if (provider == null)
+ {
+ Log.Error(LogTag, "Provider not exist ");
+ return;
+ }
+
+ result = provider.OnBulkInsert(queryList, bulkData);
+ if (result != null)
+ {
+ if (result.Result)
+ {
+ ret = Interop.DataControl.SendBulkInsertResult(requestId, result.BulkResultData.SafeBulkDataHandle);
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendBulkInsertResult fail " + ret.ToString());
+ }
+ }
+ else
+ {
+ ret = Interop.DataControl.SendError(requestId, result.Result.ToString());
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendError fail " + ret.ToString());
+ }
+ }
+
+ if (result.BulkResultData != null)
+ {
+ result.BulkResultData.Dispose();
+ }
+ }
+ else
+ {
+ Log.Info(LogTag, $"BulkInsertResult is null : {requestId.ToString()}");
+ }
+ }
+
+ private static void SendNativeProtocol(int socketFd, ICursor cursor, int requestId)
+ {
+ uint write_len;
+ int DATACONTROL_RESULT_NO_DATA = -1;
+ int COLUMN_TYPE_NULL = 5;
+ int column_count, i, rowcount, size = 0, total_len_of_column_names = 0;
+ byte[] type_array, length_array, string_array, int_tmp, value_array = null;
+ string txt;
+ ResultType result;
+ MemoryStream ms;
+
+ if (cursor.Reset() == false)
+ {
+ Log.Error(LogTag, "Reset is failed : " + requestId.ToString());
+ return;
+ }
+
+ if (cursor.GetRowCount() <= 0)
+ {
+ Log.Error(LogTag, "The DB does not have another row : " + requestId.ToString());
+ int_tmp = BitConverter.GetBytes(DATACONTROL_RESULT_NO_DATA);
+ result = (ResultType)Interop.DataControl.UnsafeCode.WriteResult(socketFd, int_tmp, int_tmp.Length, out write_len);
+ return;
+ }
+
+ /* 1. column count */
+ column_count = cursor.GetColumnCount();
+ int_tmp = BitConverter.GetBytes(column_count);
+ result = (ResultType)Interop.DataControl.UnsafeCode.WriteResult(socketFd, int_tmp, int_tmp.Length, out write_len);
+ if (result != ResultType.Success)
+ {
+ Log.Error(LogTag, "Writing a column_count to a file descriptor is failed.");
+ return;
+ }
+
+ Log.Info(LogTag, "Writing a column_count " + column_count.ToString());
+
+ /* 2.column type x column_count */
+ for (i = 0; i < column_count; i++)
+ {
+ type_array = BitConverter.GetBytes((int)cursor.GetColumnType(i));
+ result = (ResultType)Interop.DataControl.UnsafeCode.WriteResult(socketFd, type_array, type_array.Length, out write_len);
+ if (result != ResultType.Success)
+ {
+ Log.Error(LogTag, "Writing a type to a file descriptor is failed.");
+ return;
+ }
+
+ Log.Info(LogTag, "Writing a column_type " + cursor.GetColumnType(i).ToString());
+ }
+
+ /* 3. column name x column_count */
+ for (i = 0; i < column_count; i++)
+ {
+ Log.Info(LogTag, "Writing a name " + cursor.GetColumnName(i));
+
+ total_len_of_column_names += cursor.GetColumnName(i).Length;
+ string_array = Encoding.UTF8.GetBytes(cursor.GetColumnName(i));
+ value_array = new byte[string_array.Length + 1];/*insert null */
+ string_array.CopyTo(value_array, 0);
+ length_array = BitConverter.GetBytes(value_array.Length);
+
+ result = (ResultType)Interop.DataControl.UnsafeCode.WriteResult(socketFd, length_array, length_array.Length, out write_len);
+ if (result != ResultType.Success)
+ {
+ Log.Error(LogTag, "Writing a type to a file descriptor is failed.");
+ return;
+ }
+
+ result = (ResultType)Interop.DataControl.UnsafeCode.WriteResult(socketFd, value_array, value_array.Length, out write_len);
+ if (result != ResultType.Success)
+ {
+ Log.Error(LogTag, "Writing a type to a file descriptor is failed.");
+ return;
+ }
+
+ }
+
+ /* 4. total length of column names */
+ length_array = BitConverter.GetBytes(total_len_of_column_names);
+ result = (ResultType)Interop.DataControl.UnsafeCode.WriteResult(socketFd, length_array, length_array.Length, out write_len);
+ if (result != ResultType.Success)
+ {
+ Log.Error(LogTag, "Writing a total_len_of_column_names to a file descriptor is failed");
+ return;
+ }
+
+ Log.Info(LogTag, "Writing total length of column namese " + total_len_of_column_names.ToString());
+
+ /* 5. row count */
+ length_array = BitConverter.GetBytes(cursor.GetRowCount());
+ Log.Error(LogTag, "=========================== select rowcount " + cursor.GetRowCount().ToString());
+ result = (ResultType)Interop.DataControl.UnsafeCode.WriteResult(socketFd, length_array, length_array.Length, out write_len);
+ if (result != ResultType.Success)
+ {
+ Log.Error(LogTag, "Writing a row count to a file descriptor is failed");
+ return;
+ }
+
+ Log.Error(LogTag, "Writing a row count " + cursor.GetRowCount().ToString());
+
+ rowcount = 0;
+ do
+ {
+ ms = new MemoryStream();
+
+ for (i = 0; i < column_count; i++)
+ {
+ type_array = BitConverter.GetBytes((int)cursor.GetColumnType(i));
+ switch (cursor.GetColumnType(i))
+ {
+ case ColumnType.ColumnTypeInt:
+ value_array = BitConverter.GetBytes(cursor.GetInt64Value(i));
+ size = value_array.Length;
+ break;
+
+ case ColumnType.ColumnTypeDouble:
+ value_array = BitConverter.GetBytes(cursor.GetDoubleValue(i));
+ size = value_array.Length;
+ break;
+
+ case ColumnType.ColumnTypeString:
+ txt = cursor.GetStringValue(i);
+ if (txt == null)
+ {
+ type_array = BitConverter.GetBytes(COLUMN_TYPE_NULL);
+ size = 0;
+ break;
+ }
+
+ string_array = Encoding.UTF8.GetBytes(txt);
+ value_array = new byte[string_array.Length + 1];/*insert null */
+ string_array.CopyTo(value_array, 0);
+ size = value_array.Length;
+ break;
+
+ case ColumnType.ColumnTypeBlob:
+ int_tmp = cursor.GetBlobValue(i);
+ if (int_tmp == null)
+ {
+ type_array = BitConverter.GetBytes(COLUMN_TYPE_NULL);
+ size = 0;
+ break;
+ }
+
+ value_array = int_tmp;
+ size = value_array.Length;
+ break;
+ }
+
+ ms.Write(type_array, 0, type_array.Length);
+
+ length_array = BitConverter.GetBytes(size);
+ ms.Write(length_array, 0, length_array.Length);
+ if (size > 0)
+ {
+ ms.Write(value_array, 0, value_array.Length);
+ }
+ }
+
+ value_array = ms.ToArray();
+
+ result = (ResultType)Interop.DataControl.UnsafeCode.WriteResult(socketFd, value_array, value_array.Length, out write_len);
+ if (result != ResultType.Success)
+ {
+ Log.Error(LogTag, "Writing a row to a file descriptor is failed");
+ ms.Dispose();
+ return;
+ }
+
+ ms.Dispose();
+ Log.Info(LogTag, "row_count ~~~~ ", rowcount.ToString());
+
+ }
+ while (cursor.Next());
+ }
+
+ private static void SelectRequest(int requestId,
+ IntPtr handlePtr, IntPtr columnList, int columnCount, string where, string order, IntPtr userData)
+ {
+ Provider provider;
+ SelectResult result;
+ int pageNum = 0;
+ int countPerPage = 0;
+ int MAX_WRITE_SIZE = 1024; /* 1kbyte */
+ string query = null;
+ int socketFd, write_size, i;
+ uint write_len;
+ ResultType ret;
+ string[] _columnList = new string[columnCount];
+ byte[] buffer;
+
+ unsafe
+ {
+ byte** _sbyte_columnList = (byte**)columnList;
+
+ for (i = 0; i < columnCount; i++)
+ {
+ _columnList[i] = Marshal.PtrToStringAnsi((IntPtr)_sbyte_columnList[i]);
+ }
+ }
+
+ Interop.DataControl.GetSelectPageInfo(requestId, out pageNum, out countPerPage);
+ query = CreateSelectQuery(handlePtr, _columnList, _columnList.Length, where, order, pageNum, countPerPage);
+ provider = GetProvider(handlePtr);
+ if (provider == null)
+ {
+ Log.Error(LogTag, "Provider not exist ");
+ return;
+ }
+
+ result = provider.OnSelect(query, where, _columnList, _columnList.Length, order, pageNum, countPerPage);
+ if (result != null)
+ {
+ if (result.Result)
+ {
+ Interop.DataControl.SendSelectResult(requestId, out socketFd);
+
+ MatrixCursor mc = result.ResultCursor as MatrixCursor;
+
+ if (mc == null)
+ {
+ SendNativeProtocol(socketFd, result.ResultCursor, requestId);
+ }
+ else
+ {
+ FileStream fs = mc.GetFileStream();
+ fs.Seek(0, SeekOrigin.Begin);
+
+ buffer = new byte[MAX_WRITE_SIZE];
+
+ do
+ {
+ write_size = fs.Read(buffer, 0, MAX_WRITE_SIZE);
+
+ if (write_size > 0)
+ {
+ ret = (ResultType)Interop.DataControl.UnsafeCode.WriteResult(socketFd, buffer, write_size, out write_len);
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "Writing a row to a file descriptor is failed");
+ mc.Dispose();
+ return;
+ }
+ }
+ }
+ while (write_size > 0);
+ mc.Dispose();
+ }
+
+ }
+ else
+ {
+ ret = Interop.DataControl.SendError(requestId, result.Result.ToString());
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendError fail " + ret.ToString());
+ }
+ }
+ }
+ else
+ {
+ Log.Info(LogTag, $"SelectResult is null : {requestId.ToString()}");
+ }
+ }
+
+ private static void UpdateRequest(int requestId,
+ IntPtr handlePtr, IntPtr updateData, string where, IntPtr userData)
+ {
+ Provider provider;
+ UpdateResult result;
+ SafeBundleHandle sbh = new SafeBundleHandle(updateData, false);
+ string query = GetQuery(handlePtr, sbh, where, OperationType.Update);
+ ResultType ret;
+
+ provider = GetProvider(handlePtr);
+ if (provider == null)
+ {
+ Log.Error(LogTag, "Provider not exist ");
+ return;
+ }
+
+ result = provider.OnUpdate(query, where, new Bundle(sbh));
+ if (result != null)
+ {
+ if (result.Result)
+ {
+ ret = Interop.DataControl.SendUpdateResult(requestId);
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendUpdateResult fail " + ret.ToString());
+ }
+ }
+ else
+ {
+ ret = Interop.DataControl.SendError(requestId, result.Result.ToString());
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendError fail " + ret.ToString());
+ }
+ }
+ }
+ else
+ {
+ Log.Info(LogTag, $"UpdateResult is null : {requestId.ToString()}");
+ }
+ }
+
+ private static void DeleteRequest(int requestId,
+ IntPtr handlePtr, string where, IntPtr userData)
+ {
+ Provider provider;
+ DeleteResult result;
+ string query = GetQuery(handlePtr, null, where, OperationType.Delete);
+ ResultType ret;
+
+ provider = GetProvider(handlePtr);
+ if (provider == null)
+ {
+ Log.Error(LogTag, "Provider not exist ");
+ return;
+ }
+
+ result = provider.OnDelete(query, where);
+ if (result != null)
+ {
+ if (result.Result)
+ {
+ ret = Interop.DataControl.SendDeleteResult(requestId);
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendDeleteResult fail " + ret.ToString());
+ }
+
+ }
+ else
+ {
+ ret = Interop.DataControl.SendError(requestId, result.Result.ToString());
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendError fail " + ret.ToString());
+ }
+ }
+ }
+ else
+ {
+ Log.Info(LogTag, $"DeleteResult is null : {requestId.ToString()}");
+ }
+ }
+
+ private static void MapAddRequest(int requestId, IntPtr handlePtr, string key, string value, IntPtr userData)
+ {
+ Provider provider;
+ MapAddResult result;
+ ResultType ret;
+
+ provider = GetProvider(handlePtr);
+ if (provider == null)
+ {
+ Log.Error(LogTag, "Provider not exist");
+ return;
+ }
+
+ result = provider.OnMapAdd(key, value);
+ if (result != null)
+ {
+ if (result.Result)
+ {
+ ret = Interop.DataControl.SendMapResult(requestId);
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendMapResult fail " + ret.ToString());
+ }
+ }
+ else
+ {
+ ret = Interop.DataControl.SendError(requestId, result.Result.ToString());
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendError fail " + ret.ToString());
+ }
+ }
+ }
+ else
+ {
+ Log.Info(LogTag, $"MapAddResult is null : {requestId.ToString()}");
+ }
+ }
+
+ private static void MapSetRequest(int requestId, IntPtr handlePtr, string key, string oldValue, string newValue, IntPtr userData)
+ {
+ Provider provider;
+ MapSetResult result;
+ ResultType ret;
+
+ provider = GetProvider(handlePtr);
+ if (provider == null)
+ {
+ Log.Error(LogTag, "Provider not exist");
+ return;
+ }
+
+ result = provider.OnMapSet(key, oldValue, newValue);
+ if (result != null)
+ {
+ if (result.Result)
+ {
+ ret = Interop.DataControl.SendMapResult(requestId);
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendMapResult fail " + ret.ToString());
+ }
+ }
+ else
+ {
+ ret = Interop.DataControl.SendError(requestId, result.Result.ToString());
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendError fail " + ret.ToString());
+ }
+ }
+ }
+ else
+ {
+ Log.Info(LogTag, $"MapSetResult is null : {requestId.ToString()}");
+ }
+ }
+
+ private static void MapRemoveRequest(int requestId, IntPtr handlePtr, string key, string value, IntPtr userData)
+ {
+ Provider provider;
+ MapRemoveResult result;
+ ResultType ret;
+
+ provider = GetProvider(handlePtr);
+ if (provider == null)
+ {
+ Log.Error(LogTag, "Provider not exist");
+ return;
+ }
+
+ result = provider.OnMapRemove(key, value);
+ if (result != null)
+ {
+ if (result.Result)
+ {
+ ret = Interop.DataControl.SendMapResult(requestId);
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendMapResult fail " + ret.ToString());
+ }
+
+ }
+ else
+ {
+ ret = Interop.DataControl.SendError(requestId, result.Result.ToString());
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendError fail " + ret.ToString());
+ }
+ }
+ }
+ else
+ {
+ Log.Info(LogTag, $"MapRemoveRequest is null : {requestId.ToString()}");
+ }
+ }
+
+ private static void MapGetRequest(int requestID, IntPtr handlePtr, string key, IntPtr userData)
+ {
+ Provider provider;
+ MapGetResult result;
+ ResultType ret;
+
+ provider = GetProvider(handlePtr);
+ if (provider == null)
+ {
+ Log.Error(LogTag, "Provider not exist");
+ return;
+ }
+
+ result = provider.OnMapGet(key);
+ if (result != null)
+ {
+ if (result.Result)
+ {
+ int valueCount = 0;
+ if (result.ValueList != null)
+ valueCount = result.ValueList.Length;
+ ret = Interop.DataControl.SendMapGetResult(requestID, result.ValueList, valueCount);
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendMapGetResult fail " + ret.ToString());
+ }
+
+ }
+ else
+ {
+ ret = Interop.DataControl.SendError(requestID, result.Result.ToString());
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendError fail " + ret.ToString());
+ }
+ }
+ }
+ else
+ {
+ Log.Info(LogTag, $"MapRemoveRequest is null : {requestID.ToString()}");
+ }
+ }
+
+ private static void MapBulkAddRequest(int requestID, IntPtr handlePtr, IntPtr bulkDataPtr, IntPtr userData)
+ {
+ Provider provider;
+ MapBulkAddResult result;
+ BulkData bulkData = new BulkData(new Interop.DataControl.SafeBulkDataHandle(bulkDataPtr, false));
+ Interop.DataControl.SafeBulkDataHandle sbdh = bulkData.SafeBulkDataHandle;
+ IntPtr bundleHandel;
+ int count = bulkData.GetCount();
+ List<string> queryList = new List<string>();
+ ResultType ret;
+
+ for (int i = 0; i < count; i++)
+ {
+ Interop.DataControl.BulkGetData(sbdh, i, out bundleHandel);
+ queryList.Add(GetQuery(handlePtr, new SafeBundleHandle(bundleHandel, false), null, OperationType.Insert));
+ }
+
+ provider = GetProvider(handlePtr);
+ if (provider == null)
+ {
+ Log.Error(LogTag, "Provider not exist");
+ return;
+ }
+
+ result = provider.OnMapBulkAdd(bulkData);
+ if (result != null)
+ {
+ if (result.Result)
+ {
+ ret = Interop.DataControl.SendMapBulkAddResult(requestID, result.BulkResultData.SafeBulkDataHandle);
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendMapBulkAddResult fail " + ret.ToString());
+ }
+ }
+ else
+ {
+ ret = Interop.DataControl.SendError(requestID, result.Result.ToString());
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendError fail " + ret.ToString());
+ }
+ }
+
+ if (result.BulkResultData != null)
+ {
+ result.BulkResultData.Dispose();
+ }
+ }
+ else
+ {
+ Log.Info(LogTag, $"MapBulkAddRequest is null : {requestID.ToString()}");
+ }
+ }
+
+ private static string GetQuery(IntPtr handlePtr, SafeBundleHandle data, string where, OperationType type)
+ {
+ Interop.DataControl.SafeDataControlHandle handle = new Interop.DataControl.SafeDataControlHandle(handlePtr, false);
+ string query = null;
+
+ switch (type)
+ {
+ case OperationType.Select:
+ break;
+ case OperationType.Update:
+ query = Interop.DataControl.CreateUpdateStatement(handle, data, where);
+ break;
+ case OperationType.Delete:
+ query = Interop.DataControl.CreateDeleteStatement(handle, where);
+ break;
+ case OperationType.Insert:
+ query = Interop.DataControl.CreateInsertStatement(handle, data);
+ break;
+ default:
+ break;
+ }
+ handle.Dispose();
+
+ return query;
+ }
+
+ private static Provider GetProvider(IntPtr handlePtr)
+ {
+ Interop.DataControl.SafeDataControlHandle handle = new Interop.DataControl.SafeDataControlHandle(handlePtr, false);
+ Provider provider = null;
+ string dataID;
+
+ Interop.DataControl.DataControlGetDataId(handle, out dataID);
+ if (dataID != null && _providerDict.ContainsKey(dataID))
+ {
+ provider = _providerDict[dataID];
+ provider._nativeHandle = handlePtr;
+ Log.Info(LogTag, "DataID :" + dataID + ", hash code : " + provider.GetHashCode().ToString());
+ }
+ handle.Dispose();
+
+ return provider;
+ }
+
+ /// <summary>
+ /// Sends a data change notification to consumer applications which have successfully added a data change listen.
+ /// </summary>
+ /// <param name="type">Changed data type</param>
+ /// <param name="changedData">Customized information about changed data</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ public void SendDataChange(ChangeType type, Bundle changedData)
+ {
+ ResultType ret;
+
+ if (changedData == null || changedData.SafeBundleHandle.IsInvalid)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "changedData");
+ }
+
+ if (this._nativeHandle == IntPtr.Zero)
+ {
+ return;
+ }
+
+ ret = Interop.DataControl.SendDataChange(this._nativeHandle, type, changedData.SafeBundleHandle);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false);
+ }
+ }
+
+ /// <summary>
+ /// Initializes Provider class with dataID.
+ /// </summary>
+ /// <param name="dataID">DataControl Data ID</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public Provider(string dataID)
+ {
+ if (string.IsNullOrEmpty(dataID))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "dataID");
+ }
+
+ DataID = dataID;
+ }
+
+ /// <summary>
+ /// Starts Provider service.
+ /// </summary>
+ /// <remarks>Only one Provider service can be ran for each process</remarks>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ public void Run()
+ {
+ ResultType ret;
+ _lock.WaitOne();
+ if (_providerDict.ContainsKey(DataID))
+ {
+ _lock.ReleaseMutex();
+ ErrorFactory.ThrowException((ResultType)1, true, "The provider is already running");
+ return;
+ }
+
+ if (_providerDict.Count == 0)
+ {
+ Log.Debug(LogTag, "Provider create");
+
+ _sqlRequestCallbacks.Insert = new Interop.DataControl.SqlInsertRequestCallback(InsertRequest);
+ _sqlRequestCallbacks.Select = new Interop.DataControl.SqlSelectRequestCallback(SelectRequest);
+ _sqlRequestCallbacks.Update = new Interop.DataControl.SqlUpdateRequestCallback(UpdateRequest);
+ _sqlRequestCallbacks.Delete = new Interop.DataControl.SqlDeleteRequestCallback(DeleteRequest);
+
+ ret = Interop.DataControl.RegisterSqlRequest(ref _sqlRequestCallbacks, IntPtr.Zero);
+ if (ret != ResultType.Success)
+ {
+ _lock.ReleaseMutex();
+ ErrorFactory.ThrowException(ret, false);
+ }
+
+ _sqlBulkCallback = new Interop.DataControl.SqlBulkInsertRequestCallback(BulkInsertRequest);
+ ret = Interop.DataControl.RegisterSqlBulkRequest(_sqlBulkCallback, IntPtr.Zero);
+ if (ret != ResultType.Success)
+ {
+ _lock.ReleaseMutex();
+ ErrorFactory.ThrowException(ret, false);
+ }
+
+ _mapRequestCallbacks.Add = new Interop.DataControl.MapAddRequestCallback(MapAddRequest);
+ _mapRequestCallbacks.Remove = new Interop.DataControl.MapRemoveRequestCallback(MapRemoveRequest);
+ _mapRequestCallbacks.Set = new Interop.DataControl.MapSetRequestCallback(MapSetRequest);
+ _mapRequestCallbacks.Get = new Interop.DataControl.MapGetRequestCallback(MapGetRequest);
+ ret = Interop.DataControl.RegisterMapRequest(ref _mapRequestCallbacks, IntPtr.Zero);
+ if (ret != ResultType.Success)
+ {
+ _lock.ReleaseMutex();
+ ErrorFactory.ThrowException(ret, false);
+ }
+
+ _mapBulkCallback = new Interop.DataControl.MapBulkAddRequestCallback(MapBulkAddRequest);
+ ret = Interop.DataControl.RegisterMapBulkRequest(_mapBulkCallback, IntPtr.Zero);
+ if (ret != ResultType.Success)
+ {
+ _lock.ReleaseMutex();
+ ErrorFactory.ThrowException(ret, false);
+ }
+
+ if (_filterRegistered == false)
+ {
+ if (_filterCallback == null)
+ _filterCallback = new Interop.DataControl.DataChangeConsumerFilterCb(DataChangeListenFilter);
+
+ ret = Interop.DataControl.AddDataChangeConsumerFilterCallback(
+ _filterCallback,
+ IntPtr.Zero, out _filterCallbackID);
+
+ if (ret != ResultType.Success)
+ {
+ _lock.ReleaseMutex();
+ ErrorFactory.ThrowException(ret, false);
+ }
+ }
+
+ _filterRegistered = true;
+ }
+
+ _providerDict.Add(DataID, this);
+ Log.Info(LogTag, "DataID :" + DataID + ", hash code : " + this.GetHashCode().ToString());
+ _isRunning = true;
+ _lock.ReleaseMutex();
+ }
+
+ /// <summary>
+ /// Stop Provider service.
+ /// </summary>
+ public void Stop()
+ {
+ if (_isRunning == true)
+ {
+ Log.Info(LogTag, "DataID :" + DataID);
+ _isRunning = false;
+ _providerDict.Remove(DataID);
+ }
+ }
+
+ ~Provider()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the select request is received.
+ /// </summary>
+ protected abstract SelectResult OnSelect(string query, string where, string[] columList, int columnCount, string order, int pageNum, int countPerPage);
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the insert request is received.
+ /// </summary>
+ protected abstract InsertResult OnInsert(string query, Bundle insertData);
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the update request is received.
+ /// </summary>
+ protected abstract UpdateResult OnUpdate(string query, string where, Bundle updateData);
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the delete request is received.
+ /// </summary>
+ protected abstract DeleteResult OnDelete(string query, string where);
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the bulk insert request is received.
+ /// </summary>
+ protected virtual BulkInsertResult OnBulkInsert(IEnumerable<string> query, BulkData bulkInsertData)
+ {
+ Log.Info(LogTag, "The OnBulkInsert is not implemented.");
+ return null;
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the map get request is received.
+ /// </summary>
+ protected virtual MapGetResult OnMapGet(string key)
+ {
+ Log.Info(LogTag, "The OnMapGet is not implemented.");
+ return null;
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the map add request is received.
+ /// </summary>
+ protected virtual MapAddResult OnMapAdd(string key, string value)
+ {
+ Log.Info(LogTag, "The OnMapAdd is not implemented.");
+ return null;
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the update request is received.
+ /// </summary>
+ protected virtual MapSetResult OnMapSet(string key, string oldValue, string newValue)
+ {
+ Log.Info(LogTag, "The OnMapSet is not implemented.");
+ return null;
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the delete request is received.
+ /// </summary>
+ protected virtual MapRemoveResult OnMapRemove(string key, string value)
+ {
+ Log.Info(LogTag, "The OnMapRemove is not implemented.");
+ return null;
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the bulk add request is received.
+ /// </summary>
+ protected virtual MapBulkAddResult OnMapBulkAdd(BulkData bulkAddData)
+ {
+ Log.Info(LogTag, "The OnMapBulkAdd is not implemented.");
+ return null;
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the data change listen request is received.
+ /// </summary>
+ protected virtual DataChangeListenResult OnDataChangeListenRequest(string requestAppID)
+ {
+ Log.Info(LogTag, "The OnDataChangeListenRequest is not implemented.");
+ return null;
+ }
+
+ /// <summary>
+ /// Releases the unmanaged resourced used by the Provider class specifying whether to perform a normal dispose operation.
+ /// </summary>
+ /// <param name="disposing">true for a normal dispose operation; false to finalize the handle.</param>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ Stop();
+ _disposed = true;
+ }
+ if (disposing)
+ {
+ GC.SuppressFinalize(this);
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by the Provider class.
+ /// </summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+ }
+}
diff --git a/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl/Results.cs b/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl/Results.cs
new file mode 100755
index 0000000..81f63a5
--- /dev/null
+++ b/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl/Results.cs
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications.DataControl
+{
+ /// <summary>
+ /// This class is for containing insert operation result.
+ /// </summary>
+ public class InsertResult
+ {
+ /// <summary>
+ /// Gets the insert data's row id.
+ /// </summary>
+ public long RowID
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Gets the insert operation result.
+ /// </summary>
+ public bool Result
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Initializes InsertResult class with columnNames and columnTypes.
+ /// </summary>
+ /// <param name="rowID">Inserted row ID</param>
+ /// <param name="result">Insert request result</param>
+ public InsertResult(long rowID, bool result)
+ {
+ RowID = rowID;
+ Result = result;
+ }
+ }
+
+ /// <summary>
+ /// This class is for containing bulk insert operation result.
+ /// </summary>
+ public class BulkInsertResult
+ {
+ /// <summary>
+ /// Gets the bulk insert operation result data.
+ /// </summary>
+ public BulkResultData BulkResultData
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Gets the bulk insert operation result.
+ /// </summary>
+ public bool Result
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Initializes InsertResult class with bulkResultData and result.
+ /// </summary>
+ /// <param name="bulkResultData">Bulk insert request result data</param>
+ /// <param name="result">Bulk insert request result</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public BulkInsertResult(BulkResultData bulkResultData, bool result)
+ {
+ if (result == true && (bulkResultData == null || bulkResultData.SafeBulkDataHandle.IsInvalid))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "bulkResultData");
+ }
+
+ BulkResultData = bulkResultData;
+ Result = result;
+ }
+ }
+
+ /// <summary>
+ /// This class is for containing update operation result.
+ /// </summary>
+ public class UpdateResult
+ {
+ /// <summary>
+ /// Gets the update operation result.
+ /// </summary>
+ public bool Result
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Initializes UpdateResult class with result.
+ /// </summary>
+ /// <param name="result">Update request result</param>
+ public UpdateResult(bool result)
+ {
+ Result = result;
+ }
+ }
+
+ /// <summary>
+ /// This class is for containing delete operation result.
+ /// </summary>
+ public class DeleteResult
+ {
+ /// <summary>
+ /// Gets the delete operation result.
+ /// </summary>
+ public bool Result
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Initializes DeleteResult class with result.
+ /// </summary>
+ /// <param name="result">Delete request result</param>
+ public DeleteResult(bool result)
+ {
+ Result = result;
+ }
+ }
+
+ /// <summary>
+ /// This class is for containing select operation result.
+ /// </summary>
+ public class SelectResult
+ {
+ /// <summary>
+ /// Gets the select operation result cursor.
+ /// </summary>
+ public ICursor ResultCursor
+ {
+ get;
+ private set;
+ }
+ /// <summary>
+ /// Gets the select operation result.
+ /// </summary>
+ public bool Result
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Initializes SelectResult class with cursor and result.
+ /// </summary>
+ /// <param name="cursor">Cursor with selected data</param>
+ /// <param name="result">Select request result</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public SelectResult(ICursor cursor, bool result)
+ {
+ int i;
+
+ if (result == true && cursor == null)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "cursor");
+ }
+
+ if (result == true && (cursor is MatrixCursor) == false)
+ {
+ if (cursor.GetColumnCount() <= 0)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "column count");
+ }
+
+ for (i = 0; i < cursor.GetColumnCount(); i++)
+ {
+ if (string.IsNullOrEmpty(cursor.GetColumnName(i)))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "column name index " + i.ToString());
+ }
+
+ if (cursor.GetColumnType(i) < ColumnType.ColumnTypeInt || cursor.GetColumnType(i) > ColumnType.ColumnTypeBlob)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "column type index" + i.ToString());
+ }
+ }
+ }
+
+ ResultCursor = cursor;
+ Result = result;
+ }
+ }
+
+ /// <summary>
+ /// This class is for containing MapAdd operation result.
+ /// </summary>
+ public class MapAddResult
+ {
+
+ /// <summary>
+ /// Gets the MapAdd operation result.
+ /// </summary>
+ public bool Result
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Initializes MapAddResult class with result.
+ /// </summary>
+ /// <param name="result">MapAdd request result</param>
+ public MapAddResult(bool result)
+ {
+ Result = result;
+ }
+ }
+
+ /// <summary>
+ /// This class is for containing MapBulkAdd operation result.
+ /// </summary>
+ public class MapBulkAddResult
+ {
+ /// <summary>
+ /// Gets the MapBulkAdd operation result data.
+ /// </summary>
+ public BulkResultData BulkResultData
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Gets the MapBulkAdd operation result.
+ /// </summary>
+ public bool Result
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Initializes MapBulkAddResult class with bulkResultData and result.
+ /// </summary>
+ /// <param name="bulkResultData">MapBulkAdd request result data</param>
+ /// <param name="result">MapBulkAdd request result</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public MapBulkAddResult(BulkResultData bulkResultData, bool result)
+ {
+ if (result == true && (bulkResultData == null || bulkResultData.SafeBulkDataHandle.IsInvalid))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "bulkResultData");
+ }
+
+ BulkResultData = bulkResultData;
+ Result = result;
+ }
+ }
+
+ /// <summary>
+ /// This class is for containing MapSet operation result.
+ /// </summary>
+ public class MapSetResult
+ {
+ /// <summary>
+ /// Gets the MapSet operation result.
+ /// </summary>
+ public bool Result
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Initializes MapSetResult class with result.
+ /// </summary>
+ /// <param name="result">MapSet request result</param>
+ public MapSetResult(bool result)
+ {
+ Result = result;
+ }
+ }
+
+ /// <summary>
+ /// This class is for containing MapRemove operation result.
+ /// </summary>
+ public class MapRemoveResult
+ {
+ /// <summary>
+ /// Gets the MapRemove operation result.
+ /// </summary>
+ public bool Result
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Initializes MapRemoveResult class with result.
+ /// </summary>
+ /// <param name="result">MapRemove request result</param>
+ public MapRemoveResult(bool result)
+ {
+ Result = result;
+ }
+ }
+
+ /// <summary>
+ /// This class is for containing MapGet operation result.
+ /// </summary>
+ public class MapGetResult
+ {
+ /// <summary>
+ /// Gets the result value list of the MapGet operation.
+ /// </summary>
+ public string[] ValueList
+ {
+ get;
+ private set;
+ }
+ /// <summary>
+ /// Gets the MapGet operation result.
+ /// </summary>
+ public bool Result
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Initializes MapGetResult class with data and result.
+ /// </summary>
+ /// <param name="valueLIst">MapGet request result data</param>
+ /// <param name="result">MapGet request result</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public MapGetResult(string[] valueLIst, bool result)
+ {
+ if (result == true && valueLIst == null)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "valueLIst");
+ }
+
+ ValueList = valueLIst;
+ Result = result;
+ }
+ }
+
+ /// <summary>
+ /// This class is for containing DataChangeListen operation result.
+ /// </summary>
+ public class DataChangeListenResult
+ {
+ /// <summary>
+ /// Gets the DataChangeListen operation result.
+ /// </summary>
+ public ResultType Result
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Initializes DataChangeListenResult class with result.
+ /// </summary>
+ /// <param name="result">DataChangeListen request result</param>
+ public DataChangeListenResult(ResultType result)
+ {
+ Result = result;
+ }
+ }
+}
diff --git a/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl/Types.cs b/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl/Types.cs
new file mode 100755
index 0000000..09d25a6
--- /dev/null
+++ b/src/Tizen.Applications.DataControl/Tizen.Applications.DataControl/Types.cs
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications.DataControl
+{
+
+ /// <summary>
+ /// Enumeration for DataControl column type
+ /// </summary>
+ public enum ColumnType : short
+ {
+ /// <summary>
+ /// Value representing DataControl operation Success
+ /// </summary>
+ ColumnTypeInt = 1,
+ /// <summary>
+ /// Value representing DataControl operation Success
+ /// </summary>
+ ColumnTypeDouble = 2,
+ /// <summary>
+ /// Value representing DataControl operation Success
+ /// </summary>
+ ColumnTypeString = 3,
+ /// <summary>
+ /// Value representing DataControl operation Success
+ /// </summary>
+ ColumnTypeBlob = 4
+ }
+
+ /// <summary>
+ /// Enumeration for DataControl column type
+ /// </summary>
+ public enum ChangeType : short
+ {
+ /// <summary>
+ /// Value representing DataControl provider data changed by update
+ /// </summary>
+ Update,
+ /// <summary>
+ /// Value representing DataControl provider data changed by insert
+ /// </summary>
+ Insert,
+ /// <summary>
+ /// Value representing DataControl provider data changed by delete
+ /// </summary>
+ Delete,
+ /// <summary>
+ /// Value representing DataControl provider data changed by map add
+ /// </summary>
+ MapAdd,
+ /// <summary>
+ /// Value representing DataControl provider data changed by map remove
+ /// </summary>
+ MapRemove,
+ /// <summary>
+ /// Value representing DataControl provider data changed by map set
+ /// </summary>
+ MapSet,
+ }
+
+ /// <summary>
+ /// Enumeration for DataControl result type
+ /// </summary>
+ public enum ResultType : int
+ {
+ /// <summary>
+ /// Value representing DataControl operation success
+ /// </summary>
+ Success = Interop.DataControl.NativeResultType.Success,
+ /// <summary>
+ /// Value representing DataControl operation cause out of memory error
+ /// </summary>
+ OutOfMemory = Interop.DataControl.NativeResultType.OutOfMemory,
+ /// <summary>
+ /// Value representing DataControl operation cause IO error
+ /// </summary>
+ IoError = Interop.DataControl.NativeResultType.IoError,
+ /// <summary>
+ /// Value representing DataControl operation cause Invalid parameter error
+ /// </summary>
+ InvalidParameter = Interop.DataControl.NativeResultType.InvalidParameter,
+ /// <summary>
+ /// Value representing DataControl operation cause permission denied error
+ /// </summary>
+ PermissionDenied = Interop.DataControl.NativeResultType.PermissionDenied,
+ /// <summary>
+ /// Value representing DataControl operation cause max exceed error
+ /// </summary>
+ MaxExceed = Interop.DataControl.NativeResultType.MaxExceed,
+ }
+}
diff --git a/src/Tizen.Applications.MessagePort/Interop/Interop.Libraries.cs b/src/Tizen.Applications.MessagePort/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..2b7e4da
--- /dev/null
+++ b/src/Tizen.Applications.MessagePort/Interop/Interop.Libraries.cs
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string MessagePort = "libmessage-port.so.1";
+ }
+}
diff --git a/src/Tizen.Applications.MessagePort/Interop/Interop.MessagePort.cs b/src/Tizen.Applications.MessagePort/Interop/Interop.MessagePort.cs
new file mode 100755
index 0000000..bcbbc63
--- /dev/null
+++ b/src/Tizen.Applications.MessagePort/Interop/Interop.MessagePort.cs
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+using Tizen.Applications;
+
+internal static partial class Interop
+{
+ internal static partial class MessagePort
+ {
+ [DllImport(Libraries.MessagePort, EntryPoint = "message_port_register_local_port", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int RegisterPort(string local_port, message_port_message_cb callback, IntPtr userData);
+
+ [DllImport(Libraries.MessagePort, EntryPoint = "message_port_register_trusted_local_port", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int RegisterTrustedPort(string trusted_local_port, message_port_message_cb callback, IntPtr userData);
+
+ [DllImport(Libraries.MessagePort, EntryPoint = "message_port_unregister_local_port", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int UnregisterPort(int local_port_id);
+
+ [DllImport(Libraries.MessagePort, EntryPoint = "message_port_unregister_trusted_local_port", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int UnregisterTrustedPort(int trusted_local_port_id);
+
+ [DllImport(Libraries.MessagePort, EntryPoint = "message_port_send_message_with_local_port", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int SendMessageWithLocalPort(string remote_app_id, string remote_port, SafeBundleHandle message, int local_port_id);
+
+ [DllImport(Libraries.MessagePort, EntryPoint = "message_port_send_trusted_message_with_local_port", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int SendTrustedMessageWithLocalPort(string remote_app_id, string remote_port, SafeBundleHandle message, int local_port_id);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void message_port_message_cb(int local_port_id, string remote_app_id, string remote_port, bool trusted_remote_port, IntPtr message, IntPtr userData);
+ }
+}
diff --git a/src/Tizen.Applications.MessagePort/Tizen.Applications.MessagePort.csproj b/src/Tizen.Applications.MessagePort/Tizen.Applications.MessagePort.csproj
new file mode 100755
index 0000000..99f4360
--- /dev/null
+++ b/src/Tizen.Applications.MessagePort/Tizen.Applications.MessagePort.csproj
@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen.Applications.Common\Tizen.Applications.Common.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Applications.MessagePort/Tizen.Applications.Messages/MessagePort.cs b/src/Tizen.Applications.MessagePort/Tizen.Applications.Messages/MessagePort.cs
new file mode 100755
index 0000000..26632e4
--- /dev/null
+++ b/src/Tizen.Applications.MessagePort/Tizen.Applications.Messages/MessagePort.cs
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using Tizen.Applications;
+
+namespace Tizen.Applications.Messages
+{
+ /// <summary>
+ /// The Message Port API provides functions to send and receive messages between applications.
+ /// </summary>
+ /// <remarks>
+ /// The Message Port API provides functions for passing messages between applications. An application should register its own local port to receive messages from remote applications.
+ /// If a remote application sends a message, the registered callback function of the local port is called.
+ /// The trusted message-port API allows communications between applications that are signed by the same developer(author) certificate.
+ /// </remarks>
+ public class MessagePort : IDisposable
+ {
+ private static readonly object s_lock = new object();
+ private static readonly HashSet<string> s_portMap = new HashSet<string>();
+
+ // The name of the local message port
+ private readonly string _portName = null;
+
+ // If true the message port is a trusted port, otherwise false it is not
+ private readonly bool _trusted = false;
+
+ // The local message port ID
+ private int _portId = 0;
+
+ // If true the message port is listening, otherwise false it is not
+ private bool _listening = false;
+
+ private Interop.MessagePort.message_port_message_cb _messageCallBack;
+
+ /// <summary>
+ /// Initializes the instance of the MessagePort class.
+ /// </summary>
+ /// <param name="portName">The name of the local message port</param>
+ /// <param name="trusted">If true is the trusted message port of application, otherwise false</param>
+ /// <exception cref="System.InvalidOperationException">Thrown when portName is null or empty</exception>
+ /// <code>
+ /// MessagePort messagePort = new MessagePort("SenderPort", true);
+ /// </code>
+ public MessagePort(string portName, bool trusted)
+ {
+ if (String.IsNullOrEmpty(portName))
+ {
+ MessagePortErrorFactory.ThrowException((int)MessagePortError.InvalidParameter, "Invalid PortName", "PortName");
+ }
+ _portName = portName;
+ _trusted = trusted;
+ }
+
+ /// <summary>
+ /// Destructor of the MessagePort class.
+ /// </summary>
+ ~MessagePort()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Called when a message is received.
+ /// </summary>
+ /// <code>
+ /// MessagePort messagePort = new MessagePort("SenderPort", true);
+ /// messagePort.MessageReceived += MessageReceivedCallback;
+ /// static void MessageReceivedCallback(object sender, MessageReceivedEventArgs e)
+ /// {
+ /// Console.WriteLine("Message Received ");
+ /// if (e.Remote.AppId != null) {
+ /// Console.WriteLine("from :"+e.Remote.AppId);
+ /// }
+ /// }
+ /// </code>
+ public event EventHandler<MessageReceivedEventArgs> MessageReceived;
+
+ /// <summary>
+ /// The name of the local message port
+ /// </summary>
+ public string PortName
+ {
+ get
+ {
+ return _portName;
+ }
+ }
+ /// <summary>
+ /// If true the message port is a trusted port, otherwise false it is not
+ /// </summary>
+ public bool Trusted
+ {
+ get
+ {
+ return _trusted;
+ }
+ }
+
+ /// <summary>
+ /// If true the message port is listening, otherwise false it is not
+ /// </summary>
+ public bool Listening
+ {
+ get
+ {
+ return _listening;
+ }
+ }
+
+ /// <summary>
+ /// Register the local message port.
+ /// </summary>
+ /// <exception cref="System.InvalidOperationException">Thrown when portName is already used, when there is an invalid parameter, when out of memory, when there is an I/O error</exception>
+ /// <code>
+ /// MessagePort messagePort = new MessagePort("SenderPort", true);
+ /// messagePort.MessageReceived += MessageReceivedCallback;
+ /// messagePort.Listen();
+ /// </code>
+ public void Listen()
+ {
+ lock (s_lock)
+ {
+ if (s_portMap.Contains(_portName))
+ {
+ throw new InvalidOperationException(_portName + " is already used");
+ }
+ _messageCallBack = (int localPortId, string remoteAppId, string remotePortName, bool trusted, IntPtr message, IntPtr userData) =>
+ {
+ MessageReceivedEventArgs args = new MessageReceivedEventArgs()
+ {
+ Message = new Bundle(new SafeBundleHandle(message, false))
+ };
+
+ if (!String.IsNullOrEmpty(remotePortName) && !String.IsNullOrEmpty(remoteAppId))
+ {
+ args.Remote = new RemoteValues()
+ {
+ AppId = remoteAppId,
+ PortName = remotePortName,
+ Trusted = trusted
+ };
+ }
+ MessageReceived?.Invoke(this, args);
+ };
+
+ _portId = _trusted ?
+ Interop.MessagePort.RegisterTrustedPort(_portName, _messageCallBack, IntPtr.Zero) :
+ Interop.MessagePort.RegisterPort(_portName, _messageCallBack, IntPtr.Zero);
+
+ if (_portId <= 0)
+ throw new InvalidOperationException("Can't Listening with " + _portName);
+
+ s_portMap.Add(_portName);
+ _listening = true;
+ }
+ }
+
+ /// <summary>
+ /// Unregisters the local message port.
+ /// </summary>
+ /// <exception cref="System.InvalidOperationException">Thrown when messageport is already stopped, when there is an invalid parameter, when the port is not found, when out of memory, when there is an I/O error</exception>
+ /// <code>
+ /// MessagePort messagePort = new MessagePort("SenderPort", true);
+ /// messagePort.MessageReceived += MessageReceivedCallback;
+ /// messagePort.Listen();
+ /// using (var message = new Tizen.Application.Bundle())
+ /// {
+ /// message.AddItem("message", "a_string");
+ /// messagePort.Send(message, "ReceiverAppID", "ReceiverPort");
+ /// }
+ /// messageProt.StopListening();
+ /// </code>
+ public void StopListening()
+ {
+ if (!_listening)
+ {
+ throw new InvalidOperationException("Already stopped");
+ }
+
+ int ret = _trusted ?
+ Interop.MessagePort.UnregisterTrustedPort(_portId) :
+ Interop.MessagePort.UnregisterPort(_portId);
+
+ if (ret != (int)MessagePortError.None)
+ {
+ MessagePortErrorFactory.ThrowException(ret);
+ }
+
+ lock (s_lock)
+ {
+ s_portMap.Remove(_portName);
+ }
+ _portId = 0;
+ _listening = false;
+ }
+
+ /// <summary>
+ /// Sends a untrusted message to the message port of a remote application.
+ /// </summary>
+ /// <param name="message">The message to be passed to the remote application, the recommended message size is under 4KB</param>
+ /// <param name="remoteAppId">The ID of the remote application</param>
+ /// <param name="remotePortName">The name of the remote message port</param>
+ /// <exception cref="System.InvalidOperationException">Thrown when there is an invalid parameter, when the port is not found, when out of memory, when there is an I/O error</exception>
+ /// <exception cref="System.ArgumentOutOfRangeException">Thrown when message has exceeded the maximum limit(4KB)</exception>
+ /// <code>
+ /// MessagePort messagePort = new MessagePort("SenderPort", true);
+ /// messagePort.MessageReceived += MessageReceivedCallback;
+ /// messagePort.Listen();
+ /// using (var message = new Tizen.Application.Bundle())
+ /// {
+ /// message.AddItem("message", "a_string");
+ /// messagePort.Send(message, "ReceiverAppID", "ReceiverPort");
+ /// }
+ /// </code>
+ public void Send(Bundle message, string remoteAppId, string remotePortName)
+ {
+ Send(message, remoteAppId, remotePortName, false);
+ }
+
+ /// <summary>
+ /// Sends a message to the message port of a remote application.
+ /// </summary>
+ /// <param name="message">The message to be passed to the remote application, the recommended message size is under 4KB</param>
+ /// <param name="remoteAppId">The ID of the remote application</param>
+ /// <param name="remotePortName">The name of the remote message port</param>
+ /// <param name="trusted">If true the trusted message port of remote application otherwise false</param>
+ /// <exception cref="System.InvalidOperationException">Thrown when there is an invalid parameter, when the port is not found, when out of memory, when there is an I/O error</exception>
+ /// <exception cref="System.ArgumentOutOfRangeException">Thrown when message has exceeded the maximum limit(4KB)</exception>
+ /// <code>
+ /// MessagePort messagePort = new MessagePort("SenderPort", true);
+ /// messagePort.MessageReceived += MessageReceivedCallback;
+ /// messagePort.Listen();
+ /// using (var message = new Tizen.Application.Bundle())
+ /// {
+ /// message.AddItem("message", "a_string");
+ /// messagePort.Send(message, "ReceiverAppID", "ReceiverPort", true);
+ /// }
+ /// </code>
+ public void Send(Bundle message, string remoteAppId, string remotePortName, bool trusted)
+ {
+ if (!_listening)
+ {
+ throw new InvalidOperationException("Should start listen before send");
+ }
+ if (message == null)
+ {
+ throw new ArgumentNullException("message");
+ }
+ int ret = trusted ?
+ Interop.MessagePort.SendTrustedMessageWithLocalPort(remoteAppId, remotePortName, message.SafeBundleHandle, _portId) :
+ Interop.MessagePort.SendMessageWithLocalPort(remoteAppId, remotePortName, message.SafeBundleHandle, _portId);
+
+ if (ret != (int)MessagePortError.None)
+ {
+ if (ret == (int)MessagePortError.MaxExceeded)
+ {
+ MessagePortErrorFactory.ThrowException(ret, "Message has exceeded the maximum limit(4KB)", "Message");
+ }
+ MessagePortErrorFactory.ThrowException(ret, "Can't send message");
+ }
+ }
+
+ /// <summary>
+ /// Releases the unmanaged resourced used by the MessagePort class specifying whether to perform a normal dispose operation.
+ /// </summary>
+ /// <param name="disposing">true for a normal dispose operation; false to finalize the handle.</param>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_listening)
+ {
+ try
+ {
+ StopListening();
+ }
+ catch (Exception e)
+ {
+ Log.Warn(GetType().Namespace, "Exception in Dispose :" + e.Message);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by the MessagePort class.
+ /// </summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ }
+}
diff --git a/src/Tizen.Applications.MessagePort/Tizen.Applications.Messages/MessagePortErrorFactory.cs b/src/Tizen.Applications.MessagePort/Tizen.Applications.Messages/MessagePortErrorFactory.cs
new file mode 100755
index 0000000..949d067
--- /dev/null
+++ b/src/Tizen.Applications.MessagePort/Tizen.Applications.Messages/MessagePortErrorFactory.cs
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Applications.Messages
+{
+ internal enum MessagePortError
+ {
+ None = ErrorCode.None,
+ IOError = ErrorCode.IoError,
+ OutOfMemory = ErrorCode.OutOfMemory,
+ InvalidParameter = ErrorCode.InvalidParameter,
+ InvalidOperation = ErrorCode.InvalidOperation,
+ PortNotFound = -0x01130000 | 0x01,
+ CertificateNotMatch = -0x01130000 | 0x02,
+ MaxExceeded = -0x01130000 | 0x03,
+ ResourceUnavailable = -0x01130000 | 0x04
+ }
+
+ internal static class MessagePortErrorFactory
+ {
+ internal static void ThrowException(int errorCode, string errorMessage = null, string paramName = null)
+ {
+ MessagePortError err = (MessagePortError)errorCode;
+ if (String.IsNullOrEmpty(errorMessage))
+ {
+ errorMessage = err.ToString();
+ }
+ switch ((MessagePortError)errorCode)
+ {
+ case MessagePortError.IOError:
+ case MessagePortError.OutOfMemory:
+ case MessagePortError.InvalidOperation:
+ case MessagePortError.PortNotFound:
+ case MessagePortError.ResourceUnavailable: throw new InvalidOperationException(errorMessage);
+ case MessagePortError.InvalidParameter:
+ case MessagePortError.CertificateNotMatch: throw new ArgumentException(errorMessage, paramName);
+ case MessagePortError.MaxExceeded: throw new ArgumentOutOfRangeException(paramName, errorMessage);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.MessagePort/Tizen.Applications.Messages/MessageReceivedEventArgs.cs b/src/Tizen.Applications.MessagePort/Tizen.Applications.Messages/MessageReceivedEventArgs.cs
new file mode 100755
index 0000000..cfe1762
--- /dev/null
+++ b/src/Tizen.Applications.MessagePort/Tizen.Applications.Messages/MessageReceivedEventArgs.cs
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+
+namespace Tizen.Applications.Messages
+{
+ /// <summary>
+ /// An extended EventArgs class which contains remote message port information and message
+ /// </summary>
+ public class MessageReceivedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Contains AppId, Port Name, Trusted
+ /// </summary>
+ public RemoteValues Remote { get; internal set; }
+
+ /// <summary>
+ /// The message passed from the remote application
+ /// </summary>
+ public Bundle Message { get; internal set; }
+ }
+}
diff --git a/src/Tizen.Applications.MessagePort/Tizen.Applications.Messages/RemoteValues.cs b/src/Tizen.Applications.MessagePort/Tizen.Applications.Messages/RemoteValues.cs
new file mode 100755
index 0000000..db853d3
--- /dev/null
+++ b/src/Tizen.Applications.MessagePort/Tizen.Applications.Messages/RemoteValues.cs
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.Messages
+{
+ /// <summary>
+ /// Contains AppId, Port Name, Trusted
+ /// </summary>
+ public class RemoteValues
+ {
+ /// <summary>
+ /// The ID of the remote application that sent this message
+ /// </summary>
+ public string AppId { get; set; }
+
+ /// <summary>
+ /// The name of the remote message port
+ /// </summary>
+ public string PortName { get; set; }
+
+ /// <summary>
+ /// If true the remote port is a trusted port, otherwise if false it is not
+ /// </summary>
+ public bool Trusted { get; set; }
+ }
+}
diff --git a/src/Tizen.Applications.Notification/Interop/Interop.Libraries.cs b/src/Tizen.Applications.Notification/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..d5edebd
--- /dev/null
+++ b/src/Tizen.Applications.Notification/Interop/Interop.Libraries.cs
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string Notification = "libnotification.so.0";
+ }
+}
diff --git a/src/Tizen.Applications.Notification/Interop/Interop.Notification.cs b/src/Tizen.Applications.Notification/Interop/Interop.Notification.cs
new file mode 100755
index 0000000..e865ab1
--- /dev/null
+++ b/src/Tizen.Applications.Notification/Interop/Interop.Notification.cs
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Applications;
+using Tizen.Applications.Notifications;
+
+internal static partial class Interop
+{
+ internal static class Notification
+ {
+ [DllImport(Libraries.Notification, EntryPoint = "notification_create")]
+ internal static extern IntPtr Create(NotificationType type);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_free")]
+ internal static extern NotificationError Destroy(IntPtr handle);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_text")]
+ internal static extern NotificationError GetTextReferenceType(NotificationSafeHandle handle, NotificationText type, out IntPtr text);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_set_text")]
+ internal static extern NotificationError SetText(NotificationSafeHandle handle, NotificationText type, string text, string key, int args);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_image")]
+ internal static extern NotificationError GetImageReferenceType(NotificationSafeHandle handle, NotificationImage type, out IntPtr path);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_set_image")]
+ internal static extern NotificationError SetImage(NotificationSafeHandle handle, NotificationImage type, string path);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_time")]
+ internal static extern NotificationError GetTime(NotificationSafeHandle handle, out int time);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_set_time")]
+ internal static extern NotificationError SetTime(NotificationSafeHandle handle, int time);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_insert_time")]
+ internal static extern NotificationError GetInsertTime(NotificationSafeHandle handle, out long time);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_sound")]
+ internal static extern NotificationError GetSoundReferenceType(NotificationSafeHandle handle, out AccessoryOption type, out IntPtr path);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_set_sound")]
+ internal static extern NotificationError SetSound(NotificationSafeHandle handle, AccessoryOption type, string path);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_vibration")]
+ internal static extern NotificationError GetVibrationReferenceType(NotificationSafeHandle handle, out AccessoryOption type, out IntPtr path);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_set_vibration")]
+ internal static extern NotificationError SetVibration(NotificationSafeHandle handle, AccessoryOption type, string path);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_led")]
+ internal static extern NotificationError GetLed(NotificationSafeHandle handle, out AccessoryOption type, out int color);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_set_led")]
+ internal static extern NotificationError SetLed(NotificationSafeHandle handle, AccessoryOption type, int color);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_led_time_period")]
+ internal static extern NotificationError GetLedTimePeriod(NotificationSafeHandle handle, out int onMillisecond, out int offMillisecond);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_set_led_time_period")]
+ internal static extern NotificationError SetLedTimePeriod(NotificationSafeHandle handle, int onMillisecond, int offMillisecond);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_launch_option")]
+ internal static extern NotificationError GetAppControl(NotificationSafeHandle handle, LaunchOption type, out SafeAppControlHandle apphandle);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_set_launch_option")]
+ internal static extern NotificationError SetAppControl(NotificationSafeHandle handle, LaunchOption type, SafeAppControlHandle appHandle);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_event_handler")]
+ internal static extern NotificationError GetEventHandler(NotificationSafeHandle handle, int type, out SafeAppControlHandle appHandle);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_set_event_handler")]
+ internal static extern NotificationError SetEventHandler(NotificationSafeHandle handle, int type, SafeAppControlHandle appHandle);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_property")]
+ internal static extern NotificationError GetProperties(NotificationSafeHandle handle, out int flags);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_set_property")]
+ internal static extern NotificationError SetProperties(NotificationSafeHandle handle, int flags);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_display_applist")]
+ internal static extern NotificationError GetApplist(NotificationSafeHandle handle, out int flags);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_set_display_applist")]
+ internal static extern NotificationError SetApplist(NotificationSafeHandle handle, int flags);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_size")]
+ internal static extern NotificationError GetProgressSize(NotificationSafeHandle handle, out double size);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_set_size")]
+ internal static extern NotificationError SetProgressSize(NotificationSafeHandle handle, double size);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_progress")]
+ internal static extern NotificationError GetProgress(NotificationSafeHandle handle, out double progress);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_set_progress")]
+ internal static extern NotificationError SetProgress(NotificationSafeHandle handle, double progress);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_layout")]
+ internal static extern NotificationError GetLayout(NotificationSafeHandle handle, out NotificationLayout layout);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_set_layout")]
+ internal static extern NotificationError SetLayout(NotificationSafeHandle handle, NotificationLayout layout);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_type")]
+ internal static extern NotificationError GetType(NotificationSafeHandle handle, out NotificationType type);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_update")]
+ internal static extern NotificationError Update(NotificationSafeHandle handle);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_delete")]
+ internal static extern NotificationError Delete(NotificationSafeHandle handle);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_delete_all")]
+ internal static extern NotificationError DeleteAll(int type);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_post")]
+ internal static extern NotificationError Post(NotificationSafeHandle handle);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_pkgname")]
+ internal static extern NotificationError GetPackageName(NotificationSafeHandle handle, out IntPtr name);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_set_event_handler")]
+ internal static extern NotificationError AddButtonAction(NotificationSafeHandle handle, ButtonIndex type, SafeAppControlHandle appcontrol);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_remove_button")]
+ internal static extern NotificationError RemoveButton(NotificationSafeHandle handle, ButtonIndex index);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_set_tag")]
+ internal static extern NotificationError SetTag(NotificationSafeHandle handle, string tag);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_tag")]
+ internal static extern NotificationError GetTagReferenceType(NotificationSafeHandle handle, out IntPtr tag);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_load_by_tag")]
+ internal static extern IntPtr Load(string text);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_id")]
+ internal static extern NotificationError GetID(NotificationSafeHandle handle, out int groupID, out int privID);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_set_priv_id")]
+ internal static extern NotificationError SetID(NotificationSafeHandle handle, int privID);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_save_as_template")]
+ internal static extern NotificationError SaveTemplate(NotificationSafeHandle handle, string name);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_create_from_template")]
+ internal static extern IntPtr LoadTemplate(string name);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_noti_block_state")]
+ internal static extern NotificationError GetBlockState(out NotificationBlockState status);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_set_auto_remove")]
+ internal static extern NotificationError SetAutoRemove(NotificationSafeHandle handle, bool autoRemove);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_auto_remove")]
+ internal static extern NotificationError GetAutoRemove(NotificationSafeHandle handle, out bool autoRemove);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_set_ongoing_value_type")]
+ internal static extern NotificationError SetProgressType(NotificationSafeHandle handle, ProgressCategory category);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_ongoing_value_type")]
+ internal static extern NotificationError GetProgressType(NotificationSafeHandle handle, out ProgressCategory category);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_set_ongoing_flag")]
+ internal static extern NotificationError SetOngoingFlag(NotificationSafeHandle handle, bool flag);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_ongoing_flag")]
+ internal static extern NotificationError GetProgressFlag(NotificationSafeHandle handle, bool flag);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_ongoing_flag")]
+ internal static extern NotificationError GetProgressFlag(NotificationSafeHandle handle, out bool flag);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_set_text_input")]
+ internal static extern NotificationError SetPlaceHolderLength(NotificationSafeHandle handle, int length);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_text_input_max_length")]
+ internal static extern NotificationError GetPlaceHolderLength(NotificationSafeHandle handle, out int length);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_hide_timeout")]
+ internal static extern NotificationError GetHideTime(NotificationSafeHandle handle, out int timeout);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_set_hide_timeout")]
+ internal static extern NotificationError SetHideTime(NotificationSafeHandle handle, int timeout);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_delete_timeout")]
+ internal static extern NotificationError GetDeleteTime(NotificationSafeHandle handle, out int timeout);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_set_delete_timeout")]
+ internal static extern NotificationError SetDeleteTime(NotificationSafeHandle handle, int timeout);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_set_extention_data")]
+ internal static extern NotificationError SetExtentionData(NotificationSafeHandle handle, string key, SafeBundleHandle bundleHandle);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_extention_data")]
+ internal static extern NotificationError GetExtentionData(NotificationSafeHandle handle, string key, out SafeBundleHandle bundleHandle);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_args")]
+ internal static extern NotificationError GetExtentionBundle(NotificationSafeHandle handle, out IntPtr args, out IntPtr group_args);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_get_default_button")]
+ internal static extern NotificationError GetDefaultButton(NotificationSafeHandle handle, out int index);
+
+ [DllImport(Libraries.Notification, EntryPoint = "notification_set_default_button")]
+ internal static extern NotificationError SetDefaultButton(NotificationSafeHandle handle, int index);
+
+ internal static NotificationError GetText(NotificationSafeHandle handle, NotificationText type, out string text)
+ {
+ NotificationError ret;
+ IntPtr ptr;
+ ret = GetTextReferenceType(handle, type, out ptr);
+
+ if (ptr == IntPtr.Zero)
+ {
+ text = null;
+ }
+ else
+ {
+ text = Marshal.PtrToStringAnsi(ptr);
+ }
+
+ return ret;
+ }
+
+ internal static NotificationError GetImage(NotificationSafeHandle handle, NotificationImage type, out string path)
+ {
+ NotificationError ret;
+ IntPtr ptr;
+ ret = GetImageReferenceType(handle, type, out ptr);
+
+ if (ptr == IntPtr.Zero)
+ {
+ path = null;
+ }
+ else
+ {
+ path = Marshal.PtrToStringAnsi(ptr);
+ }
+
+ return ret;
+ }
+
+ internal static NotificationError GetSound(NotificationSafeHandle handle, out AccessoryOption type, out string path)
+ {
+ NotificationError ret;
+ IntPtr ptr;
+ ret = GetSoundReferenceType(handle, out type, out ptr);
+
+ if (ptr == IntPtr.Zero)
+ {
+ path = null;
+ }
+ else
+ {
+ path = Marshal.PtrToStringAnsi(ptr);
+ }
+
+ return ret;
+ }
+
+ internal static NotificationError GetVibration(NotificationSafeHandle handle, out AccessoryOption type, out string path)
+ {
+ NotificationError ret;
+ IntPtr ptr;
+ ret = GetVibrationReferenceType(handle, out type, out ptr);
+
+ if (ptr == IntPtr.Zero)
+ {
+ path = null;
+ }
+ else
+ {
+ path = Marshal.PtrToStringAnsi(ptr);
+ }
+
+ return ret;
+ }
+
+ internal static NotificationError GetTag(NotificationSafeHandle handle, out string tag)
+ {
+ NotificationError ret;
+ IntPtr ptr;
+ ret = GetTagReferenceType(handle, out ptr);
+
+ if (ptr == IntPtr.Zero)
+ {
+ tag = null;
+ }
+ else
+ {
+ tag = Marshal.PtrToStringAnsi(ptr);
+ }
+
+ return ret;
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Notification/Tizen.Applications.Notification.csproj b/src/Tizen.Applications.Notification/Tizen.Applications.Notification.csproj
new file mode 100755
index 0000000..517b746
--- /dev/null
+++ b/src/Tizen.Applications.Notification/Tizen.Applications.Notification.csproj
@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen.Applications.Common\Tizen.Applications.Common.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project> \ No newline at end of file
diff --git a/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/Notification.cs b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/Notification.cs
new file mode 100755
index 0000000..ec7202a
--- /dev/null
+++ b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/Notification.cs
@@ -0,0 +1,505 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.Notifications
+{
+ using System;
+ using System.Collections.Generic;
+ using System.ComponentModel;
+
+ /// <summary>
+ /// Class containing common properties and methods of Notifications
+ /// </summary>
+ /// <remarks>
+ /// A notification is a message that is displayed on the notification area.
+ /// It is created to notify information to the user through the application.
+ /// This class helps you to provide method and property for creating notification object.
+ /// </remarks>
+ public sealed partial class Notification : IDisposable
+ {
+ internal static readonly string LogTag = "Tizen.Applications.Notification";
+
+ private NotificationSafeHandle safeHandle;
+ private bool disposed = false;
+
+ private IDictionary<string, StyleBase> styleDictionary;
+ private IDictionary<string, Bundle> extenderDictionary;
+ private int count = 0;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Notification"/> class.
+ /// </summary>
+ public Notification()
+ {
+ styleDictionary = new Dictionary<string, StyleBase>();
+ extenderDictionary = new Dictionary<string, Bundle>();
+ }
+
+ /// <summary>
+ /// Gets or sets Tag of Notification.
+ /// </summary>
+ public string Tag { get; set; } = string.Empty;
+
+ /// <summary>
+ /// Gets or sets Title of Notification.
+ /// </summary>
+ public string Title { get; set; } = string.Empty;
+
+ /// <summary>
+ /// Gets or sets icon of Notification.
+ /// </summary>
+ public string Icon { get; set; } = string.Empty;
+
+ /// <summary>
+ /// Gets or sets sub icon of Notification.
+ /// This SubIcon is displayed in Icon you set.
+ /// </summary>
+ public string SubIcon { get; set; } = string.Empty;
+
+ /// <summary>
+ /// Gets or sets content of Notification.
+ /// </summary>
+ public string Content { get; set; } = string.Empty;
+
+ /// <summary>
+ /// Gets or sets a value indicating whether TimeStamp of Notification is Visible or not.
+ /// Default to true.
+ /// </summary>
+ public bool IsTimeStampVisible { get; set; } = true;
+
+ /// <summary>
+ /// Gets or sets TimeStamp of Notification.
+ /// </summary>
+ /// <remarks>
+ /// If you don't set TimeStamp, It will be set value that time when the notification is posted.
+ /// TimeStamp requires NotificationManager.Post() to be called.
+ /// If you set IsVisibleTimeStamp property is false, TimeStamp is not Visible in Notification.
+ /// </remarks>
+ public DateTime TimeStamp { get; set; }
+
+ /// <summary>
+ /// Gets or sets Action which is invoked when notification is clicked
+ /// </summary>
+ /// <remarks>
+ /// If you set it to null, the already set AppControl will be removed and nothing will happen when you click on notification.
+ /// </remarks>
+ /// <seealso cref="Tizen.Applications.AppControl"></seealso>
+ public AppControl Action { get; set; }
+
+ /// <summary>
+ /// Gets or sets Count which is displayed at the right side of notification.
+ /// </summary>
+ /// <remarks>
+ /// You must set only positive number.
+ /// If you set count to negative number, This property throw exception.
+ /// </remarks>
+ /// <exception cref="ArgumentException">Thrown when argument is invalid</exception>
+ public int Count
+ {
+ get
+ {
+ return count;
+ }
+
+ set
+ {
+ if (value < 0)
+ {
+ Log.Error(LogTag, "Count value is negative");
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "The Count must be a positive integer.");
+ }
+
+ count = value;
+ }
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public bool IsOngoing { get; set; } = false;
+
+ /// <summary>
+ /// Gets or sets property
+ /// </summary>
+ /// <seealso cref="Tizen.Applications.Notifications.NotificationProperty"></seealso>
+ public NotificationProperty Property { get; set; } = NotificationProperty.None;
+
+ /// <summary>
+ /// Gets or sets <see cref="Notification.ProgressType"/> object for display at notification
+ /// </summary>
+ /// <seealso cref="Tizen.Applications.Notifications.Notification.ProgressType"></seealso>
+ public ProgressType Progress { get; set; }
+
+ /// <summary>
+ /// Gets or sets <see cref="Notification.AccessorySet"/> which is included vibration, led and sound option to be applied at Notification.
+ /// </summary>
+ /// <remarks>
+ /// If you set it to null, the already set AccessorySet will be initialized.
+ /// </remarks>
+ /// <example>
+ /// <code>
+ /// Notification notification = new Notification
+ /// {
+ /// Title = "Notification",
+ /// Content = "Hello Tizen",
+ /// Icon = "Icon path",
+ /// Count = 3
+ /// };
+ ///
+ /// Notification.AccessorySet accessory = new Notification.AccessorySet
+ /// {
+ /// SoundOption = AccessoryOption.Custom,
+ /// SoundPath = "Sound File Path",
+ /// IsVibration = true,
+ /// LedOption = AccessoryOption.Custom,
+ /// LedOnMs = 100;
+ /// LedOffMs = 50;
+ /// LedColor = Color.Lime
+ /// };
+ ///
+ /// notification.Accessory = accessory;
+ ///
+ /// NotificationManager.Post(notification);
+ /// </code>
+ /// </example>
+ public AccessorySet Accessory { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether notification is displayed on default viewer.
+ /// If you set false and add style, you can see only style notification.
+ /// </summary>
+ public bool IsDisplay { get; set; } = true;
+
+ /// <summary>
+ /// Gets or sets NotificationSafeHandle
+ /// </summary>
+ internal NotificationSafeHandle Handle
+ {
+ get
+ {
+ return safeHandle;
+ }
+
+ set
+ {
+ if (value == null)
+ {
+ Log.Error(LogTag, "Invalid argument NotificationSafeHandle");
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "invalid argument to set NotificationSafeHandle");
+ }
+
+ safeHandle = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets Private ID
+ /// </summary>
+ internal int PrivID { get; set; } = -1;
+
+ /// <summary>
+ /// Method to add various style to be applied to notification.
+ /// </summary>
+ /// <remarks>
+ /// The user always see about valid notification style. If you add style which is not supported in platform,
+ /// this method has no effect.
+ /// </remarks>
+ /// <param name="style">The style to be applied to notification</param>
+ /// <exception cref="ArgumentException">Thrown when argument is invalid</exception>
+ /// <example>
+ /// <code>
+ /// Notification notification = new Notification
+ /// {
+ /// Title = "Notification",
+ /// Content = "Hello Tizen",
+ /// Icon = "Icon path",
+ /// Count = 3
+ /// };
+ ///
+ /// Notification.LockStyle lockStyle = new Notification.LockStyle
+ /// {
+ /// IconPath = "Icon path",
+ /// ThumbnailPath = "Thumbnail Path"
+ /// };
+ ///
+ /// notification.AddStyle(lockStyle);
+ ///
+ /// NotificationManager.Post(notification);
+ /// </code>
+ /// </example>
+ public void AddStyle(StyleBase style)
+ {
+ if (style == null)
+ {
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "invalid parameter entered");
+ }
+
+ if (styleDictionary.ContainsKey(style.Key) == true)
+ {
+ Log.Info(LogTag, "The Style is existed, so extender data is replaced");
+ styleDictionary.Remove(style.Key);
+ styleDictionary.Add(style.Key, style);
+ }
+ else
+ {
+ styleDictionary.Add(style.Key, style);
+ }
+ }
+
+ /// <summary>
+ /// Method to remove style you already added.
+ /// </summary>
+ /// <typeparam name="T">Type of notification style to be queried</typeparam>
+ /// <exception cref="ArgumentException">Thrown when argument is invalid</exception>
+ public void RemoveStyle<T>() where T : Notification.StyleBase, new()
+ {
+ T type = new T();
+
+ if (styleDictionary.ContainsKey(type.Key))
+ {
+ styleDictionary.Remove(type.Key);
+ }
+ else
+ {
+ Log.Error(LogTag, "Sytle Can't be removed, there is no style matched input key");
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "invalid parameter entered");
+ }
+ }
+
+ /// <summary>
+ /// Method to get style you already added.
+ /// </summary>
+ /// <typeparam name="T">Type of notification style to be queried</typeparam>
+ /// <returns>
+ /// The Notification.Style object associated with the given style
+ /// </returns>
+ /// <exception cref="ArgumentException">Thrown when argument is invalid</exception>
+ public T GetStyle<T>() where T : Notification.StyleBase, new()
+ {
+ T type = new T();
+ StyleBase style = null;
+
+ styleDictionary.TryGetValue(type.Key, out style);
+
+ if (style == null)
+ {
+ Log.Error(LogTag, "Invalid Style");
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "invalid parameter entered");
+ }
+ else
+ {
+ return style as T;
+ }
+ }
+
+ /// <summary>
+ /// Method to set extender data to add extra data
+ /// </summary>
+ /// <remarks>
+ /// The type of extra data is Bundle.
+ /// </remarks>
+ /// <param name="key">The key of the extra data you want to add.</param>
+ /// <param name="value">The value you want to add.</param>
+ /// <exception cref="ArgumentException">Thrown when argument is invalid</exception>
+ /// <example>
+ /// <code>
+ /// Notification notification = new Notification
+ /// {
+ /// Title = "Notification",
+ /// Content = "Hello Tizen",
+ /// Icon = "Icon path",
+ /// };
+ ///
+ /// Bundle bundle = new Bundle();
+ /// bundle.AddItem("key", "value");
+ ///
+ /// notification.SetExtender("firstKey", bundle);
+ /// </code>
+ /// </example>
+ public void SetExtender(string key, Bundle value)
+ {
+ if (value == null || value.SafeBundleHandle.IsInvalid || string.IsNullOrEmpty(key))
+ {
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "invalid parameter entered");
+ }
+
+ if (extenderDictionary.ContainsKey(key) == true)
+ {
+ Log.Info(LogTag, "The key is existed, so extender data is replaced");
+ extenderDictionary.Remove(key);
+ extenderDictionary.Add(key, value);
+ }
+ else
+ {
+ extenderDictionary.Add(key, value);
+ }
+ }
+
+ /// <summary>
+ /// Method to remove extender you already added.
+ /// </summary>
+ /// <remarks>
+ /// The type of extra data is Bundle.
+ /// </remarks>
+ /// <param name="key">The key of the extra data to add.</param>
+ /// <exception cref="ArgumentException">Thrown when argument is invalid</exception>
+ public void RemoveExtender(string key)
+ {
+ if (string.IsNullOrEmpty(key))
+ {
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "invalid parameter entered");
+ }
+
+ if (extenderDictionary.ContainsKey(key))
+ {
+ extenderDictionary.Remove(key);
+ }
+ else
+ {
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "invalid parameter entered");
+ }
+ }
+
+ /// <summary>
+ /// Method to get extender data you already set
+ /// </summary>
+ /// <param name="key">The key of the extra data to get.</param>
+ /// <returns>Bundle Object that include extender data</returns>
+ /// <exception cref="ArgumentException">Thrown when argument is invalid</exception>
+ public Bundle GetExtender(string key)
+ {
+ if (string.IsNullOrEmpty(key))
+ {
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "invalid parameter entered");
+ }
+
+ Bundle bundle;
+ if (extenderDictionary.TryGetValue(key, out bundle) == false)
+ {
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "invalid parameter entered : " + key);
+ }
+
+ return bundle;
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object.
+ /// </summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ internal void Dispose(bool disposing)
+ {
+ if (disposed)
+ {
+ return;
+ }
+
+ if (disposing)
+ {
+ Handle.Dispose();
+ }
+
+ disposed = true;
+ }
+
+ internal IDictionary<string, StyleBase> GetStyleDictionary()
+ {
+ return styleDictionary;
+ }
+
+ internal IDictionary<string, Bundle> GetExtenderDictionary()
+ {
+ return extenderDictionary;
+ }
+
+ internal StyleBase GetStyle(string key)
+ {
+ if (string.IsNullOrEmpty(key))
+ {
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "Key is null or empty");
+ }
+
+ StyleBase style = null;
+ bool ret = styleDictionary.TryGetValue(key, out style);
+ if (ret == false)
+ {
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "The Style object matched input key is not existed");
+ }
+
+ return style;
+ }
+
+ internal void Make()
+ {
+ NotificationBinder.BindObject(this);
+
+ foreach (string key in GetExtenderDictionary().Keys)
+ {
+ Log.Info(LogTag, "Start to bind Notification.ExtenderData to SafeHandle");
+ Interop.Notification.SetExtentionData(Handle, key, extenderDictionary[key].SafeBundleHandle);
+ }
+
+ foreach (Notification.StyleBase style in styleDictionary.Values)
+ {
+ Log.Info(LogTag, "Start to bind Notification.Style to SafeHandle [" + style.Key + "]");
+ style.Make(this);
+ }
+
+ if (Accessory != null)
+ {
+ Log.Info(LogTag, "Start to bind Notification.AccessetSet to SafeHandle");
+ Accessory.Make(this);
+ }
+
+ if (Progress != null)
+ {
+ Log.Info(LogTag, "Start to bind Notification.Progress to SafeHandle");
+ Progress.Make(this);
+ }
+ }
+
+ internal Notification Build()
+ {
+ IntPtr extention = IntPtr.Zero;
+ IntPtr extentionBundlePtr = IntPtr.Zero;
+
+ NotificationBinder.BindSafeHandle(this);
+
+ Interop.Notification.GetExtentionBundle(Handle, out extention, out extentionBundlePtr);
+
+ if (extention != IntPtr.Zero)
+ {
+ Bundle bundle = new Bundle(new SafeBundleHandle(extention, false));
+ foreach (string key in bundle.Keys)
+ {
+ SafeBundleHandle sbh;
+ Interop.Notification.GetExtentionData(Handle, key, out sbh);
+ extenderDictionary.Add(key, new Bundle(sbh));
+ }
+ }
+
+ ProgressBinder.BindSafeHandle(this);
+ AccessorySetBinder.BindSafeHandle(this);
+ IndicatorBinder.BindSafeHandle(this);
+ ActiveBinder.BindSafeHandle(this);
+ LockBinder.BindSafehandle(this);
+
+ return this;
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationAccessorySet.cs b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationAccessorySet.cs
new file mode 100755
index 0000000..ec7958d
--- /dev/null
+++ b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationAccessorySet.cs
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.Notifications
+{
+ using Tizen.Common;
+
+ /// <summary>
+ /// Class containing common properties and methods of Notifications
+ /// </summary>
+ /// <remarks>
+ /// A notification is a message that is displayed on the notification area.
+ /// It is created to notify information to the user through the application.
+ /// This class helps you to provide method and property for creating notification object.
+ /// </remarks>
+ public sealed partial class Notification
+ {
+ /// <summary>
+ /// Class for Notification AccessorySet which is included vibration, led, sound option
+ /// </summary>
+ public sealed class AccessorySet : MakerBase
+ {
+ /// <summary>
+ /// Gets or sets the sound option. Default to AccessoryOption.Off.
+ /// </summary>
+ /// <remarks>
+ /// If you set AccessoryOption.Custom and not set SoundPath, then turn on the default sound.
+ /// </remarks>
+ public AccessoryOption SoundOption { get; set; } = AccessoryOption.Off;
+
+ /// <summary>
+ /// Gets or sets the sound path, It will play on the sound file you set.
+ /// </summary>
+ public string SoundPath { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether vibration is operated. Default to false.
+ /// </summary>
+ public bool CanVibrate { get; set; } = false;
+
+ /// <summary>
+ /// Gets or sets the led option. Default to AccessoryOption.Off.
+ /// </summary>
+ /// <remarks>
+ /// If you set AccessoryOption.Custom and not set LedColor, then turn on the LED with default color.
+ /// </remarks>
+ public AccessoryOption LedOption { get; set; } = AccessoryOption.Off;
+
+ /// <summary>
+ /// Gets or sets the led on time period that you would like the LED on the device to blink. as well as the rate
+ /// </summary>
+ /// <remarks>
+ /// Default value of LedOnMillisecond is 0.
+ /// The rate is specified in terms of the number of Milliseconds to be on.
+ /// You should always set LedOnMillisecond with LedOffMillisecond. Otherwise, it may not operate normally.
+ /// </remarks>
+ public int LedOnMillisecond { get; set; }
+
+ /// <summary>
+ /// Gets or sets the led on time period that you would like the LED on the device to blink. as well as the rate.
+ /// </summary>
+ /// <remarks>
+ /// The rate is specified in terms of the number of Milliseconds to be off.
+ /// You should always set LedOffMillisecond with LedOnMillisecond. Otherwise, it may not operate normally.
+ /// </remarks>
+ public int LedOffMillisecond { get; set; }
+
+ /// <summary>
+ /// Gets or sets the led color that you would like the LED on the device to blink.
+ /// </summary>
+ /// <remarks>
+ /// If you want to set LedColor, you should always set LedOption is AccessoryOption.Custom. Otherwise, it may operate default led color.
+ /// </remarks>
+ public Color LedColor { get; set; }
+
+ internal override void Make(Notification notification)
+ {
+ AccessorySetBinder.BindObject(notification);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationAccessorySetBinder.cs b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationAccessorySetBinder.cs
new file mode 100755
index 0000000..91e2282
--- /dev/null
+++ b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationAccessorySetBinder.cs
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.Notifications
+{
+ using Tizen.Common;
+
+ internal static class AccessorySetBinder
+ {
+ internal static void BindObject(Notification notification)
+ {
+ BindLedToHandle(notification);
+ BindSoundToHandle(notification);
+ BindVibrationToHandle(notification);
+ }
+
+ internal static void BindSafeHandle(Notification notification)
+ {
+ Notification.AccessorySet accessory = new Notification.AccessorySet();
+ BindHandleToLed(notification, accessory);
+ BindHandleToSound(notification, accessory);
+ BindHandleToVibration(notification, accessory);
+ notification.Accessory = accessory;
+ }
+
+ private static void BindLedToHandle(Notification notification)
+ {
+ NotificationError ret = NotificationError.None;
+ Notification.AccessorySet accessory = notification.Accessory;
+
+ ret = Interop.Notification.SetLed(notification.Handle, accessory.LedOption, 0);
+ if (ret != NotificationError.None)
+ {
+ throw NotificationErrorFactory.GetException(ret, "unable to set led");
+ }
+
+ ret = Interop.Notification.SetLedTimePeriod(notification.Handle, accessory.LedOnMillisecond, accessory.LedOffMillisecond);
+ if (ret != NotificationError.None)
+ {
+ throw NotificationErrorFactory.GetException(ret, "unable to set led period");
+ }
+
+ if (notification.Accessory.LedOption == AccessoryOption.Custom)
+ {
+ Color color = accessory.LedColor;
+ ret = Interop.Notification.SetLed(notification.Handle, AccessoryOption.Custom, color.GetArgb());
+ if (ret != NotificationError.None)
+ {
+ throw NotificationErrorFactory.GetException(ret, "unable to set led color");
+ }
+ }
+ }
+
+ private static void BindVibrationToHandle(Notification notification)
+ {
+ Notification.AccessorySet accessory = notification.Accessory;
+ if (accessory.CanVibrate == false)
+ {
+ Interop.Notification.SetVibration(notification.Handle, AccessoryOption.Off, null);
+ }
+ else
+ {
+ Interop.Notification.SetVibration(notification.Handle, AccessoryOption.On, null);
+ }
+ }
+
+ private static void BindSoundToHandle(Notification notification)
+ {
+ Notification.AccessorySet accessory = notification.Accessory;
+
+ if (accessory.SoundOption == AccessoryOption.Custom && string.IsNullOrEmpty(accessory.SoundPath))
+ {
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "If the option is set to Custom, the path must also be set.");
+ }
+
+ NotificationError ret = Interop.Notification.SetSound(notification.Handle, accessory.SoundOption, accessory.SoundPath);
+ if (ret != NotificationError.None)
+ {
+ throw NotificationErrorFactory.GetException(ret, "unable to set sound");
+ }
+ }
+
+ private static void BindHandleToLed(Notification notification, Notification.AccessorySet accessory)
+ {
+ AccessoryOption type;
+ int argb;
+ Interop.Notification.GetLed(notification.Handle, out type, out argb);
+
+ accessory.LedOption = type;
+ if (type == AccessoryOption.Custom)
+ {
+ accessory.LedColor = new Color(argb >> 16 & 255, argb >> 8 & 255, argb >> 0 & 255, argb >> 24 & 255);
+ }
+
+ int onMillisecond, offMillisecond;
+ Interop.Notification.GetLedTimePeriod(notification.Handle, out onMillisecond, out offMillisecond);
+ accessory.LedOnMillisecond = onMillisecond;
+ accessory.LedOffMillisecond = offMillisecond;
+ }
+
+ private static void BindHandleToSound(Notification notification, Notification.AccessorySet accessory)
+ {
+ AccessoryOption type;
+ string path;
+
+ Interop.Notification.GetSound(notification.Handle, out type, out path);
+
+ accessory.SoundOption = type;
+ if (type == AccessoryOption.Custom)
+ {
+ accessory.SoundPath = path;
+ }
+ }
+
+ private static void BindHandleToVibration(Notification notification, Notification.AccessorySet accessory)
+ {
+ AccessoryOption type;
+ string path;
+
+ Interop.Notification.GetVibration(notification.Handle, out type, out path);
+ if (type == AccessoryOption.Off)
+ {
+ accessory.CanVibrate = false;
+ }
+ else
+ {
+ accessory.CanVibrate = true;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationActiveStyle.cs b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationActiveStyle.cs
new file mode 100755
index 0000000..d7b9d7f
--- /dev/null
+++ b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationActiveStyle.cs
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.Notifications
+{
+ using System.Collections.Generic;
+
+ /// <summary>
+ /// Class containing common properties and methods of Notifications
+ /// </summary>
+ /// <remarks>
+ /// A notification is a message that is displayed on the notification area.
+ /// It is created to notify information to the user through the application.
+ /// This class helps you to provide method and property for creating notification object.
+ /// </remarks>
+ public sealed partial class Notification
+ {
+ /// <summary>
+ /// Class for generating Active style notification
+ /// </summary>
+ public sealed class ActiveStyle : StyleBase
+ {
+ private IDictionary<ButtonIndex, ButtonAction> buttonDictionary;
+ private int hideTimeout = 0;
+ private int deleteTimeout = 0;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ActiveStyle"/> class.
+ /// </summary>
+ public ActiveStyle()
+ {
+ buttonDictionary = new Dictionary<ButtonIndex, ButtonAction>();
+ }
+
+ /// <summary>
+ /// Gets or sets an absolute path for an image file to display on the background of active notification
+ /// </summary>
+ public string BackgroundImage { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether the active notification is removed automatically. Default value is true.
+ /// </summary>
+ /// <remarks>
+ /// IsAutoRemove option lets the active notification be removed several seconds after it shows.
+ /// When 'IsAutoRemove' is set as false, the active notification will not be removed as long as the user removes
+ /// the active notification or the app which posted the active notification removes the active notification.
+ /// </remarks>>
+ public bool IsAutoRemove { get; set; } = true;
+
+ /// <summary>
+ /// Gets or sets the default button to display highlight on the active notification
+ /// </summary>
+ /// <remarks>
+ /// The default button for display highlight is only reflected on Tizen TV.
+ /// If you use this Property on other profile, this value have no effect
+ /// </remarks>
+ public ButtonIndex DefaultButton { get; set; } = ButtonIndex.None;
+
+ /// <summary>
+ /// Gets or sets a ReplyAction to this active notification style.
+ /// </summary>
+ /// <remarks>
+ /// When you add a ReplyAction to the ActiveStyle, the notification UI will show a ReplyAction with button.
+ /// If you set null parameter, ReplyAction is disappeared.
+ /// </remarks>
+ /// <example>
+ /// <code>
+ ///
+ /// ButtonAction button = new ButtonAction
+ /// {
+ /// Index = ButtonIndex.First,
+ /// Text = "Yes"
+ /// Action = new AppControl{ ApplicationId = "org.tizen.app" };
+ /// };
+ ///
+ /// ReplyAction reply = new ReplyAction
+ /// {
+ /// ParentIndex = ButtonIndex.First;
+ /// PlaceHolderText = "Please write your reply."
+ /// ReplyMax = 160,
+ /// Button = new ButtonAction
+ /// {
+ /// Text = "Yes",
+ /// ImagePath = "image path"
+ /// Action = new AppControl{ ApplicationId = "org.tizen.app" };
+ /// };
+ /// };
+ ///
+ /// ActiveStyle active = new ActiveStyle
+ /// {
+ /// AutoRemove = true,
+ /// BackgroundImage = "image path",
+ /// ReplyAction = reply
+ /// };
+ ///
+ /// active.AddButtonAction(button);
+ /// </code>
+ /// </example>
+ public ReplyAction ReplyAction { get; set; }
+
+ /// <summary>
+ /// Gets the key of ActiveStyle
+ /// </summary>
+ internal override string Key
+ {
+ get
+ {
+ return "Active";
+ }
+ }
+
+ /// <summary>
+ /// Method to set times to hide or delete notification.
+ /// </summary>
+ /// <remarks>
+ /// The time settings for hiding and deleting are only reflected on Tizen TV.
+ /// If you use this API on other profile, this time settings have no effect
+ /// </remarks>
+ /// <param name="hideTime">The value in second when the notification can be hidden from the notification viewer after notification is posted</param>
+ /// <param name="deleteTime">The value in second when the notification can be deleted from the notification list in setting application after notification is posted</param>
+ /// <exception cref="ArgumentException">Thrown when argument is invalid</exception>
+ public void SetRemoveTime(int hideTime, int deleteTime)
+ {
+ if (hideTime < 0 || deleteTime < 0)
+ {
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "invalid argument");
+ }
+
+ hideTimeout = hideTime;
+ deleteTimeout = deleteTime;
+ }
+
+ /// <summary>
+ /// Method to get times to hide or delete notification.
+ /// </summary>
+ /// <param name="hideTime">The value in second when the notification can be hidden from the notification viewer after notification is posted</param>
+ /// <param name="deleteTime">The value in second when the notification can be deleted from the notification list in setting application after notification is posted</param>
+ public void GetRemoveTime(out int hideTime, out int deleteTime)
+ {
+ hideTime = hideTimeout;
+ deleteTime = deleteTimeout;
+ }
+
+ /// <summary>
+ /// Method to add a button to the active notification style.
+ /// Buttons are displayed on the notification.
+ /// </summary>
+ /// <remarks>
+ /// If you add button that has same index, the button is replaced to latest adding button.
+ /// If you don't set an index on ButtonAction, the index is set sequentially from zero.
+ /// </remarks>
+ /// <param name="button">An ButtonAction for appear to the notification</param>
+ /// <exception cref="ArgumentException">Thrown when argument is invalid</exception>
+ /// <example>
+ /// <code>
+ ///
+ /// ButtonAction button = new ButtonAction
+ /// {
+ /// Index = 0,
+ /// Text = "Yes"
+ /// Action = new AppControl{ ApplicationId = "org.tizen.app" };
+ /// };
+ ///
+ /// ActiveStyle active = new ActiveStyle
+ /// {
+ /// IsAutoRemove = true,
+ /// BackgroundImage = "image path",
+ /// };
+ ///
+ /// active.AddButtonAction(button);
+ ///
+ /// </code>
+ /// </example>
+ public void AddButtonAction(ButtonAction button)
+ {
+ if (button == null)
+ {
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "invalid ButtonAction object");
+ }
+
+ if (button.Index == ButtonIndex.None)
+ {
+ button.Index = (ButtonIndex)buttonDictionary.Count;
+ buttonDictionary.Add(button.Index, button);
+ }
+ else if (button.Index >= ButtonIndex.First)
+ {
+ if (buttonDictionary.ContainsKey(button.Index))
+ {
+ buttonDictionary.Remove(button.Index);
+ }
+
+ buttonDictionary.Add(button.Index, button);
+ }
+ }
+
+ /// <summary>
+ /// Remove the ButtonAction you already add.
+ /// </summary>
+ /// <param name="index">The index to remove a button</param>
+ /// <returns>true if the element is successfully found and removed; otherwise, false</returns>
+ public bool RemoveButtonAction(ButtonIndex index)
+ {
+ bool ret = buttonDictionary.Remove(index);
+
+ if (ret == false)
+ {
+ Log.Debug(Notification.LogTag, "Invalid key, there is no button matched input index");
+ }
+ else
+ {
+ Log.Debug(Notification.LogTag, "The button was removed.");
+ }
+
+ return ret;
+ }
+
+ /// <summary>
+ /// Gets the ButtonAction of the active notification.
+ /// </summary>
+ /// <param name="index">The index to get a button you already add</param>
+ /// <returns>The ButtonAction object which is you already add</returns>
+ /// <exception cref="ArgumentException">Thrown when argument is invalid</exception>
+ public ButtonAction GetButtonAction(ButtonIndex index)
+ {
+ ButtonAction button = null;
+
+ if (buttonDictionary.ContainsKey(index) == true)
+ {
+ buttonDictionary.TryGetValue(index, out button);
+ }
+ else
+ {
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "The value is not existed.");
+ }
+
+ return button;
+ }
+
+ internal ICollection<ButtonAction> GetButtonAction()
+ {
+ return buttonDictionary.Values;
+ }
+
+ internal override void Make(Notification notification)
+ {
+ ActiveBinder.BindObject(notification);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationBinder.cs b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationBinder.cs
new file mode 100755
index 0000000..2d7eb4b
--- /dev/null
+++ b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationBinder.cs
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.Notifications
+{
+ using System;
+
+ internal static class NotificationBinder
+ {
+ private static readonly int DoNotShowTimeStamp = -1;
+
+ internal static void BindObject(Notification notification)
+ {
+ BindNotificationSafeHandle(notification);
+ BindNotificationText(notification);
+ BindNotificationTime(notification);
+
+ Interop.Notification.SetID(notification.Handle, notification.PrivID);
+
+ if (notification.IsDisplay)
+ {
+ Interop.Notification.SetApplist(notification.Handle, (int)NotificationDisplayApplist.Tray);
+ }
+ else
+ {
+ Interop.Notification.SetApplist(notification.Handle, 0);
+ }
+
+ if (notification.IsOngoing == true)
+ {
+ Log.Info(Notification.LogTag, "Start to set IsOngoing to SafeHandle");
+ Interop.Notification.SetLayout(notification.Handle, NotificationLayout.Ongoing);
+ Interop.Notification.SetOngoingFlag(notification.Handle, true);
+ }
+
+ if (string.IsNullOrEmpty(notification.Tag) != true)
+ {
+ Interop.Notification.SetTag(notification.Handle, notification.Tag);
+ }
+
+ if (notification.Action != null && notification.Action.SafeAppControlHandle.IsInvalid == false)
+ {
+ Interop.Notification.SetAppControl(notification.Handle, LaunchOption.AppControl, notification.Action.SafeAppControlHandle);
+ }
+
+ Interop.Notification.SetProperties(notification.Handle, (int)notification.Property);
+ }
+
+ internal static void BindSafeHandle(Notification notification)
+ {
+ int privID, groupID;
+ Interop.Notification.GetID(notification.Handle, out groupID, out privID);
+ notification.PrivID = privID;
+
+ NotificationLayout layout;
+ Interop.Notification.GetLayout(notification.Handle, out layout);
+ NotificationType type;
+ Interop.Notification.GetType(notification.Handle, out type);
+ if (layout == NotificationLayout.Ongoing && type == NotificationType.Ongoing)
+ {
+ notification.IsOngoing = true;
+ }
+
+ int appList;
+ Interop.Notification.GetApplist(notification.Handle, out appList);
+ if ((appList & (int)NotificationDisplayApplist.Tray) == 0)
+ {
+ notification.IsDisplay = false;
+ }
+
+ BindSafeHandleText(notification);
+ BindSafeHandleTime(notification);
+ BindSafeHandleTag(notification);
+ BindSafeHandleAction(notification);
+ }
+
+ private static void BindNotificationSafeHandle(Notification notification)
+ {
+ IntPtr ptr;
+ NotificationError ret;
+
+ if (notification.Handle != null && notification.Handle.IsInvalid == false)
+ {
+ notification.Handle.Dispose();
+ }
+
+ if (notification.IsOngoing == true || notification.Progress != null)
+ {
+ ptr = Interop.Notification.Create(NotificationType.Ongoing);
+ }
+ else
+ {
+ ptr = Interop.Notification.Create(NotificationType.Basic);
+ }
+
+ if (ptr == IntPtr.Zero)
+ {
+ ret = (NotificationError)Tizen.Internals.Errors.ErrorFacts.GetLastResult();
+ throw NotificationErrorFactory.GetException(ret, "Unable to create IntPtr Notification");
+ }
+
+ notification.Handle = new NotificationSafeHandle(ptr, true);
+ }
+
+ private static void BindNotificationText(Notification notification)
+ {
+ Interop.Notification.SetText(notification.Handle, NotificationText.Title, notification.Title, null, -1);
+ Interop.Notification.SetText(notification.Handle, NotificationText.Content, notification.Content, null, -1);
+ Interop.Notification.SetImage(notification.Handle, NotificationImage.Icon, notification.Icon);
+ Interop.Notification.SetImage(notification.Handle, NotificationImage.SubIcon, notification.SubIcon);
+ Interop.Notification.SetText(notification.Handle, NotificationText.EventCount, notification.Count.ToString(), null, -1);
+ }
+
+ private static void BindNotificationTime(Notification notification)
+ {
+ if (notification.IsTimeStampVisible == true)
+ {
+ if (notification.TimeStamp != DateTime.MinValue)
+ {
+ TimeSpan datatime = notification.TimeStamp.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+ Interop.Notification.SetTime(notification.Handle, (int)datatime.TotalSeconds);
+ }
+ }
+ else
+ {
+ Interop.Notification.SetTime(notification.Handle, DoNotShowTimeStamp);
+ }
+ }
+
+ private static void BindSafeHandleText(Notification notification)
+ {
+ string text;
+ Interop.Notification.GetText(notification.Handle, NotificationText.Title, out text);
+ if (string.IsNullOrEmpty(text) == false)
+ {
+ notification.Title = text;
+ }
+
+ Interop.Notification.GetText(notification.Handle, NotificationText.Content, out text);
+ if (string.IsNullOrEmpty(text) == false)
+ {
+ notification.Content = text;
+ }
+
+ string path;
+ Interop.Notification.GetImage(notification.Handle, NotificationImage.Icon, out path);
+ if (string.IsNullOrEmpty(path) == false)
+ {
+ notification.Icon = path;
+ }
+
+ Interop.Notification.GetImage(notification.Handle, NotificationImage.SubIcon, out path);
+ if (string.IsNullOrEmpty(path) == false)
+ {
+ notification.SubIcon = path;
+ }
+
+ Interop.Notification.GetText(notification.Handle, NotificationText.EventCount, out text);
+ if (string.IsNullOrEmpty(text) == false)
+ {
+ try
+ {
+ notification.Count = int.Parse(text);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(Notification.LogTag, ex.ToString());
+ }
+ }
+ }
+
+ private static void BindSafeHandleTime(Notification notification)
+ {
+ int time;
+
+ Interop.Notification.GetTime(notification.Handle, out time);
+
+ if (time == DoNotShowTimeStamp)
+ {
+ notification.IsTimeStampVisible = false;
+ }
+ else
+ {
+ notification.IsTimeStampVisible = true;
+
+ if (time != 0)
+ {
+ notification.TimeStamp = (new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Local)).AddSeconds(time).ToLocalTime();
+ }
+ }
+ }
+
+ private static void BindSafeHandleTag(Notification notification)
+ {
+ string text;
+ Interop.Notification.GetTag(notification.Handle, out text);
+ if (string.IsNullOrEmpty(text) != true)
+ {
+ notification.Tag = text;
+ }
+ }
+
+ private static void BindSafeHandleProperty(Notification notification)
+ {
+ int property;
+ Interop.Notification.GetProperties(notification.Handle, out property);
+ notification.Property = (NotificationProperty)property;
+ }
+
+ private static void BindSafeHandleAction(Notification notification)
+ {
+ SafeAppControlHandle appcontrol = null;
+ Interop.Notification.GetAppControl(notification.Handle, LaunchOption.AppControl, out appcontrol);
+ if (appcontrol != null && appcontrol.IsInvalid == false)
+ {
+ notification.Action = new AppControl(appcontrol);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationButtonAction.cs b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationButtonAction.cs
new file mode 100755
index 0000000..c4c2ed5
--- /dev/null
+++ b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationButtonAction.cs
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.Notifications
+{
+ /// <summary>
+ /// Class containing common properties and methods of Notifications
+ /// </summary>
+ /// <remarks>
+ /// A notification is a message that is displayed on the notification area.
+ /// It is created to notify information to the user through the application.
+ /// This class helps you to provide method and property for creating notification object.
+ /// </remarks>
+ public sealed partial class Notification
+ {
+ /// <summary>
+ /// Class to help you set button on Active style of Notification
+ /// </summary>
+ /// <remarks>
+ /// It must include a Text, an Index, an ImagePath, and an Action to be invoked when user select the button.
+ /// </remarks>>
+ public sealed class ButtonAction : MakerBase
+ {
+ /// <summary>
+ /// Gets or sets the index of Button which is appeared at Notification.
+ /// </summary>
+ public ButtonIndex Index { get; set; } = ButtonIndex.None;
+
+ /// <summary>
+ /// Gets or sets the text describing the button
+ /// </summary>
+ public string Text { get; set; }
+
+ /// <summary>
+ /// Gets or sets the image path that represent the button
+ /// </summary>
+ public string ImagePath { get; set; }
+
+ /// <summary>
+ /// Gets or sets the action which is invoked when button is clicked
+ /// </summary>
+ /// <value>
+ /// If you don't set Action, nothing happens when button is clicked.
+ /// </value>
+ /// <example>
+ /// <code>
+ /// ButtonAction button = new ButtonAction
+ /// {
+ /// Index = ButtonIndex.First,
+ /// text = "Yes",
+ /// ImagePath = "image path",
+ /// Action = new AppControl{ ApplicationId = "org.tizen.app" };
+ /// };
+ /// </code>
+ /// </example>
+ /// <seealso cref="Tizen.Applications.AppControl"></seealso>
+ public AppControl Action { get; set; }
+
+ internal override void Make(Notification notification)
+ {
+ int enumIndex = (int)NotificationText.FirstButton + (int)Index;
+
+ Interop.Notification.SetText(notification.Handle, (NotificationText)enumIndex, Text, null, -1);
+ enumIndex = (int)NotificationImage.FirstButton + (int)Index;
+ Interop.Notification.SetImage(notification.Handle, (NotificationImage)enumIndex, ImagePath);
+ if (Action != null && Action.SafeAppControlHandle.IsInvalid == false)
+ {
+ Interop.Notification.SetEventHandler(notification.Handle, (int)Index, Action.SafeAppControlHandle);
+ }
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationEnumerations.cs b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationEnumerations.cs
new file mode 100755
index 0000000..7cb41d9
--- /dev/null
+++ b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationEnumerations.cs
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.Notifications
+{
+ using System;
+
+ /// <summary>
+ /// Enumeration for Progress category
+ /// </summary>
+ public enum ProgressCategory
+ {
+ /// <summary>
+ /// Value for percent type
+ /// </summary>
+ Percent,
+
+ /// <summary>
+ /// Value for time type
+ /// </summary>
+ Time,
+
+ /// <summary>
+ /// Value for pending type which is not updated progress current value
+ /// </summary>
+ PendingBar
+ }
+
+ /// <summary>
+ /// Enumeration for Accessory option
+ /// </summary>
+ public enum AccessoryOption
+ {
+ /// <summary>
+ /// Value for off accessory option
+ /// </summary>
+ Off = -1,
+
+ /// <summary>
+ /// Value for on accessory option
+ /// </summary>
+ On,
+
+ /// <summary>
+ /// Value for custom accessory option
+ /// </summary>
+ Custom
+ }
+
+ /// <summary>
+ /// Enumeration for Button Index
+ /// </summary>
+ public enum ButtonIndex
+ {
+ /// <summary>
+ /// Value for default button index
+ /// </summary>
+ None = -1,
+
+ /// <summary>
+ /// Value for first button index
+ /// </summary>
+ First,
+
+ /// <summary>
+ /// Value for second button index
+ /// </summary>
+ Second,
+
+ /// <summary>
+ /// Value for third button index
+ /// </summary>
+ Third
+ }
+
+ /// <summary>
+ /// Enumeration for notification particular property
+ /// </summary>
+ [Flags]
+ public enum NotificationProperty
+ {
+ /// <summary>
+ /// Value for adjust nothing
+ /// </summary>
+ None = 0x00,
+
+ /// <summary>
+ /// Value for display only SIM card inserted
+ /// </summary>
+ DisplayOnlySimmode = 0x01,
+
+ /// <summary>
+ /// Value for disable application launch when it selected
+ /// </summary>
+ DisableAppLaunch = 0x02,
+
+ /// <summary>
+ /// Value for disable auto delete when it selected
+ /// </summary>
+ DisableAutoDelete = 0x04,
+
+ /// <summary>
+ /// Value for deleted when device is rebooted even though notification is not set Ongoing
+ /// </summary>
+ VolatileDisplay = 0x100
+ }
+
+ /// <summary>
+ /// Enumeration for block state
+ /// </summary>
+ public enum NotificationBlockState
+ {
+ /// <summary>
+ /// Value to check the app is allowed to post notification
+ /// </summary>
+ Allowed = 0,
+
+ /// <summary>
+ /// Value to check the app is not allowed to post any notification
+ /// </summary>
+ Blocked,
+
+ /// <summary>
+ /// Value to check do not disturb mode which is user set
+ /// </summary>
+ DoNotDisturb
+ }
+
+ internal enum NotificationType
+ {
+ None = -1,
+ Basic = 0,
+ Ongoing,
+ }
+
+ internal enum NotificationEventType
+ {
+ FirstButton = 0,
+ SecondButton,
+ ThirdButton,
+ ClickOnIcon = 6,
+ ClockOnThumbnail = 7,
+ ClickOnTextInputButton = 8
+ }
+
+ internal enum NotificationLayout
+ {
+ None = 0,
+ SingleEvent = 1,
+ Thumbnail = 3,
+ Ongoing = 4,
+ Progress = 5,
+ Extension = 6
+ }
+
+ internal enum NotificationText
+ {
+ Title = 0,
+ Content,
+ EventCount = 3,
+ FirstMainText,
+ FirstSubText,
+ SecondMainText,
+ SecondSubText,
+ FirstButton = 13,
+ SeceondButton = 14,
+ ThirdButton = 15,
+ PlaceHolder = 19,
+ InputButton = 20,
+ }
+
+ internal enum NotificationImage
+ {
+ Icon = 0,
+ IconForIndicator,
+ IconForLock,
+ Thumbnail,
+ ThumbnailForLock,
+ SubIcon,
+ Background,
+ FirstButton = 12,
+ SecondButton,
+ ThirdButton,
+ TextInputButton = 18,
+ }
+
+ internal enum LaunchOption
+ {
+ AppControl = 1
+ }
+
+ [Flags]
+ internal enum NotificationDisplayApplist
+ {
+ Tray = 0x00000001,
+ Ticker = 0x00000002,
+ Lock = 0x00000004,
+ Indicator = 0x00000008,
+ Active = 0x00000010,
+ All = 0x0000000f,
+ }
+}
diff --git a/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationErrorFactory.cs b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationErrorFactory.cs
new file mode 100755
index 0000000..12f92f3
--- /dev/null
+++ b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationErrorFactory.cs
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.Notifications
+{
+ using System;
+ using System.Runtime.CompilerServices;
+
+ internal enum NotificationError
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None,
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+ OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
+ IoError = Tizen.Internals.Errors.ErrorCode.IoError,
+ DbError = -0x01140000 | 0x01,
+ AlreadyExists = -0x01140000 | 0x02,
+ DBusError = -0x01140000 | 0x03,
+ DoesnotExist = -0x01140000 | 0x04,
+ ServiceError = -0x01140000 | 0x05,
+ PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied,
+ InvalidOperation = Tizen.Internals.Errors.ErrorCode.InvalidOperation
+ }
+
+ internal static class NotificationErrorFactory
+ {
+ internal static Exception GetException(NotificationError ret, string msg, [CallerMemberName] string memberName = "", [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNumber = 0)
+ {
+ Log.Error(Notification.LogTag, memberName + " : " + lineNumber);
+
+ switch (ret)
+ {
+ case NotificationError.InvalidParameter:
+ Log.Error(Notification.LogTag, msg);
+ return new ArgumentException(ret + " error occurred.");
+ case NotificationError.PermissionDenied:
+ throw new UnauthorizedAccessException("Permission denied (http://tizen.org/privilege/notification)");
+ default:
+ Log.Error(Notification.LogTag, msg);
+ return new InvalidOperationException(ret + " error occurred.");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationIndicatorStyle.cs b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationIndicatorStyle.cs
new file mode 100755
index 0000000..7e87c84
--- /dev/null
+++ b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationIndicatorStyle.cs
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.Notifications
+{
+ /// <summary>
+ /// Class containing common properties and methods of Notifications
+ /// </summary>
+ /// <remarks>
+ /// A notification is a message that is displayed on the notification area.
+ /// It is created to notify information to the user through the application.
+ /// This class helps you to provide method and property for creating notification object.
+ /// </remarks>
+ public sealed partial class Notification
+ {
+ /// <summary>
+ /// Class for generating Indicator style notification
+ /// </summary>
+ public sealed class IndicatorStyle : StyleBase
+ {
+ /// <summary>
+ /// Gets or sets an absolute path for an image file.
+ /// If you set IconPath, you can see the icon on the right side of indicator.
+ /// </summary>
+ public string IconPath { get; set; }
+
+ /// <summary>
+ /// Gets or sets a sub text for displaying Indicator style
+ /// </summary>
+ public string SubText { get; set; }
+
+ /// <summary>
+ /// Gets the key of IndicatorStyle
+ /// </summary>
+ internal override string Key
+ {
+ get
+ {
+ return "Indicator";
+ }
+ }
+
+ internal override void Make(Notification notification)
+ {
+ IndicatorBinder.BindObject(notification);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationLockStyle.cs b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationLockStyle.cs
new file mode 100755
index 0000000..78029a7
--- /dev/null
+++ b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationLockStyle.cs
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.Notifications
+{
+ /// <summary>
+ /// Class containing common properties and methods of Notifications
+ /// </summary>
+ /// <remarks>
+ /// A notification is a message that is displayed on the notification area.
+ /// It is created to notify information to the user through the application.
+ /// This class helps you to provide method and property for creating notification object.
+ /// </remarks>
+ public sealed partial class Notification
+ {
+ /// <summary>
+ /// Class for generating Lock style notification
+ /// </summary>
+ public sealed class LockStyle : StyleBase
+ {
+ /// <summary>
+ /// Gets or sets an absolute path for an image file to display on the icon of Lock style
+ /// </summary>
+ public string IconPath { get; set; }
+
+ /// <summary>
+ /// Gets or sets an absolute path for a thumbnail image file to display on Lock style
+ /// </summary>
+ public string ThumbnailPath { get; set; }
+
+ /// <summary>
+ /// Gets the key of LockStyle
+ /// </summary>
+ internal override string Key
+ {
+ get
+ {
+ return "Lock";
+ }
+ }
+
+ internal override void Make(Notification notification)
+ {
+ LockBinder.BindObject(notification);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationMakerBase.cs b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationMakerBase.cs
new file mode 100755
index 0000000..859a81f
--- /dev/null
+++ b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationMakerBase.cs
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.Notifications
+{
+ using System.ComponentModel;
+
+ /// <summary>
+ /// Class containing common properties and methods of Notifications
+ /// </summary>
+ /// <remarks>
+ /// A notification is a message that is displayed on the notification area.
+ /// It is created to notify information to the user through the application.
+ /// This class helps you to provide method and property for creating notification object.
+ /// </remarks>
+ public sealed partial class Notification
+ {
+ /// <summary>
+ /// An object that help notification make to SafeHandle.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public abstract class MakerBase
+ {
+ internal abstract void Make(Notification notification);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationManager.cs b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationManager.cs
new file mode 100755
index 0000000..1a890f3
--- /dev/null
+++ b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationManager.cs
@@ -0,0 +1,480 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.Notifications
+{
+ using System;
+ using System.ComponentModel;
+
+ /// <summary>
+ /// NotificationManager class to post, update, delete and get Notification.
+ /// </summary>
+ public static class NotificationManager
+ {
+ /// <summary>
+ /// Posts a new Notification.
+ /// </summary>
+ /// <param name="notification">Notification to post</param>
+ /// <exception cref="ArgumentException">Thrown when argument is invalid</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <example>
+ /// <code>
+ /// Notification notification = new Notification
+ /// {
+ /// Title = "title",
+ /// Content = "content",
+ /// Icon = "absolute icon path",
+ /// Tag = "first notification"
+ /// };
+ ///
+ /// Notification.AccessorySet accessory = new Notification.AccessorySet
+ /// {
+ /// SoundOption = AccessoryOption.On,
+ /// CanVibrate = true
+ /// };
+ /// notification.Accessory = accessory;
+ ///
+ /// // do something
+ ///
+ /// NotificationManager.Post(notification);
+ /// </code>
+ /// </example>
+ /// <privilege>http://tizen.org/privilege/notification</privilege>
+ public static void Post(Notification notification)
+ {
+ if (notification == null)
+ {
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "invalid argument to post method");
+ }
+
+ notification.Make();
+
+ NotificationError ret = Interop.Notification.Post(notification.Handle);
+ if (ret != NotificationError.None)
+ {
+ throw NotificationErrorFactory.GetException(ret, "post notification failed");
+ }
+
+ int priv_id, group_id;
+ Interop.Notification.GetID(notification.Handle, out group_id, out priv_id);
+ notification.PrivID = priv_id;
+ }
+
+ /// <summary>
+ /// Updates a posted Notification.
+ /// </summary>
+ /// <param name="notification">Notification to update</param>
+ /// <exception cref="ArgumentException">Thrown when argument is invalid</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <example>
+ /// <code>
+ /// string tag = "first tag";
+ ///
+ /// Notification notification = new Notification
+ /// {
+ /// Title = "title",
+ /// Content = "content",
+ /// Icon = "absolute icon path",
+ /// Tag = tag
+ /// };
+ ///
+ /// Notification.AccessorySet accessory = new Notification.AccessorySet
+ /// {
+ /// LedOption = AccessoryOption.On,
+ /// VibrationOption = AccessoryOption.Custom,
+ /// VibrationPath = "vibration absolute path"
+ /// }
+ /// notification.Accessory = accessory;
+ ///
+ /// NotificationManager.Post(notification);
+ ///
+ /// // do something
+ ///
+ /// Notification loadNotification = NotificationManager.Load(tag);
+ ///
+ /// loadNotification.Progress = new ProgressType(ProgressCategory.Percent, 0.0. 100.0);
+ ///
+ /// Thread thread = new Thread(new ParameterizedThreadStart(UpdateProgress));
+ /// thread.IsBackground = true;
+ /// thread.Start(notification);
+ ///
+ /// ...
+ ///
+ /// static void UpdateProgress(Object obj)
+ /// {
+ /// Notification notification = (Notification)obj;
+ ///
+ /// for (double current = 1.0; current &lt;= 100.0; current = current + 1.0)
+ /// {
+ /// notification.Progress.ProgressCurrent = current;
+ /// NotificationManager.Update(notification);
+ /// Thread.Sleep(300);
+ /// }
+ /// }
+ /// </code>
+ /// </example>
+ /// <privilege>http://tizen.org/privilege/notification</privilege>
+ /// <pre>
+ /// Post method should be called on the Notification object.
+ /// </pre>
+ public static void Update(Notification notification)
+ {
+ if (notification == null || notification.Handle == null || notification.Handle.IsInvalid)
+ {
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "invalid argument to post method");
+ }
+
+ notification.Make();
+ NotificationError ret = Interop.Notification.Update(notification.Handle);
+ if (ret != NotificationError.None)
+ {
+ throw NotificationErrorFactory.GetException(ret, "update notification failed");
+ }
+ }
+
+ /// <summary>
+ /// Deletes a posted Notification.
+ /// </summary>
+ /// <param name="notification">Notification to remove</param>
+ /// <exception cref="ArgumentException">Thrown when argument is invalid</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <example>
+ /// <code>
+ /// Notification notification = new Notification
+ /// {
+ /// Title = "title",
+ /// Content = "content",
+ /// Icon = "absolute icon path",
+ /// Tag = "first notification"
+ /// };
+ /// NotificationManager.Post(notification);
+ ///
+ /// // do something
+ ///
+ /// NotificationManager.Delete(notification);
+ /// </code>
+ /// </example>
+ /// <privilege>http://tizen.org/privilege/notification</privilege>
+ /// <pre>
+ /// Post method should be called on the Notification object.
+ /// </pre>
+ public static void Delete(Notification notification)
+ {
+ if (notification == null || notification.Handle == null || notification.Handle.IsInvalid)
+ {
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "invalid argument to post method");
+ }
+
+ NotificationError ret = Interop.Notification.Delete(notification.Handle);
+ if (ret != NotificationError.None)
+ {
+ throw NotificationErrorFactory.GetException(ret, "delete notification failed");
+ }
+ }
+
+ /// <summary>
+ /// Removes all posted Notification of calling application.
+ /// </summary>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <example>
+ /// <code>
+ /// Notification firstNotification = new Notification
+ /// {
+ /// Title = "title",
+ /// Content = "content",
+ /// Icon = "absolute icon path",
+ /// Tag = "first notification"
+ /// };
+ /// NotificationManager.Post(firstNotification);
+ ///
+ /// Notification secondNotification = new Notification
+ /// {
+ /// Title = "title",
+ /// Content = "content",
+ /// Icon = "absolute icon path",
+ /// Tag = "second notification"
+ /// };
+ /// NotificationManager.Post(secondNotification);
+ /// NotificationManager.DeleteAll();
+ /// </code>
+ /// </example>
+ /// <privilege>http://tizen.org/privilege/notification</privilege>
+ public static void DeleteAll()
+ {
+ NotificationError ret;
+
+ ret = Interop.Notification.DeleteAll((int)NotificationType.Basic);
+ if (ret != NotificationError.None)
+ {
+ throw NotificationErrorFactory.GetException(ret, "delete all notifications failed of Noti type");
+ }
+
+ ret = Interop.Notification.DeleteAll((int)NotificationType.Ongoing);
+ if (ret != NotificationError.None)
+ {
+ throw NotificationErrorFactory.GetException(ret, "delete all notifications failed of Ongoing type");
+ }
+ }
+
+ /// <summary>
+ /// Searches for a posted notification which has the inputted tag and isn't deleted not yet.
+ /// </summary>
+ /// <remarks>
+ /// Load method should be called only for notifications which have been posted using NotificationManager.Post method.
+ /// If two or more notifications share the same tag, the notification posted most recently is returned.
+ /// </remarks>
+ /// <param name="tag">Tag used to query</param>
+ /// <returns>Notification Object with inputted tag</returns>
+ /// <exception cref="ArgumentException">Thrown when argument is invalid or when the tag does not exist</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <example>
+ /// <code>
+ /// Notification notification = new Notification
+ /// {
+ /// Title = "title",
+ /// Content = "content",
+ /// Icon = "absolute icon path",
+ /// Tag = "first notification"
+ /// };
+ /// NotificationManager.Post(notification);
+ ///
+ /// // do someting
+ ///
+ /// Notification loadNotification = NotificationManager.Load("first notification");
+ /// </code>
+ /// </example>
+ /// <privilege>http://tizen.org/privilege/notification</privilege>
+ public static Notification Load(string tag)
+ {
+ IntPtr ptr = IntPtr.Zero;
+
+ if (string.IsNullOrEmpty(tag))
+ {
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "invalid parameter entered");
+ }
+
+ ptr = Interop.Notification.Load(tag);
+
+ if (ptr == IntPtr.Zero)
+ {
+ NotificationError ret = (NotificationError)Tizen.Internals.Errors.ErrorFacts.GetLastResult();
+ Log.Error(Notification.LogTag, "unable to load Notification : " + ret.ToString());
+ if (ret == NotificationError.DbError)
+ {
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "the tag does not exist");
+ }
+ else
+ {
+ throw NotificationErrorFactory.GetException(ret, "unable to load Notification");
+ }
+ }
+
+ Notification notification = new Notification
+ {
+ Handle = new NotificationSafeHandle(ptr, true)
+ }.Build();
+
+ return notification;
+ }
+
+ /// <summary>
+ /// Saves a notification template to the notification database
+ /// </summary>
+ /// <param name="notification">Notification to save as template</param>
+ /// <param name="name">Template name</param>
+ /// <exception cref="ArgumentException">Thrown when argument is invalid</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when can't save as template</exception>
+ /// <example>
+ /// <code>
+ /// Notification notification = new Notification
+ /// {
+ /// Title = "title",
+ /// Content = "content",
+ /// Icon = "absolute icon path",
+ /// Tag = "first notification"
+ /// };
+ ///
+ /// Notification.Accessory accessory = new Notification.Accessory
+ /// {
+ /// LedOption = AccessoryOption.On,
+ /// VibrationOption = AccessoryOption.Custom,
+ /// VibrationPath = "vibration absolute path"
+ /// }
+ /// notification.setAccessory(accessory);
+ ///
+ /// // do something
+ ///
+ /// NotificationManager.Post(notification);
+ ///
+ /// Notification.LockStyle style = new Notification.LockStyle
+ /// {
+ /// IconPath = "icon path",
+ /// ThumbnailPath = "Thumbnail path"
+ /// }
+ /// notification.AddStyle(style);
+ /// NotificationManager.SaveTemplate(notification, "firstTemplate");
+ /// </code>
+ /// </example>
+ /// <privilege>http://tizen.org/privilege/notification</privilege>
+ public static void SaveTemplate(Notification notification, string name)
+ {
+ if (notification == null || string.IsNullOrEmpty(name))
+ {
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "invalid argument to save template");
+ }
+
+ notification.Make();
+
+ NotificationError ret = Interop.Notification.SaveTemplate(notification.Handle, name);
+ if (ret != NotificationError.None)
+ {
+ throw NotificationErrorFactory.GetException(ret, "save as template failed");
+ }
+ }
+
+ /// <summary>
+ /// Loads a notification template from the notification database
+ /// </summary>
+ /// <param name="name">Template name</param>
+ /// <returns>Notification Object with inputted template name</returns>
+ /// <exception cref="ArgumentException">Thrown when argument is invalid or when no template with input name exists</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <example>
+ /// <code>
+ /// Notification notification = new Notification
+ /// {
+ /// Title = "title",
+ /// Content = "content",
+ /// Icon = "absolute icon path",
+ /// Tag = "first notification"
+ /// };
+ ///
+ /// Notification.Accessory accessory = new Notification.Accessory
+ /// {
+ /// LedOption = AccessoryOption.On,
+ /// VibrationOption = AccessoryOption.Custom,
+ /// VibrationPath = "vibration absolute path"
+ /// }
+ /// notification.setAccessory(accessory);
+ ///
+ /// // do something
+ ///
+ /// NotificationManager.Post(notification);
+ ///
+ /// Notification.LockStyle style = new Notification.LockStyle
+ /// {
+ /// IconPath = "icon path",
+ /// ThumbnailPath = "Thumbnail path"
+ /// }
+ /// notification.AddStyle(style);
+ /// NotificationManager.SaveTemplate(notification, "firstTemplate");
+ /// Notification notificationTemplate = NotificationManager.LoadTemplate("firstTemplate");
+ /// </code>
+ /// </example>
+ /// <privilege>http://tizen.org/privilege/notification</privilege>
+ public static Notification LoadTemplate(string name)
+ {
+ IntPtr handle = IntPtr.Zero;
+
+ if (string.IsNullOrEmpty(name))
+ {
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "invalid argument to load template");
+ }
+
+ handle = Interop.Notification.LoadTemplate(name);
+ if (handle == IntPtr.Zero)
+ {
+ NotificationError ret = (NotificationError)Tizen.Internals.Errors.ErrorFacts.GetLastResult();
+ if (ret == NotificationError.DbError)
+ {
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "the name does not exist");
+ }
+ else
+ {
+ throw NotificationErrorFactory.GetException(ret, "unable to create Notification from template");
+ }
+ }
+
+ Notification notification = new Notification
+ {
+ Handle = new NotificationSafeHandle(handle, true)
+ }.Build();
+
+ return notification;
+ }
+
+ /// <summary>
+ /// Gets notification block state.
+ /// </summary>
+ /// <remarks>
+ /// The user can set the notification block state in settings.
+ /// The block state indicates whether or not notifications can be posted.
+ /// Additionally only notifications to the notification panel are allowed in "Do not disturb mode".
+ /// Sound, Vibrate and Active notifications are blocked.
+ /// </remarks>
+ /// <returns>NotificationBlockState is state if notification is posted</returns>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/notification</privilege>
+ public static NotificationBlockState GetBlockState()
+ {
+ NotificationBlockState state;
+ NotificationError ret;
+
+ ret = Interop.Notification.GetBlockState(out state);
+ if (ret != NotificationError.None)
+ {
+ throw NotificationErrorFactory.GetException(ret, "GetBlockState failed");
+ }
+
+ Log.Info(Notification.LogTag, "Current block state is " + state.ToString());
+ return state;
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static NotificationSafeHandle MakeNotificationSafeHandle(Notification notification)
+ {
+ if (notification == null)
+ {
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "invalid notification object");
+ }
+
+ notification.Make();
+
+ return notification.Handle;
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static Notification MakeNotification(NotificationSafeHandle handle)
+ {
+ if (handle == null || handle.IsInvalid == true)
+ {
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "handle is invalid or null");
+ }
+
+ Notification notification = new Notification { Handle = handle }.Build();
+
+ return notification;
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationProgress.cs b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationProgress.cs
new file mode 100755
index 0000000..3630755
--- /dev/null
+++ b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationProgress.cs
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.Notifications
+{
+ /// <summary>
+ /// Class containing common properties and methods of Notifications
+ /// </summary>
+ /// <remarks>
+ /// A notification is a message that is displayed on the notification area.
+ /// It is created to notify information to the user through the application.
+ /// This class helps you to provide method and property for creating notification object.
+ /// </remarks>
+ public sealed partial class Notification
+ {
+ /// <summary>
+ /// Class for displaying progress notification
+ /// You must initialize progress category, current, max value when you create object.
+ /// </summary>
+ public sealed class ProgressType : MakerBase
+ {
+ private double progressCurrent;
+ private double progressMax;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ProgressType"/> class.
+ /// You must initialize category, current, max value of progress.
+ /// </summary>
+ /// <param name="category">The category of progress that appeared on Notification</param>
+ /// <param name="current">The current value of the progress</param>
+ /// <param name="max">The max value of the progress</param>
+ /// <exception cref="ArgumentException">Thrown when argument is invalid</exception>
+ public ProgressType(ProgressCategory category, double current, double max)
+ {
+ if (IsNegativeNumber(current))
+ {
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "The current must be a positive integer.");
+ }
+
+ if (IsNegativeNumber(max))
+ {
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "The max must be a positive integer.");
+ }
+
+ Category = category;
+ ProgressCurrent = current;
+ ProgressMax = max;
+ }
+
+ /// <summary>
+ /// Gets or sets category of ProgressType.
+ /// </summary>
+ /// <seealso cref="Tizen.Applications.Notifications.ProgressCategory"></seealso>
+ public ProgressCategory Category { get; set; }
+
+ /// <summary>
+ /// Gets or sets current value of ProgressType
+ /// </summary>
+ /// <exception cref="ArgumentException">Thrown when argument is invalid</exception>
+ public double ProgressCurrent
+ {
+ get
+ {
+ return progressCurrent;
+ }
+
+ set
+ {
+ if (IsNegativeNumber(value))
+ {
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "The value must be a positive integer.");
+ }
+
+ progressCurrent = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets max value of ProgressType
+ /// </summary>
+ /// <exception cref="ArgumentException">Thrown when argument is invalid</exception>
+ public double ProgressMax
+ {
+ get
+ {
+ return progressMax;
+ }
+
+ set
+ {
+ if (IsNegativeNumber(value))
+ {
+ throw NotificationErrorFactory.GetException(NotificationError.InvalidParameter, "The value must be a positive integer.");
+ }
+
+ progressMax = value;
+ }
+ }
+
+ internal override void Make(Notification notification)
+ {
+ ProgressBinder.BindObject(notification);
+ }
+
+ private bool IsNegativeNumber(double number)
+ {
+ return number < 0;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationProgressBinder.cs b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationProgressBinder.cs
new file mode 100755
index 0000000..6afd5c5
--- /dev/null
+++ b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationProgressBinder.cs
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.Notifications
+{
+ internal static class ProgressBinder
+ {
+ internal static void BindObject(Notification notification)
+ {
+ double current, max;
+
+ Notification.ProgressType progress = notification.Progress;
+
+ if (progress.Category == ProgressCategory.PendingBar)
+ {
+ Interop.Notification.SetProgressType(notification.Handle, ProgressCategory.Percent);
+ current = 0;
+ max = 0;
+ }
+ else if (progress.Category == ProgressCategory.Percent)
+ {
+ Interop.Notification.SetProgressType(notification.Handle, progress.Category);
+ current = progress.ProgressCurrent / 100;
+ max = progress.ProgressMax;
+ }
+ else
+ {
+ Interop.Notification.SetProgressType(notification.Handle, progress.Category);
+ current = progress.ProgressCurrent;
+ max = progress.ProgressMax;
+ }
+
+ Interop.Notification.SetProgress(notification.Handle, current);
+ Interop.Notification.SetProgressSize(notification.Handle, max);
+ Interop.Notification.SetLayout(notification.Handle, NotificationLayout.Progress);
+ Interop.Notification.SetOngoingFlag(notification.Handle, true);
+ }
+
+ internal static void BindSafeHandle(Notification notification)
+ {
+ NotificationLayout layout;
+ Interop.Notification.GetLayout(notification.Handle, out layout);
+
+ if (layout == NotificationLayout.Progress)
+ {
+ ProgressCategory category;
+ double current, max;
+
+ Interop.Notification.GetProgressType(notification.Handle, out category);
+ Interop.Notification.GetProgress(notification.Handle, out current);
+ Interop.Notification.GetProgressSize(notification.Handle, out max);
+
+ if (category == ProgressCategory.Percent)
+ {
+ current *= 100;
+ }
+
+ notification.Progress = new Notification.ProgressType(category, current, max);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationReplyAction.cs b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationReplyAction.cs
new file mode 100755
index 0000000..f3bc10a
--- /dev/null
+++ b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationReplyAction.cs
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.Notifications
+{
+ /// <summary>
+ /// Class containing common properties and methods of Notifications
+ /// </summary>
+ /// <remarks>
+ /// A notification is a message that is displayed on the notification area.
+ /// It is created to notify information to the user through the application.
+ /// This class helps you to provide method and property for creating notification object.
+ /// </remarks>
+ public sealed partial class Notification
+ {
+ /// <summary>
+ /// Class for displaying direct-reply at notification.
+ /// You must set a ReplyMax and Button. Otherwise user can't send written text to application which is set by AppControl.
+ /// </summary>
+ public sealed class ReplyAction : MakerBase
+ {
+ /// <summary>
+ /// Gets or sets the Index of Button which is appeared at Notification.
+ /// If you set ParentIndex, ReplyAction is displayed when button matched with ParentIndex click by the user.
+ /// If you don't set ParentIndex, appeared to notification directly.
+ /// </summary>
+ public ButtonIndex ParentIndex { get; set; } = ButtonIndex.None;
+
+ /// <summary>
+ /// Gets or sets the PlaceHolderText of ReplyAction which is appeared at Notification.
+ /// If you set PlaceHolderText, it is displayed to placeholder in notification.
+ /// </summary>
+ public string PlaceHolderText { get; set; }
+
+ /// <summary>
+ /// Gets or sets the ReplyMax of ReplyAction which is appeared at Notification.
+ /// You must set a ReplyMax. Otherwise user don't write text to placeholder in notification.
+ /// </summary>
+ /// <value>
+ /// Default value is 160.
+ /// </value>
+ public int ReplyMax { get; set; } = 160;
+
+ /// <summary>
+ /// Gets or sets the Button which is appeared to ReplyAction in Notification.
+ /// You must set a Button. Otherwise user can't send written text to application which is set by AppControl.
+ /// </summary>
+ /// <remarks>
+ /// If you set it to null, the already set ButtonAction will be removed.
+ /// </remarks>
+ /// <example>
+ /// <code>
+ /// ReplyAction button = new ReplyAction
+ /// {
+ /// ParentIndex = ButtonIndex.Second;
+ /// PlaceHolderText = "Please write your reply."
+ /// ReplyMax = 160,
+ /// Button = new ButtonAction
+ /// {
+ /// text = "Yes",
+ /// ImagePath = "image path",
+ /// Action = new AppControl{ ApplicationId = "org.tizen.app" };
+ /// };
+ /// };
+ /// </code>
+ /// </example>
+ public ButtonAction Button { get; set; }
+
+ internal override void Make(Notification notification)
+ {
+ string replyKey = "__PARENT_INDEX__";
+
+ if (Button != null)
+ {
+ Interop.Notification.SetText(notification.Handle, NotificationText.InputButton, Button.Text, null, -1);
+ Interop.Notification.SetImage(notification.Handle, NotificationImage.TextInputButton, Button.ImagePath);
+
+ if (this.Button.Action != null && this.Button.Action.SafeAppControlHandle.IsInvalid == false)
+ {
+ Interop.Notification.SetEventHandler(notification.Handle, (int)NotificationEventType.ClickOnTextInputButton, this.Button.Action.SafeAppControlHandle);
+
+ if (this.ParentIndex != ButtonIndex.None)
+ {
+ Interop.Notification.SetEventHandler(notification.Handle, (int)this.ParentIndex, this.Button.Action.SafeAppControlHandle);
+ }
+ }
+ }
+
+ Bundle bundle = new Bundle();
+ bundle.AddItem(replyKey, ((int)this.ParentIndex).ToString());
+ Interop.Notification.SetExtentionData(notification.Handle, replyKey, bundle.SafeBundleHandle);
+
+ Interop.Notification.SetPlaceHolderLength(notification.Handle, this.ReplyMax);
+ Interop.Notification.SetText(notification.Handle, NotificationText.PlaceHolder, PlaceHolderText, null, -1);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationSafeHandle.cs b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationSafeHandle.cs
new file mode 100755
index 0000000..28ce60a
--- /dev/null
+++ b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationSafeHandle.cs
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.Notifications
+{
+ using System;
+ using System.ComponentModel;
+ using System.Runtime.InteropServices;
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public sealed class NotificationSafeHandle : SafeHandle
+ {
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public NotificationSafeHandle()
+ : base(IntPtr.Zero, true)
+ {
+ }
+
+ internal NotificationSafeHandle(IntPtr existingHandle, bool ownsHandle) : base(IntPtr.Zero, ownsHandle)
+ {
+ SetHandle(existingHandle);
+ }
+
+ /// <summary>
+ /// Gets a value that indicates whether the handle is invalid.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override bool IsInvalid
+ {
+ get { return this.DangerousGetHandle() == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ Interop.Notification.Destroy(this.handle);
+ this.SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationStyle.cs b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationStyle.cs
new file mode 100755
index 0000000..84ec3a7
--- /dev/null
+++ b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationStyle.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.Notifications
+{
+ /// <summary>
+ /// Class containing common properties and methods of Notifications
+ /// </summary>
+ /// <remarks>
+ /// A notification is a message that is displayed on the notification area.
+ /// It is created to notify information to the user through the application.
+ /// This class helps you to provide method and property for creating notification object.
+ /// </remarks>
+ public sealed partial class Notification
+ {
+ /// <summary>
+ /// An object that can apply a rich notification style to a Notification object.
+ /// If the platform does not provide rich notification styles in this class have no effect.
+ /// </summary>
+ public abstract class StyleBase : MakerBase
+ {
+ internal abstract string Key { get; }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationStyleBinder.cs b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationStyleBinder.cs
new file mode 100755
index 0000000..587c6ef
--- /dev/null
+++ b/src/Tizen.Applications.Notification/Tizen.Applications.Notifications/NotificationStyleBinder.cs
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.Notifications
+{
+ using System;
+
+ internal static class IndicatorBinder
+ {
+ internal static void BindObject(Notification notification)
+ {
+ int flag;
+ NotificationError ret = NotificationError.None;
+ Notification.IndicatorStyle style = (Notification.IndicatorStyle)notification.GetStyle("Indicator");
+ Interop.Notification.GetApplist(notification.Handle, out flag);
+
+ if (string.IsNullOrEmpty(style.SubText) == false)
+ {
+ ret = Interop.Notification.SetText(notification.Handle, NotificationText.FirstMainText, style.SubText, null, -1);
+ if (ret != NotificationError.None)
+ {
+ throw NotificationErrorFactory.GetException(ret, "unable to set indicator text");
+ }
+ flag |= (int)NotificationDisplayApplist.Ticker;
+ }
+
+ if (string.IsNullOrEmpty(style.IconPath) == false)
+ {
+ ret = Interop.Notification.SetImage(notification.Handle, NotificationImage.IconForIndicator, style.IconPath);
+ if (ret != NotificationError.None)
+ {
+ throw NotificationErrorFactory.GetException(ret, "unable to set indicator image");
+ }
+ flag |= (int)NotificationDisplayApplist.Indicator;
+ }
+ Interop.Notification.SetApplist(notification.Handle, flag);
+ }
+
+ internal static void BindSafeHandle(Notification notification)
+ {
+ int appList;
+ Interop.Notification.GetApplist(notification.Handle, out appList);
+ if ((appList & (int)NotificationDisplayApplist.Ticker) != 0 || (appList & (int)NotificationDisplayApplist.Indicator) != 0)
+ {
+ string path, text;
+ Notification.IndicatorStyle indicator = new Notification.IndicatorStyle();
+ Interop.Notification.GetImage(notification.Handle, NotificationImage.IconForIndicator, out path);
+ indicator.IconPath = path;
+ Interop.Notification.GetText(notification.Handle, NotificationText.FirstMainText, out text);
+ indicator.SubText = text;
+
+ notification.AddStyle(indicator);
+ }
+ }
+ }
+
+ internal static class ActiveBinder
+ {
+ internal static void BindObject(Notification notification)
+ {
+ int flag;
+ NotificationError ret = NotificationError.None;
+ Notification.ActiveStyle style = (Notification.ActiveStyle)notification.GetStyle("Active");
+
+ Interop.Notification.SetAutoRemove(notification.Handle, style.IsAutoRemove);
+ if (style.IsAutoRemove == true)
+ {
+ int hidetime;
+ int deletetime;
+ style.GetRemoveTime(out hidetime, out deletetime);
+
+ Interop.Notification.SetHideTime(notification.Handle, hidetime);
+ try
+ {
+ Interop.Notification.SetDeleteTime(notification.Handle, deletetime);
+ }
+ catch (TypeLoadException)
+ {
+ // To support in API version 3.0
+ style.SetRemoveTime(hidetime, 60);
+ }
+ }
+
+ ret = Interop.Notification.SetImage(notification.Handle, NotificationImage.Background, style?.BackgroundImage);
+ if (ret != NotificationError.None)
+ {
+ throw NotificationErrorFactory.GetException(ret, "unable to set background Image");
+ }
+
+ if (style.DefaultButton != ButtonIndex.None)
+ {
+ Interop.Notification.SetDefaultButton(notification.Handle, (int)style.DefaultButton + 1);
+ }
+
+ Interop.Notification.GetApplist(notification.Handle, out flag);
+ Interop.Notification.SetApplist(notification.Handle, flag | (int)NotificationDisplayApplist.Active);
+
+ foreach (Notification.ButtonAction button in style.GetButtonAction())
+ {
+ button.Make(notification);
+ }
+
+ if (style.ReplyAction != null)
+ {
+ style.ReplyAction.Make(notification);
+ }
+ }
+
+ internal static void BindSafeHandle(Notification notification)
+ {
+ int appList;
+ Interop.Notification.GetApplist(notification.Handle, out appList);
+
+ if ((appList & (int)NotificationDisplayApplist.Active) != 0)
+ {
+ Notification.ActiveStyle active = new Notification.ActiveStyle();
+ bool isExisted = false;
+ bool autoRemove;
+ string path, text;
+ SafeAppControlHandle appcontrol = null;
+ string replyKey = "__PARENT_INDEX__";
+
+ for (int i = (int)ButtonIndex.First; i <= (int)ButtonIndex.Third; i++)
+ {
+ appcontrol = null;
+
+ Interop.Notification.GetImage(notification.Handle, NotificationImage.FirstButton + i, out path);
+ Interop.Notification.GetText(notification.Handle, NotificationText.FirstButton + i, out text);
+ Interop.Notification.GetEventHandler(notification.Handle, i, out appcontrol);
+
+ if (string.IsNullOrEmpty(path) == false || string.IsNullOrEmpty(text) == false
+ || (appcontrol != null && appcontrol.IsInvalid == false))
+ {
+ Notification.ButtonAction button = new Notification.ButtonAction();
+ if (appcontrol != null && appcontrol.IsInvalid == false)
+ {
+ button.Action = new AppControl(appcontrol);
+ }
+
+ button.ImagePath = path;
+ button.Text = text;
+ button.Index = (ButtonIndex)i;
+ active.AddButtonAction(button);
+ isExisted = true;
+ }
+ }
+
+ Interop.Notification.GetAutoRemove(notification.Handle, out autoRemove);
+ active.IsAutoRemove = autoRemove;
+ if (autoRemove)
+ {
+ int hidetime, deletetime;
+ Interop.Notification.GetHideTime(notification.Handle, out hidetime);
+ try
+ {
+ Interop.Notification.GetDeleteTime(notification.Handle, out deletetime);
+ }
+ catch (TypeLoadException)
+ {
+ // To support in API version 3.0
+ deletetime = 60;
+ }
+
+ active.SetRemoveTime(hidetime, deletetime);
+ }
+
+ Interop.Notification.GetImage(notification.Handle, NotificationImage.Background, out path);
+ if (string.IsNullOrEmpty(path) == false)
+ {
+ isExisted = true;
+ active.BackgroundImage = path;
+ }
+
+ int defaultIndex;
+ Interop.Notification.GetDefaultButton(notification.Handle, out defaultIndex);
+ active.DefaultButton = (ButtonIndex)(defaultIndex - 1);
+
+ appcontrol = null;
+ Interop.Notification.GetImage(notification.Handle, NotificationImage.TextInputButton, out path);
+ Interop.Notification.GetText(notification.Handle, NotificationText.InputButton, out text);
+ Interop.Notification.GetEventHandler(notification.Handle, (int)NotificationEventType.ClickOnTextInputButton, out appcontrol);
+
+ if (string.IsNullOrEmpty(path) == false || string.IsNullOrEmpty(text) == false
+ || (appcontrol != null && appcontrol.IsInvalid == false))
+ {
+ Notification.ReplyAction reply = new Notification.ReplyAction();
+ Notification.ButtonAction button = new Notification.ButtonAction();
+ if (appcontrol != null && appcontrol.IsInvalid == false)
+ {
+ button.Action = new AppControl(appcontrol);
+ }
+
+ button.ImagePath = path;
+ button.Text = text;
+ reply.Button = button;
+
+ Interop.Notification.GetText(notification.Handle, NotificationText.PlaceHolder, out text);
+ reply.PlaceHolderText = text;
+
+ int holderLength;
+ Interop.Notification.GetPlaceHolderLength(notification.Handle, out holderLength);
+ reply.ReplyMax = holderLength;
+
+ isExisted = true;
+
+ try
+ {
+ SafeBundleHandle bundleHandle;
+ Interop.Notification.GetExtentionData(notification.Handle, replyKey, out bundleHandle);
+ Bundle bundle = new Bundle(bundleHandle);
+ reply.ParentIndex = (ButtonIndex)int.Parse(bundle.GetItem(replyKey).ToString());
+ }
+ catch (Exception ex)
+ {
+ Log.Error(Notification.LogTag, ex.ToString());
+ }
+
+ active.ReplyAction = reply;
+ }
+
+ if (isExisted)
+ {
+ notification.AddStyle(active);
+ }
+ }
+ }
+ }
+
+ internal static class LockBinder
+ {
+ internal static void BindObject(Notification notification)
+ {
+ int flag;
+ NotificationError ret = NotificationError.None;
+ Notification.LockStyle style = (Notification.LockStyle)notification.GetStyle("Lock");
+
+ ret = Interop.Notification.SetImage(notification.Handle, NotificationImage.IconForLock, style.IconPath);
+ if (ret != NotificationError.None)
+ {
+ throw NotificationErrorFactory.GetException(ret, "unable to set lock icon");
+ }
+
+ ret = Interop.Notification.SetImage(notification.Handle, NotificationImage.ThumbnailForLock, style.ThumbnailPath);
+ if (ret != NotificationError.None)
+ {
+ throw NotificationErrorFactory.GetException(ret, "unable to set lock thumbnail");
+ }
+
+ Interop.Notification.GetApplist(notification.Handle, out flag);
+ Interop.Notification.SetApplist(notification.Handle, flag | (int)NotificationDisplayApplist.Lock);
+ }
+
+ internal static void BindSafehandle(Notification notification)
+ {
+ int applist;
+ Interop.Notification.GetApplist(notification.Handle, out applist);
+
+ if ((applist & (int)NotificationDisplayApplist.Lock) != 0)
+ {
+ string path;
+ Notification.LockStyle lockStyle = new Notification.LockStyle();
+
+ Interop.Notification.GetImage(notification.Handle, NotificationImage.IconForLock, out path);
+ lockStyle.IconPath = path;
+
+ Interop.Notification.GetImage(notification.Handle, NotificationImage.ThumbnailForLock, out path);
+ lockStyle.ThumbnailPath = path;
+
+ notification.AddStyle(lockStyle);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.NotificationEventListener/Interop/Interop.Libraries.cs b/src/Tizen.Applications.NotificationEventListener/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..75347d4
--- /dev/null
+++ b/src/Tizen.Applications.NotificationEventListener/Interop/Interop.Libraries.cs
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string NotificationEventListener = "libnotification.so.0";
+ }
+}
diff --git a/src/Tizen.Applications.NotificationEventListener/Interop/Interop.NotificationEventListener.cs b/src/Tizen.Applications.NotificationEventListener/Interop/Interop.NotificationEventListener.cs
new file mode 100755
index 0000000..1e8b413
--- /dev/null
+++ b/src/Tizen.Applications.NotificationEventListener/Interop/Interop.NotificationEventListener.cs
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+using Tizen.Applications;
+using Tizen.Applications.NotificationEventListener;
+
+internal static partial class Interop
+{
+ internal static class NotificationEventListener
+ {
+ internal delegate void ChangedCallback(IntPtr userData, NotificationType type, IntPtr operationList, int num);
+
+ internal enum ErrorCode
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None,
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+ OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
+ IoError = Tizen.Internals.Errors.ErrorCode.IoError,
+ DbError = -0x01140000 | 0x01,
+ AlreadyExists = -0x01140000 | 0x02,
+ DBusError = -0x01140000 | 0x03,
+ DoesnotExist = -0x01140000 | 0x04,
+ ServiceError = -0x01140000 | 0x05,
+ PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied,
+ InvalidOperation = Tizen.Internals.Errors.ErrorCode.InvalidOperation
+ }
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_free")]
+ internal static extern ErrorCode Destroy(IntPtr handle);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_get_id")]
+ internal static extern ErrorCode GetID(NotificationSafeHandle handle, out int groupId, out int privateId);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_get_pkgname")]
+ internal static extern ErrorCode GetAppIdReferenceType(NotificationSafeHandle handle, out IntPtr appid);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_get_text")]
+ internal static extern ErrorCode GetTextReferenceType(NotificationSafeHandle handle, NotificationText type, out IntPtr text);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_get_image")]
+ internal static extern ErrorCode GetImageReferenceType(NotificationSafeHandle handle, NotificationImage type, out IntPtr text);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_get_insert_time")]
+ internal static extern ErrorCode GetInsertTime(NotificationSafeHandle handle, out int time);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_get_time")]
+ internal static extern ErrorCode GetTime(NotificationSafeHandle handle, out int time);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_get_sound")]
+ internal static extern ErrorCode GetSoundReferenceType(NotificationSafeHandle handle, out AccessoryOption type, out IntPtr path);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_get_vibration")]
+ internal static extern ErrorCode GetVibrationReferenceType(NotificationSafeHandle handle, out AccessoryOption type, out IntPtr path);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_get_led")]
+ internal static extern ErrorCode GetLed(NotificationSafeHandle handle, out AccessoryOption type, out int color);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_get_led_time_period")]
+ internal static extern ErrorCode GetLedTime(NotificationSafeHandle handle, out int onMilliSeconds, out int offMilliSeconds);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_get_tag")]
+ internal static extern ErrorCode GetTagReferenceType(NotificationSafeHandle handle, out IntPtr tag);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_get_display_applist")]
+ internal static extern ErrorCode GetStyleList(NotificationSafeHandle handle, out int styleList);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_get_auto_remove")]
+ internal static extern ErrorCode GetAutoRemove(NotificationSafeHandle handle, out bool autoRemove);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_get_text_input_max_length")]
+ internal static extern ErrorCode GetPlaceHolderLength(NotificationSafeHandle handle, out int max);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_get_launch_option")]
+ internal static extern ErrorCode GetAppControl(NotificationSafeHandle handle, LaunchOption type, out SafeAppControlHandle appControlHandle);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_get_event_handler")]
+ internal static extern ErrorCode GetEventHandler(NotificationSafeHandle handle, int type, out SafeAppControlHandle appControlHandle);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_register_detailed_changed_cb")]
+ internal static extern ErrorCode SetChangedCallback(ChangedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_unregister_detailed_changed_cb")]
+ internal static extern ErrorCode UnsetChangedCallback(ChangedCallback callback);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_op_get_data")]
+ internal static extern ErrorCode GetOperationData(IntPtr operationList, NotificationOperationDataType type, out IntPtr userData);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_list_get_data")]
+ internal static extern IntPtr GetData(IntPtr notificationList);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_list_get_next")]
+ internal static extern IntPtr GetNext(IntPtr notificationList);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_delete_by_priv_id")]
+ internal static extern ErrorCode Delete(string appId, NotificationType type, int uniqueNumber);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_clear")]
+ internal static extern ErrorCode DeleteAll(int type);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_get_list")]
+ internal static extern ErrorCode GetList(NotificationType type, int count, out IntPtr notification);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_send_event_by_priv_id")]
+ internal static extern ErrorCode SendEvent(int uniqueNumber, int evnetType);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_get_layout")]
+ internal static extern ErrorCode GetLayout(NotificationSafeHandle handle, out NotificationLayout type);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_get_type")]
+ internal static extern ErrorCode GetType(NotificationSafeHandle handle, out NotificationType type);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_get_ongoing_value_type")]
+ internal static extern ErrorCode GetOngoingType(NotificationSafeHandle handle, out ProgressCategory category);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_get_size")]
+ internal static extern ErrorCode GetProgressSize(NotificationSafeHandle handle, out double value);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_get_progress")]
+ internal static extern ErrorCode GetProgress(NotificationSafeHandle handle, out double value);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_get_property")]
+ internal static extern ErrorCode GetProperties(NotificationSafeHandle handle, out int flags);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_get_extention_data")]
+ internal static extern ErrorCode GetExtender(NotificationSafeHandle handle, string key, out SafeBundleHandle value);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_clone")]
+ internal static extern ErrorCode GetClone(IntPtr handle, out IntPtr value);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_free_list")]
+ internal static extern ErrorCode NotificationListFree(IntPtr list);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_get_args")]
+ internal static extern ErrorCode GetExtentionBundle(NotificationSafeHandle handle, out IntPtr args, out IntPtr groupArgs);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_get_hide_timeout")]
+ internal static extern ErrorCode GetHideTimeout(NotificationSafeHandle handle, out int timeout);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_get_delete_timeout")]
+ internal static extern ErrorCode GetDeleteTimeout(NotificationSafeHandle handle, out int timeout);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_get_event_flag")]
+ internal static extern ErrorCode GetEventFlag(NotificationSafeHandle handle, out bool eventFlag);
+
+ [DllImport(Libraries.NotificationEventListener, EntryPoint = "notification_get_default_button")]
+ internal static extern ErrorCode GetDefaultButton(NotificationSafeHandle handle, out int index);
+
+ internal static ErrorCode GetAppId(NotificationSafeHandle handle, out string appid)
+ {
+ ErrorCode err;
+ IntPtr ptr;
+ err = GetAppIdReferenceType(handle, out ptr);
+
+ if (ptr == IntPtr.Zero)
+ {
+ appid = null;
+ }
+ else
+ {
+ appid = Marshal.PtrToStringAnsi(ptr);
+ }
+
+ return err;
+ }
+
+ internal static ErrorCode GetText(NotificationSafeHandle handle, NotificationText type, out string text)
+ {
+ ErrorCode err;
+ IntPtr ptr;
+ err = GetTextReferenceType(handle, type, out ptr);
+
+ if (ptr == IntPtr.Zero)
+ {
+ text = null;
+ }
+ else
+ {
+ text = Marshal.PtrToStringAnsi(ptr);
+ }
+
+ return err;
+ }
+
+ internal static ErrorCode GetImage(NotificationSafeHandle handle, NotificationImage type, out string text)
+ {
+ ErrorCode err;
+ IntPtr ptr;
+ err = GetImageReferenceType(handle, type, out ptr);
+
+ if (ptr == IntPtr.Zero)
+ {
+ text = null;
+ }
+ else
+ {
+ text = Marshal.PtrToStringAnsi(ptr);
+ }
+
+ return err;
+ }
+
+ internal static ErrorCode GetSound(NotificationSafeHandle handle, out AccessoryOption type, out string path)
+ {
+ ErrorCode err;
+ IntPtr ptr;
+ err = GetSoundReferenceType(handle, out type, out ptr);
+
+ if (ptr == IntPtr.Zero)
+ {
+ path = null;
+ }
+ else
+ {
+ path = Marshal.PtrToStringAnsi(ptr);
+ }
+
+ return err;
+ }
+
+ internal static ErrorCode GetVibration(NotificationSafeHandle handle, out AccessoryOption type, out string path)
+ {
+ ErrorCode err;
+ IntPtr ptr;
+ err = GetVibrationReferenceType(handle, out type, out ptr);
+
+ if (ptr == IntPtr.Zero)
+ {
+ path = null;
+ }
+ else
+ {
+ path = Marshal.PtrToStringAnsi(ptr);
+ }
+
+ return err;
+ }
+
+ internal static ErrorCode GetTag(NotificationSafeHandle handle, out string tag)
+ {
+ ErrorCode err;
+ IntPtr ptr;
+ err = GetTagReferenceType(handle, out ptr);
+
+ if (ptr == IntPtr.Zero)
+ {
+ tag = null;
+ }
+ else
+ {
+ tag = Marshal.PtrToStringAnsi(ptr);
+ }
+
+ return err;
+ }
+
+ internal sealed class NotificationSafeHandle : SafeHandle
+ {
+ public NotificationSafeHandle()
+ : base(IntPtr.Zero, true)
+ {
+ }
+
+ internal NotificationSafeHandle(IntPtr existingHandle, bool ownsHandle) : base(IntPtr.Zero, ownsHandle)
+ {
+ SetHandle(existingHandle);
+ }
+
+ public override bool IsInvalid
+ {
+ get { return this.handle == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ NotificationEventListener.Destroy(this.handle);
+ this.SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener.csproj b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener.csproj
new file mode 100755
index 0000000..99f4360
--- /dev/null
+++ b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener.csproj
@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen.Applications.Common\Tizen.Applications.Common.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationAccessoryArgsBinder.cs b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationAccessoryArgsBinder.cs
new file mode 100755
index 0000000..30dd573
--- /dev/null
+++ b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationAccessoryArgsBinder.cs
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.NotificationEventListener
+{
+ internal static class NotificationAccessoryAgsBinder
+ {
+ internal static void BindObject(NotificationEventArgs eventargs)
+ {
+ AccessoryOption type;
+ int color;
+ string path;
+
+ NotificationEventArgs.AccessoryArgs accessory = new NotificationEventArgs.AccessoryArgs();
+
+ Interop.NotificationEventListener.GetLed(eventargs.Handle, out type, out color);
+ accessory.LedOption = type;
+ if (type != AccessoryOption.Off)
+ {
+ int on, off;
+
+ Interop.NotificationEventListener.GetLedTime(eventargs.Handle, out on, out off);
+ accessory.LedOnMillisecond = on;
+ accessory.LedOffMillisecond = off;
+
+ if (type == AccessoryOption.Custom)
+ {
+ accessory.LedColor = new Common.Color(color >> 16 & 255, color >> 8 & 255, color >> 0 & 255, color >> 24 & 255);
+ }
+ }
+
+ Interop.NotificationEventListener.GetSound(eventargs.Handle, out type, out path);
+ accessory.SoundOption = type;
+ if (type == AccessoryOption.Custom)
+ {
+ accessory.SoundPath = path;
+ }
+
+ Interop.NotificationEventListener.GetVibration(eventargs.Handle, out type, out path);
+ if (type == AccessoryOption.Off)
+ {
+ accessory.CanVibrate = false;
+ }
+ else
+ {
+ accessory.CanVibrate = true;
+ }
+
+ eventargs.Accessory = accessory;
+ }
+ }
+}
diff --git a/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationButtonActionArgsBinder.cs b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationButtonActionArgsBinder.cs
new file mode 100755
index 0000000..e252015
--- /dev/null
+++ b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationButtonActionArgsBinder.cs
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.NotificationEventListener
+{
+ internal static class NotificationButtonActionArgBinder
+ {
+ internal static void BindObject(NotificationEventArgs eventargs, int index)
+ {
+ string text;
+ bool isExisted = false;
+ SafeAppControlHandle appcontrol = null;
+ NotificationEventArgs.ButtonActionArgs button = new NotificationEventArgs.ButtonActionArgs();
+
+ button.Index = (ButtonIndex)index;
+
+ Interop.NotificationEventListener.GetImage(eventargs.Handle, NotificationImage.Button_1 + index, out text);
+ if (string.IsNullOrEmpty(text) == false)
+ {
+ isExisted = true;
+ button.ImagePath = text;
+ }
+
+ Interop.NotificationEventListener.GetText(eventargs.Handle, NotificationText.FirstButton + index, out text);
+ if (string.IsNullOrEmpty(text) == false)
+ {
+ isExisted = true;
+ button.Text = text;
+ }
+
+ Interop.NotificationEventListener.GetEventHandler(eventargs.Handle, index, out appcontrol);
+
+ if (appcontrol != null && appcontrol.IsInvalid == false)
+ {
+ button.Action = new AppControl(appcontrol);
+ isExisted = true;
+ }
+
+ if (isExisted)
+ {
+ (eventargs.Style["Active"] as NotificationEventArgs.ActiveStyleArgs).Button.Add(button);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationDeleteEventArgs.cs b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationDeleteEventArgs.cs
new file mode 100755
index 0000000..5d05883
--- /dev/null
+++ b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationDeleteEventArgs.cs
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.NotificationEventListener
+{
+ using System;
+ /// <summary>
+ /// This class provides the property to get information about the deleted notification.
+ /// </summary>
+ public class NotificationDeleteEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Gets the unique number of the Notification.
+ /// </summary>
+ public int UniqueNumber { get; internal set; }
+ }
+}
diff --git a/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationDeleteEventArgsBinder.cs b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationDeleteEventArgsBinder.cs
new file mode 100755
index 0000000..35108cd
--- /dev/null
+++ b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationDeleteEventArgsBinder.cs
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.NotificationEventListener
+{
+ internal static class NotificationDeleteEventArgsBinder
+ {
+ internal static NotificationDeleteEventArgs BindObject(int uniqueNumber)
+ {
+ NotificationDeleteEventArgs deleteargs = new NotificationDeleteEventArgs();
+
+ deleteargs.UniqueNumber = uniqueNumber;
+
+ return deleteargs;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgs.cs b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgs.cs
new file mode 100755
index 0000000..9f348f6
--- /dev/null
+++ b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgs.cs
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.NotificationEventListener
+{
+ using System;
+ using System.Collections.Generic;
+ using System.ComponentModel;
+
+ /// <summary>
+ /// This class provides the methods and properties to get information about the posted or updated notification.
+ /// </summary>
+ public partial class NotificationEventArgs : EventArgs
+ {
+ private const string LogTag = "Tizen.Applications.NotificationEventListener";
+
+ internal IDictionary<string, StyleArgs> Style;
+ internal IDictionary<string, Bundle> Extender;
+ internal Interop.NotificationEventListener.NotificationSafeHandle Handle;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="NotificationEventArgs"/> class.
+ /// </summary>
+ public NotificationEventArgs()
+ {
+ Style = new Dictionary<string, StyleArgs>();
+ Extender = new Dictionary<string, Bundle>();
+ }
+
+ /// <summary>
+ /// Gets the unique id of Notification.
+ /// </summary>
+ public int UniqueNumber { get; internal set; }
+
+ /// <summary>
+ /// Gets the appId of Notification.
+ /// </summary>
+ public string AppID { get; internal set; }
+
+ /// <summary>
+ /// Gets the title of Notification.
+ /// </summary>
+ public string Title { get; internal set; }
+
+ /// <summary>
+ /// Gets the content text of Notification.
+ /// </summary>
+ public string Content { get; internal set; }
+
+ /// <summary>
+ /// Gets the icon's path of Notification.
+ /// </summary>
+ public string Icon { get; internal set; }
+
+ /// <summary>
+ /// Gets the sub icon path of Notification.
+ /// </summary>
+ public string SubIcon { get; internal set; }
+
+ /// <summary>
+ /// Gets the Timestamp of notification is visible or not.
+ /// </summary>
+ public bool IsTimeStampVisible { get; internal set; }
+
+ /// <summary>
+ /// Gets TimeStamp of Notification.
+ /// </summary>
+ /// <remarks>
+ /// If IsTimeStampVisible property is set false, this TimeStamp property is meanless.
+ /// </remarks>
+ public DateTime TimeStamp { get; internal set; }
+
+ /// <summary>
+ /// Gets the count which is displayed at the right side of notification.
+ /// </summary>
+ public int Count { get; internal set; }
+
+ /// <summary>
+ /// Gets the Tag of notification.
+ /// </summary>
+ public string Tag { get; internal set; }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public bool IsOngoing { get; internal set; } = false;
+
+ /// <summary>
+ /// Gets a value that determines whether notification is displayed on the default viewer.
+ /// If IsDisplay property set false and add style, you can see only style notification.
+ /// </summary>
+ public bool IsDisplay { get; internal set; } = true;
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public bool HasEventFlag { get; internal set; } = false;
+
+ /// <summary>
+ /// Gets the AppControl which is invoked when notification is clicked.
+ /// </summary>
+ public AppControl Action { get; internal set; }
+
+ /// <summary>
+ /// Gets the object of the progress notification.
+ /// </summary>
+ public ProgressArgs Progress { get; internal set; }
+
+ /// <summary>
+ /// Gets the AccessoryArgs which has option of Sound, Vibration, LED.
+ /// </summary>
+ public AccessoryArgs Accessory { get; internal set; }
+
+ /// <summary>
+ /// Gets the key for extender.
+ /// </summary>
+ public ICollection<string> ExtenderKey
+ {
+ get
+ {
+ return Extender.Keys;
+ }
+ }
+
+ /// <summary>
+ /// Gets the property.
+ /// </summary>
+ public NotificationProperty Property { get; internal set; }
+
+ /// <summary>
+ /// Gets the styleArgs of active, lock, indicator, bigpicture.
+ /// </summary>
+ /// <typeparam name="T">Type of notification style to be queried</typeparam>
+ /// <returns>The NotificationEventListener.StyleArgs object associated with the given style</returns>
+ /// <exception cref="ArgumentException">Thrown when argument is invalid</exception>
+ public T GetStyle<T>() where T : StyleArgs, new()
+ {
+ T type = new T();
+ StyleArgs style = null;
+
+ Style.TryGetValue(type.Key, out style);
+
+ if (style == null)
+ {
+ Log.Error(LogTag, "Invalid Style");
+ throw NotificationEventListenerErrorFactory.GetException(Interop.NotificationEventListener.ErrorCode.InvalidParameter, "invalid parameter entered");
+ }
+ else
+ {
+ return style as T;
+ }
+ }
+
+ /// <summary>
+ /// Gets the ExtenderArgs.
+ /// </summary>
+ /// <param name="key">The key that specifies which extender</param>
+ /// <returns>Returns the bundle for key</returns>
+ public Bundle GetExtender(string key)
+ {
+ Bundle bundle;
+
+ if (string.IsNullOrEmpty(key))
+ {
+ throw NotificationEventListenerErrorFactory.GetException(Interop.NotificationEventListener.ErrorCode.InvalidParameter, "invalid parameter entered");
+ }
+
+ if (Extender.TryGetValue(key, out bundle) == false)
+ {
+ throw NotificationEventListenerErrorFactory.GetException(Interop.NotificationEventListener.ErrorCode.InvalidParameter, "invalid parameter entered : " + key);
+ }
+
+ return bundle;
+ }
+ }
+}
diff --git a/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsAccessory.cs b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsAccessory.cs
new file mode 100755
index 0000000..b09398c
--- /dev/null
+++ b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsAccessory.cs
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.NotificationEventListener
+{
+ using Tizen.Common;
+
+ /// <summary>
+ /// This class provides the methods and properties to get information about the posted or updated notification.
+ /// </summary>
+ public partial class NotificationEventArgs
+ {
+ /// <summary>
+ /// Class to get infomation about Notification accessory.
+ /// </summary>
+ public class AccessoryArgs
+ {
+ /// <summary>
+ /// Gets the sound option.
+ /// </summary>
+ public AccessoryOption SoundOption { get; internal set; }
+
+ /// <summary>
+ /// Gets the sound path.
+ /// </summary>
+ public string SoundPath { get; internal set; }
+
+ /// <summary>
+ /// Gets the vibration option.
+ /// </summary>
+ public bool CanVibrate { get; internal set; }
+
+ /// <summary>
+ /// Gets the led option.
+ /// </summary>
+ public AccessoryOption LedOption { get; internal set; }
+
+ /// <summary>
+ /// Gets led on time period that you would like the LED on the device to blink. as well as the rate.
+ /// </summary>
+ /// <value>
+ /// Default value of LedOnMilliseconds is 0.
+ /// The rate is specified in terms of the number of milliseconds to be on.
+ /// </value>
+ public int LedOnMillisecond { get; internal set; }
+
+ /// <summary>
+ /// Gets led on time period that you would like the LED on the device to blink. as well as the rate.
+ /// </summary>
+ /// <value>
+ /// Default value of LedOffMillisecond is 0.
+ /// The rate is specified in terms of the number of millisecond to be off.
+ /// </value>
+ public int LedOffMillisecond { get; internal set; }
+
+ /// <summary>
+ /// Gets led color that you would like the LED on the device to blink.
+ /// </summary>
+ public Color LedColor { get; internal set; }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsActiveStyle.cs b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsActiveStyle.cs
new file mode 100755
index 0000000..7495ffc
--- /dev/null
+++ b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsActiveStyle.cs
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.NotificationEventListener
+{
+ using System.Collections.Generic;
+
+ /// <summary>
+ /// This class provides the methods and properties to get information about the posted or updated notification.
+ /// </summary>
+ public partial class NotificationEventArgs
+ {
+ /// <summary>
+ /// Class to get infomation about Notification Active style.
+ /// </summary>
+ public class ActiveStyleArgs : StyleArgs
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ActiveStyleArgs"/> class.
+ /// </summary>
+ public ActiveStyleArgs()
+ {
+ Button = new List<ButtonActionArgs>();
+ }
+
+ /// <summary>
+ /// Gets the IsAutoRemove option of the active notification.
+ /// IsAutoRemove option lets the active notification be removed several seconds after it shows.
+ /// </summary>
+ /// <value>
+ /// When 'IsAutoRemove' is set as false, the active notification will not be removed as long as the user removes
+ /// the active notification or the app which posted the active notification removes the active notification.
+ /// </value>
+ public bool IsAutoRemove { get; internal set; }
+
+ /// <summary>
+ /// Gets an absolute path for an image file to display on the background of active notification.
+ /// </summary>
+ public string BackgroundImage { get; internal set; }
+
+ /// <summary>
+ /// Gets the default button to display highlight on the active notification
+ /// </summary>
+ public ButtonIndex DefaultButton { get; internal set; }
+
+ /// <summary>
+ /// Gets timeout value in second when the notification can be hidden from the viewer.
+ /// </summary>
+ public int HideTimeout { get; internal set; }
+
+ /// <summary>
+ /// Gets timeout value in second when the notification can be deleted from the viewer.
+ /// </summary>
+ public int DeleteTimeout { get; internal set; }
+
+ /// <summary>
+ /// Gets a button to this active notification style.
+ /// Buttons are displayed in the notification content.
+ /// </summary>
+ public IList<ButtonActionArgs> Button { get; internal set; }
+
+ /// <summary>
+ /// Gets a ReplyAction to this active notification style.
+ /// </summary>
+ public ReplyActionArgs Reply { get; internal set; }
+
+ internal override string Key
+ {
+ get
+ {
+ return "Active";
+ }
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsBinder.cs b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsBinder.cs
new file mode 100755
index 0000000..e38f331
--- /dev/null
+++ b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsBinder.cs
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.NotificationEventListener
+{
+ using System;
+
+ internal static class NotificationEventArgsBinder
+ {
+ private const string LogTag = "Tizen.Applications.NotificationEventListener";
+
+ internal static NotificationEventArgs BindObject(IntPtr notification, bool data)
+ {
+ Interop.NotificationEventListener.ErrorCode err;
+ int time;
+ int uniqueNumber = -1;
+ int groupNumber = -1;
+ int property;
+ int doNotShowTimeStamp = -1;
+ int displayList;
+ bool eventFlag = false;
+ NotificationLayout layout;
+ NotificationType type;
+ string text;
+ IntPtr extention = IntPtr.Zero;
+ IntPtr dummy = IntPtr.Zero;
+ SafeAppControlHandle appcontrol = null;
+
+ NotificationEventArgs eventargs = new NotificationEventArgs();
+
+ eventargs.Handle = new Interop.NotificationEventListener.NotificationSafeHandle(notification, data);
+
+ err = Interop.NotificationEventListener.GetID(eventargs.Handle, out groupNumber, out uniqueNumber);
+ if (err != Interop.NotificationEventListener.ErrorCode.None)
+ {
+ Log.Error(LogTag, "unable to get UniqueNumber");
+ }
+
+ eventargs.UniqueNumber = uniqueNumber;
+
+ Interop.NotificationEventListener.GetAppId(eventargs.Handle, out text);
+ if (string.IsNullOrEmpty(text) == false)
+ {
+ eventargs.AppID = text;
+ }
+
+ Interop.NotificationEventListener.GetText(eventargs.Handle, NotificationText.Title, out text);
+ if (string.IsNullOrEmpty(text) == false)
+ {
+ eventargs.Title = text;
+ }
+
+ Interop.NotificationEventListener.GetText(eventargs.Handle, NotificationText.Content, out text);
+ if (string.IsNullOrEmpty(text) == false)
+ {
+ eventargs.Content = text;
+ }
+
+ Interop.NotificationEventListener.GetImage(eventargs.Handle, NotificationImage.Icon, out text);
+ if (string.IsNullOrEmpty(text) == false)
+ {
+ eventargs.Icon = text;
+ }
+
+ Interop.NotificationEventListener.GetImage(eventargs.Handle, NotificationImage.SubIcon, out text);
+ if (string.IsNullOrEmpty(text) == false)
+ {
+ eventargs.SubIcon = text;
+ }
+
+ err = Interop.NotificationEventListener.GetTime(eventargs.Handle, out time);
+ if (err != Interop.NotificationEventListener.ErrorCode.None)
+ {
+ Log.Info(LogTag, "unable to get TimeStamp");
+ }
+
+ if (time == doNotShowTimeStamp)
+ {
+ eventargs.IsTimeStampVisible = false;
+ }
+ else
+ {
+ eventargs.IsTimeStampVisible = true;
+
+ if (time == 0)
+ {
+ err = Interop.NotificationEventListener.GetInsertTime(eventargs.Handle, out time);
+ if (err != Interop.NotificationEventListener.ErrorCode.None)
+ {
+ Log.Info(LogTag, "unable to get InsertTime");
+ }
+ }
+
+ eventargs.TimeStamp = (new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).AddSeconds(time).ToLocalTime();
+ }
+
+ err = Interop.NotificationEventListener.GetText(eventargs.Handle, NotificationText.EventCount, out text);
+ if (err != Interop.NotificationEventListener.ErrorCode.None)
+ {
+ Log.Info(LogTag, "unable to get Event Count");
+ }
+
+ if (string.IsNullOrEmpty(text) == false)
+ {
+ try
+ {
+ eventargs.Count = int.Parse(text);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(LogTag, ex.ToString());
+ }
+ }
+
+ err = Interop.NotificationEventListener.GetAppControl(eventargs.Handle, LaunchOption.AppControl, out appcontrol);
+ if (err != Interop.NotificationEventListener.ErrorCode.None)
+ {
+ Log.Info(LogTag, "unable to get Action");
+ }
+
+ if (appcontrol != null && appcontrol.IsInvalid == false)
+ {
+ eventargs.Action = new AppControl(appcontrol);
+ }
+
+ Interop.NotificationEventListener.GetTag(eventargs.Handle, out text);
+ if (string.IsNullOrEmpty(text) == false)
+ {
+ eventargs.Tag = text;
+ }
+
+ err = Interop.NotificationEventListener.GetProperties(eventargs.Handle, out property);
+ if (err != Interop.NotificationEventListener.ErrorCode.None)
+ {
+ Log.Info(LogTag, "unable to get Property");
+ }
+ else
+ {
+ eventargs.Property = (NotificationProperty)property;
+ }
+
+ Interop.NotificationEventListener.GetStyleList(eventargs.Handle, out displayList);
+ if ((displayList & (int)NotificationDisplayApplist.Tray) == 0)
+ {
+ eventargs.IsDisplay = false;
+ }
+
+ err = Interop.NotificationEventListener.GetExtentionBundle(eventargs.Handle, out extention, out dummy);
+ if (err != Interop.NotificationEventListener.ErrorCode.None)
+ {
+ Log.Info(LogTag, "unable to get Extender");
+ }
+
+ if (extention != IntPtr.Zero)
+ {
+ Bundle bundle = new Bundle(new SafeBundleHandle(extention, false));
+ foreach (string key in bundle.Keys)
+ {
+ SafeBundleHandle sbh;
+ Interop.NotificationEventListener.GetExtender(eventargs.Handle, key, out sbh);
+ eventargs.Extender.Add(key, new Bundle(sbh));
+ }
+ }
+
+ err = Interop.NotificationEventListener.GetLayout(eventargs.Handle, out layout);
+ if (err != Interop.NotificationEventListener.ErrorCode.None)
+ {
+ Log.Info(LogTag, "unable to get layout");
+ }
+
+ err = Interop.NotificationEventListener.GetType(eventargs.Handle, out type);
+ if (err != Interop.NotificationEventListener.ErrorCode.None)
+ {
+ Log.Info(LogTag, "unable to get type");
+ }
+
+ if (layout == NotificationLayout.OngoingEvent && type == NotificationType.Ongoing)
+ {
+ eventargs.IsOngoing = true;
+ }
+
+ err = Interop.NotificationEventListener.GetEventFlag(eventargs.Handle, out eventFlag);
+ if (err != Interop.NotificationEventListener.ErrorCode.None)
+ {
+ Log.Info(LogTag, "unable to get event flag");
+ }
+
+ eventargs.HasEventFlag = eventFlag;
+
+ NotificationAccessoryAgsBinder.BindObject(eventargs);
+ NotificationStyleArgBinder.BindObject(eventargs);
+ NotificationProgressArgBinder.BindObject(eventargs);
+
+ return eventargs;
+ }
+ }
+}
diff --git a/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsButtonAction.cs b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsButtonAction.cs
new file mode 100755
index 0000000..2e39158
--- /dev/null
+++ b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsButtonAction.cs
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.NotificationEventListener
+{
+ /// <summary>
+ /// This class provides the methods and properties to get information about the posted or updated notification.
+ /// </summary>
+ public partial class NotificationEventArgs
+ {
+ /// <summary>
+ /// Class to get infomation about Notification ButtonAction.
+ /// </summary>
+ public class ButtonActionArgs
+ {
+ /// <summary>
+ /// Gets the Index of the Button which is appeared at Notification.
+ /// </summary>
+ public ButtonIndex Index { get; internal set; }
+
+ /// <summary>
+ /// Gets the text that describes the button.
+ /// </summary>
+ public string Text { get; internal set; }
+
+ /// <summary>
+ /// Gets the image's path that represent the button.
+ /// </summary>
+ public string ImagePath { get; internal set; }
+
+ /// <summary>
+ /// Gets the AppControl that is invoked when the button is clicked.
+ /// </summary>
+ public AppControl Action { get; internal set; }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsEnumerations.cs b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsEnumerations.cs
new file mode 100755
index 0000000..348a016
--- /dev/null
+++ b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsEnumerations.cs
@@ -0,0 +1,488 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.NotificationEventListener
+{
+ using System;
+ using System.ComponentModel;
+
+ /// <summary>
+ /// Enumeration for Progress category
+ /// </summary>
+ public enum ProgressCategory
+ {
+ /// <summary>
+ /// Value for percent type
+ /// </summary>
+ Percent,
+
+ /// <summary>
+ /// Value for time type
+ /// </summary>
+ Time,
+
+ /// <summary>
+ /// Value for pending type which is not updated progress current value
+ /// </summary>
+ PendingBar
+ }
+
+ /// <summary>
+ /// Enumeration for Accessory option
+ /// </summary>
+ public enum AccessoryOption
+ {
+ /// <summary>
+ /// Value for off accessory option
+ /// </summary>
+ Off = -1,
+
+ /// <summary>
+ /// Value for on accessory option
+ /// </summary>
+ On,
+
+ /// <summary>
+ /// Value for custom accessory option
+ /// </summary>
+ Custom
+ }
+
+ /// <summary>
+ /// Enumeration for Button Index
+ /// </summary>
+ public enum ButtonIndex
+ {
+ /// <summary>
+ /// Value for default button index
+ /// </summary>
+ None = -1,
+
+ /// <summary>
+ /// Value for first button index
+ /// </summary>
+ First,
+
+ /// <summary>
+ /// Value for second button index
+ /// </summary>
+ Second,
+
+ /// <summary>
+ /// Value for third button index
+ /// </summary>
+ Third
+ }
+
+ /// <summary>
+ /// Enumeration for notification particular property
+ /// </summary>
+ [Flags]
+ public enum NotificationProperty
+ {
+ /// <summary>
+ /// Value for adjust nothing
+ /// </summary>
+ None = 0x00,
+
+ /// <summary>
+ /// Value for display only SIM card inserted
+ /// </summary>
+ DisplayOnlySimMode = 0x01,
+
+ /// <summary>
+ /// Value for disable application launch when it selected
+ /// </summary>
+ DisableAppLaunch = 0x02,
+
+ /// <summary>
+ /// Value for disable auto delete when it selected
+ /// </summary>
+ DisableAutoDelete = 0x04,
+
+ /// <summary>
+ /// Value for deleted when device is rebooted even though notification is not set OngoingType
+ /// </summary>
+ VolatileDisplay = 0x100,
+ }
+
+ /// <summary>
+ /// Enumeration for event type on notification.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public enum UserEventType
+ {
+ /// <summary>
+ /// Event type : Click on button 1
+ /// </summary>
+ ClickOnButton1 = 0,
+
+ /// <summary>
+ /// Event type : Click on button 2
+ /// </summary>
+ ClickOnButton2,
+
+ /// <summary>
+ /// Event type : Click on button 3
+ /// </summary>
+ ClickOnButton3,
+
+ /// <summary>
+ /// Event type : Click on text_input button
+ /// </summary>
+ ClickOnReplyButton = 8,
+
+ /// <summary>
+ /// Event type : Hidden by user
+ /// </summary>
+ HiddenByUser = 100,
+
+ /// <summary>
+ /// Event type : Deleted by timer
+ /// </summary>
+ HiddenByTimeout = 101,
+
+ /// <summary>
+ /// Event type : Clicked by user
+ /// </summary>
+ ClickOnNotification = 200,
+
+ /// <summary>
+ /// Event type : Deleted by user
+ /// </summary>
+ DeleteNotification = 201,
+ }
+
+ /// <summary>
+ /// Enumeration for notification type.
+ /// </summary>
+ internal enum NotificationType
+ {
+ /// <summary>
+ /// Notification type
+ /// </summary>
+ Notification = 0,
+
+ /// <summary>
+ /// Ongoing type
+ /// </summary>
+ Ongoing,
+ }
+
+ /// <summary>
+ /// Enumeration for notification text type.
+ /// </summary>
+ internal enum NotificationText
+ {
+ /// <summary>
+ /// Title
+ /// </summary>
+ Title = 0,
+
+ /// <summary>
+ /// Content
+ /// </summary>
+ Content,
+
+ /// <summary>
+ /// Text to display event count
+ /// </summary>
+ EventCount = 3,
+
+ /// <summary>
+ /// Box contents 1
+ /// </summary>
+ FirstMainText,
+
+ /// <summary>
+ /// Box contents 1-1
+ /// </summary>
+ FirstSubText,
+
+ /// <summary>
+ /// Box contents 2
+ /// </summary>
+ SecondMainText,
+
+ /// <summary>
+ /// Box contents 2-1
+ /// </summary>
+ SecondSubText,
+
+ /// <summary>
+ /// Text on button 1
+ /// </summary>
+ FirstButton = 13,
+
+ /// <summary>
+ /// Text on button 2
+ /// </summary>
+ SecondButton,
+
+ /// <summary>
+ /// Text on button 3
+ /// </summary>
+ ThirdButton,
+
+ /// <summary>
+ /// Guide text on the message reply box
+ /// </summary>
+ PlaceHolder = 19,
+
+ /// <summary>
+ /// Text on button the on message reply box
+ /// </summary>
+ InputButton = 20,
+ }
+
+ /// <summary>
+ /// Enumeration for image type.
+ /// </summary>
+ internal enum NotificationImage
+ {
+ /// <summary>
+ /// Icon
+ /// </summary>
+ Icon = 0,
+
+ /// <summary>
+ /// Indicator icon
+ /// </summary>
+ Indicator,
+
+ /// <summary>
+ /// Lock screen icon
+ /// </summary>
+ Lockscreen,
+
+ /// <summary>
+ /// Thumbnail
+ /// </summary>
+ Thumbnail,
+
+ /// <summary>
+ /// Lock screen thumbnail
+ /// </summary>
+ ThumbnailLockscreen,
+
+ /// <summary>
+ /// Icon
+ /// </summary>
+ SubIcon,
+
+ /// <summary>
+ /// image displayed on background
+ /// </summary>
+ Background,
+
+ /// <summary>
+ /// Image for button 1
+ /// </summary>
+ Button_1 = 12,
+
+ /// <summary>
+ /// Image for button 2
+ /// </summary>
+ Button_2,
+
+ /// <summary>
+ /// Image for button 3
+ /// </summary>
+ Button_3,
+
+ /// <summary>
+ /// Image for message reply
+ /// </summary>
+ TextInputButton = 18,
+ }
+
+ /// <summary>
+ /// Enumeration for notification layout type.
+ /// </summary>
+ internal enum NotificationLayout
+ {
+ /// <summary>
+ /// Default
+ /// </summary>
+ None = 0,
+
+ /// <summary>
+ /// Layout for notification. Used to inform single event
+ /// </summary>
+ SingleEvent = 1,
+
+ /// <summary>
+ /// Layout for notification. Used to display images
+ /// </summary>
+ Thumbnail = 3,
+
+ /// <summary>
+ /// Layout for ongoing notification. Used to display text message
+ /// </summary>
+ OngoingEvent = 4,
+
+ /// <summary>
+ /// Layout for ongoing notification. Used to display progress
+ /// </summary>
+ OngoingProgress = 5,
+ }
+
+ /// <summary>
+ /// Enumeration for notification launch option type.
+ /// </summary>
+ internal enum LaunchOption
+ {
+ /// <summary>
+ /// Launching with app control
+ /// </summary>
+ AppControl = 1
+ }
+
+ /// <summary>
+ /// Enumeration for notification operation data code.
+ /// </summary>
+ internal enum NotificationOperationDataType
+ {
+ /// <summary>
+ /// Default
+ /// </summary>
+ Min = 0,
+
+ /// <summary>
+ /// Operation type
+ /// </summary>
+ Type,
+
+ /// <summary>
+ /// Private ID
+ /// </summary>
+ UniqueNumber,
+
+ /// <summary>
+ /// Notification handler
+ /// </summary>
+ Notification,
+
+ /// <summary>
+ /// Reserved
+ /// </summary>
+ ExtraInformation1,
+
+ /// <summary>
+ /// Reserved
+ /// </summary>
+ ExtraInformation2,
+ }
+
+ /// <summary>
+ /// Enumeration for notification operation code.
+ /// </summary>
+ internal enum NotificationOperationType
+ {
+ /// <summary>
+ /// Default
+ /// </summary>
+ None = 0,
+
+ /// <summary>
+ /// Notification inserted
+ /// </summary>
+ Insert,
+
+ /// <summary>
+ /// Notification updated
+ /// </summary>
+ Update,
+
+ /// <summary>
+ /// Notification deleted
+ /// </summary>
+ Delete,
+ }
+
+ /// <summary>
+ /// Enumeration for event type on notification.
+ /// </summary>
+ internal enum ClickEventType
+ {
+ /// <summary>
+ /// Event type : Click on button 1
+ /// </summary>
+ FirstButton = 0,
+
+ /// <summary>
+ /// Event type : Click on button 2
+ /// </summary>
+ SecondButton = 1,
+
+ /// <summary>
+ /// Event type : Click on button 3
+ /// </summary>
+ ThirdButton = 2,
+
+ /// <summary>
+ /// Event type : Click on icon
+ /// </summary>
+ Icon = 6,
+
+ /// <summary>
+ /// Event type : Click on thumbnail
+ /// </summary>
+ Thumbnail = 7,
+
+ /// <summary>
+ /// Event type : Click on text_input button
+ /// </summary>
+ InputButton = 8,
+ }
+
+ /// <summary>
+ /// Enumeration for display application list.
+ /// </summary>
+ [Flags]
+ internal enum NotificationDisplayApplist
+ {
+ /// <summary>
+ /// Notification Tray(Quickpanel)
+ /// </summary>
+ Tray = 0x00000001,
+
+ /// <summary>
+ /// Ticker notification
+ /// </summary>
+ Ticker = 0x00000002,
+
+ /// <summary>
+ /// Lock screen
+ /// </summary>
+ Lock = 0x00000004,
+
+ /// <summary>
+ /// Indicator
+ /// </summary>
+ Indicator = 0x00000008,
+
+ /// <summary>
+ /// Active notification
+ /// </summary>
+ Active = 0x00000010,
+
+ /// <summary>
+ /// All display application except active notification
+ /// </summary>
+ All = 0x0000000f,
+ }
+}
diff --git a/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsIndicatorStyle.cs b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsIndicatorStyle.cs
new file mode 100755
index 0000000..bc04cf1
--- /dev/null
+++ b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsIndicatorStyle.cs
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.NotificationEventListener
+{
+ /// <summary>
+ /// This class provides the methods and properties to get information about the posted or updated notification.
+ /// </summary>
+ public partial class NotificationEventArgs
+ {
+ /// <summary>
+ /// Class to generate the Indicator style notification.
+ /// </summary>
+ public class IndicatorStyleArgs : StyleArgs
+ {
+ /// <summary>
+ /// Gets the path of the image file to display on the icon of Indicator style.
+ /// </summary>
+ public string IconPath { get; internal set; }
+
+ /// <summary>
+ /// Gets the sub text to display Indicator style.
+ /// </summary>
+ public string SubText { get; internal set; }
+
+ internal override string Key
+ {
+ get
+ {
+ return "Indicator";
+ }
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsLockStyle.cs b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsLockStyle.cs
new file mode 100755
index 0000000..62ca496
--- /dev/null
+++ b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsLockStyle.cs
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.NotificationEventListener
+{
+ /// <summary>
+ /// This class provides the methods and properties to get information about the posted or updated notification.
+ /// </summary>
+ public partial class NotificationEventArgs
+ {
+ /// <summary>
+ /// Class to get infomation about Notification Lock style.
+ /// </summary>
+ public class LockStyleArgs : StyleArgs
+ {
+ /// <summary>
+ /// Gets the path of the image file to display on the icon of Lock style.
+ /// </summary>
+ public string IconPath { get; internal set; }
+
+ /// <summary>
+ /// Gets the path of the thumbnail image file to display on the icon of Lock style.
+ /// </summary>
+ public string Thumbnail { get; internal set; }
+
+ internal override string Key
+ {
+ get
+ {
+ return "Lock";
+ }
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsProgress.cs b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsProgress.cs
new file mode 100755
index 0000000..ed01380
--- /dev/null
+++ b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsProgress.cs
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.NotificationEventListener
+{
+ /// <summary>
+ /// This class provides the methods and properties to get information about the posted or updated notification.
+ /// </summary>
+ public partial class NotificationEventArgs
+ {
+ /// <summary>
+ /// Class to get infomation about Progress Notification.
+ /// </summary>
+ public class ProgressArgs
+ {
+ /// <summary>
+ /// Gets category of ProgressType.
+ /// </summary>
+ public ProgressCategory Category { get; internal set; }
+
+ /// <summary>
+ /// Gets current value of ProgressType.
+ /// </summary>
+ public double Current { get; internal set; }
+
+ /// <summary>
+ /// Gets max value of ProgressType.
+ /// </summary>
+ public double Max { get; internal set; }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsReplyAction.cs b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsReplyAction.cs
new file mode 100755
index 0000000..d96ebf0
--- /dev/null
+++ b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsReplyAction.cs
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.NotificationEventListener
+{
+ /// <summary>
+ /// This class provides the methods and properties to get information about the posted or updated notification.
+ /// </summary>
+ public partial class NotificationEventArgs
+ {
+ /// <summary>
+ /// Class to get infomation about Notification ReplyAction.
+ /// </summary>
+ public class ReplyActionArgs
+ {
+ /// <summary>
+ /// Gets Index of Button which is appeared at Notification.
+ /// If there is no ParentIndex, the ReplyAction should be displayed directly on the active notification.
+ /// </summary>
+ public ButtonIndex ParentIndex { get; internal set; } = ButtonIndex.None;
+
+ /// <summary>
+ /// Gets the PlaceHolderText of ReplyAction which is appeared at Notification.
+ /// It will be displayed to the text input box on the active notification.
+ /// </summary>
+ public string PlaceHolderText { get; internal set; }
+
+ /// <summary>
+ /// Gets a max length of text input.
+ /// </summary>
+ public int ReplyMax { get; internal set; }
+
+ /// <summary>
+ /// Gets the button displayed in the replyaction.
+ /// </summary>
+ public ButtonActionArgs Button { get; internal set; }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsStyle.cs b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsStyle.cs
new file mode 100755
index 0000000..5ba07c7
--- /dev/null
+++ b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventArgsStyle.cs
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.NotificationEventListener
+{
+ /// <summary>
+ /// This class provides the methods and properties to get information about the posted or updated notification.
+ /// </summary>
+ public partial class NotificationEventArgs
+ {
+ public abstract class StyleArgs
+ {
+ internal abstract string Key { get; }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventListenerErrorFactory.cs b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventListenerErrorFactory.cs
new file mode 100755
index 0000000..8a6bbcb
--- /dev/null
+++ b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationEventListenerErrorFactory.cs
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.NotificationEventListener
+{
+ using System;
+ using System.Runtime.CompilerServices;
+
+ internal static class NotificationEventListenerErrorFactory
+ {
+ private const string LogTag = "Tizen.Applications.NotificationEventListener";
+
+ internal static Exception GetException(
+ Interop.NotificationEventListener.ErrorCode err,
+ string msg,
+ [CallerMemberName] string memberName = "",
+ [CallerFilePath] string filePath = "",
+ [CallerLineNumber] int lineNumber = 0)
+ {
+ Log.Error(LogTag, memberName + " : " + lineNumber);
+ switch (err)
+ {
+ case Interop.NotificationEventListener.ErrorCode.InvalidParameter:
+ Log.Error(LogTag, msg);
+ return new ArgumentException(err + " error occurred.");
+ case Interop.NotificationEventListener.ErrorCode.PermissionDenied:
+ Log.Error(LogTag, msg);
+ return new UnauthorizedAccessException(err + "Permission denied.");
+ default:
+ Log.Error(LogTag, msg);
+ return new InvalidOperationException(err + " error occurred.");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationListenerManager.cs b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationListenerManager.cs
new file mode 100755
index 0000000..5f02395
--- /dev/null
+++ b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationListenerManager.cs
@@ -0,0 +1,417 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.NotificationEventListener
+{
+ using System;
+ using System.Collections.Generic;
+ using System.ComponentModel;
+ using System.Runtime.InteropServices;
+
+ /// <summary>
+ /// This class provides a way to register callback function for some notification events.
+ /// </summary>
+ /// <remarks>
+ /// The event listener can use this class to get a list of notification or to clear notifications.
+ /// </remarks>
+ public partial class NotificationListenerManager
+ {
+ private const string LogTag = "Tizen.Applications.NotificationEventListener";
+
+ private static event EventHandler<NotificationEventArgs> AddEventHandler;
+
+ private static event EventHandler<NotificationEventArgs> UpdateEventHandler;
+
+ private static event EventHandler<NotificationDeleteEventArgs> DeleteEventHandler;
+
+ private static Interop.NotificationEventListener.ChangedCallback callback;
+
+ [StructLayout(LayoutKind.Sequential)]
+ private struct NotificationOperation
+ {
+ NotificationOperationType type;
+ int uniqueNumber;
+ int extraInformation1;
+ int extraInformation2;
+ IntPtr notification;
+ }
+
+ private static int GetEventHandleLength()
+ {
+ int length = 0;
+
+ length += (DeleteEventHandler == null) ? 0 : DeleteEventHandler.GetInvocationList().Length;
+ length += (UpdateEventHandler == null) ? 0 : UpdateEventHandler.GetInvocationList().Length;
+ length += (AddEventHandler == null) ? 0 : AddEventHandler.GetInvocationList().Length;
+
+ return length;
+ }
+
+ /// <summary>
+ /// Registers a callback for notification insert event.
+ /// </summary>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parameter.</exception>
+ /// <exception cref="UnauthorizedAccessException"> Thrown in case of Permission deny.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/notification</privilege>
+ public static event EventHandler<NotificationEventArgs> NotificationAddEventHandler
+ {
+ add
+ {
+ if (callback == null)
+ {
+ callback = new Interop.NotificationEventListener.ChangedCallback(ChangedEvent);
+ }
+
+ if (GetEventHandleLength() == 0)
+ {
+ Interop.NotificationEventListener.ErrorCode err = Interop.NotificationEventListener.SetChangedCallback(callback, IntPtr.Zero);
+ if (err != (int)Interop.NotificationEventListener.ErrorCode.None)
+ {
+ throw NotificationEventListenerErrorFactory.GetException(err, "unable to set changed callback");
+ }
+ }
+
+ AddEventHandler += value;
+ }
+
+ remove
+ {
+ if (AddEventHandler != null && AddEventHandler.GetInvocationList().Length > 0)
+ {
+ AddEventHandler -= value;
+
+ if (GetEventHandleLength() == 0)
+ {
+ Interop.NotificationEventListener.ErrorCode err = Interop.NotificationEventListener.UnsetChangedCallback(callback);
+ if (err != (int)Interop.NotificationEventListener.ErrorCode.None)
+ {
+ throw NotificationEventListenerErrorFactory.GetException(err, "unable to unset changed callback");
+ }
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Registers a callback for notification update event.
+ /// </summary>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parameter.</exception>
+ /// <exception cref="UnauthorizedAccessException"> Thrown in case of Permission deny.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/notification</privilege>
+ public static event EventHandler<NotificationEventArgs> NotificationUpdateEventHandler
+ {
+ add
+ {
+ if (callback == null)
+ {
+ callback = new Interop.NotificationEventListener.ChangedCallback(ChangedEvent);
+ }
+
+ if (GetEventHandleLength() == 0)
+ {
+ Interop.NotificationEventListener.ErrorCode err = Interop.NotificationEventListener.SetChangedCallback(callback, IntPtr.Zero);
+ if (err != Interop.NotificationEventListener.ErrorCode.None)
+ {
+ throw NotificationEventListenerErrorFactory.GetException(err, "unable to set changed callback");
+ }
+ }
+
+ UpdateEventHandler += value;
+ }
+
+ remove
+ {
+ if (UpdateEventHandler != null && UpdateEventHandler.GetInvocationList().Length > 0)
+ {
+ UpdateEventHandler -= value;
+
+ if (GetEventHandleLength() == 0)
+ {
+ Interop.NotificationEventListener.ErrorCode err = Interop.NotificationEventListener.UnsetChangedCallback(callback);
+ if (err != Interop.NotificationEventListener.ErrorCode.None)
+ {
+ throw NotificationEventListenerErrorFactory.GetException(err, "unable to unset changed callback");
+ }
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Registers a callback for notification delete event.
+ /// </summary>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parameter.</exception>
+ /// <exception cref="UnauthorizedAccessException"> Thrown in case of Permission deny.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/notification</privilege>
+ public static event EventHandler<NotificationDeleteEventArgs> NotificationDeleteEventHandler
+ {
+ add
+ {
+ if (callback == null)
+ {
+ callback = new Interop.NotificationEventListener.ChangedCallback(ChangedEvent);
+ }
+
+ if (GetEventHandleLength() == 0)
+ {
+ Interop.NotificationEventListener.ErrorCode err = Interop.NotificationEventListener.SetChangedCallback(callback, IntPtr.Zero);
+ if (err != Interop.NotificationEventListener.ErrorCode.None)
+ {
+ throw NotificationEventListenerErrorFactory.GetException(err, "unable to set changed callback");
+ }
+ }
+
+ DeleteEventHandler += value;
+ }
+
+ remove
+ {
+ if (DeleteEventHandler != null && DeleteEventHandler.GetInvocationList().Length > 0)
+ {
+ DeleteEventHandler -= value;
+
+ if (GetEventHandleLength() == 0)
+ {
+ Interop.NotificationEventListener.ErrorCode err = Interop.NotificationEventListener.UnsetChangedCallback(callback);
+ if (err != Interop.NotificationEventListener.ErrorCode.None)
+ {
+ throw NotificationEventListenerErrorFactory.GetException(err, "unable to unset changed callback");
+ }
+ }
+ }
+ }
+ }
+
+ private static void ChangedEvent(IntPtr userData, NotificationType type, IntPtr operationList, int num)
+ {
+ IntPtr operationType;
+ IntPtr uniqueNumber;
+ IntPtr notification;
+
+ NotificationEventArgs eventargs;
+ NotificationDeleteEventArgs deleteargs;
+
+ for (int i = 0; i < num; i++)
+ {
+ uniqueNumber = IntPtr.Zero;
+ operationType = IntPtr.Zero;
+ notification = IntPtr.Zero;
+
+ Interop.NotificationEventListener.GetOperationData(operationList + (i * Marshal.SizeOf<NotificationOperation>()), NotificationOperationDataType.Type, out operationType);
+ Interop.NotificationEventListener.GetOperationData(operationList + (i * Marshal.SizeOf<NotificationOperation>()), NotificationOperationDataType.UniqueNumber, out uniqueNumber);
+ Interop.NotificationEventListener.GetOperationData(operationList + (i * Marshal.SizeOf<NotificationOperation>()), NotificationOperationDataType.Notification, out notification);
+
+ if (operationType == IntPtr.Zero)
+ {
+ Log.Error(LogTag, "unable to get operationType");
+ continue;
+ }
+
+ Log.Info(LogTag, "type : " + ((int)operationType).ToString());
+ Log.Info(LogTag, "Add : " + (AddEventHandler == null ? "0" : AddEventHandler.GetInvocationList().Length.ToString()));
+ Log.Info(LogTag, "update: " + (UpdateEventHandler == null ? "0" : UpdateEventHandler.GetInvocationList().Length.ToString()));
+ Log.Info(LogTag, "delete : " + (DeleteEventHandler == null ? "0" : DeleteEventHandler.GetInvocationList().Length.ToString()));
+
+ switch ((int)operationType)
+ {
+ case (int)NotificationOperationType.Insert:
+ if (notification != IntPtr.Zero)
+ {
+ try
+ {
+ eventargs = NotificationEventArgsBinder.BindObject(notification, false);
+ AddEventHandler?.Invoke(null, eventargs);
+ }
+ catch (Exception e)
+ {
+ Log.Error(LogTag, e.Message);
+ }
+ }
+
+ break;
+
+ case (int)NotificationOperationType.Update:
+ if (notification != IntPtr.Zero)
+ {
+ try
+ {
+ eventargs = NotificationEventArgsBinder.BindObject(notification, false);
+ UpdateEventHandler?.Invoke(null, eventargs);
+ }
+ catch (Exception e)
+ {
+ Log.Error(LogTag, e.Message);
+ }
+ }
+
+ break;
+
+ case (int)NotificationOperationType.Delete:
+ if (uniqueNumber != IntPtr.Zero)
+ {
+ try
+ {
+ deleteargs = NotificationDeleteEventArgsBinder.BindObject((int)uniqueNumber);
+ DeleteEventHandler?.Invoke(null, deleteargs);
+ }
+ catch (Exception e)
+ {
+ Log.Error(LogTag, e.Message);
+ }
+ }
+
+ break;
+
+ default:
+ Log.Info(LogTag, "Event : " + (int)operationType);
+ break;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Deletes a Notification with appId and uniqueNumber.
+ /// </summary>
+ /// <param name="appId">The name of the application you want to delete.</param>
+ /// <param name="uniqueNumber">The unique number of the notification.</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parameter.</exception>
+ /// <exception cref="UnauthorizedAccessException"> Thrown in case of Permission deny.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/notification</privilege>
+ public static void Delete(string appId, int uniqueNumber)
+ {
+ Interop.NotificationEventListener.ErrorCode err;
+
+ if (string.IsNullOrEmpty(appId) || uniqueNumber < 0)
+ {
+ throw NotificationEventListenerErrorFactory.GetException(Interop.NotificationEventListener.ErrorCode.InvalidParameter, "invalid parameter");
+ }
+
+ err = Interop.NotificationEventListener.Delete(appId, 0, uniqueNumber);
+ if (err != Interop.NotificationEventListener.ErrorCode.None)
+ {
+ throw NotificationEventListenerErrorFactory.GetException(err, "unable to delete");
+ }
+ }
+
+ /// <summary>
+ /// Deletes all Notification.
+ /// </summary>
+ /// <exception cref="UnauthorizedAccessException"> Thrown in case of Permission deny.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/notification</privilege>
+ public static void DeleteAll()
+ {
+ Interop.NotificationEventListener.ErrorCode err;
+
+ err = Interop.NotificationEventListener.DeleteAll((int)NotificationType.Notification);
+ if (err != Interop.NotificationEventListener.ErrorCode.None)
+ {
+ throw NotificationEventListenerErrorFactory.GetException(err, "delete all notifications failed of Noti type");
+ }
+
+ err = Interop.NotificationEventListener.DeleteAll((int)NotificationType.Ongoing);
+ if (err != Interop.NotificationEventListener.ErrorCode.None)
+ {
+ throw NotificationEventListenerErrorFactory.GetException(err, "delete all notifications failed of Ongoing type");
+ }
+ }
+
+ /// <summary>
+ /// Returns the notification list handle.
+ /// </summary>
+ /// <exception cref="UnauthorizedAccessException"> Thrown in case of Permission deny.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/notification</privilege>
+ public static IList<NotificationEventArgs> GetList()
+ {
+ Interop.NotificationEventListener.ErrorCode err;
+ IntPtr notificationList = IntPtr.Zero;
+ IntPtr currentList = IntPtr.Zero;
+ IList<NotificationEventArgs> list = new List<NotificationEventArgs>();
+
+ err = Interop.NotificationEventListener.GetList(NotificationType.Notification, -1, out notificationList);
+ if (err != Interop.NotificationEventListener.ErrorCode.None)
+ {
+ throw NotificationEventListenerErrorFactory.GetException(err, "unable to get notification list");
+ }
+
+ if (notificationList != IntPtr.Zero)
+ {
+ currentList = notificationList;
+ while (currentList != IntPtr.Zero)
+ {
+ IntPtr notification;
+ NotificationEventArgs eventargs = new NotificationEventArgs();
+
+ notification = Interop.NotificationEventListener.GetData(currentList);
+
+ eventargs = NotificationEventArgsBinder.BindObject(notification, false);
+
+ list.Add(eventargs);
+
+ currentList = Interop.NotificationEventListener.GetNext(currentList);
+ }
+
+ Interop.NotificationEventListener.NotificationListFree(notificationList);
+ notificationList = IntPtr.Zero;
+ }
+
+ err = Interop.NotificationEventListener.GetList(NotificationType.Ongoing, -1, out notificationList);
+ if (err != Interop.NotificationEventListener.ErrorCode.None)
+ {
+ throw NotificationEventListenerErrorFactory.GetException(err, "unable to get notification list");
+ }
+
+ if (notificationList != IntPtr.Zero)
+ {
+ currentList = notificationList;
+ while (currentList != IntPtr.Zero)
+ {
+ IntPtr notification;
+ NotificationEventArgs eventargs = new NotificationEventArgs();
+
+ notification = Interop.NotificationEventListener.GetData(currentList);
+
+ eventargs = NotificationEventArgsBinder.BindObject(notification, false);
+
+ list.Add(eventargs);
+
+ currentList = Interop.NotificationEventListener.GetNext(currentList);
+ }
+
+ Interop.NotificationEventListener.NotificationListFree(notificationList);
+ }
+
+ return list;
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static void SendEvent(int uniqueNumber, UserEventType type)
+ {
+ Interop.NotificationEventListener.ErrorCode err;
+
+ err = Interop.NotificationEventListener.SendEvent(uniqueNumber, (int)type);
+ if (err != Interop.NotificationEventListener.ErrorCode.None)
+ {
+ throw NotificationEventListenerErrorFactory.GetException(err, "failed to send event");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationProgressArgsBinder.cs b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationProgressArgsBinder.cs
new file mode 100755
index 0000000..8611503
--- /dev/null
+++ b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationProgressArgsBinder.cs
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.NotificationEventListener
+{
+ internal static class NotificationProgressArgBinder
+ {
+ internal static void BindObject(NotificationEventArgs eventargs)
+ {
+ NotificationLayout layout;
+ Interop.NotificationEventListener.GetLayout(eventargs.Handle, out layout);
+
+ if (layout == NotificationLayout.OngoingProgress)
+ {
+ ProgressCategory category;
+ double current, max;
+
+ Interop.NotificationEventListener.GetOngoingType(eventargs.Handle, out category);
+ Interop.NotificationEventListener.GetProgress(eventargs.Handle, out current);
+ Interop.NotificationEventListener.GetProgressSize(eventargs.Handle, out max);
+
+ if (category == ProgressCategory.Percent)
+ {
+ current *= 100;
+
+ if (current == 0 && max == 0)
+ category = ProgressCategory.PendingBar;
+ }
+
+ eventargs.Progress = new NotificationEventArgs.ProgressArgs();
+ eventargs.Progress.Current = current;
+ eventargs.Progress.Max = max;
+ eventargs.Progress.Category = category;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationReplyActionArgsBinder.cs b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationReplyActionArgsBinder.cs
new file mode 100755
index 0000000..a851009
--- /dev/null
+++ b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationReplyActionArgsBinder.cs
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.NotificationEventListener
+{
+ using System;
+
+ internal static class NotificationReplyActionArgBinder
+ {
+ private const string LogTag = "Tizen.Applications.NotificationEventListener";
+
+ internal static void BindObject(NotificationEventArgs eventargs)
+ {
+ string text;
+ int max;
+ bool isExisted = false;
+ SafeAppControlHandle appcontrol = null;
+ Bundle bundle;
+ NotificationEventArgs.ReplyActionArgs reply = new NotificationEventArgs.ReplyActionArgs();
+ NotificationEventArgs.ButtonActionArgs button = new NotificationEventArgs.ButtonActionArgs();
+ string replyKey = "__PARENT_INDEX__";
+
+ Interop.NotificationEventListener.GetImage(eventargs.Handle, NotificationImage.TextInputButton, out text);
+ if (string.IsNullOrEmpty(text) == false)
+ {
+ isExisted = true;
+ button.ImagePath = text;
+ }
+
+ Interop.NotificationEventListener.GetText(eventargs.Handle, NotificationText.InputButton, out text);
+ if (string.IsNullOrEmpty(text) == false)
+ {
+ isExisted = true;
+ button.Text = text;
+ }
+
+ Interop.NotificationEventListener.GetEventHandler(eventargs.Handle, (int)ClickEventType.InputButton, out appcontrol);
+
+ if (appcontrol != null && appcontrol.IsInvalid == false)
+ {
+ button.Action = new AppControl(appcontrol);
+ isExisted = true;
+ }
+
+ reply.Button = button;
+
+ Interop.NotificationEventListener.GetText(eventargs.Handle, NotificationText.PlaceHolder, out text);
+
+ if (string.IsNullOrEmpty(text) == false)
+ {
+ isExisted = true;
+ reply.PlaceHolderText = text;
+ }
+
+ Interop.NotificationEventListener.GetPlaceHolderLength(eventargs.Handle, out max);
+ reply.ReplyMax = max;
+ if (max > 0)
+ {
+ isExisted = true;
+ }
+
+ if (eventargs.Extender.TryGetValue(replyKey, out bundle))
+ {
+ if (bundle.Contains(replyKey))
+ {
+ string parentIndex;
+ if (bundle.TryGetItem(replyKey, out parentIndex))
+ {
+ try
+ {
+ reply.ParentIndex = (ButtonIndex)int.Parse(parentIndex);
+ isExisted = true;
+ }
+ catch (Exception ex)
+ {
+ Log.Error(LogTag, "unable to get ParentIndex " + ex.Message);
+ }
+ }
+ }
+ }
+
+ if (isExisted)
+ {
+ (eventargs.Style["Active"] as NotificationEventArgs.ActiveStyleArgs).Reply = reply;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationStyleArgsBinder.cs b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationStyleArgsBinder.cs
new file mode 100755
index 0000000..f45e4aa
--- /dev/null
+++ b/src/Tizen.Applications.NotificationEventListener/Tizen.Applications.NotificationEventListener/NotificationStyleArgsBinder.cs
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications.NotificationEventListener
+{
+ using System;
+
+ internal static class NotificationStyleArgBinder
+ {
+ internal static void BindObject(NotificationEventArgs eventargs)
+ {
+ bool autoRemove;
+ string path;
+ int styleList;
+ int timeout;
+
+ Interop.NotificationEventListener.GetStyleList(eventargs.Handle, out styleList);
+
+ if ((styleList & (int)NotificationDisplayApplist.Active) != 0)
+ {
+ NotificationEventArgs.ActiveStyleArgs activeStyle = new NotificationEventArgs.ActiveStyleArgs();
+ eventargs.Style.Add(activeStyle.Key, activeStyle);
+
+ for (int i = (int)ClickEventType.FirstButton; i <= (int)ClickEventType.ThirdButton; i++)
+ {
+ NotificationButtonActionArgBinder.BindObject(eventargs, i);
+ }
+
+ Interop.NotificationEventListener.GetAutoRemove(eventargs.Handle, out autoRemove);
+ activeStyle.IsAutoRemove = autoRemove;
+
+ Interop.NotificationEventListener.GetImage(eventargs.Handle, NotificationImage.Background, out path);
+ activeStyle.BackgroundImage = path;
+
+ int index;
+ Interop.NotificationEventListener.GetDefaultButton(eventargs.Handle, out index);
+ activeStyle.DefaultButton = (ButtonIndex)(index - 1);
+
+ Interop.NotificationEventListener.GetHideTimeout(eventargs.Handle, out timeout);
+ activeStyle.HideTimeout = timeout;
+
+ try
+ {
+ Interop.NotificationEventListener.GetDeleteTimeout(eventargs.Handle, out timeout);
+ }
+ catch (TypeLoadException)
+ {
+ //To support in API version 3.0
+ timeout = 60;
+ }
+ activeStyle.DeleteTimeout = timeout;
+
+ NotificationReplyActionArgBinder.BindObject(eventargs);
+ }
+
+ if ((styleList & (int)NotificationDisplayApplist.Lock) != 0)
+ {
+ NotificationEventArgs.LockStyleArgs lockStyle = new NotificationEventArgs.LockStyleArgs();
+ eventargs.Style.Add(lockStyle.Key, lockStyle);
+
+ Interop.NotificationEventListener.GetImage(eventargs.Handle, NotificationImage.Lockscreen, out path);
+ lockStyle.IconPath = path;
+
+ Interop.NotificationEventListener.GetImage(eventargs.Handle, NotificationImage.ThumbnailLockscreen, out path);
+ lockStyle.Thumbnail = path;
+ }
+
+ if ((styleList & (int)NotificationDisplayApplist.Ticker) != 0 || (styleList & (int)NotificationDisplayApplist.Indicator) != 0)
+ {
+ NotificationEventArgs.IndicatorStyleArgs indicatorStyle = new NotificationEventArgs.IndicatorStyleArgs();
+ eventargs.Style.Add(indicatorStyle.Key, indicatorStyle);
+
+ Interop.NotificationEventListener.GetImage(eventargs.Handle, NotificationImage.Indicator, out path);
+ indicatorStyle.IconPath = path;
+
+ Interop.NotificationEventListener.GetText(eventargs.Handle, NotificationText.FirstMainText, out path);
+ indicatorStyle.SubText = path;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.PackageManager/Interop/Interop.Libraries.cs b/src/Tizen.Applications.PackageManager/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..83cbc6e
--- /dev/null
+++ b/src/Tizen.Applications.PackageManager/Interop/Interop.Libraries.cs
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string PackageManager = "libcapi-appfw-package-manager.so.0";
+ }
+}
diff --git a/src/Tizen.Applications.PackageManager/Interop/Interop.Package.cs b/src/Tizen.Applications.PackageManager/Interop/Interop.Package.cs
new file mode 100644
index 0000000..67de930
--- /dev/null
+++ b/src/Tizen.Applications.PackageManager/Interop/Interop.Package.cs
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+using ErrorCode = Interop.PackageManager.ErrorCode;
+using StorageType = Interop.PackageManager.StorageType;
+using CertCompareResultType = Interop.PackageManager.CertCompareResultType;
+
+internal static partial class Interop
+{
+ internal static partial class Package
+ {
+ [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+ internal delegate bool PackageInfoAppInfoCallback(AppType appType, string appId, IntPtr userData);
+
+ [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+ internal delegate bool PackageInfoCertificateInfoCallback(IntPtr handle, CertificateType certType, string certValue, IntPtr userData);
+
+ [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+ internal delegate bool PackageInfoPrivilegeInfoCallback(string privilege, IntPtr userData);
+
+ // Any change here might require changes in Tizen.Applications.AppType enum
+ internal enum AppType
+ {
+ All = 0,
+ Ui = 1,
+ Service = 2
+ }
+
+ internal enum CertificateType
+ {
+ AuthorRootCertificate = 0,
+ AuthorIntermediateCertificate = 1,
+ AuthorSignerCertificate = 2,
+ DistributorRootCertificate = 3,
+ DistributorIntermediateCertificate = 4,
+ DistributorSignerCertificate = 5,
+ Distributor2RootCertificate = 6,
+ Distributor2IntermediateCertificate = 7,
+ Distributor2SignerCertificate = 8
+ }
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_info_foreach_app_from_package")]
+ internal static extern ErrorCode PackageInfoForeachAppInfo(IntPtr handle, AppType appType, PackageInfoAppInfoCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_info_foreach_cert_info")]
+ internal static extern ErrorCode PackageInfoForeachCertificateInfo(IntPtr handle, PackageInfoCertificateInfoCallback callback, IntPtr user_data);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_info_foreach_privilege_info")]
+ internal static extern ErrorCode PackageInfoForeachPrivilegeInfo(IntPtr handle, PackageInfoPrivilegeInfoCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_info_create")]
+ internal static extern ErrorCode PackageInfoCreate(string packageId, out IntPtr handle);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_info_destroy")]
+ internal static extern ErrorCode PackageInfoDestroy(IntPtr handle);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_info_get_package")]
+ internal static extern ErrorCode PackageInfoGetPackage(IntPtr handle, out string packageId);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_info_get_label")]
+ internal static extern ErrorCode PackageInfoGetLabel(IntPtr handle, out string label);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_info_get_icon")]
+ internal static extern ErrorCode PackageInfoGetIconPath(IntPtr handle, out string path);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_info_get_version")]
+ internal static extern ErrorCode PackageInfoGetVersion(IntPtr handle, out string version);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_info_get_type")]
+ internal static extern ErrorCode PackageInfoGetType(IntPtr handle, out string type);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_info_get_installed_storage")]
+ internal static extern ErrorCode PackageInfoGetInstalledStorage(IntPtr handle, out StorageType storage);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_info_get_root_path")]
+ internal static extern ErrorCode PackageInfoGetRootPath(IntPtr handle, out string path);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_info_get_tep_name")]
+ internal static extern ErrorCode PackageInfoGetTepName(IntPtr handle, out string name);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_info_is_system_package")]
+ internal static extern ErrorCode PackageInfoIsSystemPackage(IntPtr handle, out bool system);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_info_is_removable_package")]
+ internal static extern ErrorCode PackageInfoIsRemovablePackage(IntPtr handle, out bool removable);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_info_is_preload_package")]
+ internal static extern ErrorCode PackageInfoIsPreloadPackage(IntPtr handle, out bool preload);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_info_is_accessible")]
+ internal static extern ErrorCode PackageInfoIsAccessible(IntPtr handle, out bool accessible);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_info_get_installed_time")]
+ internal static extern ErrorCode PackageInfoGetInstalledTime(IntPtr handle, out int installedTime);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_compare_package_cert_info")]
+ internal static extern ErrorCode PackageCompareCertInfo(string lhsPackageId, string rhsPackageId, out CertCompareResultType result);
+ }
+}
diff --git a/src/Tizen.Applications.PackageManager/Interop/Interop.PackageManager.cs b/src/Tizen.Applications.PackageManager/Interop/Interop.PackageManager.cs
new file mode 100644
index 0000000..e8fac2d
--- /dev/null
+++ b/src/Tizen.Applications.PackageManager/Interop/Interop.PackageManager.cs
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Applications;
+
+internal static partial class Interop
+{
+ internal static partial class PackageManager
+ {
+ [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+ internal delegate void PackageManagerEventCallback(string type, string packageId, EventType eventType, PackageEventState eventState, int progress, ErrorCode error, IntPtr userData);
+
+ [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+ internal delegate bool PackageManagerPackageInfoCallback(IntPtr handle, IntPtr userData);
+
+ [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+ internal delegate void PackageManagerSizeInfoCallback(string packageId, IntPtr sizeInfoHandle, IntPtr userData);
+
+ [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+ internal delegate void PackageManagerTotalSizeInfoCallback(IntPtr sizeInfoHandle, IntPtr userData);
+
+ [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+ internal delegate void PackageManagerRequestEventCallback(int requestId, string type, string packageId, EventType eventType, PackageEventState eventState, int progress, ErrorCode error, IntPtr userData);
+
+ // Any change here might require changes in Tizen.Applications.PackageManagerEventError enum
+ internal enum ErrorCode
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None,
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+ OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
+ IoError = Tizen.Internals.Errors.ErrorCode.IoError,
+ NoSuchPackage = -0x01150000 | 0x71,
+ SystemError = -0x01150000 | 0x72,
+ PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied
+ }
+
+ // Any change here might require changes in Tizen.Applications.PackageEventState enum
+ internal enum PackageEventState
+ {
+ Started = 0,
+ Processing = 1,
+ Completed = 2,
+ Failed = 3
+ }
+
+ [Flags]
+ internal enum EventStatus
+ {
+ All = 0x00,
+ Install = 0x01,
+ Uninstall = 0x02,
+ Upgrade = 0x04,
+ Move = 0x08,
+ ClearData = 0x10,
+ Progress = 0x20,
+ }
+
+ internal enum EventType
+ {
+ Install = 0,
+ Uninstall = 1,
+ Update = 2,
+ Move = 3,
+ ClearData = 4
+ }
+
+ internal enum CertCompareResultType
+ {
+ Match = 0,
+ Mismatch,
+ LhsNoCert,
+ RhsNoCert,
+ BothNoCert
+ }
+
+ internal enum PackageManagerPermissionType
+ {
+ Normal = 0,
+ Signature,
+ Privilege
+ }
+
+ // Any change here might require changes in Tizen.Applications.StorageType enum
+ internal enum StorageType
+ {
+ Internal = 0,
+ External = 1
+ }
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_create")]
+ internal static extern ErrorCode PackageManagerCreate(out SafePackageManagerHandle managerHandle);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_destroy")]
+ internal static extern ErrorCode PackageManagerDestroy(IntPtr managerHandle);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_set_event_status")]
+ internal static extern ErrorCode PackageManagerSetEvenStatus(SafePackageManagerHandle managerHandle, EventStatus eventStatus);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_set_event_cb")]
+ internal static extern ErrorCode PackageManagerSetEvent(SafePackageManagerHandle managerHandle, PackageManagerEventCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_unset_event_cb")]
+ internal static extern ErrorCode PackageManagerUnsetEvent(SafePackageManagerHandle managerHandle);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_foreach_package_info")]
+ internal static extern ErrorCode PackageManagerForeachPackageInfo(PackageManagerPackageInfoCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_get_package_size_info")]
+ internal static extern ErrorCode PackageManagerGetSizeInfo(string packageId, PackageManagerSizeInfoCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_get_total_package_size_info")]
+ internal static extern ErrorCode PackageManagerGetTotalSizeInfo(PackageManagerTotalSizeInfoCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_get_package_id_by_app_id")]
+ internal static extern ErrorCode PackageManageGetPackageIdByAppId(string app_id, out string package_id);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_get_package_info")]
+ internal static extern ErrorCode PackageManagerGetPackageInfo(string packageId, out IntPtr packageInfoHandle);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_clear_cache_dir")]
+ internal static extern ErrorCode PackageManagerClearCacheDir(string packageId);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_clear_all_cache_dir")]
+ internal static extern ErrorCode PackageManagerClearAllCacheDir();
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_clear_data_dir")]
+ internal static extern ErrorCode PackageManagerClearDataDir(string packageId);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_filter_create")]
+ internal static extern ErrorCode PackageManagerFilterCreate(out IntPtr handle);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_filter_destroy")]
+ internal static extern ErrorCode PackageManagerFilterDestroy(IntPtr handle);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_filter_add_bool")]
+ internal static extern ErrorCode PackageManagerFilterAdd(IntPtr handle, string property, bool value);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_filter_foreach_package_info")]
+ internal static extern ErrorCode PackageManagerFilterForeachPackageInfo(IntPtr handle, PackageManagerPackageInfoCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_size_info_get_data_size")]
+ internal static extern ErrorCode PackageSizeInfoGetDataSize(IntPtr handle, out long dataSize);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_size_info_get_cache_size")]
+ internal static extern ErrorCode PackageSizeInfoGetCacheSize(IntPtr handle, out long cacheSize);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_size_info_get_app_size")]
+ internal static extern ErrorCode PackageSizeInfoGetAppSize(IntPtr handle, out long appSize);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_size_info_get_external_data_size")]
+ internal static extern ErrorCode PackageSizeInfoGetExtDataSize(IntPtr handle, out long extDataSize);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_size_info_get_external_cache_size")]
+ internal static extern ErrorCode PackageSizeInfoGetExtCacheSize(IntPtr handle, out long extCacheSize);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_size_info_get_external_app_size")]
+ internal static extern ErrorCode PackageSizeInfoGetExtAppSize(IntPtr handle, out long extAppSize);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_request_create")]
+ internal static extern ErrorCode PackageManagerRequestCreate(out SafePackageManagerRequestHandle requestHandle);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_request_destroy")]
+ internal static extern ErrorCode PackageManagerRequestDestroy(IntPtr requestHandle);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_request_set_type")]
+ internal static extern ErrorCode PackageManagerRequestSetType(SafePackageManagerRequestHandle requestHandle, string type);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_request_set_tep")]
+ internal static extern ErrorCode PackageManagerRequestSetTepPath(SafePackageManagerRequestHandle requestHandle, string tepPath);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_request_install")]
+ internal static extern ErrorCode PackageManagerRequestInstall(SafePackageManagerRequestHandle requestHandle, string path, out int id);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_request_uninstall")]
+ internal static extern ErrorCode PackageManagerRequestUninstall(SafePackageManagerRequestHandle requestHandle, string name, out int id);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_request_move")]
+ internal static extern ErrorCode PackageManagerRequestMove(SafePackageManagerRequestHandle requestHandle, string name, StorageType moveToStorageType);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_compare_package_cert_info")]
+ internal static extern ErrorCode PackageManagerCompareCertInfo(string lhsPackageId, string rhsPackageId, out CertCompareResultType CompareResult);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_compare_app_cert_info")]
+ internal static extern ErrorCode PackageManagerCompareCertInfoByApplicationId(string lhsPackageId, string rhsPackageId, out CertCompareResultType CompareResult);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_is_preload_package_by_app_id")]
+ internal static extern ErrorCode PackageManagerIsPreloadPackageByApplicationId(string ApplicationId, out bool IsPreload);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_get_permission_type")]
+ internal static extern ErrorCode PackageManagerGetPermissionType(string ApplicationId, out PackageManagerPermissionType PermissionType);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_drm_generate_license_request")]
+ internal static extern ErrorCode PackageManagerDrmGenerateLicenseRequest(string responseData, out string requestData, out string licenseUrl);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_drm_register_license")]
+ internal static extern ErrorCode PackageManagerDrmRegisterLicense(string responseData);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_drm_decrypt_package")]
+ internal static extern ErrorCode PackageManagerDrmDecryptPackage(string drmFilePath, string decryptedFilePath);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_request_install_with_cb")]
+ internal static extern ErrorCode PackageManagerRequestInstallWithCB(SafePackageManagerRequestHandle requestHandle, string path, PackageManagerRequestEventCallback callback, IntPtr userData, out int id);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_request_uninstall_with_cb")]
+ internal static extern ErrorCode PackageManagerRequestUninstallWithCB(SafePackageManagerRequestHandle requestHandle, string name, PackageManagerRequestEventCallback callback, IntPtr userData, out int id);
+
+ [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_request_move_with_cb")]
+ internal static extern ErrorCode PackageManagerRequestMoveWithCB(SafePackageManagerRequestHandle requestHandle, string name, StorageType moveToStorageType, PackageManagerRequestEventCallback callback, IntPtr userData, out int id);
+ }
+}
diff --git a/src/Tizen.Applications.PackageManager/Tizen.Applications.PackageManager.csproj b/src/Tizen.Applications.PackageManager/Tizen.Applications.PackageManager.csproj
new file mode 100755
index 0000000..517b746
--- /dev/null
+++ b/src/Tizen.Applications.PackageManager/Tizen.Applications.PackageManager.csproj
@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen.Applications.Common\Tizen.Applications.Common.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project> \ No newline at end of file
diff --git a/src/Tizen.Applications.PackageManager/Tizen.Applications/CertCompareResultType.cs b/src/Tizen.Applications.PackageManager/Tizen.Applications/CertCompareResultType.cs
new file mode 100644
index 0000000..cd1512b
--- /dev/null
+++ b/src/Tizen.Applications.PackageManager/Tizen.Applications/CertCompareResultType.cs
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Enumeration for certificate compare result type.
+ /// </summary>
+ public enum CertCompareResultType
+ {
+ /// <summary>
+ /// Certificates are matched.
+ /// </summary>
+ Match = Interop.PackageManager.CertCompareResultType.Match,
+ /// <summary>
+ /// Certificates are not matched.
+ /// </summary>
+ Mismatch = Interop.PackageManager.CertCompareResultType.Mismatch,
+ /// <summary>
+ /// First package doesn't have certificate.
+ /// </summary>
+ LhsNoCert = Interop.PackageManager.CertCompareResultType.LhsNoCert,
+ /// <summary>
+ /// Second package doesn't have certificate.
+ /// </summary>
+ RhsNoCert = Interop.PackageManager.CertCompareResultType.RhsNoCert,
+ /// <summary>
+ /// Certificates of both packages are not exist.
+ /// </summary>
+ BothNoCert = Interop.PackageManager.CertCompareResultType.BothNoCert
+ }
+}
diff --git a/src/Tizen.Applications.PackageManager/Tizen.Applications/CertificateType.cs b/src/Tizen.Applications.PackageManager/Tizen.Applications/CertificateType.cs
new file mode 100755
index 0000000..b9d5858
--- /dev/null
+++ b/src/Tizen.Applications.PackageManager/Tizen.Applications/CertificateType.cs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Enumeration for certification type.
+ /// </summary>
+ public enum CertificateType
+ {
+ /// <summary>
+ /// Author Certificate.
+ /// </summary>
+ Author,
+ /// <summary>
+ /// Distributor Certificate.
+ /// </summary>
+ Distributor,
+ /// <summary>
+ /// Distributor2 Certificate.
+ /// </summary>
+ Distributor2,
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Applications.PackageManager/Tizen.Applications/Package.cs b/src/Tizen.Applications.PackageManager/Tizen.Applications/Package.cs
new file mode 100644
index 0000000..544409b
--- /dev/null
+++ b/src/Tizen.Applications.PackageManager/Tizen.Applications/Package.cs
@@ -0,0 +1,346 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// This class provide methods and properties to get information about packages.
+ /// </summary>
+ public class Package
+ {
+ private const string LogTag = "Tizen.Applications";
+
+ private string _id = string.Empty;
+ private string _label = string.Empty;
+ private string _iconPath = string.Empty;
+ private string _version = string.Empty;
+ private PackageType _type;
+ private Interop.PackageManager.StorageType _installedStorageType;
+ private string _rootPath = string.Empty;
+ private string _expansionPackageName = string.Empty;
+ private bool _isSystemPackage;
+ private bool _isRemovable;
+ private bool _isPreloaded;
+ private bool _isAccessible;
+ private IReadOnlyDictionary<CertificateType, PackageCertificate> _certificates;
+ private List<string> _privileges;
+ private int _installedTime;
+
+ private Package(string pkgId)
+ {
+ _id = pkgId;
+ }
+
+ /// <summary>
+ /// Package ID.
+ /// </summary>
+ public string Id { get { return _id; } }
+
+ /// <summary>
+ /// Label of the package.
+ /// </summary>
+ public string Label { get { return _label; } }
+
+ /// <summary>
+ /// Absolute path to the icon image.
+ /// </summary>
+ public string IconPath { get { return _iconPath; } }
+
+ /// <summary>
+ /// Version of the package.
+ /// </summary>
+ public string Version { get { return _version; } }
+
+ /// <summary>
+ /// Type of the package.
+ /// </summary>
+ public PackageType PackageType { get { return _type; } }
+
+ /// <summary>
+ /// Installed storage type for the package.
+ /// </summary>
+ public StorageType InstalledStorageType { get { return (StorageType)_installedStorageType; } }
+
+ /// <summary>
+ /// Root path for the package.
+ /// </summary>
+ public string RootPath { get { return _rootPath; } }
+
+ /// <summary>
+ /// Expansion package name for the package.
+ /// </summary>
+ public string TizenExpansionPackageName { get { return _expansionPackageName; } }
+
+ /// <summary>
+ /// Checks whether the package is system package.
+ /// </summary>
+ public bool IsSystemPackage { get { return _isSystemPackage; } }
+
+ /// <summary>
+ /// Checks whether the package is removable.
+ /// </summary>
+ public bool IsRemovable { get { return _isRemovable; } }
+
+ /// <summary>
+ /// Checks whether the package is preloaded.
+ /// </summary>
+ public bool IsPreloaded { get { return _isPreloaded; } }
+
+ /// <summary>
+ /// Checks whether the current package is accessible.
+ /// </summary>
+ public bool IsAccessible { get { return _isAccessible; } }
+
+ /// <summary>
+ /// Certificate information for the package
+ /// </summary>
+ public IReadOnlyDictionary<CertificateType, PackageCertificate> Certificates { get { return _certificates; } }
+
+ /// <summary>
+ /// Requested privilege for the package
+ /// </summary>
+ public IEnumerable<string> Privileges { get { return _privileges; } }
+
+ /// <summary>
+ /// Installed time of the package.
+ /// </summary>
+ public int InstalledTime { get { return _installedTime; } }
+
+ /// <summary>
+ /// Retrieves all application IDs of this package.
+ /// </summary>
+ /// <returns>Returns a dictionary containing all application info for given application type.</returns>
+ public IEnumerable<ApplicationInfo> GetApplications()
+ {
+ return GetApplications(ApplicationType.All);
+ }
+
+ /// <summary>
+ /// Retrieves all application IDs of this package.
+ /// </summary>
+ /// <param name="type">Optional: AppType enum value</param>
+ /// <returns>Returns a dictionary containing all application info for given application type.</returns>
+ public IEnumerable<ApplicationInfo> GetApplications(ApplicationType type)
+ {
+ List<ApplicationInfo> appInfoList = new List<ApplicationInfo>();
+ Interop.Package.PackageInfoAppInfoCallback cb = (Interop.Package.AppType appType, string appId, IntPtr userData) =>
+ {
+ appInfoList.Add(new ApplicationInfo(appId));
+ return true;
+ };
+
+ IntPtr packageInfoHandle;
+ Interop.PackageManager.ErrorCode err = Interop.Package.PackageInfoCreate(Id, out packageInfoHandle);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to create native handle for package info of {0}. err = {1}", Id, err));
+ }
+
+ err = Interop.Package.PackageInfoForeachAppInfo(packageInfoHandle, (Interop.Package.AppType)type, cb, IntPtr.Zero);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to application info of {0}. err = {1}", Id, err));
+ }
+
+ err = Interop.Package.PackageInfoDestroy(packageInfoHandle);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to destroy native handle for package info of {0}. err = {1}", Id, err));
+ }
+ return appInfoList;
+ }
+
+ /// <summary>
+ /// Gets size information for this package.
+ /// </summary>
+ /// <returns>package size information</returns>
+ /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
+ public async Task<PackageSizeInformation> GetSizeInformationAsync()
+ {
+ TaskCompletionSource<PackageSizeInformation> tcs = new TaskCompletionSource<PackageSizeInformation>();
+ Interop.PackageManager.PackageManagerSizeInfoCallback sizeInfoCb = (pkgId, sizeInfoHandle, userData) =>
+ {
+ if (sizeInfoHandle != IntPtr.Zero && Id == pkgId)
+ {
+ var pkgSizeInfo = PackageSizeInformation.GetPackageSizeInformation(sizeInfoHandle);
+ tcs.TrySetResult(pkgSizeInfo);
+ }
+ };
+
+ Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerGetSizeInfo(Id, sizeInfoCb, IntPtr.Zero);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ tcs.TrySetException(PackageManagerErrorFactory.GetException(err, "Failed to get total package size info of " + Id));
+ }
+ return await tcs.Task.ConfigureAwait(false);
+ }
+
+ /// <summary>
+ /// Compare certificate information with given package id.
+ /// </summary>
+ /// <param name="packageId">Id of the package</param>
+ /// <returns>Certificate comparison result</returns>
+ /// <exception cref="ArgumentException">Thrown when failed when input package ID is invalid</exception>
+ /// <exception cref="System.IO.IOException">Thrown when method failed due to internal IO error</exception>
+ public CertCompareResultType CompareCertInfo(string packageId)
+ {
+ Interop.PackageManager.CertCompareResultType compareResult;
+ Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerCompareCertInfo(Id, packageId, out compareResult);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ throw PackageManagerErrorFactory.GetException(err, "Failed to compare package cert info");
+ }
+
+ return (CertCompareResultType)compareResult;
+ }
+
+ // This method assumes that given arguments are already validated and have valid values.
+ internal static Package CreatePackage(IntPtr handle, string pkgId)
+ {
+ Package package = new Package(pkgId);
+
+ var err = Interop.PackageManager.ErrorCode.None;
+ err = Interop.Package.PackageInfoGetLabel(handle, out package._label);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get package label of " + pkgId);
+ }
+ err = Interop.Package.PackageInfoGetIconPath(handle, out package._iconPath);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get package icon path of " + pkgId);
+ }
+ err = Interop.Package.PackageInfoGetVersion(handle, out package._version);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get package version of " + pkgId);
+ }
+
+ string type;
+ Interop.Package.PackageInfoGetType(handle, out type);
+ if (Enum.TryParse(type, true, out package._type) == false)
+ {
+ Log.Warn(LogTag, "Failed to get package type of " + pkgId);
+ }
+ err = Interop.Package.PackageInfoGetRootPath(handle, out package._rootPath);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get package root directory of " + pkgId);
+ }
+ err = Interop.Package.PackageInfoGetTepName(handle, out package._expansionPackageName);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get expansion package name of " + pkgId);
+ package._expansionPackageName = string.Empty;
+ }
+
+ err = Interop.Package.PackageInfoGetInstalledStorage(handle, out package._installedStorageType);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get installed storage type of " + pkgId);
+ }
+ Interop.Package.PackageInfoIsSystemPackage(handle, out package._isSystemPackage);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get whether package " + pkgId + " is system package or not");
+ }
+ Interop.Package.PackageInfoIsRemovablePackage(handle, out package._isRemovable);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get whether package " + pkgId + " is removable or not");
+ }
+ Interop.Package.PackageInfoIsPreloadPackage(handle, out package._isPreloaded);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get whether package " + pkgId + " is preloaded or not");
+ }
+ Interop.Package.PackageInfoIsAccessible(handle, out package._isAccessible);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get whether package " + pkgId + " is accessible or not");
+ }
+ try
+ {
+ Interop.Package.PackageInfoGetInstalledTime(handle, out package._installedTime);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, "Failed to get installed time of " + pkgId);
+ }
+ }
+ catch (TypeLoadException)
+ {
+ // To support in API vesion 3.0
+ package._installedTime = 0;
+ }
+
+ package._certificates = PackageCertificate.GetPackageCertificates(handle);
+ package._privileges = GetPackagePrivilegeInformation(handle);
+ return package;
+ }
+
+ internal static Package GetPackage(string packageId)
+ {
+ IntPtr packageInfoHandle;
+ Interop.PackageManager.ErrorCode err = Interop.Package.PackageInfoCreate(packageId, out packageInfoHandle);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ throw PackageManagerErrorFactory.GetException(err, string.Format("Failed to create native handle for package info of {0}", packageId));
+ }
+
+ Package package = CreatePackage(packageInfoHandle, packageId);
+
+ err = Interop.Package.PackageInfoDestroy(packageInfoHandle);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to destroy native handle for package info of {0}. err = {1}", packageId, err));
+ }
+ return package;
+ }
+
+ internal static Package GetPackage(IntPtr packageInfoHandle)
+ {
+ String packageId;
+ Interop.PackageManager.ErrorCode err = Interop.Package.PackageInfoGetPackage(packageInfoHandle, out packageId);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ throw PackageManagerErrorFactory.GetException(err, "Failed to get package id for given package handle.");
+ }
+ return CreatePackage(packageInfoHandle, packageId);
+ }
+
+ private static List<string> GetPackagePrivilegeInformation(IntPtr packageInfoHandle)
+ {
+ List<string> privileges = new List<string>();
+ Interop.Package.PackageInfoPrivilegeInfoCallback privilegeInfoCb = (privilege, userData) =>
+ {
+ privileges.Add(privilege);
+ return true;
+ };
+
+ Interop.PackageManager.ErrorCode err = Interop.Package.PackageInfoForeachPrivilegeInfo(packageInfoHandle, privilegeInfoCb, IntPtr.Zero);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to get privilage info. err = {0}", err));
+ }
+ return privileges;
+ }
+ }
+}
diff --git a/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageCertificate.cs b/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageCertificate.cs
new file mode 100755
index 0000000..914d21a
--- /dev/null
+++ b/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageCertificate.cs
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// This class provides information about package certification.
+ /// </summary>
+ public class PackageCertificate
+ {
+ private const string LogTag = "Tizen.Applications";
+
+ private readonly string _root;
+ private readonly string _intermediate;
+ private readonly string _signer;
+
+ internal PackageCertificate(string root, string intermediate, string signer)
+ {
+ _root = root;
+ _intermediate = intermediate;
+ _signer = signer;
+ }
+
+ /// <summary>
+ /// Root certificate
+ /// </summary>
+ public string Root { get { return _root; } }
+
+ /// <summary>
+ /// Intermediate certificate
+ /// </summary>
+ public string Intermediate { get { return _intermediate; } }
+
+ /// <summary>
+ /// Signer certificate
+ /// </summary>
+ public string Signer { get { return _signer; } }
+
+ internal static IReadOnlyDictionary<CertificateType, PackageCertificate> GetPackageCertificates(IntPtr packageInfoHandle)
+ {
+ Dictionary<Interop.Package.CertificateType, string> nativeCertificates = new Dictionary<Interop.Package.CertificateType, string>();
+ Interop.Package.PackageInfoCertificateInfoCallback certificateInfoCb = (handle, certType, certValue, userData) =>
+ {
+ if (certValue == null) certValue = string.Empty;
+ nativeCertificates.Add(certType, certValue);
+ return true;
+ };
+
+ Interop.PackageManager.ErrorCode err = Interop.Package.PackageInfoForeachCertificateInfo(packageInfoHandle, certificateInfoCb, IntPtr.Zero);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to get certificate info. err = {0}", err));
+ }
+
+ Dictionary<CertificateType, PackageCertificate> certificates = new Dictionary<CertificateType, PackageCertificate>();
+ string authorRootCertificate = GetValue(nativeCertificates, Interop.Package.CertificateType.AuthorRootCertificate);
+ string authorIntermediateCertificate = GetValue(nativeCertificates, Interop.Package.CertificateType.AuthorIntermediateCertificate);
+ string aurthorSignerCertificate = GetValue(nativeCertificates, Interop.Package.CertificateType.AuthorSignerCertificate);
+ certificates.Add(CertificateType.Author, new PackageCertificate(authorRootCertificate, authorIntermediateCertificate, aurthorSignerCertificate));
+
+ string distRootCertificate = GetValue(nativeCertificates, Interop.Package.CertificateType.DistributorRootCertificate);
+ string distIntermediateCertificate = GetValue(nativeCertificates, Interop.Package.CertificateType.DistributorIntermediateCertificate);
+ string distSignerCertificate = GetValue(nativeCertificates, Interop.Package.CertificateType.DistributorSignerCertificate);
+ certificates.Add(CertificateType.Distributor, new PackageCertificate(distRootCertificate, distIntermediateCertificate, distSignerCertificate));
+
+ string dist2RootCertificate = GetValue(nativeCertificates, Interop.Package.CertificateType.Distributor2RootCertificate);
+ string dist2IntermediateCertificate = GetValue(nativeCertificates, Interop.Package.CertificateType.Distributor2RootCertificate);
+ string dist2SignerCertificate = GetValue(nativeCertificates, Interop.Package.CertificateType.Distributor2RootCertificate);
+ certificates.Add(CertificateType.Distributor2, new PackageCertificate(dist2RootCertificate, dist2IntermediateCertificate, dist2SignerCertificate));
+
+ return certificates;
+ }
+
+ private static string GetValue(IDictionary<Interop.Package.CertificateType, string> dict, Interop.Package.CertificateType key)
+ {
+ string value;
+ dict.TryGetValue(key, out value);
+ return value;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageDrm.cs b/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageDrm.cs
new file mode 100644
index 0000000..cb45bbb
--- /dev/null
+++ b/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageDrm.cs
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// This class provide methods and properties for DRM operation
+ /// </summary>
+ public class PackageDrm
+ {
+ private string _responseData;
+ private string _requestData;
+ private string _licenseUrl;
+ private PackageDrm(string responseData, string requestData, string licenseUrl)
+ {
+ _responseData = responseData;
+ _requestData = requestData;
+ _licenseUrl = licenseUrl;
+ }
+
+ /// <summary>
+ /// Returns response data
+ /// </summary>
+ /// <returns>Returns response data which is given when GenerateLicenseRequest has invoked</returns>
+ public string ResponseData { get { return _responseData; } }
+
+ /// <summary>
+ /// Returns request data
+ /// </summary>
+ /// <returns>Returns request data which is generated when GenerateLicenseRequest has invoked</returns>
+ public string RequestData { get { return _requestData; } }
+
+ /// <summary>
+ /// Returns license URL
+ /// </summary>
+ /// <returns>Returns license URL which is generated when GenerateLicenseRequest has invoked</returns>
+ public string LicenseUrl { get { return _licenseUrl; } }
+
+ internal static PackageDrm CreateDrmRequest(string responseData, string requestData, string licenseUrl)
+ {
+ PackageDrm packageDrm = new PackageDrm(responseData, requestData, licenseUrl);
+ return packageDrm;
+ }
+
+ internal static PackageDrm GenerateLicenseRequest(string responseData)
+ {
+ string requestData;
+ string licenseUrl;
+ Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerDrmGenerateLicenseRequest(responseData, out requestData, out licenseUrl);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ throw PackageManagerErrorFactory.GetException(err, "Failed to generate license request");
+ }
+
+ PackageDrm packageDrm = CreateDrmRequest(responseData, requestData, licenseUrl);
+ return packageDrm;
+ }
+ }
+}
diff --git a/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageEventState.cs b/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageEventState.cs
new file mode 100755
index 0000000..827a87f
--- /dev/null
+++ b/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageEventState.cs
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Enumeration for package manager event state.
+ /// </summary>
+ public enum PackageEventState
+ {
+ /// <summary>
+ /// Processing started
+ /// </summary>
+ Started = Interop.PackageManager.PackageEventState.Started,
+ /// <summary>
+ /// Processing state.
+ /// </summary>
+ Processing = Interop.PackageManager.PackageEventState.Processing,
+ /// <summary>
+ /// Processing Completed.
+ /// </summary>
+ Completed = Interop.PackageManager.PackageEventState.Completed,
+ /// <summary>
+ /// Processing Failed.
+ /// </summary>
+ Failed = Interop.PackageManager.PackageEventState.Failed
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageEventType.cs b/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageEventType.cs
new file mode 100755
index 0000000..15d1f1b
--- /dev/null
+++ b/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageEventType.cs
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Enumeration for package manager event type.
+ /// </summary>
+ public enum PackageEventType
+ {
+ /// <summary>
+ /// Install event.
+ /// </summary>
+ Install = Interop.PackageManager.EventType.Install,
+ /// <summary>
+ /// Uninstall event.
+ /// </summary>
+ Uninstall = Interop.PackageManager.EventType.Uninstall,
+ /// <summary>
+ /// Update event.
+ /// </summary>
+ Update = Interop.PackageManager.EventType.Update,
+ /// <summary>
+ /// Move event.
+ /// </summary>
+ Move = Interop.PackageManager.EventType.Move,
+ /// <summary>
+ /// ClearData event.
+ /// </summary>
+ ClearData = Interop.PackageManager.EventType.ClearData
+ }
+}
diff --git a/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageFilter.cs b/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageFilter.cs
new file mode 100755
index 0000000..8ebff43
--- /dev/null
+++ b/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageFilter.cs
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System.Collections.Generic;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// This class is a parameter of PackageManager::GetPackages method.
+ /// </summary>
+ public class PackageFilter
+ {
+ private IDictionary<string, bool> _filter;
+
+ /// <summary>
+ /// Default constructor with empty filter list. All installed applications will satisfy this filter unless updated with more specific filters.
+ /// </summary>
+ public PackageFilter()
+ {
+ _filter = new Dictionary<string, bool>();
+ }
+
+ /// <summary>
+ /// Constructor with specific filters. Using this will filter out installed packages which do not meet the criteria of the filters.
+ /// </summary>
+ public PackageFilter(IDictionary<string, bool> filter)
+ {
+ _filter = filter;
+ }
+
+ /// <summary>
+ /// Filters to be used in the GetPackages method.
+ /// </summary>
+ public IDictionary<string, bool> Filters
+ {
+ get
+ {
+ return _filter;
+ }
+ }
+
+ /// <summary>
+ /// This class contains possible keys for filter to be used in the GetPackages method.
+ /// </summary>
+ public static class Keys
+ {
+ /// <summary>
+ /// Key of the boolean property for filtering whether the package is removable
+ /// </summary>
+ public const string Removable = "PMINFO_PKGINFO_PROP_PACKAGE_REMOVABLE";
+ /// <summary>
+ /// Key of the boolean property for filtering whether the package is readonly.
+ /// </summary>
+ public const string ReadOnly = "PMINFO_PKGINFO_PROP_PACKAGE_READONLY";
+ /// <summary>
+ /// Key of the boolean property for filtering whether the package supports disabling.
+ /// </summary>
+ public const string SupportsDisable = "PMINFO_PKGINFO_PROP_PACKAGE_SUPPORT_DISABLE";
+ /// <summary>
+ /// Key of the boolean property for filtering whether the package is disabled.
+ /// </summary>
+ public const string Disable = "PMINFO_PKGINFO_PROP_PACKAGE_DISABLE";
+ /// <summary>
+ /// Key of the boolean property for filtering whether the package is preloaded.
+ /// </summary>
+ public const string Preload = "PMINFO_PKGINFO_PROP_PACKAGE_PRELOAD";
+ }
+ }
+}
diff --git a/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageManager.cs b/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageManager.cs
new file mode 100644
index 0000000..6b49900
--- /dev/null
+++ b/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageManager.cs
@@ -0,0 +1,1103 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using System.IO;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// PackageManager class. This class has the methods and events of the PackageManager.
+ /// </summary>
+ /// <remarks>
+ /// The package manager is one of the core modules of Tizen application framework, and responsible for getting their information.
+ /// You can also retrieve information related to the packages that are installed on the device.
+ /// </remarks>
+ public static class PackageManager
+ {
+ private const string LogTag = "Tizen.Applications.PackageManager";
+
+ private static SafePackageManagerHandle s_handle = new SafePackageManagerHandle();
+ private static Interop.PackageManager.EventStatus s_eventStatus = Interop.PackageManager.EventStatus.All;
+ private static event EventHandler<PackageManagerEventArgs> s_installEventHandler;
+ private static event EventHandler<PackageManagerEventArgs> s_uninstallEventHandler;
+ private static event EventHandler<PackageManagerEventArgs> s_updateEventHandler;
+ private static event EventHandler<PackageManagerEventArgs> s_moveEventHandler;
+ private static event EventHandler<PackageManagerEventArgs> s_clearDataEventHandler;
+
+ private static Interop.PackageManager.PackageManagerEventCallback s_packageManagerEventCallback;
+
+ /// <summary>
+ /// Event Callback Method for the request.
+ /// </summary>
+ /// <param name="type">Type of the package which was requested</param>
+ /// <param name="packageId">ID of the package which was requested</param>
+ /// <param name="eventType">Event type of the request</param>
+ /// <param name="eventState">Current event state of the request</param>
+ /// <param name="progress">Progress for the request being processed by the package manager (in percent)</param>
+ public delegate void RequestEventCallback(string type, string packageId, PackageEventType eventType, PackageEventState eventState, int progress);
+
+ private static Dictionary<int, RequestEventCallback> RequestCallbacks = new Dictionary<int, RequestEventCallback>();
+ private static Dictionary<int, SafePackageManagerRequestHandle> RequestHandles = new Dictionary<int, SafePackageManagerRequestHandle>();
+
+ /// <summary>
+ /// InstallProgressChanged event. This event is occurred when a package is getting installed and the progress of the request to the package manager changes.
+ /// </summary>
+ public static event EventHandler<PackageManagerEventArgs> InstallProgressChanged
+ {
+ add
+ {
+ SetPackageManagerEventStatus(Interop.PackageManager.EventStatus.Install);
+ RegisterPackageManagerEventIfNeeded();
+ s_installEventHandler += value;
+ }
+ remove
+ {
+ s_installEventHandler -= value;
+ UnregisterPackageManagerEventIfNeeded();
+ UnsetPackageManagerEventStatus();
+ }
+ }
+
+ /// <summary>
+ /// UninstallProgressChanged event. This event is occurred when a package is getting uninstalled and the progress of the request to the package manager changes.
+ /// </summary>
+ public static event EventHandler<PackageManagerEventArgs> UninstallProgressChanged
+ {
+ add
+ {
+ SetPackageManagerEventStatus(Interop.PackageManager.EventStatus.Uninstall);
+ RegisterPackageManagerEventIfNeeded();
+ s_uninstallEventHandler += value;
+ }
+ remove
+ {
+ s_uninstallEventHandler -= value;
+ UnregisterPackageManagerEventIfNeeded();
+ UnsetPackageManagerEventStatus();
+ }
+ }
+
+ /// <summary>
+ /// UpdateProgressChanged event. This event is occurred when a package is getting updated and the progress of the request to the package manager changes.
+ /// </summary>
+ public static event EventHandler<PackageManagerEventArgs> UpdateProgressChanged
+ {
+ add
+ {
+ SetPackageManagerEventStatus(Interop.PackageManager.EventStatus.Upgrade);
+ RegisterPackageManagerEventIfNeeded();
+ s_updateEventHandler += value;
+ }
+ remove
+ {
+ s_updateEventHandler -= value;
+ UnregisterPackageManagerEventIfNeeded();
+ UnsetPackageManagerEventStatus();
+ }
+ }
+
+ /// <summary>
+ /// MoveProgressChanged event. This event is occurred when a package is getting moved and the progress of the request to the package manager changes.
+ /// </summary>
+ public static event EventHandler<PackageManagerEventArgs> MoveProgressChanged
+ {
+ add
+ {
+ SetPackageManagerEventStatus(Interop.PackageManager.EventStatus.Move);
+ RegisterPackageManagerEventIfNeeded();
+ s_moveEventHandler += value;
+ }
+ remove
+ {
+ s_moveEventHandler -= value;
+ UnregisterPackageManagerEventIfNeeded();
+ UnsetPackageManagerEventStatus();
+ }
+ }
+
+ /// <summary>
+ /// ClearDataProgressChanged event. This event is occurred when data directories are cleared in the given package.
+ /// </summary>
+ public static event EventHandler<PackageManagerEventArgs> ClearDataProgressChanged
+ {
+ add
+ {
+ SetPackageManagerEventStatus(Interop.PackageManager.EventStatus.ClearData);
+ RegisterPackageManagerEventIfNeeded();
+ s_clearDataEventHandler += value;
+ }
+ remove
+ {
+ s_clearDataEventHandler -= value;
+ UnregisterPackageManagerEventIfNeeded();
+ UnsetPackageManagerEventStatus();
+ }
+ }
+
+ private static SafePackageManagerHandle Handle
+ {
+ get
+ {
+ if (s_handle.IsInvalid)
+ {
+ var err = Interop.PackageManager.PackageManagerCreate(out s_handle);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to create package manager handle. err = {0}", err));
+ }
+ }
+ return s_handle;
+ }
+ }
+
+ private static Interop.PackageManager.PackageManagerRequestEventCallback internalRequestEventCallback = (id, packageType, packageId, eventType, eventState, progress, error, userData) =>
+ {
+ if (RequestCallbacks.ContainsKey(id))
+ {
+ try
+ {
+ RequestCallbacks[id](packageType, packageId, (PackageEventType)eventType, (PackageEventState)eventState, progress);
+ if (eventState == Interop.PackageManager.PackageEventState.Completed || eventState == Interop.PackageManager.PackageEventState.Failed)
+ {
+ Log.Debug(LogTag, string.Format("release request handle for id : {0}", id));
+ RequestHandles[id].Dispose();
+ RequestHandles.Remove(id);
+ RequestCallbacks.Remove(id);
+ }
+ }
+ catch (Exception e)
+ {
+ Log.Warn(LogTag, e.Message);
+ RequestHandles[id].Dispose();
+ RequestHandles.Remove(id);
+ RequestCallbacks.Remove(id);
+ }
+ }
+ };
+
+ /// <summary>
+ /// Gets the package ID for the given app ID.
+ /// </summary>
+ /// <param name="applicationId">The ID of the application</param>
+ /// <returns>Returns the ID of the package. Empty string if App ID does not exist</returns>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access this method</exception>
+ /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
+ public static string GetPackageIdByApplicationId(string applicationId)
+ {
+ string packageId;
+ var err = Interop.PackageManager.PackageManageGetPackageIdByAppId(applicationId, out packageId);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to get package Id of {0}. err = {1}", applicationId, err));
+ if (err != Interop.PackageManager.ErrorCode.InvalidParameter)
+ {
+ throw PackageManagerErrorFactory.GetException(err, "Failed to get package Id");
+ }
+ }
+ return packageId;
+ }
+
+ /// <summary>
+ /// Gets the package information for the given package.
+ /// </summary>
+ /// <param name="packageId">The ID of the package</param>
+ /// <returns>Returns the package information for the given package ID.</returns>
+ /// <exception cref="ArgumentException">Thrown when failed when input package ID is invalid</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method</exception>
+ /// <exception cref="System.IO.IOException">Thrown when method failed due to internal IO error</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access this method</exception>
+ /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
+ public static Package GetPackage(string packageId)
+ {
+ return Package.GetPackage(packageId);
+ }
+
+ /// <summary>
+ /// Clears the application's internal and external cache directory.
+ /// </summary>
+ /// <param name="packageId">Id of the package</param>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method</exception>
+ /// <exception cref="System.IO.IOException">Thrown when method failed due to internal IO error</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access this method</exception>
+ /// <exception cref="SystemException">Thrown when method failed due to internal system error</exception>
+ /// <privilege>http://tizen.org/privilege/packagemanager.clearcache</privilege>
+ public static void ClearCacheDirectory(string packageId)
+ {
+ Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerClearCacheDir(packageId);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to clear cache directory for {0}. err = {1}", packageId, err));
+ throw PackageManagerErrorFactory.GetException(err, "Failed to clear cache directory");
+ }
+ }
+
+ /// <summary>
+ /// Clears all application's internal and external cache directory.
+ /// </summary>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method</exception>
+ /// <exception cref="System.IO.IOException">Thrown when method failed due to internal IO error</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access this method</exception>
+ /// <exception cref="SystemException">Thrown when method failed due to internal system error</exception>
+ /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
+ public static void ClearAllCacheDirectory()
+ {
+ var err = Interop.PackageManager.PackageManagerClearAllCacheDir();
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to clear all cache directories. err = {0}", err));
+ throw PackageManagerErrorFactory.GetException(err, "Failed to clear all cache directories");
+ }
+ }
+
+ /// <summary>
+ /// Clears the application's internal and external data directories
+ /// </summary>
+ /// <remarks>
+ /// All files under data, shared/data and shared/trusted in the internal storage are removed.
+ /// And, If external storeage exists, then all files under data and shared/trusted in the external storage are removed.
+ /// </remarks>
+ /// <param name="packageId">Id of the package</param>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method</exception>
+ /// <exception cref="System.IO.IOException">Thrown when method failed due to internal IO error</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access this method</exception>
+ /// <exception cref="SystemException">Thrown when method failed due to internal system error</exception>
+ /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
+ public static void ClearDataDirectory(string packageId)
+ {
+ Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerClearDataDir(packageId);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to clear data directory for {0}. err = {1}", packageId, err));
+ throw PackageManagerErrorFactory.GetException(err, "Failed to clear data directory");
+ }
+ }
+
+ /// <summary>
+ /// Retrieves package information of all installed packages.
+ /// </summary>
+ /// <returns>Returns the list of packages.</returns>
+ /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
+ public static IEnumerable<Package> GetPackages()
+ {
+ return GetPackages(null);
+ }
+
+ /// <summary>
+ /// Retrieves package information of all installed packages satisfying filter conditions.
+ /// </summary>
+ /// <param name="filter">Optional - package filters</param>
+ /// <returns>Returns the list of packages.</returns>
+ /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
+ public static IEnumerable<Package> GetPackages(PackageFilter filter)
+ {
+ List<Package> packageList = new List<Package>();
+
+ IntPtr filterHandle;
+ var err = Interop.PackageManager.PackageManagerFilterCreate(out filterHandle);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to create package filter handle. err = {0}", err));
+ return packageList;
+ }
+
+ if (filter != null && filter.Filters != null)
+ {
+ foreach (KeyValuePair<string, bool> entry in filter?.Filters)
+ {
+ err = Interop.PackageManager.PackageManagerFilterAdd(filterHandle, entry.Key, entry.Value);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to configure package filter. err = {0}", err));
+ break;
+ }
+ }
+ }
+
+ if (err == Interop.PackageManager.ErrorCode.None)
+ {
+ Interop.PackageManager.PackageManagerPackageInfoCallback cb = (handle, userData) =>
+ {
+ packageList.Add(Package.GetPackage(handle));
+ return true;
+ };
+
+ err = Interop.PackageManager.PackageManagerFilterForeachPackageInfo(filterHandle, cb, IntPtr.Zero);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to get package Informations. err = {0}", err));
+ }
+ }
+
+ err = Interop.PackageManager.PackageManagerFilterDestroy(filterHandle);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to destroy package filter handle. err = {0}", err));
+ }
+ return packageList;
+ }
+
+ /// <summary>
+ /// Gets the total package size information.
+ /// </summary>
+ /// <returns>Returns the total package size information asynchronously.</returns>
+ /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
+ public static async Task<PackageSizeInformation> GetTotalSizeInformationAsync()
+ {
+ TaskCompletionSource<PackageSizeInformation> tcs = new TaskCompletionSource<PackageSizeInformation>();
+ Interop.PackageManager.PackageManagerTotalSizeInfoCallback cb = (handle, userData) =>
+ {
+ if (handle != IntPtr.Zero)
+ {
+ tcs.TrySetResult(PackageSizeInformation.GetPackageSizeInformation(handle));
+ }
+ };
+
+ var err = Interop.PackageManager.PackageManagerGetTotalSizeInfo(cb, IntPtr.Zero);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ tcs.TrySetException(PackageManagerErrorFactory.GetException(err, "Failed to get total package size info"));
+ }
+ return await tcs.Task.ConfigureAwait(false);
+ }
+
+ /// <summary>
+ /// Installs package located at the given path
+ /// </summary>
+ /// <param name="packagePath">Absolute path for the package to be installed</param>
+ /// <returns>Returns true if installtion request is successful, false otherwise.</returns>
+ /// <remarks>
+ /// The 'true' means that just the request of installation is seccessful.
+ /// To check the result of installation, the caller should check the progress using InstallProgressChanged event.
+ /// </remarks>
+ /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
+ public static bool Install(string packagePath)
+ {
+ return Install(packagePath, null, PackageType.UNKNOWN, null);
+ }
+
+ /// <summary>
+ /// Installs package located at the given path
+ /// </summary>
+ /// <param name="packagePath">Absolute path for the package to be installed</param>
+ /// <param name="eventCallback">Optional - The event callback will be invoked only for the current request</param>
+ /// <returns>Returns true if installtion request is successful, false otherwise.</returns>
+ /// <remarks>
+ /// The 'true' means that just the request of installation is seccessful.
+ /// To check the result of installation, the caller should check the progress using InstallProgressChanged event OR eventCallback.
+ /// </remarks>
+ /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
+ public static bool Install(string packagePath, RequestEventCallback eventCallback)
+ {
+ return Install(packagePath, null, PackageType.UNKNOWN, eventCallback);
+ }
+
+ /// <summary>
+ /// Installs package located at the given path
+ /// </summary>
+ /// <param name="packagePath">Absolute path for the package to be installed</param>
+ /// <param name="type">Optional - Package type for the package to be installed</param>
+ /// <returns>Returns true if installtion request is successful, false otherwise.</returns>
+ /// <remarks>
+ /// The 'true' means that just the request of installation is seccessful.
+ /// To check the result of installation, the caller should check the progress using InstallProgressChanged event.
+ /// </remarks>
+ /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
+ public static bool Install(string packagePath, PackageType type)
+ {
+ return Install(packagePath, null, type, null);
+ }
+
+ /// <summary>
+ /// Installs package located at the given path
+ /// </summary>
+ /// <param name="packagePath">Absolute path for the package to be installed</param>
+ /// <param name="expansionPackagePath">Optional - Absolute path for the expansion package to be installed</param>
+ /// <returns>Returns true if installtion request is successful, false otherwise.</returns>
+ /// <remarks>
+ /// The 'true' means that just the request of installation is seccessful.
+ /// To check the result of installation, the caller should check the progress using InstallProgressChanged event.
+ /// </remarks>
+ /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
+ public static bool Install(string packagePath, string expansionPackagePath)
+ {
+ return Install(packagePath, expansionPackagePath, PackageType.UNKNOWN, null);
+ }
+
+ /// <summary>
+ /// Installs package located at the given path
+ /// </summary>
+ /// <param name="packagePath">Absolute path for the package to be installed</param>
+ /// <param name="type">Optional - Package type for the package to be installed</param>
+ /// <param name="eventCallback">Optional - The event callback will be invoked only for the current request</param>
+ /// <returns>Returns true if installtion request is successful, false otherwise.</returns>
+ /// <remarks>
+ /// The 'true' means that just the request of installation is seccessful.
+ /// To check the result of installation, the caller should check the progress using InstallProgressChanged event OR eventCallback.
+ /// </remarks>
+ /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
+ public static bool Install(string packagePath, PackageType type, RequestEventCallback eventCallback)
+ {
+ return Install(packagePath, null, type, eventCallback);
+ }
+
+ /// <summary>
+ /// Installs package located at the given path
+ /// </summary>
+ /// <param name="packagePath">Absolute path for the package to be installed</param>
+ /// <param name="expansionPackagePath">Optional - Absolute path for the expansion package to be installed</param>
+ /// <param name="eventCallback">Optional - The event callback will be invoked only for the current request</param>
+ /// <returns>Returns true if installtion request is successful, false otherwise.</returns>
+ /// <remarks>
+ /// The 'true' means that just the request of installation is seccessful.
+ /// To check the result of installation, the caller should check the progress using InstallProgressChanged event OR eventCallback.
+ /// </remarks>
+ /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
+ public static bool Install(string packagePath, string expansionPackagePath, RequestEventCallback eventCallback)
+ {
+ return Install(packagePath, expansionPackagePath, PackageType.UNKNOWN, eventCallback);
+ }
+
+ /// <summary>
+ /// Installs package located at the given path
+ /// </summary>
+ /// <param name="packagePath">Absolute path for the package to be installed</param>
+ /// <param name="expansionPackagePath">Optional - Absolute path for the expansion package to be installed</param>
+ /// <param name="type">Optional - Package type for the package to be installed</param>
+ /// <returns>Returns true if installtion request is successful, false otherwise.</returns>
+ /// <remarks>
+ /// The 'true' means that just the request of installation is seccessful.
+ /// To check the result of installation, the caller should check the progress using InstallProgressChanged event.
+ /// </remarks>
+ /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
+ public static bool Install(string packagePath, string expansionPackagePath, PackageType type)
+ {
+ return Install(packagePath, expansionPackagePath, type, null);
+ }
+
+ /// <summary>
+ /// Installs package located at the given path
+ /// </summary>
+ /// <param name="packagePath">Absolute path for the package to be installed</param>
+ /// <param name="expansionPackagePath">Optional - Absolute path for the expansion package to be installed</param>
+ /// <param name="type">Optional - Package type for the package to be installed</param>
+ /// <param name="eventCallback">Optional - The event callback will be invoked only for the current request</param>
+ /// <returns>Returns true if installtion request is successful, false otherwise.</returns>
+ /// <remarks>
+ /// The 'true' means that just the request of installation is seccessful.
+ /// To check the result of installation, the caller should check the progress using InstallProgressChanged event OR eventCallback.
+ /// </remarks>
+ /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
+ public static bool Install(string packagePath, string expansionPackagePath, PackageType type, RequestEventCallback eventCallback)
+ {
+ SafePackageManagerRequestHandle RequestHandle;
+ var err = Interop.PackageManager.PackageManagerRequestCreate(out RequestHandle);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to install package {0}. Error in creating package manager request handle. err = {1}", packagePath, err));
+ return false;
+ }
+
+ try
+ {
+ if (type != PackageType.UNKNOWN)
+ {
+ err = Interop.PackageManager.PackageManagerRequestSetType(RequestHandle, type.ToString().ToLower());
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to install package {0}. Error in setting request package type. err = {1}", packagePath, err));
+ RequestHandle.Dispose();
+ return false;
+ }
+ }
+
+ if (!string.IsNullOrEmpty(expansionPackagePath))
+ {
+ err = Interop.PackageManager.PackageManagerRequestSetTepPath(RequestHandle, expansionPackagePath);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to install package {0}. Error in setting request package mode. err = {1}", packagePath, err));
+ RequestHandle.Dispose();
+ return false;
+ }
+ }
+
+ int requestId;
+ if (eventCallback != null)
+ {
+ err = Interop.PackageManager.PackageManagerRequestInstallWithCB(RequestHandle, packagePath, internalRequestEventCallback, IntPtr.Zero, out requestId);
+ if (err == Interop.PackageManager.ErrorCode.None)
+ {
+ RequestCallbacks.Add(requestId, eventCallback);
+ RequestHandles.Add(requestId, RequestHandle);
+ }
+ else
+ {
+ Log.Warn(LogTag, string.Format("Failed to install package {0}. err = {1}", packagePath, err));
+ RequestHandle.Dispose();
+ return false;
+ }
+ }
+ else
+ {
+ err = Interop.PackageManager.PackageManagerRequestInstall(RequestHandle, packagePath, out requestId);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to install package {0}. err = {1}", packagePath, err));
+ RequestHandle.Dispose();
+ return false;
+ }
+ // RequestHandle isn't necessary when this method is called without 'eventCallback' parameter.
+ RequestHandle.Dispose();
+ }
+ return true;
+ }
+ catch (Exception e)
+ {
+ Log.Warn(LogTag, e.Message);
+ RequestHandle.Dispose();
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Uninstalls package with the given name.
+ /// </summary>
+ /// <param name="packageId">Id of the package to be uninstalled</param>
+ /// <returns>Returns true if uninstallation request is successful, false otherwise.</returns>
+ /// <remarks>
+ /// The 'true' means that just the request of uninstallation is seccessful.
+ /// To check the result of uninstallation, the caller should check the progress using UninstallProgressChanged event.
+ /// </remarks>
+ /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
+ public static bool Uninstall(string packageId)
+ {
+ return Uninstall(packageId, PackageType.UNKNOWN, null);
+ }
+
+ /// <summary>
+ /// Uninstalls package with the given name.
+ /// </summary>
+ /// <param name="packageId">Id of the package to be uninstalled</param>
+ /// <param name="type">Optional - Package type for the package to be uninstalled</param>
+ /// <returns>Returns true if uninstalltion request is successful, false otherwise.</returns>
+ /// <remarks>
+ /// The 'true' means that just the request of uninstallation is seccessful.
+ /// To check the result of uninstallation, the caller should check the progress using UninstallProgressChanged event.
+ /// </remarks>
+ /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
+ public static bool Uninstall(string packageId, PackageType type)
+ {
+ return Uninstall(packageId, type, null);
+ }
+
+ /// <summary>
+ /// Uninstalls package with the given name.
+ /// </summary>
+ /// <param name="packageId">Id of the package to be uninstalled</param>
+ /// <param name="eventCallback">Optional - The event callback will be invoked only for the current request</param>
+ /// <returns>Returns true if uninstalltion request is successful, false otherwise.</returns>
+ /// <remarks>
+ /// The 'true' means that just the request of uninstallation is seccessful.
+ /// To check the result of uninstallation, the caller should check the progress using UninstallProgressChanged event OR eventCallback.
+ /// </remarks>
+ /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
+ public static bool Uninstall(string packageId, RequestEventCallback eventCallback)
+ {
+ return Uninstall(packageId, PackageType.UNKNOWN, eventCallback);
+ }
+
+ /// <summary>
+ /// Uninstalls package with the given name.
+ /// </summary>
+ /// <param name="packageId">Id of the package to be uninstalled</param>
+ /// <param name="type">Optional - Package type for the package to be uninstalled</param>
+ /// <param name="eventCallback">Optional - The event callback will be invoked only for the current request</param>
+ /// <returns>Returns true if uninstalltion request is successful, false otherwise.</returns>
+ /// <remarks>
+ /// The 'true' means that just the request of uninstallation is seccessful.
+ /// To check the result of uninstallation, the caller should check the progress using UninstallProgressChanged event OR eventCallback.
+ /// </remarks>
+ /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
+ public static bool Uninstall(string packageId, PackageType type, RequestEventCallback eventCallback)
+ {
+ SafePackageManagerRequestHandle RequestHandle;
+ var err = Interop.PackageManager.PackageManagerRequestCreate(out RequestHandle);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to uninstall package {0}. Error in creating package manager request handle. err = {1}", packageId, err));
+ return false;
+ }
+
+ try
+ {
+ err = Interop.PackageManager.PackageManagerRequestSetType(RequestHandle, type.ToString().ToLower());
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to uninstall package {0}. Error in setting request package type. err = {1}", packageId, err));
+ RequestHandle.Dispose();
+ return false;
+ }
+
+ int requestId;
+ if (eventCallback != null)
+ {
+ err = Interop.PackageManager.PackageManagerRequestUninstallWithCB(RequestHandle, packageId, internalRequestEventCallback, IntPtr.Zero, out requestId);
+ if (err == Interop.PackageManager.ErrorCode.None)
+ {
+ RequestCallbacks.Add(requestId, eventCallback);
+ RequestHandles.Add(requestId, RequestHandle);
+ }
+ else
+ {
+ Log.Warn(LogTag, string.Format("Failed to uninstall package {0}. err = {1}", packageId, err));
+ RequestHandle.Dispose();
+ return false;
+ }
+ }
+ else
+ {
+ err = Interop.PackageManager.PackageManagerRequestUninstall(RequestHandle, packageId, out requestId);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to uninstall package. err = {0}", err));
+ RequestHandle.Dispose();
+ return false;
+ }
+ // RequestHandle isn't necessary when this method is called without 'eventCallback' parameter.
+ RequestHandle.Dispose();
+ }
+ return true;
+ }
+ catch (Exception e)
+ {
+ Log.Warn(LogTag, e.Message);
+ RequestHandle.Dispose();
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Move package to given storage.
+ /// </summary>
+ /// <param name="packageId">Id of the package to be moved</param>
+ /// <param name="newStorage">Storage, package should be moved to</param>
+ /// <returns>Returns true if move request is successful, false otherwise.</returns>
+ /// <remarks>
+ /// The 'true' means that just the request of move is seccessful.
+ /// To check the result of move, the caller should check the progress using MoveProgressChanged event.
+ /// </remarks>
+ /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
+ public static bool Move(string packageId, StorageType newStorage)
+ {
+ return Move(packageId, PackageType.UNKNOWN, newStorage, null);
+ }
+
+ /// <summary>
+ /// Move package to given storage.
+ /// </summary>
+ /// <param name="packageId">Id of the package to be moved</param>
+ /// <param name="type">Optional - Package type for the package to be moved</param>
+ /// <param name="newStorage">Storage, package should be moved to</param>
+ /// <returns>Returns true if move request is successful, false otherwise.</returns>
+ /// <remarks>
+ /// The 'true' means that just the request of move is seccessful.
+ /// To check the result of move, the caller should check the progress using MoveProgressChanged event.
+ /// </remarks>
+ /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
+ public static bool Move(string packageId, PackageType type, StorageType newStorage)
+ {
+ return Move(packageId, type, newStorage, null);
+ }
+
+ /// <summary>
+ /// Move package to given storage.
+ /// </summary>
+ /// <param name="packageId">Id of the package to be moved</param>
+ /// <param name="newStorage">Storage, package should be moved to</param>
+ /// <param name="eventCallback">Optional - The event callback will be invoked only for the current request</param>
+ /// <returns>Returns true if move request is successful, false otherwise.</returns>
+ /// <remarks>
+ /// The 'true' means that just the request of move is seccessful.
+ /// To check the result of move, the caller should check the progress using MoveProgressChanged event.
+ /// </remarks>
+ /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
+ public static bool Move(string packageId, StorageType newStorage, RequestEventCallback eventCallback)
+ {
+ return Move(packageId, PackageType.UNKNOWN, newStorage, eventCallback);
+ }
+
+ /// <summary>
+ /// Move package to given storage.
+ /// </summary>
+ /// <param name="packageId">Id of the package to be moved</param>
+ /// <param name="type">Optional - Package type for the package to be moved</param>
+ /// <param name="newStorage">Storage, package should be moved to</param>
+ /// <param name="eventCallback">Optional - The event callback will be invoked only for the current request</param>
+ /// <returns>Returns true if move request is successful, false otherwise.</returns>
+ /// <remarks>
+ /// The 'true' means that just the request of move is seccessful.
+ /// To check the result of move, the caller should check the progress using MoveProgressChanged event.
+ /// </remarks>
+ /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
+ public static bool Move(string packageId, PackageType type, StorageType newStorage, RequestEventCallback eventCallback)
+ {
+ SafePackageManagerRequestHandle RequestHandle;
+ var err = Interop.PackageManager.PackageManagerRequestCreate(out RequestHandle);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to create package manager request handle. err = {0}", err));
+ return false;
+ }
+
+ try
+ {
+ bool result = true;
+ err = Interop.PackageManager.PackageManagerRequestSetType(RequestHandle, type.ToString().ToLower());
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to move package. Error in setting request package type. err = {0}", err));
+ RequestHandle.Dispose();
+ return false;
+ }
+
+ if (eventCallback != null)
+ {
+ int requestId;
+ err = Interop.PackageManager.PackageManagerRequestMoveWithCB(RequestHandle, packageId, (Interop.PackageManager.StorageType)newStorage, internalRequestEventCallback, IntPtr.Zero, out requestId);
+ if (err == Interop.PackageManager.ErrorCode.None)
+ {
+ RequestCallbacks.Add(requestId, eventCallback);
+ RequestHandles.Add(requestId, RequestHandle);
+ }
+ else
+ {
+ Log.Warn(LogTag, string.Format("Failed to move package to requested location. err = {0}", err));
+ RequestHandle.Dispose();
+ result = false;
+ }
+ }
+ else
+ {
+ err = Interop.PackageManager.PackageManagerRequestMove(RequestHandle, packageId, (Interop.PackageManager.StorageType)newStorage);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to move package to requested location. err = {0}", err));
+ RequestHandle.Dispose();
+ result = false;
+ }
+ // RequestHandle isn't necessary when this method is called without 'eventCallback' parameter.
+ RequestHandle.Dispose();
+ }
+ return result;
+ }
+ catch (Exception e)
+ {
+ Log.Warn(LogTag, e.Message);
+ RequestHandle.Dispose();
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Gets permission type of package which has given application id
+ /// </summary>
+ /// <param name="applicationId">Id of the application</param>
+ /// <returns>Returns permission type.</returns>
+ /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
+ /// <exception cref="ArgumentException">Thrown when failed when input package ID is invalid</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access this method</exception>
+ public static PermissionType GetPermissionTypeByApplicationId(string applicationId)
+ {
+ Interop.PackageManager.PackageManagerPermissionType permissionType;
+ Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerGetPermissionType(applicationId, out permissionType);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ throw PackageManagerErrorFactory.GetException(err, "Failed to get permission type.");
+ }
+
+ return (PermissionType)permissionType;
+ }
+
+ /// <summary>
+ /// Gets package's preload attribute which contain given applicion id
+ /// </summary>
+ /// <param name="applicationId">Id of the application</param>
+ /// <returns>Returns true if package is preloaded. Otherwise return false.</returns>
+ /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
+ /// <exception cref="ArgumentException">Thrown when failed when input package ID is invalid</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access this method</exception>
+ public static bool IsPreloadPackageByApplicationId(string applicationId)
+ {
+ bool isPreloadPackage;
+ Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerIsPreloadPackageByApplicationId(applicationId, out isPreloadPackage);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ throw PackageManagerErrorFactory.GetException(err, "Failed to get preload info");
+ }
+
+ return isPreloadPackage;
+ }
+
+ /// <summary>
+ /// Compare certificate of two packages
+ /// </summary>
+ /// <param name="lhsPackageId">package id to compare</param>
+ /// <param name="rhsPackageId">package id to be compared</param>
+ /// <returns>Returns certificate comparison result.</returns>
+ /// <exception cref="ArgumentException">Thrown when failed when input package ID is invalid</exception>
+ /// <exception cref="System.IO.IOException">Thrown when method failed due to internal IO error</exception>
+ public static CertCompareResultType CompareCertInfo(string lhsPackageId, string rhsPackageId)
+ {
+ Interop.PackageManager.CertCompareResultType compareResult;
+ Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerCompareCertInfo(lhsPackageId, rhsPackageId, out compareResult);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ throw PackageManagerErrorFactory.GetException(err, "Failed to compare cert info");
+ }
+
+ return (CertCompareResultType)compareResult;
+ }
+
+ /// <summary>
+ /// Compare certificate of two packages which contain each given application id
+ /// </summary>
+ /// <param name="lhsApplicationId">application id to compare</param>
+ /// <param name="rhsApplicationId">application id to be compared</param>
+ /// <returns>Returns certificate comparison result.</returns>
+ /// <exception cref="ArgumentException">Thrown when failed when input package ID is invalid</exception>
+ /// <exception cref="System.IO.IOException">Thrown when method failed due to internal IO error</exception>
+ public static CertCompareResultType CompareCertInfoByApplicationId(string lhsApplicationId, string rhsApplicationId)
+ {
+ Interop.PackageManager.CertCompareResultType compareResult;
+ Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerCompareCertInfoByApplicationId(lhsApplicationId, rhsApplicationId, out compareResult);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ throw PackageManagerErrorFactory.GetException(err, "Failed to compare cert info by application id");
+ }
+
+ return (CertCompareResultType)compareResult;
+ }
+
+ /// <summary>
+ /// Drm nested class. This class has the PackageManager's drm related methods.
+ /// </summary>
+ public static class Drm
+ {
+ /// <summary>
+ /// Generates request for getting license
+ /// </summary>
+ /// <param name="responseData">Response data string of the purchase request</param>
+ /// <returns>Returns package drm information of given response data which contains require data and license url</returns>
+ /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
+ /// <exception cref="ArgumentException">Thrown when failed when input package ID is invalid</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access this method</exception>
+ /// <exception cref="SystemException">Thrown when method failed due to internal system error</exception>
+ public static PackageDrm GenerateLicenseRequest(string responseData)
+ {
+ return PackageDrm.GenerateLicenseRequest(responseData);
+
+ }
+
+ /// <summary>
+ /// Registers encrypted license
+ /// </summary>
+ /// <param name="responseData">The response data string of the rights request</param>
+ /// <returns>Returns true if succeed. Otherwise return false</returns>
+ /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
+ /// <exception cref="ArgumentException">Thrown when failed when input package ID is invalid</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access this method</exception>
+ /// <exception cref="SystemException">Thrown when method failed due to internal system error</exception>
+ public static bool RegisterLicense(string responseData)
+ {
+ Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerDrmRegisterLicense(responseData);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ throw PackageManagerErrorFactory.GetException(err, "Failed to register drm license");
+ }
+
+ return true;
+ }
+
+ /// <summary>
+ /// Decrypts contents which is encrypted
+ /// </summary>
+ /// <param name="drmFilePath">Drm file path</param>
+ /// <param name="decryptedFilePath">Decrypted file path</param>
+ /// <returns>Returns true if succeed. Otherwise return false</returns>
+ /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
+ /// <exception cref="ArgumentException">Thrown when failed when input package ID is invalid</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access this method</exception>
+ /// <exception cref="SystemException">Thrown when method failed due to internal system error</exception>
+ public static bool DecryptPackage(string drmFilePath, string decryptedFilePath)
+ {
+ Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerDrmDecryptPackage(drmFilePath, decryptedFilePath);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ throw PackageManagerErrorFactory.GetException(err, "Failed to decrypt drm package");
+ }
+
+ return true;
+ }
+ }
+
+ private static void SetPackageManagerEventStatus(Interop.PackageManager.EventStatus status)
+ {
+ if (Handle.IsInvalid) return;
+
+ Interop.PackageManager.EventStatus eventStatus = s_eventStatus;
+ eventStatus |= status;
+ if (eventStatus != Interop.PackageManager.EventStatus.All)
+ eventStatus |= Interop.PackageManager.EventStatus.Progress;
+
+ var err = Interop.PackageManager.ErrorCode.None;
+ if (s_eventStatus != eventStatus)
+ {
+ err = Interop.PackageManager.PackageManagerSetEvenStatus(Handle, eventStatus);
+ if (err == Interop.PackageManager.ErrorCode.None)
+ {
+ s_eventStatus = eventStatus;
+ Log.Debug(LogTag, string.Format("New Event Status flag: {0}", s_eventStatus));
+ return;
+ }
+ Log.Debug(LogTag, string.Format("Failed to set flag for {0} event. err = {1}", eventStatus, err));
+ }
+ }
+
+ private static void UnsetPackageManagerEventStatus()
+ {
+ if (Handle.IsInvalid) return;
+
+ Interop.PackageManager.EventStatus eventStatus = Interop.PackageManager.EventStatus.All;
+ if (s_installEventHandler != null) eventStatus |= Interop.PackageManager.EventStatus.Install;
+ if (s_uninstallEventHandler != null) eventStatus |= Interop.PackageManager.EventStatus.Uninstall;
+ if (s_updateEventHandler != null) eventStatus |= Interop.PackageManager.EventStatus.Upgrade;
+ if (s_moveEventHandler != null) eventStatus |= Interop.PackageManager.EventStatus.Move;
+ if (s_clearDataEventHandler != null) eventStatus |= Interop.PackageManager.EventStatus.ClearData;
+ if (eventStatus != Interop.PackageManager.EventStatus.All)
+ eventStatus |= Interop.PackageManager.EventStatus.Progress;
+
+ var err = Interop.PackageManager.ErrorCode.None;
+ if (s_eventStatus != eventStatus)
+ {
+ err = Interop.PackageManager.PackageManagerSetEvenStatus(Handle, eventStatus);
+ if (err == Interop.PackageManager.ErrorCode.None)
+ {
+ s_eventStatus = eventStatus;
+ Log.Debug(LogTag, string.Format("New Event Status flag: {0}", s_eventStatus));
+ return;
+ }
+ Log.Debug(LogTag, string.Format("Failed to set flag for {0} event. err = {1}", eventStatus, err));
+ }
+ }
+
+ private static void RegisterPackageManagerEventIfNeeded()
+ {
+ if (s_installEventHandler != null && s_uninstallEventHandler != null && s_updateEventHandler != null && s_moveEventHandler != null && s_clearDataEventHandler != null)
+ {
+ return;
+ }
+
+ var err = Interop.PackageManager.ErrorCode.None;
+ s_packageManagerEventCallback = (packageType, packageId, eventType, eventState, progress, error, user_data) =>
+ {
+ try
+ {
+ if (eventType == Interop.PackageManager.EventType.Install)
+ {
+ s_installEventHandler?.Invoke(null, new PackageManagerEventArgs(packageType, packageId, (PackageEventState)eventState, progress));
+ }
+ else if (eventType == Interop.PackageManager.EventType.Uninstall)
+ {
+ s_uninstallEventHandler?.Invoke(null, new PackageManagerEventArgs(packageType, packageId, (PackageEventState)eventState, progress));
+ }
+ else if (eventType == Interop.PackageManager.EventType.Update)
+ {
+ s_updateEventHandler?.Invoke(null, new PackageManagerEventArgs(packageType, packageId, (PackageEventState)eventState, progress));
+ }
+ else if (eventType == Interop.PackageManager.EventType.Move)
+ {
+ s_moveEventHandler?.Invoke(null, new PackageManagerEventArgs(packageType, packageId, (PackageEventState)eventState, progress));
+ }
+ else if (eventType == Interop.PackageManager.EventType.ClearData)
+ {
+ s_clearDataEventHandler?.Invoke(null, new PackageManagerEventArgs(packageType, packageId, (PackageEventState)eventState, progress));
+ }
+ }
+ catch (Exception e)
+ {
+ Log.Warn(LogTag, e.Message);
+ }
+ };
+
+ if (!Handle.IsInvalid)
+ {
+ Log.Debug(LogTag, "Reset Package Event");
+ err = Interop.PackageManager.PackageManagerUnsetEvent(Handle);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ throw PackageManagerErrorFactory.GetException(err, "Failed to unregister package manager event event.");
+ }
+
+ err = Interop.PackageManager.PackageManagerSetEvent(Handle, s_packageManagerEventCallback, IntPtr.Zero);
+ }
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to register callback for package manager event. err = {0}", err));
+ }
+ }
+
+ private static void UnregisterPackageManagerEventIfNeeded()
+ {
+ if (Handle.IsInvalid || s_installEventHandler != null || s_uninstallEventHandler != null || s_updateEventHandler != null || s_moveEventHandler != null || s_clearDataEventHandler != null)
+ {
+ return;
+ }
+
+ var err = Interop.PackageManager.PackageManagerUnsetEvent(Handle);
+ if (err != Interop.PackageManager.ErrorCode.None)
+ {
+ throw PackageManagerErrorFactory.GetException(err, "Failed to unregister package manager event event.");
+ }
+ }
+ }
+
+ internal static class PackageManagerErrorFactory
+ {
+ internal static Exception GetException(Interop.PackageManager.ErrorCode err, string message)
+ {
+ string errMessage = string.Format("{0} err = {1}", message, err);
+ switch (err)
+ {
+ case Interop.PackageManager.ErrorCode.InvalidParameter:
+ case Interop.PackageManager.ErrorCode.NoSuchPackage:
+ return new ArgumentException(errMessage);
+ case Interop.PackageManager.ErrorCode.PermissionDenied:
+ return new UnauthorizedAccessException(errMessage);
+ case Interop.PackageManager.ErrorCode.IoError:
+ return new global::System.IO.IOException(errMessage);
+ default:
+ return new InvalidOperationException(errMessage);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageManagerEventArgs.cs b/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageManagerEventArgs.cs
new file mode 100755
index 0000000..ba0466f
--- /dev/null
+++ b/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageManagerEventArgs.cs
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// PackageManagerEventArgs class. This class is an event arguments of the InstallProgressChanged, UninstallProgressChanged and UpdateProgressChanged events.
+ /// </summary>
+ public class PackageManagerEventArgs : EventArgs
+ {
+ private readonly PackageType _packageType;
+ private readonly string _packageId;
+ private readonly PackageEventState _state;
+ private readonly int _progress;
+
+ internal PackageManagerEventArgs(string packageType, string packageId, PackageEventState state, int progress)
+ {
+ _packageType = PackageTypeMethods.ToPackageType(packageType);
+ _packageId = packageId;
+ _state = state;
+ _progress = progress;
+ }
+
+ /// <summary>
+ /// Type of the package to be installed, uninstalled or updated
+ /// </summary>
+ public PackageType PackageType { get { return _packageType; } }
+
+ /// <summary>
+ /// package ID to be installed, uninstalled or updated
+ /// </summary>
+ public string PackageId { get { return _packageId; } }
+
+ /// <summary>
+ /// Current state of the request to the package manager
+ /// </summary>
+ public PackageEventState State { get { return _state; } }
+
+ /// <summary>
+ /// Progress for the request being processed by the package manager (in percent).
+ /// </summary>
+ public int Progress { get { return _progress; } }
+ }
+}
diff --git a/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageSizeInformation.cs b/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageSizeInformation.cs
new file mode 100755
index 0000000..7269f74
--- /dev/null
+++ b/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageSizeInformation.cs
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// This class has the read only properties to get package size information.
+ /// </summary>
+ public class PackageSizeInformation
+ {
+ private long _dataSize;
+ private long _cacheSize;
+ private long _appSize;
+ private long _externalDataSize;
+ private long _externalCacheSize;
+ private long _externalAppSize;
+
+ private PackageSizeInformation() { }
+
+ /// <summary>
+ /// Data size for package.
+ /// </summary>
+ public long DataSize { get { return _dataSize; } }
+
+ /// <summary>
+ /// Cache size for package.
+ /// </summary>
+ public long CacheSize { get { return _cacheSize; } }
+
+ /// <summary>
+ /// Application size for package.
+ /// </summary>
+ public long AppSize { get { return _appSize; } }
+
+ /// <summary>
+ /// External data size for package.
+ /// </summary>
+ public long ExternalDataSize { get { return _externalDataSize; } }
+
+ /// <summary>
+ /// External cache size for package.
+ /// </summary>
+ public long ExternalCacheSize { get { return _externalCacheSize; } }
+
+ /// <summary>
+ /// External application size for package.
+ /// </summary>
+ public long ExternalAppSize { get { return _externalAppSize; } }
+
+ // This method assumes that pass handle is already validated
+ internal static PackageSizeInformation GetPackageSizeInformation(IntPtr handle)
+ {
+ var pkgSizeInfo = new PackageSizeInformation();
+ Interop.PackageManager.PackageSizeInfoGetDataSize(handle, out pkgSizeInfo._dataSize);
+ Interop.PackageManager.PackageSizeInfoGetCacheSize(handle, out pkgSizeInfo._cacheSize);
+ Interop.PackageManager.PackageSizeInfoGetAppSize(handle, out pkgSizeInfo._appSize);
+ Interop.PackageManager.PackageSizeInfoGetExtDataSize(handle, out pkgSizeInfo._externalDataSize);
+ Interop.PackageManager.PackageSizeInfoGetExtCacheSize(handle, out pkgSizeInfo._externalCacheSize);
+ Interop.PackageManager.PackageSizeInfoGetExtAppSize(handle, out pkgSizeInfo._externalAppSize);
+ return pkgSizeInfo;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageType.cs b/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageType.cs
new file mode 100755
index 0000000..e8a0042
--- /dev/null
+++ b/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageType.cs
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Enumeration for package type.
+ /// </summary>
+ public enum PackageType
+ {
+ UNKNOWN,
+ /// <summary>
+ /// Tizen native application package
+ /// </summary>
+ TPK,
+ /// <summary>
+ /// Tizen web/ hybrid application Package
+ /// </summary>
+ WGT,
+ /// <summary>
+ /// It's a special meaning type to represent the tizen application package which is installed using rpm spec.
+ /// Only some preloaded packages can have this type.
+ /// </summary>
+ RPM
+ }
+
+ internal static class PackageTypeMethods
+ {
+ internal static PackageType ToPackageType(string type)
+ {
+ if (string.IsNullOrEmpty(type))
+ {
+ throw PackageManagerErrorFactory.GetException(Interop.PackageManager.ErrorCode.InvalidParameter, "type can't be null or empty");
+ }
+
+ string lowerType = type.ToLower();
+ if (lowerType == "tpk")
+ {
+ return PackageType.TPK;
+ }
+ else if (lowerType == "wgt")
+ {
+ return PackageType.WGT;
+ }
+ else if (lowerType == "rpm")
+ {
+ return PackageType.RPM;
+ }
+ else
+ {
+ throw PackageManagerErrorFactory.GetException(Interop.PackageManager.ErrorCode.InvalidParameter, "type should be tpk or wgt");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.PackageManager/Tizen.Applications/PermissionType.cs b/src/Tizen.Applications.PackageManager/Tizen.Applications/PermissionType.cs
new file mode 100644
index 0000000..c4a4e2f
--- /dev/null
+++ b/src/Tizen.Applications.PackageManager/Tizen.Applications/PermissionType.cs
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Enumeration for permission type.
+ /// </summary>
+ public enum PermissionType
+ {
+ /// <summary>
+ /// Permission is normal
+ /// </summary>
+ Normal,
+ /// <summary>
+ /// Permission is signature
+ /// </summary>
+ Signature,
+ /// <summary>
+ /// Permission is privilege
+ /// </summary>
+ Privilege
+ }
+}
diff --git a/src/Tizen.Applications.PackageManager/Tizen.Applications/SafePackageManagerHandle.cs b/src/Tizen.Applications.PackageManager/Tizen.Applications/SafePackageManagerHandle.cs
new file mode 100755
index 0000000..15e0c82
--- /dev/null
+++ b/src/Tizen.Applications.PackageManager/Tizen.Applications/SafePackageManagerHandle.cs
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Applications
+{
+ internal class SafePackageManagerHandle : SafeHandle
+ {
+ /// <summary>
+ /// Initializes a new instance of the SafePackageManagerHandle class.
+ /// </summary>
+ public SafePackageManagerHandle() : base(IntPtr.Zero, true)
+ {
+ }
+
+ /// <summary>
+ /// Gets a value that indicates whether the handle is invalid.
+ /// </summary>
+ public override bool IsInvalid
+ {
+ get { return handle == IntPtr.Zero; }
+ }
+
+ /// <summary>
+ /// Executes the code required to free the SafePackageManagerHandle.
+ /// </summary>
+ /// <returns>true if the handle is released successfully</returns>
+ protected override bool ReleaseHandle()
+ {
+ Interop.PackageManager.PackageManagerDestroy(handle);
+ this.SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+}
diff --git a/src/Tizen.Applications.PackageManager/Tizen.Applications/SafePackageManagerRequestHandle.cs b/src/Tizen.Applications.PackageManager/Tizen.Applications/SafePackageManagerRequestHandle.cs
new file mode 100755
index 0000000..add74f5
--- /dev/null
+++ b/src/Tizen.Applications.PackageManager/Tizen.Applications/SafePackageManagerRequestHandle.cs
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Applications
+{
+ internal class SafePackageManagerRequestHandle : SafeHandle
+ {
+ /// <summary>
+ /// Initializes a new instance of the SafePackageManagerRequestHandle class.
+ /// </summary>
+ public SafePackageManagerRequestHandle() : base(IntPtr.Zero, true)
+ {
+ }
+
+ /// <summary>
+ /// Gets a value that indicates whether the handle is invalid.
+ /// </summary>
+ public override bool IsInvalid
+ {
+ get { return handle == IntPtr.Zero; }
+ }
+
+ /// <summary>
+ /// Executes the code required to free the SafePackageManagerRequestHandle.
+ /// </summary>
+ /// <returns>true if the handle is released successfully</returns>
+ protected override bool ReleaseHandle()
+ {
+ Interop.PackageManager.PackageManagerRequestDestroy(handle);
+ this.SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Applications.PackageManager/Tizen.Applications/StorageType.cs b/src/Tizen.Applications.PackageManager/Tizen.Applications/StorageType.cs
new file mode 100755
index 0000000..8246188
--- /dev/null
+++ b/src/Tizen.Applications.PackageManager/Tizen.Applications/StorageType.cs
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Enumeration for storage type.
+ /// </summary>
+ public enum StorageType
+ {
+ /// <summary>
+ /// Internal storage.
+ /// </summary>
+ Internal = Interop.PackageManager.StorageType.Internal,
+ /// <summary>
+ /// External storage.
+ /// </summary>
+ External = Interop.PackageManager.StorageType.External
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Applications.Preference/Interop/Interop.Libraries.cs b/src/Tizen.Applications.Preference/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..d65c742
--- /dev/null
+++ b/src/Tizen.Applications.Preference/Interop/Interop.Libraries.cs
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string Preference = "libcapi-appfw-preference.so.0";
+ }
+}
diff --git a/src/Tizen.Applications.Preference/Interop/Interop.Preference.cs b/src/Tizen.Applications.Preference/Interop/Interop.Preference.cs
new file mode 100755
index 0000000..dd98962
--- /dev/null
+++ b/src/Tizen.Applications.Preference/Interop/Interop.Preference.cs
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Applications;
+
+/// <summary>
+/// Contains Interop declarations of Preference classes.
+/// </summary>
+internal static partial class Interop
+{
+ /// <summary>
+ /// Contains Interop declarations of Preference device API.
+ /// </summary>
+ internal static partial class Preference
+ {
+ internal delegate void ChangedCallback(string key, IntPtr userData);
+
+ internal delegate bool ItemCallback(string key, IntPtr userData);
+
+ [DllImport(Libraries.Preference, EntryPoint = "preference_set_int")]
+ internal static extern int SetInt(string key, int value);
+
+ [DllImport(Libraries.Preference, EntryPoint = "preference_get_int")]
+ internal static extern int GetInt(string key, out int value);
+
+ [DllImport(Libraries.Preference, EntryPoint = "preference_set_double")]
+ internal static extern int SetDouble(string key, double value);
+
+ [DllImport(Libraries.Preference, EntryPoint = "preference_get_double")]
+ internal static extern int GetDouble(string key, out double value);
+
+ [DllImport(Libraries.Preference, EntryPoint = "preference_set_string")]
+ internal static extern int SetString(string key, string value);
+
+ [DllImport(Libraries.Preference, EntryPoint = "preference_get_string")]
+ internal static extern int GetString(string key, out string value);
+
+ [DllImport(Libraries.Preference, EntryPoint = "preference_set_boolean")]
+ internal static extern int SetBoolean(string key, bool value);
+
+ [DllImport(Libraries.Preference, EntryPoint = "preference_get_boolean")]
+ internal static extern int GetBoolean(string key, out bool value);
+
+ [DllImport(Libraries.Preference, EntryPoint = "preference_remove")]
+ internal static extern int Remove(string key);
+
+ [DllImport(Libraries.Preference, EntryPoint = "preference_is_existing")]
+ internal static extern int IsExisting(string key, out bool existing);
+
+ [DllImport(Libraries.Preference, EntryPoint = "preference_remove_all")]
+ internal static extern int RemoveAll();
+
+ [DllImport(Libraries.Preference, EntryPoint = "preference_set_changed_cb")]
+ internal static extern int SetChangedCb(string key, ChangedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Preference, EntryPoint = "preference_unset_changed_cb")]
+ internal static extern int UnsetChangedCb(string key);
+
+ [DllImport(Libraries.Preference, EntryPoint = "preference_foreach_item")]
+ internal static extern int ForeachItem(ItemCallback callback, IntPtr userData);
+ }
+}
diff --git a/src/Tizen.Applications.Preference/Tizen.Applications.Preference.csproj b/src/Tizen.Applications.Preference/Tizen.Applications.Preference.csproj
new file mode 100755
index 0000000..517b746
--- /dev/null
+++ b/src/Tizen.Applications.Preference/Tizen.Applications.Preference.csproj
@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen.Applications.Common\Tizen.Applications.Common.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project> \ No newline at end of file
diff --git a/src/Tizen.Applications.Preference/Tizen.Applications/Preference.cs b/src/Tizen.Applications.Preference/Tizen.Applications/Preference.cs
new file mode 100755
index 0000000..4fd6e79
--- /dev/null
+++ b/src/Tizen.Applications.Preference/Tizen.Applications/Preference.cs
@@ -0,0 +1,463 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// The Preference class provides APIs to store and retrieve application specific data/preference. A preference is saved in the form of a key-value pair.
+ /// Keys are always text strings and value can be any one of four types: integer, double, string and boolean.
+ /// </summary>
+ public static class Preference
+ {
+ private const string LogTag = "Tizen.Applications";
+ private static Interop.Preference.ChangedCallback s_preferenceChangedCallback;
+ private static IDictionary<string, EventContext> s_eventMap = new Dictionary<string, EventContext>();
+
+ static Preference()
+ {
+ s_preferenceChangedCallback = (string key, IntPtr userData) =>
+ {
+ try
+ {
+ s_eventMap[key]?.FireEvent();
+ }
+ catch (Exception e)
+ {
+ Log.Warn(LogTag, e.Message);
+ }
+ };
+ }
+
+ /// <summary>
+ /// Retrieves all keys of the application preferences
+ /// </summary>
+ /// <value>
+ /// The list of keys
+ /// </value>
+ /// <example>
+ /// <code>
+ /// Preference.Set("Option_enabled", true);
+ /// Preference.Set("active_user", "Joe");
+ /// Preference.Set("default_volume", 10);
+ /// Preference.Set("brightness", "0.6");
+ /// foreach(string key in Preference.Keys)
+ /// {
+ /// Console.WriteLine("key {0}", key);
+ /// }
+ /// </code>
+ /// </example>
+ public static IEnumerable<string> Keys
+ {
+ get
+ {
+ var collection = new List<string>();
+ Interop.Preference.ItemCallback itemsCallback = (string key, IntPtr userData) =>
+ {
+ collection.Add(key);
+ return true;
+ };
+ Interop.Preference.ForeachItem(itemsCallback, IntPtr.Zero);
+ return collection;
+ }
+ }
+
+ /// <summary>
+ /// Gets the event context for the given key.
+ /// </summary>
+ /// <seealso cref="EventContext"/>
+ /// <param name="key">The preference key</param>
+ /// <returns>The event context of respective key</returns>
+ /// <exception cref="KeyNotFoundException">Thrown if the key is not found</exception>
+ /// <exception cref="ArgumentException">Thrown if the key is an invalid parameter.</exception>
+ /// <example>
+ /// <code>
+ /// private static void Preference_PreferenceChanged(object sender, PreferenceChangedEventArgs e)
+ /// {
+ /// Console.WriteLine("key {0}", e.Key);
+ /// }
+ ///
+ /// Preference.EventContext context = null;
+ /// Preference.GetEventContext("active_user").TryGetTarget(out context);
+ /// if(context != null)
+ /// {
+ /// context.Changed += Preference_PreferenceChanged;
+ /// }
+ ///
+ /// Preference.Set("active_user", "Poe");
+ ///
+ /// Preference.GetEventContext("active_user").TryGetTarget(out context);
+ /// if (context != null)
+ /// {
+ /// context.Changed -= Preference_PreferenceChanged;
+ /// }
+ /// </code>
+ /// </example>
+ public static WeakReference<EventContext> GetEventContext(string key)
+ {
+ if (!s_eventMap.ContainsKey(key))
+ {
+ if (Contains(key))
+ {
+ s_eventMap[key] = new EventContext(key);
+ }
+ else
+ {
+ throw PreferenceErrorFactory.GetException((int)PreferenceErrorFactory.PreferenceError.KeyNotAvailable);
+ }
+ }
+
+ return new WeakReference<EventContext>(s_eventMap[key]);
+ }
+
+ /// <summary>
+ /// Checks whether the given key exists in the preference.
+ /// </summary>
+ /// <param name="key">The name of the key to check</param>
+ /// <returns>true if the key exists in the preference, otherwise false</returns>
+ /// <exception cref="ArgumentException">Thrown if the key is an invalid parameter.</exception>
+ /// <exception cref="IOException">Thrown when method failed due to internal IO error.</exception>
+ /// <example>
+ /// <code>
+ /// Preference.Set("active_user", "Joe");
+ /// bool exists = Preference.Contains("active_user");
+ /// if (exists)
+ /// {
+ /// string value = Preference.Get<string>("active_user");
+ /// Console.WriteLine("user {0}", value);
+ /// }
+ /// </code>
+ /// </example>
+ public static bool Contains(string key)
+ {
+ bool contains;
+ int ret = Interop.Preference.IsExisting(key, out contains);
+ if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
+ {
+ Log.Error(LogTag, "Failed to find key");
+ throw PreferenceErrorFactory.GetException(ret);
+ }
+
+ return contains;
+ }
+
+ /// <summary>
+ /// Sets a key-value pair representing the preference.
+ /// </summary>
+ /// <remarks>
+ /// If the key already exists in the Preference, old value will be overwritten with new value.
+ /// Data types supported for value are: integer, double, string and bool.
+ /// </remarks>
+ /// <param name="key">The name of the key to create/modigy</param>
+ /// <param name="value">The value corresponding to the key.</param>
+ /// <exception cref="ArgumentException">Thrown if the key is an invalid parameter.</exception>
+ /// <exception cref="System.IO.IOException">Thrown when method failed due to internal IO error.</exception>
+ /// <example>
+ /// <code>
+ /// Preference.Set("Option_enabled", true);
+ /// Preference.Set("active_user", "Joe");
+ /// Preference.Set("default_volume", 10);
+ /// Preference.Set("brightness", "0.6");
+ /// </code>
+ /// </example>
+ public static void Set(string key, object value)
+ {
+ int ret = 0;
+ if (value is int)
+ {
+ ret = Interop.Preference.SetInt(key, (int)value);
+ if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
+ {
+ Log.Error(LogTag, "Failed to find key");
+ throw PreferenceErrorFactory.GetException(ret);
+ }
+ }
+ else if (value is double)
+ {
+ ret = Interop.Preference.SetDouble(key, (double)value);
+ if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
+ {
+ Log.Error(LogTag, "Failed to find key");
+ throw PreferenceErrorFactory.GetException(ret);
+ }
+ }
+ else if (value is string)
+ {
+ ret = Interop.Preference.SetString(key, (string)value);
+ if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
+ {
+ Log.Error(LogTag, "Failed to find key");
+ throw PreferenceErrorFactory.GetException(ret);
+ }
+ }
+ else if (value is bool)
+ {
+ ret = Interop.Preference.SetBoolean(key, (bool)value);
+ if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
+ {
+ Log.Error(LogTag, "Failed to find key");
+ throw PreferenceErrorFactory.GetException(ret);
+ }
+ }
+ else
+ {
+ Log.Error(LogTag, "Failed to Set");
+ throw new ArgumentException("Invalid parameter");
+ }
+ }
+
+ /// <summary>
+ /// Gets the value of a preference item with the specified key.
+ /// Note that this is a generic method.
+ /// </summary>
+ /// <typeparam name="T">The generic type to return.</typeparam>
+ /// <param name="key">The key of the preference</param>
+ /// <returns>The value of the preference item if it is of the specified generic type.</returns>
+ /// <exception cref="KeyNotFoundException">Thrown if the key is not found</exception>
+ /// <exception cref="ArgumentException">Thrown if the key is an invalid parameter.</exception>
+ /// <exception cref="System.IO.IOException">Thrown when method failed due to internal IO error.</exception>
+ /// <example>
+ /// <code>
+ /// bool exists = Preference.Contains("active_user");
+ /// if (exists)
+ /// {
+ /// string value = Preference.Get<string>("active_user");
+ /// Console.WriteLine("user {0}", value);
+ /// }
+ /// </code>
+ /// </example>
+ public static T Get<T>(string key)
+ {
+ object result = null;
+ int ret = (int)PreferenceErrorFactory.PreferenceError.None;
+ if (typeof(T) == typeof(bool))
+ {
+ bool val;
+ ret = Interop.Preference.GetBoolean(key, out val);
+ result = val;
+ }
+ else if (typeof(T) == typeof(int))
+ {
+ int val;
+ ret = Interop.Preference.GetInt(key, out val);
+ result = val;
+ }
+ else if (typeof(T) == typeof(string))
+ {
+ string val;
+ ret = Interop.Preference.GetString(key, out val);
+ result = val;
+ }
+ else if (typeof(T) == typeof(double))
+ {
+ double val;
+ ret = Interop.Preference.GetDouble(key, out val);
+ result = val;
+ }
+ else
+ {
+ Log.Error(LogTag, "Failed to remove key");
+ throw new ArgumentException("Invalid parameter");
+ }
+
+ if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
+ {
+ Log.Error(LogTag, "Failed to remove key");
+ throw PreferenceErrorFactory.GetException(ret);
+ }
+
+ return (result != null) ? (T)result : default(T);
+ }
+
+ /// <summary>
+ /// Removes any preference value with the given key.
+ /// </summary>
+ /// <param name="key">The key to remove</param>
+ /// <exception cref="KeyNotFoundException">Thrown if the key is not found</exception>
+ /// <exception cref="System.IO.IOException">Thrown when method failed due to internal IO error.</exception>
+ /// <example>
+ /// <code>
+ /// bool exists = Preference.Contains("active_user");
+ /// if (exists)
+ /// {
+ /// string value = Preference.Remove("active_user");
+ /// }
+ /// </code>
+ /// </example>
+ public static void Remove(string key)
+ {
+ int ret = Interop.Preference.Remove(key);
+ if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
+ {
+ Log.Error(LogTag, "Failed to remove key");
+ throw PreferenceErrorFactory.GetException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Removes all key-value pairs from the preference.
+ /// </summary>
+ /// <exception cref="System.IO.IOException">Thrown when method failed due to internal IO error.</exception>
+ /// <example>
+ /// <code>
+ /// Preference.Set("Option_enabled", true);
+ /// Preference.Set("active_user", "Joe");
+ /// Preference.Set("default_volume", 10);
+ /// Preference.Set("brightness", "0.6");
+ /// Preference.RemoveAll();
+ /// </code>
+ /// </example>
+ public static void RemoveAll()
+ {
+ int ret = Interop.Preference.RemoveAll();
+ if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
+ {
+ Log.Error(LogTag, "Failed to remove all keys");
+ throw PreferenceErrorFactory.GetException(ret);
+ }
+ }
+
+ private static void AllowChangeNotifications(string key)
+ {
+ int ret = Interop.Preference.SetChangedCb(key, s_preferenceChangedCallback, IntPtr.Zero);
+ if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
+ {
+ Log.Error(LogTag, "Failed to set key notification");
+ throw PreferenceErrorFactory.GetException(ret);
+ }
+ }
+
+ private static void DisallowChangeNotifications(string key)
+ {
+ int ret = Interop.Preference.UnsetChangedCb(key);
+ if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
+ {
+ Log.Error(LogTag, "Failed to remove key notification");
+ throw PreferenceErrorFactory.GetException(ret);
+ }
+ }
+
+ /// <summary>
+ /// The class manages event handlers of preference keys. The class enables having event handlers for individual preference keys.
+ /// </summary>
+ public class EventContext
+ {
+ private string _key;
+
+ internal EventContext(string key)
+ {
+ _key = key;
+ }
+
+ /// <summary>
+ /// Occurs whenever there is change in the value of preference key.
+ /// </summary>
+ /// <exception cref="System.ArgumentException">Thrown when the key does not exist or when there is an invalid parameter.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when the Bundle instance has been disposed.</exception>
+ /// <example>
+ /// <code>
+ /// private static void Preference_PreferenceChanged(object sender, PreferenceChangedEventArgs e)
+ /// {
+ /// Console.WriteLine("key {0}", e.Key);
+ /// }
+ /// Preference.EventContext context = null;
+ /// Preference.GetEventContext("active_user").TryGetTarget(out context);
+ /// if(context != null)
+ /// {
+ /// context.Changed += Preference_PreferenceChanged;
+ /// }
+ ///
+ /// Preference.Set("active_user", "Poe");
+ ///
+ /// Preference.GetEventContext("active_user").TryGetTarget(out context);
+ /// if (context != null)
+ /// {
+ /// context.Changed -= Preference_PreferenceChanged;
+ /// }
+ /// </code>
+ /// </example>
+ public event EventHandler<PreferenceChangedEventArgs> Changed
+ {
+ add
+ {
+ if (_changed == null)
+ {
+ AllowChangeNotifications(_key);
+ }
+
+ _changed += value;
+ }
+
+ remove
+ {
+ _changed -= value;
+ if (_changed == null)
+ {
+ DisallowChangeNotifications(_key);
+ s_eventMap.Remove(_key);
+ }
+ }
+ }
+
+ private event EventHandler<PreferenceChangedEventArgs> _changed;
+
+ internal void FireEvent()
+ {
+ _changed?.Invoke(null, new PreferenceChangedEventArgs() { Key = _key });
+ }
+ }
+
+ }
+
+ internal static class PreferenceErrorFactory
+ {
+ internal enum PreferenceError
+ {
+ None = ErrorCode.None,
+ OutOfMemory = ErrorCode.OutOfMemory,
+ InvalidParameter = ErrorCode.InvalidParameter,
+ KeyNotAvailable = -0x01100000 | 0x30,
+ IoError = ErrorCode.IoError
+ }
+
+ static internal Exception GetException(int error)
+ {
+ if ((PreferenceError)error == PreferenceError.OutOfMemory)
+ {
+ return new OutOfMemoryException("Out of memory");
+ }
+ else if ((PreferenceError)error == PreferenceError.InvalidParameter)
+ {
+ return new ArgumentException("Invalid parameter");
+ }
+ else if ((PreferenceError)error == PreferenceError.KeyNotAvailable)
+ {
+ return new KeyNotFoundException("Key does not exist in the bundle");
+ }
+ else if ((PreferenceError)error == PreferenceError.IoError)
+ {
+ return new System.IO.IOException("I/O Error");
+ }
+ else
+ {
+ return new ArgumentException("Unknown error");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Preference/Tizen.Applications/PreferenceChangedEventArgs.cs b/src/Tizen.Applications.Preference/Tizen.Applications/PreferenceChangedEventArgs.cs
new file mode 100755
index 0000000..5386c77
--- /dev/null
+++ b/src/Tizen.Applications.Preference/Tizen.Applications/PreferenceChangedEventArgs.cs
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// This class is an event arguments of the PreferenceChanged events.
+ /// </summary>
+ public class PreferenceChangedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// The key of the preference whose value is changed.
+ /// </summary>
+ public string Key { get; internal set; }
+ }
+}
diff --git a/src/Tizen.Applications.RemoteView/Interop/Interop.Libraries.cs b/src/Tizen.Applications.RemoteView/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..309f4e4
--- /dev/null
+++ b/src/Tizen.Applications.RemoteView/Interop/Interop.Libraries.cs
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string WidgetViewerEvas = "libwidget_viewer_evas.so.1";
+ }
+}
diff --git a/src/Tizen.Applications.RemoteView/Interop/Interop.WidgetViewerEvas.cs b/src/Tizen.Applications.RemoteView/Interop/Interop.WidgetViewerEvas.cs
new file mode 100755
index 0000000..30ca171
--- /dev/null
+++ b/src/Tizen.Applications.RemoteView/Interop/Interop.WidgetViewerEvas.cs
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+using Tizen.Applications;
+
+internal static partial class Interop
+{
+ internal static partial class WidgetViewerEvas
+ {
+ internal enum ErrorCode : int
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None,
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+ OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
+ ResourceBusy = Tizen.Internals.Errors.ErrorCode.ResourceBusy,
+ PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied,
+ Canceled = Tizen.Internals.Errors.ErrorCode.Canceled,
+ IoError = Tizen.Internals.Errors.ErrorCode.IoError,
+ TimedOut = Tizen.Internals.Errors.ErrorCode.TimedOut,
+ NotSupported = Tizen.Internals.Errors.ErrorCode.NotSupported,
+ FileNoSpaceOnDevice = Tizen.Internals.Errors.ErrorCode.FileNoSpaceOnDevice,
+ Fault = -0x02F40000 | 0x0001,
+ AlreadyExist = -0x02F40000 | 0x0002,
+ AlreadyStarted = -0x02F40000 | 0x0004,
+ NotExist = -0x02F40000 | 0x0008,
+ Disabled = -0x02F40000 | 0x0010,
+ MaxExceeded = -0x02F40000 | 0x0011,
+ }
+
+ [DllImport(Libraries.WidgetViewerEvas, EntryPoint = "widget_viewer_evas_init")]
+ internal static extern ErrorCode Init(IntPtr win);
+
+ [DllImport(Libraries.WidgetViewerEvas, EntryPoint = "widget_viewer_evas_fini")]
+ internal static extern ErrorCode Fini();
+
+ [DllImport(Libraries.WidgetViewerEvas, EntryPoint = "widget_viewer_evas_add_widget")]
+ internal static extern IntPtr AddWidget(IntPtr parent, string widgetId, string content, double period);
+
+ [DllImport(Libraries.WidgetViewerEvas, EntryPoint = "widget_viewer_evas_notify_resumed_status_of_viewer")]
+ internal static extern ErrorCode NotifyResumedStatusOfViewer();
+
+ [DllImport(Libraries.WidgetViewerEvas, EntryPoint = "widget_viewer_evas_notify_paused_status_of_viewer")]
+ internal static extern ErrorCode NotifyPausedStatusOfViewer();
+
+ [DllImport(Libraries.WidgetViewerEvas, EntryPoint = "widget_viewer_evas_pause_widget")]
+ internal static extern ErrorCode PauseWidget(IntPtr widget);
+
+ [DllImport(Libraries.WidgetViewerEvas, EntryPoint = "widget_viewer_evas_resume_widget")]
+ internal static extern ErrorCode ResumeWidget(IntPtr widget);
+
+ [DllImport(Libraries.WidgetViewerEvas, EntryPoint = "widget_viewer_evas_get_content_info")]
+ internal static extern IntPtr GetContentInfo(IntPtr widget);
+
+ [DllImport(Libraries.WidgetViewerEvas, EntryPoint = "widget_viewer_evas_get_title_string")]
+ internal static extern IntPtr GetTitleString(IntPtr widget);
+
+ [DllImport(Libraries.WidgetViewerEvas, EntryPoint = "widget_viewer_evas_get_widget_id")]
+ internal static extern IntPtr GetWidgetId(IntPtr widget);
+
+ [DllImport(Libraries.WidgetViewerEvas, EntryPoint = "widget_viewer_evas_get_period")]
+ internal static extern double GetPeriod(IntPtr widget);
+
+ [DllImport(Libraries.WidgetViewerEvas, EntryPoint = "widget_viewer_evas_cancel_click_event")]
+ internal static extern void CancelClickEvent(IntPtr widget);
+
+ [DllImport(Libraries.WidgetViewerEvas, EntryPoint = "widget_viewer_evas_disable_loading")]
+ internal static extern void DisableLoading(IntPtr widget);
+
+ [DllImport(Libraries.WidgetViewerEvas, EntryPoint = "widget_viewer_evas_feed_mouse_up_event")]
+ internal static extern ErrorCode FeedMouseUpEvent(IntPtr widget);
+
+ [DllImport(Libraries.WidgetViewerEvas, EntryPoint = "widget_viewer_evas_disable_preview")]
+ internal static extern void DisablePreview(IntPtr widget);
+
+ [DllImport(Libraries.WidgetViewerEvas, EntryPoint = "widget_viewer_evas_disable_overlay_text")]
+ internal static extern void DisableOverlayText(IntPtr widget);
+
+ }
+}
diff --git a/src/Tizen.Applications.RemoteView/Tizen.Applications.RemoteView.csproj b/src/Tizen.Applications.RemoteView/Tizen.Applications.RemoteView.csproj
new file mode 100644
index 0000000..df0ef24
--- /dev/null
+++ b/src/Tizen.Applications.RemoteView/Tizen.Applications.RemoteView.csproj
@@ -0,0 +1,15 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\ElmSharp\ElmSharp.csproj" />
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Applications.RemoteView/Tizen.Applications/RemoteView.cs b/src/Tizen.Applications.RemoteView/Tizen.Applications/RemoteView.cs
new file mode 100755
index 0000000..44cad3b
--- /dev/null
+++ b/src/Tizen.Applications.RemoteView/Tizen.Applications/RemoteView.cs
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using ElmSharp;
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Represents proxy class for widget application.
+ /// </summary>
+ public class RemoteView
+ {
+ /// <summary>
+ /// Event types to send.
+ /// </summary>
+ public enum Event
+ {
+ /// <summary>
+ /// Type for feeding the mouse-up event to the widget application.
+ /// </summary>
+ FeedMouseUp,
+
+ /// <summary>
+ /// Type for cancelling click event procedure.
+ /// </summary>
+ CancelClick
+ }
+
+ /// <summary>
+ /// Layout object including preview image, overlay text, loading text and remote screen image.
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
+ public Layout Layout { get; internal set; }
+
+ /// <summary>
+ /// Widget ID.
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
+ public string Id
+ {
+ get
+ {
+ IntPtr ptr = Interop.WidgetViewerEvas.GetWidgetId(Layout);
+
+ return Marshal.PtrToStringAnsi(ptr);
+ }
+ }
+
+ /// <summary>
+ /// Update period.
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
+ public double Period
+ {
+ get
+ {
+ return Interop.WidgetViewerEvas.GetPeriod(Layout);
+ }
+ }
+
+ /// <summary>
+ /// Contents of widget.
+ /// </summary>
+ /// <remarks>
+ /// This string can be used for creating contents of widget again after rebooting a device or it can be recovered from crash(abnormal status).
+ /// </remarks>
+ /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
+ public string Content
+ {
+ get
+ {
+ IntPtr ptr = Interop.WidgetViewerEvas.GetContentInfo(Layout);
+
+ return Marshal.PtrToStringAnsi(ptr);
+ }
+ }
+
+ /// <summary>
+ /// Summarized string of the widget content for accessibility.
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
+ public string Title
+ {
+ get
+ {
+ IntPtr ptr = Interop.WidgetViewerEvas.GetTitleString(Layout);
+
+ return Marshal.PtrToStringAnsi(ptr);
+ }
+ }
+
+ internal RemoteView()
+ {
+ }
+
+ internal static void CheckException(Interop.WidgetViewerEvas.ErrorCode err)
+ {
+ switch (err)
+ {
+ case Interop.WidgetViewerEvas.ErrorCode.Fault:
+ throw new InvalidOperationException("Fault at unmanaged code");
+
+ case Interop.WidgetViewerEvas.ErrorCode.PermissionDenied:
+ throw new UnauthorizedAccessException();
+
+ case Interop.WidgetViewerEvas.ErrorCode.NotSupported:
+ throw new NotSupportedException();
+
+ case Interop.WidgetViewerEvas.ErrorCode.InvalidParameter:
+ throw new InvalidOperationException("Invalid parameter error at unmanaged code");
+
+ case Interop.WidgetViewerEvas.ErrorCode.AlreadyExist:
+ throw new InvalidOperationException("Already exist");
+
+ case Interop.WidgetViewerEvas.ErrorCode.MaxExceeded:
+ throw new InvalidOperationException("Max exceeded");
+ }
+ }
+
+ /// <summary>
+ /// Pauses all connected widget applications.
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
+ /// <exception cref="InvalidOperationException">Thrown when this operation failed</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when this operation was denied</exception>
+ /// <exception cref="NotSupportedException">Thrown when this operation is not supported for this device</exception>
+ public static void PauseAll()
+ {
+ CheckException(Interop.WidgetViewerEvas.NotifyPausedStatusOfViewer());
+ }
+
+ /// <summary>
+ /// Resumes all connected widget applications.
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
+ /// <exception cref="InvalidOperationException">Thrown when this operation failed</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when this operation was denied</exception>
+ /// <exception cref="NotSupportedException">Thrown when this operation is not supported for this device</exception>
+ public static void ResumeAll()
+ {
+ CheckException(Interop.WidgetViewerEvas.NotifyResumedStatusOfViewer());
+ }
+
+ /// <summary>
+ /// Pauses the widget application which is connected on this proxy.
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
+ /// <exception cref="InvalidOperationException">Thrown when this operation failed</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when this operation was denied</exception>
+ /// <exception cref="NotSupportedException">Thrown when this operation is not supported for this device</exception>
+ public void Pause()
+ {
+ CheckException(Interop.WidgetViewerEvas.PauseWidget(Layout));
+ }
+
+ /// <summary>
+ /// Resumes the widget application which is connected on this proxy.
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
+ /// <exception cref="InvalidOperationException">Thrown when this operation failed</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when this operation was denied</exception>
+ /// <exception cref="NotSupportedException">Thrown when this operation is not supported for this device</exception>
+ public void Resume()
+ {
+ CheckException(Interop.WidgetViewerEvas.ResumeWidget(Layout));
+ }
+
+ /// <summary>
+ /// Sends event to the widget application which is connected on this proxy.
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
+ /// <exception cref="UnauthorizedAccessException">Thrown when this operation was denied</exception>
+ /// <exception cref="NotSupportedException">Thrown when this operation is not supported for this device</exception>
+ public void SendEvent(Event ev)
+ {
+ switch (ev)
+ {
+ case Event.FeedMouseUp:
+ Interop.WidgetViewerEvas.FeedMouseUpEvent(Layout);
+ break;
+
+ case Event.CancelClick:
+ Interop.WidgetViewerEvas.CancelClickEvent(Layout);
+ break;
+
+ default:
+ throw new NotSupportedException("Not supported event type");
+ }
+
+ int err = Internals.Errors.ErrorFacts.GetLastResult();
+ CheckException((Interop.WidgetViewerEvas.ErrorCode)err);
+ }
+
+ internal void HideLoadingMessage()
+ {
+ Interop.WidgetViewerEvas.DisableLoading(Layout);
+ int err = Internals.Errors.ErrorFacts.GetLastResult();
+ CheckException((Interop.WidgetViewerEvas.ErrorCode)err);
+ }
+
+ internal void HidePreviewImage()
+ {
+ Interop.WidgetViewerEvas.DisablePreview(Layout);
+ int err = Internals.Errors.ErrorFacts.GetLastResult();
+ CheckException((Interop.WidgetViewerEvas.ErrorCode)err);
+ }
+
+ internal void HideOverlayText()
+ {
+ Interop.WidgetViewerEvas.DisableOverlayText(Layout);
+ int err = Internals.Errors.ErrorFacts.GetLastResult();
+ CheckException((Interop.WidgetViewerEvas.ErrorCode)err);
+ }
+
+ }
+}
diff --git a/src/Tizen.Applications.RemoteView/Tizen.Applications/RemoteViewFactory.cs b/src/Tizen.Applications.RemoteView/Tizen.Applications/RemoteViewFactory.cs
new file mode 100755
index 0000000..989c797
--- /dev/null
+++ b/src/Tizen.Applications.RemoteView/Tizen.Applications/RemoteViewFactory.cs
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using ElmSharp;
+using System;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Represents a factory class for making RemoveView objects.
+ /// </summary>
+ public static class RemoteViewFactory
+ {
+ private static bool _ready;
+
+ /// <summary>
+ /// Initializes RemoteViewFactory.
+ /// </summary>
+ /// <param name="win">Window object that will contain RemoteViews that are generated by RemoteViewFactory.
+ /// All the remote views will be located in the specified window object.
+ /// </param>
+ /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
+ /// <exception cref="InvalidOperationException">Thrown when this operation failed</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when this operation was denied</exception>
+ /// <exception cref="NotSupportedException">Thrown when this operation is not supported for this device</exception>
+ public static void Init(EvasObject win)
+ {
+ if (_ready)
+ throw new InvalidOperationException("Already initialized");
+ RemoteView.CheckException(Interop.WidgetViewerEvas.Init(win));
+ _ready = true;
+ }
+
+ /// <summary>
+ /// Creates RemoteView object.
+ /// </summary>
+ /// <param name="parent">Parent object</param>
+ /// <param name="widgetId">Widget ID</param>
+ /// <param name="content">Contents that will be given to the widget instance</param>
+ /// <param name="period">Update period</param>
+ /// <param name="previewImage">True if you want to show preview image</param>
+ /// <param name="overlayText">True if you want to show overlay text</param>
+ /// <param name="loadingMessage">True if you want to show loading message</param>
+ /// <returns>RemoteView object.</returns>
+ /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
+ /// <exception cref="InvalidOperationException">Thrown when this operation failed</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when this operation was denied</exception>
+ /// <exception cref="NotSupportedException">Thrown when this operation is not supported for this device</exception>
+ public static RemoteView Create(EvasObject parent, string widgetId, string content, double period,
+ bool previewImage = true, bool overlayText = true, bool loadingMessage = true)
+ {
+ if (!_ready)
+ throw new InvalidOperationException("Not initialized");
+
+ var obj = new RemoteView()
+ {
+ Layout = new RemoteWindow(parent, widgetId, content, period)
+ };
+
+ if (!previewImage)
+ obj.HidePreviewImage();
+
+ if (!overlayText)
+ obj.HideOverlayText();
+
+ if (!loadingMessage)
+ obj.HideLoadingMessage();
+
+ return obj;
+ }
+
+ /// <summary>
+ /// Finalizes RemoteViewFactory.
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
+ /// <exception cref="InvalidOperationException">Thrown when this operation failed</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when this operation was denied</exception>
+ /// <exception cref="NotSupportedException">Thrown when this operation is not supported for this device</exception>
+ public static void Shutdown()
+ {
+ if (!_ready)
+ throw new InvalidOperationException("Not initialized");
+ RemoteView.CheckException(Interop.WidgetViewerEvas.Fini());
+ _ready = false;
+ }
+
+ }
+}
diff --git a/src/Tizen.Applications.RemoteView/Tizen.Applications/RemoteWindow.cs b/src/Tizen.Applications.RemoteView/Tizen.Applications/RemoteWindow.cs
new file mode 100755
index 0000000..c3874fb
--- /dev/null
+++ b/src/Tizen.Applications.RemoteView/Tizen.Applications/RemoteWindow.cs
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using ElmSharp;
+using System;
+
+namespace Tizen.Applications
+{
+ internal class RemoteWindow : Layout
+ {
+ private static IntPtr _handle;
+
+ private static EvasObject PrepareHandle(EvasObject parent, string widgetId, string content, double period)
+ {
+ _handle = Interop.WidgetViewerEvas.AddWidget(parent, widgetId, content, period);
+
+ int err = Internals.Errors.ErrorFacts.GetLastResult();
+ RemoteView.CheckException((Interop.WidgetViewerEvas.ErrorCode)err);
+
+ if (_handle == IntPtr.Zero)
+ throw new InvalidOperationException("Return null pointer");
+
+ return parent;
+ }
+
+ internal RemoteWindow(EvasObject parent, string widgetId, string content, double period)
+ : base(PrepareHandle(parent, widgetId, content, period))
+ {
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ IntPtr handle = _handle;
+
+ _handle = IntPtr.Zero;
+ return handle;
+ }
+ }
+}
+
diff --git a/src/Tizen.Applications.Service/Interop/Interop.Libraries.cs b/src/Tizen.Applications.Service/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..145ff34
--- /dev/null
+++ b/src/Tizen.Applications.Service/Interop/Interop.Libraries.cs
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string AppcoreAgent = "libappcore-agent.so.1";
+ }
+}
diff --git a/src/Tizen.Applications.Service/Interop/Interop.Service.cs b/src/Tizen.Applications.Service/Interop/Interop.Service.cs
new file mode 100755
index 0000000..d4cd60d
--- /dev/null
+++ b/src/Tizen.Applications.Service/Interop/Interop.Service.cs
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Applications.CoreBackend;
+using Tizen.Internals.Errors;
+
+internal static partial class Interop
+{
+ internal static partial class Service
+ {
+ internal delegate void AppEventCallback(IntPtr handle, IntPtr data);
+
+ internal delegate bool ServiceAppCreateCallback(IntPtr userData);
+
+ internal delegate void ServiceAppTerminateCallback(IntPtr userData);
+
+ internal delegate void ServiceAppControlCallback(IntPtr appControl, IntPtr userData);
+
+ [DllImport(Libraries.AppcoreAgent, EntryPoint = "service_app_main")]
+ internal static extern ErrorCode Main(int argc, string[] argv, ref ServiceAppLifecycleCallbacks callback, IntPtr userData);
+
+ [DllImport(Libraries.AppcoreAgent, EntryPoint = "service_app_exit")]
+ internal static extern void Exit();
+
+ [DllImport(Libraries.AppcoreAgent, EntryPoint = "service_app_add_event_handler")]
+ internal static extern ErrorCode AddEventHandler(out IntPtr handle, DefaultCoreBackend.AppEventType eventType, AppEventCallback callback, IntPtr data);
+
+ [DllImport(Libraries.AppcoreAgent, EntryPoint = "service_app_remove_event_handler")]
+ internal static extern ErrorCode RemoveEventHandler(IntPtr handle);
+
+ [StructLayoutAttribute(LayoutKind.Sequential)]
+ internal struct ServiceAppLifecycleCallbacks
+ {
+ public ServiceAppCreateCallback OnCreate;
+ public ServiceAppTerminateCallback OnTerminate;
+ public ServiceAppControlCallback OnAppControl;
+ }
+ }
+}
diff --git a/src/Tizen.Applications.Service/Tizen.Applications.CoreBackend/ServiceCoreBackend.cs b/src/Tizen.Applications.Service/Tizen.Applications.CoreBackend/ServiceCoreBackend.cs
new file mode 100755
index 0000000..bc1a096
--- /dev/null
+++ b/src/Tizen.Applications.Service/Tizen.Applications.CoreBackend/ServiceCoreBackend.cs
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+using Tizen.Internals.Errors;
+
+namespace Tizen.Applications.CoreBackend
+{
+ internal class ServiceCoreBackend : DefaultCoreBackend
+ {
+ private Interop.Service.ServiceAppLifecycleCallbacks _callbacks;
+ private IntPtr _lowMemoryEventHandle = IntPtr.Zero;
+ private IntPtr _lowBatteryEventHandle = IntPtr.Zero;
+ private IntPtr _localeChangedEventHandle = IntPtr.Zero;
+ private IntPtr _regionChangedEventHandle = IntPtr.Zero;
+ private IntPtr _deviceOrientationChangedEventHandle = IntPtr.Zero;
+ private bool _disposedValue = false;
+ private Interop.Service.AppEventCallback _onLowMemoryNative;
+ private Interop.Service.AppEventCallback _onLowBatteryNative;
+ private Interop.Service.AppEventCallback _onLocaleChangedNative;
+ private Interop.Service.AppEventCallback _onRegionChangedNative;
+ private Interop.Service.AppEventCallback _onDeviceOrientationChangedNative;
+
+ public ServiceCoreBackend()
+ {
+ _callbacks.OnCreate = new Interop.Service.ServiceAppCreateCallback(OnCreateNative);
+ _callbacks.OnTerminate = new Interop.Service.ServiceAppTerminateCallback(OnTerminateNative);
+ _callbacks.OnAppControl = new Interop.Service.ServiceAppControlCallback(OnAppControlNative);
+
+ _onLowMemoryNative = new Interop.Service.AppEventCallback(OnLowMemoryNative);
+ _onLowBatteryNative = new Interop.Service.AppEventCallback(OnLowBatteryNative);
+ _onLocaleChangedNative = new Interop.Service.AppEventCallback(OnLocaleChangedNative);
+ _onRegionChangedNative = new Interop.Service.AppEventCallback(OnRegionChangedNative);
+ _onDeviceOrientationChangedNative = new Interop.Service.AppEventCallback(OnDeviceOrientationChangedNative);
+ }
+
+ public override void Exit()
+ {
+ Interop.Service.Exit();
+ }
+
+ public override void Run(string[] args)
+ {
+ base.Run(args);
+
+ ErrorCode err = ErrorCode.None;
+ err = Interop.Service.AddEventHandler(out _lowMemoryEventHandle, AppEventType.LowMemory, _onLowMemoryNative, IntPtr.Zero);
+ if (err != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to add event handler for LowMemory event. Err = " + err);
+ }
+ err = Interop.Service.AddEventHandler(out _lowBatteryEventHandle, AppEventType.LowBattery, _onLowBatteryNative, IntPtr.Zero);
+ if (err != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to add event handler for LowBattery event. Err = " + err);
+ }
+
+ err = Interop.Service.AddEventHandler(out _localeChangedEventHandle, AppEventType.LanguageChanged, _onLocaleChangedNative, IntPtr.Zero);
+ if (err != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to add event handler for LocaleChanged event. Err = " + err);
+ }
+
+ err = Interop.Service.AddEventHandler(out _regionChangedEventHandle, AppEventType.RegionFormatChanged, _onRegionChangedNative, IntPtr.Zero);
+ if (err != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to add event handler for RegionFormatChanged event. Err = " + err);
+ }
+
+ err = Interop.Service.AddEventHandler(out _deviceOrientationChangedEventHandle, AppEventType.DeviceOrientationChanged, _onDeviceOrientationChangedNative, IntPtr.Zero);
+ if (err != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to add event handler for DeviceOrientationChanged event. Err = " + err);
+ }
+
+ err = Interop.Service.Main(args.Length, args, ref _callbacks, IntPtr.Zero);
+ if (err != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to run the application. Err = " + err);
+ }
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ if (disposing)
+ {
+ // Release disposable objects
+ }
+
+ if (_lowMemoryEventHandle != IntPtr.Zero)
+ {
+ Interop.Service.RemoveEventHandler(_lowMemoryEventHandle);
+ }
+ if (_lowBatteryEventHandle != IntPtr.Zero)
+ {
+ Interop.Service.RemoveEventHandler(_lowBatteryEventHandle);
+ }
+ if (_localeChangedEventHandle != IntPtr.Zero)
+ {
+ Interop.Service.RemoveEventHandler(_localeChangedEventHandle);
+ }
+ if (_regionChangedEventHandle != IntPtr.Zero)
+ {
+ Interop.Service.RemoveEventHandler(_regionChangedEventHandle);
+ }
+
+ if (_deviceOrientationChangedEventHandle != IntPtr.Zero)
+ {
+ Interop.Service.RemoveEventHandler(_deviceOrientationChangedEventHandle);
+ }
+
+ _disposedValue = true;
+ }
+ }
+
+ private bool OnCreateNative(IntPtr data)
+ {
+ if (Handlers.ContainsKey(EventType.Created))
+ {
+ var handler = Handlers[EventType.Created] as Action;
+ handler?.Invoke();
+ }
+ return true;
+ }
+
+ private void OnTerminateNative(IntPtr data)
+ {
+ if (Handlers.ContainsKey(EventType.Terminated))
+ {
+ var handler = Handlers[EventType.Terminated] as Action;
+ handler?.Invoke();
+ }
+ }
+
+ private void OnAppControlNative(IntPtr appControlHandle, IntPtr data)
+ {
+ if (Handlers.ContainsKey(EventType.AppControlReceived))
+ {
+ // Create a SafeAppControlHandle but the ownsHandle is false,
+ // because the appControlHandle will be closed by native appfw after this method automatically.
+ SafeAppControlHandle safeHandle = new SafeAppControlHandle(appControlHandle, false);
+
+ var handler = Handlers[EventType.AppControlReceived] as Action<AppControlReceivedEventArgs>;
+ handler?.Invoke(new AppControlReceivedEventArgs(new ReceivedAppControl(safeHandle)));
+ }
+ }
+
+ protected override void OnLowMemoryNative(IntPtr infoHandle, IntPtr data)
+ {
+ base.OnLowMemoryNative(infoHandle, data);
+ }
+
+ protected override void OnLowBatteryNative(IntPtr infoHandle, IntPtr data)
+ {
+ base.OnLowBatteryNative(infoHandle, data);
+ }
+
+ protected override void OnLocaleChangedNative(IntPtr infoHandle, IntPtr data)
+ {
+ base.OnLocaleChangedNative(infoHandle, data);
+ }
+
+ protected override void OnRegionChangedNative(IntPtr infoHandle, IntPtr data)
+ {
+ base.OnRegionChangedNative(infoHandle, data);
+ }
+
+ protected override void OnDeviceOrientationChangedNative(IntPtr infoHandle, IntPtr data)
+ {
+ base.OnDeviceOrientationChangedNative(infoHandle, data);
+ }
+
+ }
+}
diff --git a/src/Tizen.Applications.Service/Tizen.Applications.Service.csproj b/src/Tizen.Applications.Service/Tizen.Applications.Service.csproj
new file mode 100755
index 0000000..517b746
--- /dev/null
+++ b/src/Tizen.Applications.Service/Tizen.Applications.Service.csproj
@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen.Applications.Common\Tizen.Applications.Common.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project> \ No newline at end of file
diff --git a/src/Tizen.Applications.Service/Tizen.Applications/ServiceApplication.cs b/src/Tizen.Applications.Service/Tizen.Applications/ServiceApplication.cs
new file mode 100755
index 0000000..d8742c1
--- /dev/null
+++ b/src/Tizen.Applications.Service/Tizen.Applications/ServiceApplication.cs
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using Tizen.Applications.CoreBackend;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Represents a service application.
+ /// </summary>
+ public class ServiceApplication : CoreApplication
+ {
+ /// <summary>
+ /// Initializes ServiceApplication class.
+ /// </summary>
+ public ServiceApplication() : base(new ServiceCoreBackend())
+ {
+ }
+
+ /// <summary>
+ /// Runs the service application's main loop.
+ /// </summary>
+ /// <param name="args">Arguments from commandline.</param>
+ public override void Run(string[] args)
+ {
+ base.Run(args);
+ }
+ }
+}
diff --git a/src/Tizen.Applications.ToastMessage/Interop/Interop.Libraries.cs b/src/Tizen.Applications.ToastMessage/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..c284ac5
--- /dev/null
+++ b/src/Tizen.Applications.ToastMessage/Interop/Interop.Libraries.cs
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string ToastMessage = "libnotification.so.0";
+ }
+}
diff --git a/src/Tizen.Applications.ToastMessage/Interop/Interop.ToastMessage.cs b/src/Tizen.Applications.ToastMessage/Interop/Interop.ToastMessage.cs
new file mode 100755
index 0000000..69e49db
--- /dev/null
+++ b/src/Tizen.Applications.ToastMessage/Interop/Interop.ToastMessage.cs
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Applications;
+
+internal static partial class Interop
+{
+ internal static class ToastMessage
+ {
+ [DllImport(Libraries.ToastMessage, EntryPoint = "notification_status_message_post")]
+ internal static extern int ToastMessagePost(string message);
+ }
+}
diff --git a/src/Tizen.Applications.ToastMessage/Tizen.Applications.ToastMessage.csproj b/src/Tizen.Applications.ToastMessage/Tizen.Applications.ToastMessage.csproj
new file mode 100755
index 0000000..517b746
--- /dev/null
+++ b/src/Tizen.Applications.ToastMessage/Tizen.Applications.ToastMessage.csproj
@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen.Applications.Common\Tizen.Applications.Common.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project> \ No newline at end of file
diff --git a/src/Tizen.Applications.ToastMessage/Tizen.Applications/ToastMessage.cs b/src/Tizen.Applications.ToastMessage/Tizen.Applications/ToastMessage.cs
new file mode 100755
index 0000000..fd136b1
--- /dev/null
+++ b/src/Tizen.Applications.ToastMessage/Tizen.Applications/ToastMessage.cs
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// The class helps you create and show ToastMessage which is a view quick message for the user
+ /// </summary>
+ public sealed class ToastMessage
+ {
+
+ /// <summary>
+ /// Gets and sets message to post ToastMessage
+ /// </summary>
+ public string Message { get; set; }
+
+ /// <summary>
+ /// Posts a message on a toast popup
+ /// </summary>
+ /// <exception cref="ArgumentNullException">Thrown when Message is null</exception>
+ /// <example>
+ /// <code>
+ /// ToastMessage toast = new ToastMessage
+ /// {
+ /// Message = "Hello TIzen"
+ /// };
+ /// toast.Post();
+ /// </code>
+ /// </example>
+ public void Post()
+ {
+ int ret = Interop.ToastMessage.ToastMessagePost(Message);
+ if (ret != (int)ToastMessageError.None)
+ {
+ throw ToastMessageErrorFactory.GetException((ToastMessageError)ret, "post toast message failed");
+ }
+ }
+ }
+
+}
diff --git a/src/Tizen.Applications.ToastMessage/Tizen.Applications/ToastMessageErrorFactory.cs b/src/Tizen.Applications.ToastMessage/Tizen.Applications/ToastMessageErrorFactory.cs
new file mode 100755
index 0000000..cd2eebc
--- /dev/null
+++ b/src/Tizen.Applications.ToastMessage/Tizen.Applications/ToastMessageErrorFactory.cs
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications
+{
+ internal enum ToastMessageError
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None,
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+ DBusError = -0x01140000 | 0x03,
+ }
+
+ internal class ToastMessageErrorFactory
+ {
+ private const string _logTag = "Tizen.Applications.ToastMessage";
+
+ internal static Exception GetException(ToastMessageError ret, string msg)
+ {
+ switch (ret)
+ {
+ case ToastMessageError.InvalidParameter:
+ Log.Error(_logTag, msg);
+ return new ArgumentException(ret + " error occurred.");
+ default:
+ Log.Error(_logTag, msg);
+ return new InvalidOperationException(ret + " error occurred.");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Applications.UI/Interop/Interop.Application.cs b/src/Tizen.Applications.UI/Interop/Interop.Application.cs
new file mode 100755
index 0000000..177bfea
--- /dev/null
+++ b/src/Tizen.Applications.UI/Interop/Interop.Application.cs
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Applications.CoreBackend;
+using Tizen.Internals.Errors;
+
+internal static partial class Interop
+{
+ internal static partial class Application
+ {
+ internal delegate void AppEventCallback(IntPtr handle, IntPtr data);
+
+ internal delegate bool AppCreateCallback(IntPtr userData);
+
+ internal delegate void AppPauseCallback(IntPtr userData);
+
+ internal delegate void AppResumeCallback(IntPtr userData);
+
+ internal delegate void AppTerminateCallback(IntPtr userData);
+
+ internal delegate void AppControlCallback(IntPtr appControl, IntPtr userData);
+
+ [DllImport(Libraries.Application, EntryPoint = "ui_app_main")]
+ internal static extern ErrorCode Main(int argc, string[] argv, ref UIAppLifecycleCallbacks callback, IntPtr userData);
+
+ [DllImport(Libraries.Application, EntryPoint = "ui_app_exit")]
+ internal static extern void Exit();
+
+ [DllImport(Libraries.Application, EntryPoint = "ui_app_add_event_handler")]
+ internal static extern ErrorCode AddEventHandler(out IntPtr handle, DefaultCoreBackend.AppEventType eventType, AppEventCallback callback, IntPtr data);
+
+ [DllImport(Libraries.Application, EntryPoint = "ui_app_remove_event_handler")]
+ internal static extern ErrorCode RemoveEventHandler(IntPtr handle);
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct UIAppLifecycleCallbacks
+ {
+ public AppCreateCallback OnCreate;
+ public AppTerminateCallback OnTerminate;
+ public AppPauseCallback OnPause;
+ public AppResumeCallback OnResume;
+ public AppControlCallback OnAppControl;
+ }
+ }
+}
+
diff --git a/src/Tizen.Applications.UI/Interop/Interop.Libraries.cs b/src/Tizen.Applications.UI/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..03047b1
--- /dev/null
+++ b/src/Tizen.Applications.UI/Interop/Interop.Libraries.cs
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string Application = "libcapi-appfw-application.so.0";
+ }
+}
diff --git a/src/Tizen.Applications.UI/Tizen.Applications.CoreBackend/UICoreBackend.cs b/src/Tizen.Applications.UI/Tizen.Applications.CoreBackend/UICoreBackend.cs
new file mode 100755
index 0000000..933a4e0
--- /dev/null
+++ b/src/Tizen.Applications.UI/Tizen.Applications.CoreBackend/UICoreBackend.cs
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+using Tizen.Internals.Errors;
+
+namespace Tizen.Applications.CoreBackend
+{
+ internal class UICoreBackend : DefaultCoreBackend
+ {
+ private Interop.Application.UIAppLifecycleCallbacks _callbacks;
+ private IntPtr _lowMemoryEventHandle = IntPtr.Zero;
+ private IntPtr _lowBatteryEventHandle = IntPtr.Zero;
+ private IntPtr _localeChangedEventHandle = IntPtr.Zero;
+ private IntPtr _regionChangedEventHandle = IntPtr.Zero;
+ private IntPtr _deviceOrientationChangedEventHandle = IntPtr.Zero;
+ private bool _disposedValue = false;
+ private Interop.Application.AppEventCallback _onLowMemoryNative;
+ private Interop.Application.AppEventCallback _onLowBatteryNative;
+ private Interop.Application.AppEventCallback _onLocaleChangedNative;
+ private Interop.Application.AppEventCallback _onRegionChangedNative;
+ private Interop.Application.AppEventCallback _onDeviceOrientationChangedNative;
+
+ public UICoreBackend()
+ {
+ _callbacks.OnCreate = new Interop.Application.AppCreateCallback(OnCreateNative);
+ _callbacks.OnTerminate = new Interop.Application.AppTerminateCallback(OnTerminateNative);
+ _callbacks.OnAppControl = new Interop.Application.AppControlCallback(OnAppControlNative);
+ _callbacks.OnResume = new Interop.Application.AppResumeCallback(OnResumeNative);
+ _callbacks.OnPause = new Interop.Application.AppPauseCallback(OnPauseNative);
+
+ _onLowMemoryNative = new Interop.Application.AppEventCallback(OnLowMemoryNative);
+ _onLowBatteryNative = new Interop.Application.AppEventCallback(OnLowBatteryNative);
+ _onLocaleChangedNative = new Interop.Application.AppEventCallback(OnLocaleChangedNative);
+ _onRegionChangedNative = new Interop.Application.AppEventCallback(OnRegionChangedNative);
+ _onDeviceOrientationChangedNative = new Interop.Application.AppEventCallback(OnDeviceOrientationChangedNative);
+ }
+
+ public override void Exit()
+ {
+ Interop.Application.Exit();
+ }
+
+ public override void Run(string[] args)
+ {
+ base.Run(args);
+
+ ErrorCode err = ErrorCode.None;
+ err = Interop.Application.AddEventHandler(out _lowMemoryEventHandle, AppEventType.LowMemory, _onLowMemoryNative, IntPtr.Zero);
+ if (err != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to add event handler for LowMemory event. Err = " + err);
+ }
+ err = Interop.Application.AddEventHandler(out _lowBatteryEventHandle, AppEventType.LowBattery, _onLowBatteryNative, IntPtr.Zero);
+ if (err != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to add event handler for LowBattery event. Err = " + err);
+ }
+
+ err = Interop.Application.AddEventHandler(out _localeChangedEventHandle, AppEventType.LanguageChanged, _onLocaleChangedNative, IntPtr.Zero);
+ if (err != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to add event handler for LocaleChanged event. Err = " + err);
+ }
+
+ err = Interop.Application.AddEventHandler(out _regionChangedEventHandle, AppEventType.RegionFormatChanged, _onRegionChangedNative, IntPtr.Zero);
+ if (err != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to add event handler for RegionFormatChanged event. Err = " + err);
+ }
+
+ err = Interop.Application.AddEventHandler(out _deviceOrientationChangedEventHandle, AppEventType.DeviceOrientationChanged, _onDeviceOrientationChangedNative, IntPtr.Zero);
+ if (err != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to add event handler for DeviceOrientationChanged event. Err = " + err);
+ }
+
+ err = Interop.Application.Main(args.Length, args, ref _callbacks, IntPtr.Zero);
+ if (err != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to run the application. Err = " + err);
+ }
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ if (disposing)
+ {
+ // Release disposable objects
+ }
+
+ if (_lowMemoryEventHandle != IntPtr.Zero)
+ {
+ Interop.Application.RemoveEventHandler(_lowMemoryEventHandle);
+ }
+ if (_lowBatteryEventHandle != IntPtr.Zero)
+ {
+ Interop.Application.RemoveEventHandler(_lowBatteryEventHandle);
+ }
+ if (_localeChangedEventHandle != IntPtr.Zero)
+ {
+ Interop.Application.RemoveEventHandler(_localeChangedEventHandle);
+ }
+ if (_regionChangedEventHandle != IntPtr.Zero)
+ {
+ Interop.Application.RemoveEventHandler(_regionChangedEventHandle);
+ }
+ if (_deviceOrientationChangedEventHandle != IntPtr.Zero)
+ {
+ Interop.Application.RemoveEventHandler(_deviceOrientationChangedEventHandle);
+ }
+
+ _disposedValue = true;
+ }
+ }
+
+ private bool OnCreateNative(IntPtr data)
+ {
+ if (Handlers.ContainsKey(EventType.PreCreated))
+ {
+ var handler = Handlers[EventType.PreCreated] as Action;
+ handler?.Invoke();
+ }
+
+ if (Handlers.ContainsKey(EventType.Created))
+ {
+ var handler = Handlers[EventType.Created] as Action;
+ handler?.Invoke();
+ }
+ return true;
+ }
+
+ private void OnTerminateNative(IntPtr data)
+ {
+ if (Handlers.ContainsKey(EventType.Terminated))
+ {
+ var handler = Handlers[EventType.Terminated] as Action;
+ handler?.Invoke();
+ }
+ }
+
+ private void OnAppControlNative(IntPtr appControlHandle, IntPtr data)
+ {
+ if (Handlers.ContainsKey(EventType.AppControlReceived))
+ {
+ // Create a SafeAppControlHandle but the ownsHandle is false,
+ // because the appControlHandle will be closed by native appfw after this method automatically.
+ SafeAppControlHandle safeHandle = new SafeAppControlHandle(appControlHandle, false);
+
+ var handler = Handlers[EventType.AppControlReceived] as Action<AppControlReceivedEventArgs>;
+ handler?.Invoke(new AppControlReceivedEventArgs(new ReceivedAppControl(safeHandle)));
+ }
+ }
+
+ private void OnResumeNative(IntPtr data)
+ {
+ if (Handlers.ContainsKey(EventType.Resumed))
+ {
+ var handler = Handlers[EventType.Resumed] as Action;
+ handler?.Invoke();
+ }
+ }
+
+ private void OnPauseNative(IntPtr data)
+ {
+ if (Handlers.ContainsKey(EventType.Paused))
+ {
+ var handler = Handlers[EventType.Paused] as Action;
+ handler?.Invoke();
+ }
+ }
+
+ protected override void OnLowMemoryNative(IntPtr infoHandle, IntPtr data)
+ {
+ base.OnLowMemoryNative(infoHandle, data);
+ }
+
+ protected override void OnLowBatteryNative(IntPtr infoHandle, IntPtr data)
+ {
+ base.OnLowBatteryNative(infoHandle, data);
+ }
+
+ protected override void OnLocaleChangedNative(IntPtr infoHandle, IntPtr data)
+ {
+ base.OnLocaleChangedNative(infoHandle, data);
+ }
+
+ protected override void OnRegionChangedNative(IntPtr infoHandle, IntPtr data)
+ {
+ base.OnRegionChangedNative(infoHandle, data);
+ }
+
+ protected override void OnDeviceOrientationChangedNative(IntPtr infoHandle, IntPtr data)
+ {
+ base.OnDeviceOrientationChangedNative(infoHandle, data);
+ }
+ }
+}
diff --git a/src/Tizen.Applications.UI/Tizen.Applications.UI.csproj b/src/Tizen.Applications.UI/Tizen.Applications.UI.csproj
new file mode 100755
index 0000000..517b746
--- /dev/null
+++ b/src/Tizen.Applications.UI/Tizen.Applications.UI.csproj
@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen.Applications.Common\Tizen.Applications.Common.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project> \ No newline at end of file
diff --git a/src/Tizen.Applications.UI/Tizen.Applications/CoreUIApplication.cs b/src/Tizen.Applications.UI/Tizen.Applications/CoreUIApplication.cs
new file mode 100755
index 0000000..03256e7
--- /dev/null
+++ b/src/Tizen.Applications.UI/Tizen.Applications/CoreUIApplication.cs
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+using Tizen.Applications.CoreBackend;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Represents an application that have UI screen. The events for resuming and pausing are provided.
+ /// </summary>
+ public class CoreUIApplication : CoreApplication
+ {
+ /// <summary>
+ /// Initializes the CoreUIApplication class.
+ /// </summary>
+ /// <remarks>
+ /// Default backend for UI application will be used.
+ /// </remarks>
+ public CoreUIApplication() : base(new UICoreBackend())
+ {
+ }
+
+ /// <summary>
+ /// Initializes the CoreUIApplication class.
+ /// </summary>
+ /// <remarks>
+ /// If want to change the backend, use this constructor.
+ /// </remarks>
+ /// <param name="backend">The backend instance implementing ICoreBacked interface.</param>
+ public CoreUIApplication(ICoreBackend backend) : base(backend)
+ {
+ }
+
+ /// <summary>
+ /// Occurs whenever the application is resumed.
+ /// </summary>
+ public event EventHandler Resumed;
+
+ /// <summary>
+ /// Occurs whenever the application is paused.
+ /// </summary>
+ public event EventHandler Paused;
+
+ /// <summary>
+ /// Runs the UI application's main loop.
+ /// </summary>
+ /// <param name="args">Arguments from commandline.</param>
+ public override void Run(string[] args)
+ {
+ Backend.AddEventHandler(EventType.PreCreated, OnPreCreate);
+ Backend.AddEventHandler(EventType.Resumed, OnResume);
+ Backend.AddEventHandler(EventType.Paused, OnPause);
+ base.Run(args);
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior before calling OnCreate().
+ /// </summary>
+ protected virtual void OnPreCreate()
+ {
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the application is resumed.
+ /// If base.OnResume() is not called, the event 'Resumed' will not be emitted.
+ /// </summary>
+ protected virtual void OnResume()
+ {
+ Resumed?.Invoke(this, EventArgs.Empty);
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the application is paused.
+ /// If base.OnPause() is not called, the event 'Paused' will not be emitted.
+ /// </summary>
+ protected virtual void OnPause()
+ {
+ Paused?.Invoke(this, EventArgs.Empty);
+ }
+ }
+}
diff --git a/src/Tizen.Applications.WidgetApplication/Interop/Interop.Libraries.cs b/src/Tizen.Applications.WidgetApplication/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..aa36259
--- /dev/null
+++ b/src/Tizen.Applications.WidgetApplication/Interop/Interop.Libraries.cs
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string AppCommon = "libcapi-appfw-app-common.so.0";
+ public const string AppcoreWidget = "libcapi-appfw-widget-application.so.1";
+ public const string WidgetService = "libwidget_service.so.1";
+ public const string Elementary = "libelementary.so.1";
+ public const string Evas = "libevas.so.1";
+ }
+}
diff --git a/src/Tizen.Applications.WidgetApplication/Interop/Interop.Widget.cs b/src/Tizen.Applications.WidgetApplication/Interop/Interop.Widget.cs
new file mode 100755
index 0000000..6d1cde2
--- /dev/null
+++ b/src/Tizen.Applications.WidgetApplication/Interop/Interop.Widget.cs
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+using Tizen.Applications;
+
+internal static partial class Interop
+{
+ internal static partial class Widget
+ {
+ internal enum WidgetAppDestroyType
+ {
+ Permanent = 0,
+ Temporary
+ }
+
+ internal enum AppEventType
+ {
+ LowMemory = 0,
+ LowBattery,
+ LanguageChanged,
+ DeviceOrientationChanged,
+ RegionFormatChanged,
+ SuspendedStateChanged
+ }
+
+ internal enum ErrorCode : int
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None,
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+ OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
+ ResourceBusy = Tizen.Internals.Errors.ErrorCode.ResourceBusy,
+ PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied,
+ Canceled = Tizen.Internals.Errors.ErrorCode.Canceled,
+ IoError = Tizen.Internals.Errors.ErrorCode.IoError,
+ TimedOut = Tizen.Internals.Errors.ErrorCode.TimedOut,
+ NotSupported = Tizen.Internals.Errors.ErrorCode.NotSupported,
+ FileNoSpaceOnDevice = Tizen.Internals.Errors.ErrorCode.FileNoSpaceOnDevice,
+ Fault = -0x02F40000 | 0x0001,
+ AlreadyExist = -0x02F40000 | 0x0002,
+ AlreadyStarted = -0x02F40000 | 0x0004,
+ NotExist = -0x02F40000 | 0x0008,
+ Disabled = -0x02F40000 | 0x0010,
+ MaxExceeded = -0x02F40000 | 0x0011,
+ }
+
+ internal delegate void AppEventCallback(IntPtr handle, IntPtr data);
+
+ internal delegate IntPtr WidgetAppCreateCallback(IntPtr userData);
+
+ internal delegate void WidgetAppTerminateCallback(IntPtr userData);
+
+ internal delegate int WidgetInstanceCreateCallback(IntPtr context, IntPtr content, int w, int h, IntPtr userData);
+
+ internal delegate int WidgetInstanceDestroyCallback(IntPtr context, WidgetAppDestroyType reason, IntPtr content, IntPtr userData);
+
+ internal delegate int WidgetInstancePauseCallback(IntPtr context, IntPtr userData);
+
+ internal delegate int WidgetInstanceResumeCallback(IntPtr context, IntPtr userData);
+
+ internal delegate int WidgetInstanceResizeCallback(IntPtr context, int w, int h, IntPtr userData);
+
+ internal delegate int WidgetInstanceUpdateCallback(IntPtr context, IntPtr content, int force, IntPtr userData);
+
+ [DllImport(Libraries.Evas)]
+ internal static extern void evas_object_size_hint_weight_set(IntPtr obj, double x, double y);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_conformant_set(IntPtr obj, bool conformant);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_win_resize_object_add(IntPtr obj, IntPtr subobj);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_conformant_add(IntPtr obj);
+
+ [DllImport(Libraries.AppcoreWidget, EntryPoint = "widget_app_main")]
+ internal static extern ErrorCode Main(int argc, string[] argv, ref WidgetAppLifecycleCallbacks callback, IntPtr userData);
+
+ [DllImport(Libraries.AppcoreWidget, EntryPoint = "widget_app_exit")]
+ internal static extern void Exit();
+
+ [DllImport(Libraries.AppcoreWidget, EntryPoint = "widget_app_add_event_handler")]
+ internal static extern ErrorCode AddEventHandler(out IntPtr handle, AppEventType eventType, AppEventCallback callback, IntPtr data);
+
+ [DllImport(Libraries.AppcoreWidget, EntryPoint = "widget_app_remove_event_handler")]
+ internal static extern ErrorCode RemoveEventHandler(IntPtr handle);
+
+ [DllImport(Libraries.AppcoreWidget, EntryPoint = "widget_app_class_create")]
+ internal static extern IntPtr CreateClass(WidgetiInstanceLifecycleCallbacks callback, IntPtr userData);
+
+ [DllImport(Libraries.AppcoreWidget, EntryPoint = "widget_app_class_add")]
+ internal static extern IntPtr AddClass(IntPtr handle, string classId, WidgetiInstanceLifecycleCallbacks callback, IntPtr userData);
+
+ [DllImport(Libraries.AppcoreWidget, EntryPoint = "widget_app_terminate_context")]
+ internal static extern ErrorCode TerminateContext(IntPtr handle);
+
+ [DllImport(Libraries.AppcoreWidget, EntryPoint = "widget_app_context_set_content_info")]
+ internal static extern ErrorCode SetContent(IntPtr handle, SafeBundleHandle content);
+
+ [DllImport(Libraries.AppcoreWidget, EntryPoint = "widget_app_context_set_title")]
+ internal static extern ErrorCode SetTitle(IntPtr handle, string title);
+
+ [DllImport(Libraries.AppcoreWidget, EntryPoint = "widget_app_get_elm_win")]
+ internal static extern ErrorCode GetWin(IntPtr handle, out IntPtr win);
+
+ [DllImport(Libraries.AppCommon, EntryPoint = "app_event_get_low_memory_status")]
+ internal static extern Tizen.Internals.Errors.ErrorCode AppEventGetLowMemoryStatus(IntPtr handle, out LowMemoryStatus status);
+
+ [DllImport(Libraries.AppCommon, EntryPoint = "app_event_get_low_battery_status")]
+ internal static extern Tizen.Internals.Errors.ErrorCode AppEventGetLowBatteryStatus(IntPtr handle, out LowBatteryStatus status);
+
+ [DllImport(Libraries.AppCommon, EntryPoint = "app_event_get_language")]
+ internal static extern Tizen.Internals.Errors.ErrorCode AppEventGetLanguage(IntPtr handle, out string lang);
+
+ [DllImport(Libraries.AppCommon, EntryPoint = "app_event_get_region_format")]
+ internal static extern Tizen.Internals.Errors.ErrorCode AppEventGetRegionFormat(IntPtr handle, out string region);
+
+ [StructLayoutAttribute(LayoutKind.Sequential)]
+ internal struct WidgetAppLifecycleCallbacks
+ {
+ public WidgetAppCreateCallback OnCreate;
+ public WidgetAppTerminateCallback OnTerminate;
+ }
+
+ [StructLayoutAttribute(LayoutKind.Sequential)]
+ internal struct WidgetiInstanceLifecycleCallbacks
+ {
+ public WidgetInstanceCreateCallback OnCreate;
+ public WidgetInstanceDestroyCallback OnDestroy;
+ public WidgetInstancePauseCallback OnPause;
+ public WidgetInstanceResumeCallback OnResume;
+ public WidgetInstanceResizeCallback OnResize;
+ public WidgetInstanceUpdateCallback OnUpdate;
+ }
+ }
+}
diff --git a/src/Tizen.Applications.WidgetApplication/Tizen.Applications.CoreBackend/WidgetCoreBackend.cs b/src/Tizen.Applications.WidgetApplication/Tizen.Applications.CoreBackend/WidgetCoreBackend.cs
new file mode 100755
index 0000000..eee864b
--- /dev/null
+++ b/src/Tizen.Applications.WidgetApplication/Tizen.Applications.CoreBackend/WidgetCoreBackend.cs
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Applications.CoreBackend
+{
+ internal class WidgetCoreBackend : ICoreBackend
+ {
+ protected static readonly string LogTag = typeof(WidgetCoreBackend).Namespace;
+
+ private Dictionary<EventType, object> _handlers = new Dictionary<EventType, object>();
+
+ private bool _disposedValue = false;
+
+ private Interop.Widget.AppEventCallback _lowMemoryCallback;
+ private Interop.Widget.AppEventCallback _lowBatteryCallback;
+ private Interop.Widget.AppEventCallback _localeChangedCallback;
+ private Interop.Widget.AppEventCallback _regionChangedCallback;
+
+ private IntPtr _lowMemoryEventHandle = IntPtr.Zero;
+ private IntPtr _lowBatteryEventHandle = IntPtr.Zero;
+ private IntPtr _localeChangedEventHandle = IntPtr.Zero;
+ private IntPtr _regionChangedEventHandle = IntPtr.Zero;
+
+ private Interop.Widget.WidgetAppLifecycleCallbacks _callbacks;
+
+ internal IList<WidgetType> WidgetTypes = new List<WidgetType>();
+
+ public WidgetCoreBackend()
+ {
+ _lowMemoryCallback = new Interop.Widget.AppEventCallback(OnLowMemoryNative);
+ _lowBatteryCallback = new Interop.Widget.AppEventCallback(OnLowBatteryNative);
+ _localeChangedCallback = new Interop.Widget.AppEventCallback(OnLocaleChangedNative);
+ _regionChangedCallback = new Interop.Widget.AppEventCallback(OnRegionChangedNative);
+
+ _callbacks.OnCreate = new Interop.Widget.WidgetAppCreateCallback(OnCreateNative);
+ _callbacks.OnTerminate = new Interop.Widget.WidgetAppTerminateCallback(OnTerminateNative);
+ }
+
+ ~WidgetCoreBackend()
+ {
+ Dispose(false);
+ }
+
+ internal void CreateWidgetTypes(IDictionary<Type, string> typeInfo)
+ {
+ foreach (Type w in typeInfo.Keys)
+ {
+ WidgetTypes.Add(new WidgetType(w, typeInfo[w]));
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ if (disposing)
+ {
+ // Release disposable objects
+ }
+
+ if (_lowMemoryEventHandle != IntPtr.Zero)
+ {
+ Interop.Widget.RemoveEventHandler(_lowMemoryEventHandle);
+ }
+ if (_lowBatteryEventHandle != IntPtr.Zero)
+ {
+ Interop.Widget.RemoveEventHandler(_lowBatteryEventHandle);
+ }
+ if (_localeChangedEventHandle != IntPtr.Zero)
+ {
+ Interop.Widget.RemoveEventHandler(_localeChangedEventHandle);
+ }
+ if (_regionChangedEventHandle != IntPtr.Zero)
+ {
+ Interop.Widget.RemoveEventHandler(_regionChangedEventHandle);
+ }
+
+ _disposedValue = true;
+ }
+ }
+
+ public void Exit()
+ {
+ Interop.Widget.Exit();
+ }
+
+ public void Run(string[] args)
+ {
+ Interop.Widget.ErrorCode err = Interop.Widget.ErrorCode.None;
+ err = Interop.Widget.AddEventHandler(out _lowMemoryEventHandle, Interop.Widget.AppEventType.LowMemory, _lowMemoryCallback, IntPtr.Zero);
+ if (err != Interop.Widget.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to add event handler for LowMemory event. Err = " + err);
+ }
+ err = Interop.Widget.AddEventHandler(out _lowBatteryEventHandle, Interop.Widget.AppEventType.LowBattery, _lowBatteryCallback, IntPtr.Zero);
+ if (err != Interop.Widget.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to add event handler for LowBattery event. Err = " + err);
+ }
+
+ err = Interop.Widget.AddEventHandler(out _localeChangedEventHandle, Interop.Widget.AppEventType.LanguageChanged, _localeChangedCallback, IntPtr.Zero);
+ if (err != Interop.Widget.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to add event handler for LocaleChanged event. Err = " + err);
+ }
+
+ err = Interop.Widget.AddEventHandler(out _regionChangedEventHandle, Interop.Widget.AppEventType.RegionFormatChanged, _regionChangedCallback, IntPtr.Zero);
+ if (err != Interop.Widget.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to add event handler for RegionFormatChanged event. Err = " + err);
+ }
+
+ err = Interop.Widget.Main(args.Length, args, ref _callbacks, IntPtr.Zero);
+ if (err != Interop.Widget.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to run the application. Err = " + err);
+ }
+ }
+
+ private IntPtr OnCreateNative(IntPtr data)
+ {
+ if (_handlers.ContainsKey(EventType.Created))
+ {
+ var handler = _handlers[EventType.Created] as Action;
+ handler?.Invoke();
+ }
+
+ IntPtr h = IntPtr.Zero;
+ foreach (WidgetType type in WidgetTypes)
+ h = type.Bind(h);
+
+ return h;
+ }
+
+ private void OnTerminateNative(IntPtr data)
+ {
+ if (_handlers.ContainsKey(EventType.Terminated))
+ {
+ var handler = _handlers[EventType.Terminated] as Action;
+ handler?.Invoke();
+ }
+ }
+
+ public void AddEventHandler(EventType evType, Action handler)
+ {
+ _handlers.Add(evType, handler);
+ }
+
+ public void AddEventHandler<TEventArgs>(EventType evType, Action<TEventArgs> handler) where TEventArgs : EventArgs
+ {
+ _handlers.Add(evType, handler);
+ }
+
+ private void OnLowMemoryNative(IntPtr infoHandle, IntPtr data)
+ {
+ LowMemoryStatus status = LowMemoryStatus.None;
+ ErrorCode err = Interop.Widget.AppEventGetLowMemoryStatus(infoHandle, out status);
+ if (err != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get memory status. Err = " + err);
+ }
+ if (_handlers.ContainsKey(EventType.LowMemory))
+ {
+ var handler = _handlers[EventType.LowMemory] as Action<LowMemoryEventArgs>;
+ handler?.Invoke(new LowMemoryEventArgs(status));
+ }
+ }
+
+ private void OnLowBatteryNative(IntPtr infoHandle, IntPtr data)
+ {
+ LowBatteryStatus status = LowBatteryStatus.None;
+ ErrorCode err = Interop.Widget.AppEventGetLowBatteryStatus(infoHandle, out status);
+ if (err != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get battery status. Err = " + err);
+ }
+ if (_handlers.ContainsKey(EventType.LowBattery))
+ {
+ var handler = _handlers[EventType.LowBattery] as Action<LowBatteryEventArgs>;
+ handler?.Invoke(new LowBatteryEventArgs(status));
+ }
+ }
+
+ private void OnLocaleChangedNative(IntPtr infoHandle, IntPtr data)
+ {
+ string lang;
+ ErrorCode err = Interop.Widget.AppEventGetLanguage(infoHandle, out lang);
+ if (err != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get changed language. Err = " + err);
+ }
+ if (_handlers.ContainsKey(EventType.LocaleChanged))
+ {
+ var handler = _handlers[EventType.LocaleChanged] as Action<LocaleChangedEventArgs>;
+ handler?.Invoke(new LocaleChangedEventArgs(lang));
+ }
+ }
+
+ private void OnRegionChangedNative(IntPtr infoHandle, IntPtr data)
+ {
+ string region;
+ ErrorCode err = Interop.Widget.AppEventGetRegionFormat(infoHandle, out region);
+ if (err != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get changed region format. Err = " + err);
+ }
+ if (_handlers.ContainsKey(EventType.RegionFormatChanged))
+ {
+ var handler = _handlers[EventType.RegionFormatChanged] as Action<RegionFormatChangedEventArgs>;
+ handler?.Invoke(new RegionFormatChangedEventArgs(region));
+ }
+ }
+
+ }
+}
diff --git a/src/Tizen.Applications.WidgetApplication/Tizen.Applications.WidgetApplication.csproj b/src/Tizen.Applications.WidgetApplication/Tizen.Applications.WidgetApplication.csproj
new file mode 100644
index 0000000..fdbb3d8
--- /dev/null
+++ b/src/Tizen.Applications.WidgetApplication/Tizen.Applications.WidgetApplication.csproj
@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\ElmSharp\ElmSharp.csproj" />
+ <ProjectReference Include="..\Tizen.Applications.Common\Tizen.Applications.Common.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Applications.WidgetApplication/Tizen.Applications/WidgetApplication.cs b/src/Tizen.Applications.WidgetApplication/Tizen.Applications/WidgetApplication.cs
new file mode 100755
index 0000000..501c1eb
--- /dev/null
+++ b/src/Tizen.Applications.WidgetApplication/Tizen.Applications/WidgetApplication.cs
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using Tizen.Applications.CoreBackend;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Represents a widget application.
+ /// </summary>
+ public class WidgetApplication : CoreApplication
+ {
+ /// <summary>
+ /// Initializes WidgetApplication class with Type and application id.
+ /// </summary>
+ /// <param name="typeInfo">map structure for derived class type and widget id</param>
+ public WidgetApplication(IDictionary<Type, string> typeInfo) : base(new WidgetCoreBackend())
+ {
+ WidgetCoreBackend core = Backend as WidgetCoreBackend;
+
+ core?.CreateWidgetTypes(typeInfo);
+ }
+
+ /// <summary>
+ /// Initializes WidgetApplication class with Type.
+ /// </summary>
+ /// <remarks> Widget id will be replaced as application id</remarks>
+ /// <param name="type">derived class type</param>
+ public WidgetApplication(Type type) : base(new WidgetCoreBackend())
+ {
+ WidgetCoreBackend core = Backend as WidgetCoreBackend;
+
+ core?.CreateWidgetTypes(new Dictionary<Type, string>() { {type, ApplicationInfo.ApplicationId } });
+ }
+
+ /// <summary>
+ /// Gets all instances of the widget associated with the type
+ /// </summary>
+ /// <param name="type">Class type for the widget</param>
+ public IEnumerable<WidgetBase> GetInstances(Type type)
+ {
+ WidgetCoreBackend core = Backend as WidgetCoreBackend;
+
+ if (core == null)
+ return null;
+
+ foreach (WidgetType w in core.WidgetTypes)
+ {
+ if (w.ClassType == type)
+ {
+ return w.WidgetInstances;
+ }
+ }
+
+ return null;
+ }
+
+ /// <summary>
+ /// Runs the widget application's main loop.
+ /// </summary>
+ /// <param name="args">Arguments from commandline.</param>
+ public override void Run(string[] args)
+ {
+ base.Run(args);
+ }
+ }
+}
diff --git a/src/Tizen.Applications.WidgetApplication/Tizen.Applications/WidgetBase.cs b/src/Tizen.Applications.WidgetApplication/Tizen.Applications/WidgetBase.cs
new file mode 100755
index 0000000..ef6c333
--- /dev/null
+++ b/src/Tizen.Applications.WidgetApplication/Tizen.Applications/WidgetBase.cs
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using ElmSharp;
+using System;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Abstract class for widget instances
+ /// </summary>
+ public abstract class WidgetBase
+ {
+ internal IntPtr Handle;
+ internal string Id;
+ internal Widget BaseWindow;
+ protected static readonly string LogTag = typeof(WidgetBase).Namespace;
+
+ /// <summary>
+ /// Window object for this widget instance.
+ /// It wii be created after OnCreate method is invoked.
+ /// </summary>
+ protected Widget Window;
+
+ /// <summary>
+ /// Delete type
+ /// </summary>
+ public enum WidgetDestroyType
+ {
+ /// <summary>
+ /// User deleted this widget from the viewer.
+ /// </summary>
+ Permanent = 0,
+
+ /// <summary>
+ /// Widget is deleted because of other reasons. (e.g. widget process is terminated temporarily by the system)
+ /// </summary>
+ Temporary
+ }
+
+ /// <summary>
+ /// Constructor
+ /// </summary>
+ public WidgetBase()
+ {
+ }
+
+ /// <summary>
+ /// Sets the content info to the widget.
+ /// </summary>
+ /// <param name="info">The data set to save</param>
+ /// <exception cref="ArgumentException">Thrown when failed because of invalid argument</exception>
+ /// <exception cref="NotSupportedException">Thrown when API is not supported in this device</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of unrecoverable error</exception>
+ public void SetContent(Bundle info)
+ {
+ Interop.Widget.ErrorCode err = Interop.Widget.SetContent(Handle, info.SafeBundleHandle);
+
+ if (err != Interop.Widget.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to set content. Err = " + err);
+
+ switch(err)
+ {
+ case Interop.Widget.ErrorCode.InvalidParameter:
+ throw new ArgumentException("Invalid parameter of SetContent()");
+
+ case Interop.Widget.ErrorCode.NotSupported:
+ throw new NotSupportedException();
+
+ case Interop.Widget.ErrorCode.OutOfMemory:
+ case Interop.Widget.ErrorCode.Fault:
+ throw new InvalidOperationException();
+ }
+
+ }
+ }
+
+ /// <summary>
+ /// Sends the title to the widget.
+ /// </summary>
+ /// <param name="title">When an accessibility mode is turned on, this string will be read</param>
+ /// <exception cref="ArgumentException">Thrown when failed because of invalid argument</exception>
+ /// <exception cref="NotSupportedException">Thrown when API is not supported in this device</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of unrecoverable error</exception>
+ public void SetTitle(string title)
+ {
+ Interop.Widget.ErrorCode err = Interop.Widget.SetTitle(Handle, title);
+
+ if (err != Interop.Widget.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to set title. Err = " + err);
+
+ switch (err)
+ {
+ case Interop.Widget.ErrorCode.InvalidParameter:
+ throw new ArgumentException("Invalid parameter of SetContent()");
+
+ case Interop.Widget.ErrorCode.NotSupported:
+ throw new NotSupportedException();
+
+ case Interop.Widget.ErrorCode.OutOfMemory:
+ case Interop.Widget.ErrorCode.Fault:
+ throw new InvalidOperationException();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Finishes context for the widget instance.
+ /// </summary>
+ /// <exception cref="NotSupportedException">Thrown when API is not supported in this device</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of unrecoverable error</exception>
+ public void Exit()
+ {
+ Interop.Widget.ErrorCode err = Interop.Widget.TerminateContext(Handle);
+
+ if (err != Interop.Widget.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to terminate context. Err = " + err);
+
+ switch (err)
+ {
+ case Interop.Widget.ErrorCode.NotSupported:
+ throw new NotSupportedException();
+
+ case Interop.Widget.ErrorCode.InvalidParameter:
+ case Interop.Widget.ErrorCode.Fault:
+ throw new InvalidOperationException();
+ }
+ }
+ }
+
+ internal void Bind(IntPtr handle, string id)
+ {
+ Handle = handle;
+ Id = id;
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the widget instance is started.
+ /// </summary>
+ /// <param name="content">The data set for the previous status</param>
+ /// <param name="w">The pixel value for widget width</param>
+ /// <param name="h">The pixel value for widget height</param>
+ public virtual void OnCreate(Bundle content, int w, int h)
+ {
+ IntPtr win;
+
+ Interop.Widget.GetWin(Handle, out win);
+ BaseWindow = new WidgetWindow(win);
+ BaseWindow.Resize(w, h);
+ BaseWindow.Show();
+ Window = new ConformantWindow(Window, win);
+ Window.Show();
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the widget instance is destroyed.
+ /// </summary>
+ /// <param name="reason">The reason for destruction</param>
+ /// <param name="content">The data set to save</param>
+ public virtual void OnDestroy(WidgetDestroyType reason, Bundle content)
+ {
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the widget instance is paused.
+ /// </summary>
+ public virtual void OnPause()
+ {
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the widget instance is resumed.
+ /// </summary>
+ public virtual void OnResume()
+ {
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the widget instance is resized.
+ /// </summary>
+ /// <param name="w">Widget width</param>
+ /// <param name="h">Widget height</param>
+ public virtual void OnResize(int w, int h)
+ {
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the widget instance should be updated.
+ /// </summary>
+ /// <param name="content">The data set for updating this widget. It will be provided by requester.</param>
+ /// <param name="isForce">Although the widget is paused, if it is TRUE, the widget can be updated</param>
+ public virtual void OnUpdate(Bundle content, bool isForce)
+ {
+ }
+
+ }
+}
diff --git a/src/Tizen.Applications.WidgetApplication/Tizen.Applications/WidgetType.cs b/src/Tizen.Applications.WidgetApplication/Tizen.Applications/WidgetType.cs
new file mode 100755
index 0000000..c19e81e
--- /dev/null
+++ b/src/Tizen.Applications.WidgetApplication/Tizen.Applications/WidgetType.cs
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Applications
+{
+ internal class WidgetType
+ {
+ internal readonly Type ClassType;
+ internal readonly string Id;
+ internal IList<WidgetBase> WidgetInstances = new List<WidgetBase>();
+
+ private Interop.Widget.WidgetiInstanceLifecycleCallbacks _callbacks;
+
+ internal WidgetType(Type ctype, string id)
+ {
+ ClassType = ctype;
+ Id = id;
+ _callbacks.OnCreate = new Interop.Widget.WidgetInstanceCreateCallback(OnCreate);
+ _callbacks.OnDestroy = new Interop.Widget.WidgetInstanceDestroyCallback(OnDestroy);
+ _callbacks.OnPause = new Interop.Widget.WidgetInstancePauseCallback(OnPause);
+ _callbacks.OnResume = new Interop.Widget.WidgetInstanceResumeCallback(OnResume);
+ _callbacks.OnResize = new Interop.Widget.WidgetInstanceResizeCallback(OnResize);
+ _callbacks.OnUpdate = new Interop.Widget.WidgetInstanceUpdateCallback(OnUpdate);
+ }
+
+ internal IntPtr Bind(IntPtr h)
+ {
+ return Interop.Widget.AddClass(h, Id, _callbacks, IntPtr.Zero);
+ }
+
+ private int OnCreate(IntPtr context, IntPtr content, int w, int h, IntPtr userData)
+ {
+ WidgetBase b = Activator.CreateInstance(ClassType) as WidgetBase;
+ Bundle bundle = null;
+
+ if (b == null)
+ return 0;
+
+ b.Bind(context, Id);
+ WidgetInstances.Add(b);
+ if (content != IntPtr.Zero)
+ bundle = new Bundle(new SafeBundleHandle(content, false));
+ b.OnCreate(bundle, w, h);
+
+ return 0;
+ }
+
+ private int OnDestroy(IntPtr context, Interop.Widget.WidgetAppDestroyType reason, IntPtr content, IntPtr userData)
+ {
+ foreach (WidgetBase w in WidgetInstances)
+ {
+ if(w.Handle == context)
+ {
+ Bundle bundle = null;
+
+ if (content != IntPtr.Zero)
+ bundle = new Bundle(new SafeBundleHandle(content, false));
+
+ w.OnDestroy(reason == Interop.Widget.WidgetAppDestroyType.Permanent ?
+ WidgetBase.WidgetDestroyType.Permanent :
+ WidgetBase.WidgetDestroyType.Temporary, bundle);
+ WidgetInstances.Remove(w);
+ break;
+ }
+ }
+
+ return 0;
+ }
+
+ private int OnPause(IntPtr context, IntPtr userData)
+ {
+ foreach (WidgetBase w in WidgetInstances)
+ {
+ if (w.Handle == context)
+ {
+ w.OnPause();
+ break;
+ }
+ }
+ return 0;
+ }
+
+ private int OnResume(IntPtr context, IntPtr userData)
+ {
+ foreach (WidgetBase w in WidgetInstances)
+ {
+ if (w.Handle == context)
+ {
+ w.OnResume();
+ break;
+ }
+ }
+ return 0;
+ }
+
+ private int OnResize(IntPtr context, int w, int h, IntPtr userData)
+ {
+ foreach (WidgetBase o in WidgetInstances)
+ {
+ if (o.Handle == context)
+ {
+ o.OnResize(w, h);
+ break;
+ }
+ }
+ return 0;
+ }
+
+ private int OnUpdate(IntPtr context, IntPtr content, int force, IntPtr userData)
+ {
+ foreach (WidgetBase o in WidgetInstances)
+ {
+ if (o.Handle == context)
+ {
+ Bundle bundle = null;
+
+ if (content != IntPtr.Zero)
+ bundle = new Bundle(new SafeBundleHandle(content, false));
+ o.OnUpdate(bundle, force != 0 ? true : false);
+ break;
+ }
+ }
+ return 0;
+ }
+ }
+}
+
diff --git a/src/Tizen.Applications.WidgetApplication/Tizen.Applications/WidgetWindow.cs b/src/Tizen.Applications.WidgetApplication/Tizen.Applications/WidgetWindow.cs
new file mode 100755
index 0000000..69e187f
--- /dev/null
+++ b/src/Tizen.Applications.WidgetApplication/Tizen.Applications/WidgetWindow.cs
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using ElmSharp;
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Applications
+{
+ internal class WidgetWindow : Widget
+ {
+ private IntPtr _handle;
+
+ internal WidgetWindow(IntPtr handle) : base()
+ {
+ _handle = handle;
+ Realize(null);
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ return _handle;
+ }
+ }
+
+ internal class ConformantWindow : Widget
+ {
+ private IntPtr _handle;
+ private IntPtr _conf;
+
+ internal ConformantWindow(EvasObject parent, IntPtr handle) : base()
+ {
+ _handle = handle;
+ Realize(parent);
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ _conf = Interop.Widget.elm_conformant_add(_handle);
+ Interop.Widget.evas_object_size_hint_weight_set(_conf, 1.0, 1.0);
+ Interop.Widget.elm_win_conformant_set(_handle, true);
+ Interop.Widget.elm_win_resize_object_add(_handle, _conf);
+ return _conf;
+ }
+
+ }
+}
+
diff --git a/src/Tizen.Applications.WidgetControl/Interop/Interop.Libraries.cs b/src/Tizen.Applications.WidgetControl/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..e447fa6
--- /dev/null
+++ b/src/Tizen.Applications.WidgetControl/Interop/Interop.Libraries.cs
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string WidgetService = "libwidget_service.so.1";
+ }
+}
diff --git a/src/Tizen.Applications.WidgetControl/Interop/Interop.WidgetService.cs b/src/Tizen.Applications.WidgetControl/Interop/Interop.WidgetService.cs
new file mode 100755
index 0000000..b49e859
--- /dev/null
+++ b/src/Tizen.Applications.WidgetControl/Interop/Interop.WidgetService.cs
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Applications;
+
+internal static partial class Interop
+{
+ internal static partial class WidgetService
+ {
+ internal enum ErrorCode : int
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None,
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+ OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
+ ResourceBusy = Tizen.Internals.Errors.ErrorCode.ResourceBusy,
+ PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied,
+ Canceled = Tizen.Internals.Errors.ErrorCode.Canceled,
+ IoError = Tizen.Internals.Errors.ErrorCode.IoError,
+ TimedOut = Tizen.Internals.Errors.ErrorCode.TimedOut,
+ NotSupported = Tizen.Internals.Errors.ErrorCode.NotSupported,
+ FileNoSpaceOnDevice = Tizen.Internals.Errors.ErrorCode.FileNoSpaceOnDevice,
+ Fault = -0x02F40000 | 0x0001,
+ AlreadyExist = -0x02F40000 | 0x0002,
+ AlreadyStarted = -0x02F40000 | 0x0004,
+ NotExist = -0x02F40000 | 0x0008,
+ Disabled = -0x02F40000 | 0x0010,
+ MaxExceeded = -0x02F40000 | 0x0011,
+ }
+
+ internal enum LifecycleEvent : int
+ {
+ AppDead = 0,
+ Created = 1,
+ Destroyed = 2,
+ Paused = 3,
+ Resumed = 4,
+ Max = 5
+ }
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void InstanceCallback(string widgetId, string instanceId, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void LifecycleCallback(string widgetId, LifecycleEvent e, string instanceId, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void WidgetListCallback(string widgetId, int isPrime, IntPtr userData);
+
+ [DllImport(Libraries.WidgetService, EntryPoint = "widget_service_get_icon")]
+ internal static extern string GetIcon(string pkgId, string lang);
+
+ [DllImport(Libraries.WidgetService, EntryPoint = "widget_service_get_name")]
+ internal static extern string GetName(string widgetId, string lang);
+
+ [DllImport(Libraries.WidgetService, EntryPoint = "widget_service_get_nodisplay")]
+ internal static extern int GetNoDisplay(string widgetId);
+
+ [DllImport(Libraries.WidgetService, EntryPoint = "widget_service_get_widget_instance_list")]
+ internal static extern ErrorCode GetInstances(string widgetId, InstanceCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.WidgetService, EntryPoint = "widget_service_set_lifecycle_event_cb")]
+ internal static extern ErrorCode SetLifecycleEvent(string widgetId, LifecycleCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.WidgetService, EntryPoint = "widget_service_unset_lifecycle_event_cb")]
+ internal static extern ErrorCode UnsetLifecycleEvent(string widgetId, IntPtr userData);
+
+ [DllImport(Libraries.WidgetService, EntryPoint = "widget_service_trigger_update")]
+ internal static extern ErrorCode UpdateContent(string widgetId, string instanceId, SafeBundleHandle bundle, int force);
+
+ [DllImport(Libraries.WidgetService, EntryPoint = "widget_service_change_period")]
+ internal static extern ErrorCode ChangePeriod(string widgetId, string instanceId, double period);
+
+ [DllImport(Libraries.WidgetService, EntryPoint = "widget_service_get_content_of_widget_instance")]
+ internal static extern ErrorCode GetContent(string widgetId, string instanceId, out IntPtr bundle);
+
+ [DllImport(Libraries.WidgetService, EntryPoint = "widget_service_get_package_id")]
+ internal static extern string GetPkgId(string widgetId);
+
+ [DllImport(Libraries.WidgetService, EntryPoint = "widget_service_get_supported_sizes")]
+ internal static extern ErrorCode GetSupportedSizes(string widgetId, ref int cnt, out int[] w, out int[] h);
+
+ [DllImport(Libraries.WidgetService, EntryPoint = "widget_service_get_supported_size_types")]
+ internal static extern ErrorCode GetSupportedSizeTypes(string widgetId, ref int cnt, out int[] types);
+
+ [DllImport(Libraries.WidgetService, EntryPoint = "widget_service_get_preview_image_path")]
+ internal static extern string GetPreviewImagePath(string widgetId, int sizeType);
+
+ [DllImport(Libraries.WidgetService, EntryPoint = "widget_service_get_widget_list_by_pkgid")]
+ internal static extern ErrorCode GetWidgetListByPkgId(string pkgId, WidgetListCallback callback, IntPtr userData);
+ }
+}
diff --git a/src/Tizen.Applications.WidgetControl/Tizen.Applications.WidgetControl.csproj b/src/Tizen.Applications.WidgetControl/Tizen.Applications.WidgetControl.csproj
new file mode 100644
index 0000000..99f4360
--- /dev/null
+++ b/src/Tizen.Applications.WidgetControl/Tizen.Applications.WidgetControl.csproj
@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen.Applications.Common\Tizen.Applications.Common.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Applications.WidgetControl/Tizen.Applications/WidgetControl.cs b/src/Tizen.Applications.WidgetControl/Tizen.Applications/WidgetControl.cs
new file mode 100755
index 0000000..86e5969
--- /dev/null
+++ b/src/Tizen.Applications.WidgetControl/Tizen.Applications/WidgetControl.cs
@@ -0,0 +1,708 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using Tizen.Applications;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Class for receiving widget events and sending data to widget.
+ /// </summary>
+ public class WidgetControl : IDisposable
+ {
+ /// <summary>
+ /// Class for widget instance.
+ /// </summary>
+ public class Instance
+ {
+ private string _widgetId;
+
+ internal Instance(string widgetId)
+ {
+ _widgetId = widgetId;
+ }
+
+ /// <summary>
+ /// Widget ID.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Id { get; internal set; }
+
+ /// <summary>
+ /// Gets widget content.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="InvalidOperationException">Thrown in case of failed conditions</exception>
+ public Bundle GetContent()
+ {
+ IntPtr h;
+
+ Interop.WidgetService.ErrorCode err = Interop.WidgetService.GetContent(_widgetId, Id, out h);
+
+ switch (err)
+ {
+ case Interop.WidgetService.ErrorCode.InvalidParameter:
+ throw new InvalidOperationException("Invalid parameter at unmanaged code");
+
+ case Interop.WidgetService.ErrorCode.IoError:
+ throw new InvalidOperationException("Failed to access DB");
+ }
+
+ return new Bundle(new SafeBundleHandle(h, true));
+ }
+
+ /// <summary>
+ /// Changes the content for the widget instance.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="content">Content to be changed</param>
+ /// <param name="force"> True if you want to update your widget even if the provider is paused otherwise false.</param>
+ /// <exception cref="ArgumentException">Thrown when failed because of invalid argument</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of failed conditions</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access this method</exception>
+ public void ChangeContent(Bundle content, bool force)
+ {
+ Interop.WidgetService.ErrorCode err = Interop.WidgetService.UpdateContent(_widgetId, Id, content.SafeBundleHandle, force ? 1 : 0);
+
+ switch (err)
+ {
+ case Interop.WidgetService.ErrorCode.InvalidParameter:
+ throw new ArgumentException("Invalid parameter");
+
+ case Interop.WidgetService.ErrorCode.Canceled:
+ throw new InvalidOperationException("Provider is paused, so this update request is canceld");
+
+ case Interop.WidgetService.ErrorCode.OutOfMemory:
+ throw new InvalidOperationException("Out-of-memory at unmanaged code");
+
+ case Interop.WidgetService.ErrorCode.Fault:
+ throw new InvalidOperationException("Failed to create a request packet");
+
+ case Interop.WidgetService.ErrorCode.PermissionDenied:
+ throw new UnauthorizedAccessException();
+ }
+ }
+
+ /// <summary>
+ /// Changes the update period for the widget instance.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="ArgumentException">Thrown when failed because of invalid argument</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of failed conditions</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access this method</exception>
+ public void ChangePeriod(double period)
+ {
+ Interop.WidgetService.ErrorCode err = Interop.WidgetService.ChangePeriod(_widgetId, Id, period);
+
+ switch (err)
+ {
+ case Interop.WidgetService.ErrorCode.InvalidParameter:
+ throw new ArgumentException("Invalid parameter");
+
+ case Interop.WidgetService.ErrorCode.OutOfMemory:
+ throw new InvalidOperationException("Out-of-memory at unmanaged code");
+
+ case Interop.WidgetService.ErrorCode.Fault:
+ throw new InvalidOperationException("Failed to create a request packet");
+
+ case Interop.WidgetService.ErrorCode.PermissionDenied:
+ throw new UnauthorizedAccessException();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Class for widget size information.
+ /// </summary>
+ public class Scale
+ {
+
+ internal Scale()
+ {
+ }
+
+ /// <summary>
+ /// Enumeration for types of widget size
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum SizeType : int
+ {
+ /// <summary>
+ /// 175x175 based on 720x1280 resolution.
+ /// </summary>
+ Basic1x1 = 0x0001,
+
+ /// <summary>
+ /// 354x175 based on 720x1280 resolution.
+ /// </summary>
+ Basic2x1 = 0x0002,
+
+ /// <summary>
+ /// 354x354 based on 720x1280 resolution.
+ /// </summary>
+ Basic2x2 = 0x0004,
+
+ /// <summary>
+ /// 712x175 based on 720x1280 resolution.
+ /// </summary>
+ Basic4x1 = 0x0008,
+
+ /// <summary>
+ /// 712x354 based on 720x1280 resolution.
+ /// </summary>
+ Basic4x2 = 0x0010,
+
+ /// <summary>
+ /// 712x533 based on 720x1280 resolution.
+ /// </summary>
+ Basic4x3 = 0x0020,
+
+ /// <summary>
+ /// 712x712 based on 720x1280 resolution.
+ /// </summary>
+ Basic4x4 = 0x0040,
+
+ /// <summary>
+ /// 712x891 based on 720x1280 resolution.
+ /// </summary>
+ Basic4x5 = 0x0080,
+
+ /// <summary>
+ /// 712x1070 based on 720x1280 resolution.
+ /// </summary>
+ Basic4x6 = 0x0100,
+
+
+ /// <summary>
+ /// 224x215 based on 720x1280 resolution.
+ /// </summary>
+ Easy1x1 = 0x1000,
+
+ /// <summary>
+ /// 680x215 based on 720x1280 resolution.
+ /// </summary>
+ Easy1x2 = 0x2000,
+
+ /// <summary>
+ /// 680x653 based on 720x1280 resolution.
+ /// </summary>
+ Easy1x3 = 0x4000,
+
+ /// <summary>
+ /// 720x1280 based on 720x1280 resolution.
+ /// </summary>
+ Full = 0x0800,
+ }
+
+ /// <summary>
+ /// Widget width.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public int Width { get; internal set; }
+
+ /// <summary>
+ /// Widget height.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public int Height { get; internal set; }
+
+ /// <summary>
+ /// The path for widget preview image file.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string PreviewImagePath { get; internal set; }
+
+ /// <summary>
+ /// The size type of the widget.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public SizeType Type { get; internal set; }
+ }
+
+ private event EventHandler<WidgetLifecycleEventArgs> _created;
+ private event EventHandler<WidgetLifecycleEventArgs> _resumed;
+ private event EventHandler<WidgetLifecycleEventArgs> _paused;
+ private event EventHandler<WidgetLifecycleEventArgs> _destroyed;
+ private bool _disposedValue = false;
+ private static IDictionary<string, int> s_lifecycleEventRefCnt = new Dictionary<string, int>();
+ private static IList<WidgetControl> s_eventObjects = new List<WidgetControl>();
+
+ /// <summary>
+ /// Factory method for WidgetControl.
+ /// It will create all objects of WidgetControl base on package ID.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="pkgId">Parkage ID</param>
+ /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
+ /// <exception cref="ArgumentException">Thrown when failed because of invalid argument</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of failed conditions</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access this method</exception>
+ public static WidgetControl[] CreateAll(string pkgId)
+ {
+ List<WidgetControl> list = new List<WidgetControl>();
+
+ Interop.WidgetService.ErrorCode err = Interop.WidgetService.GetWidgetListByPkgId(pkgId, (widgetId, isPrime, userData) =>
+ {
+ list.Add(new WidgetControl(widgetId));
+ }, IntPtr.Zero);
+
+ switch (err)
+ {
+ case Interop.WidgetService.ErrorCode.InvalidParameter:
+ throw new ArgumentException("Invalid parameter");
+
+ case Interop.WidgetService.ErrorCode.IoError:
+ throw new InvalidOperationException("Failed to access DB");
+
+ case Interop.WidgetService.ErrorCode.PermissionDenied:
+ throw new UnauthorizedAccessException();
+ }
+
+ return list.ToArray();
+ }
+
+ /// <summary>
+ /// Gets all widget IDs by package ID.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
+ /// <exception cref="ArgumentException">Thrown when failed because of invalid argument</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of failed conditions</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access this method</exception>
+ public static string[] GetWidgetIds(string pkgId)
+ {
+ List<string> list = new List<string>();
+
+ Interop.WidgetService.ErrorCode err = Interop.WidgetService.GetWidgetListByPkgId(pkgId, (widgetId, isPrime, userData) =>
+ {
+ list.Add(widgetId);
+ }, IntPtr.Zero);
+
+ switch (err)
+ {
+ case Interop.WidgetService.ErrorCode.InvalidParameter:
+ throw new ArgumentException("Invalid parameter");
+
+ case Interop.WidgetService.ErrorCode.IoError:
+ throw new InvalidOperationException("Failed to access DB");
+
+ case Interop.WidgetService.ErrorCode.PermissionDenied:
+ throw new UnauthorizedAccessException();
+ }
+
+ return list.ToArray();
+ }
+
+ /// <summary>
+ /// Widget ID.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Id { get; internal set; }
+
+ /// <summary>
+ /// The flag value for "nodisplay"
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
+ public bool IsNoDisplay
+ {
+ get
+ {
+ if (Interop.WidgetService.GetNoDisplay(Id) != 0)
+ return true;
+
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Event handler for created widget instance.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="InvalidOperationException">Thrown in case of failed conditions</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access this method</exception>
+ public event EventHandler<WidgetLifecycleEventArgs> Created
+ {
+ add
+ {
+ RegisterLifecycleEvent();
+ _created += value;
+ }
+ remove
+ {
+ _created -= value;
+ UnregisterLifecycleEvent();
+ }
+ }
+
+ /// <summary>
+ /// Event handler for resumed widget instance.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="InvalidOperationException">Thrown in case of failed conditions</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access this method</exception>
+ public event EventHandler<WidgetLifecycleEventArgs> Resumed
+ {
+ add
+ {
+ RegisterLifecycleEvent();
+ _resumed += value;
+ }
+ remove
+ {
+ _resumed -= value;
+ UnregisterLifecycleEvent();
+ }
+ }
+
+ /// <summary>
+ /// Event handler for paused widget instance.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="InvalidOperationException">Thrown in case of failed conditions</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access this method</exception>
+ public event EventHandler<WidgetLifecycleEventArgs> Paused
+ {
+ add
+ {
+ RegisterLifecycleEvent();
+ _paused += value;
+ }
+ remove
+ {
+ _paused -= value;
+ UnregisterLifecycleEvent();
+ }
+ }
+
+ /// <summary>
+ /// Event handler for destroyed widget instance.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="InvalidOperationException">Thrown in case of failed conditions</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access this method</exception>
+ public event EventHandler<WidgetLifecycleEventArgs> Destroyed
+ {
+ add
+ {
+ RegisterLifecycleEvent();
+ _destroyed += value;
+ }
+ remove
+ {
+ _destroyed -= value;
+ UnregisterLifecycleEvent();
+ }
+ }
+
+ /// <summary>
+ /// A constructor of WidgetControl object
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="widgetId">widget id.</param>
+ public WidgetControl(string widgetId)
+ {
+ Id = widgetId;
+ }
+
+ /// <summary>
+ /// Finalizer of the WidgetControl class.
+ /// </summary>
+ ~WidgetControl()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Gets objects for widget instance information.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="InvalidOperationException">Thrown in case of failed conditions</exception>
+ /// <exception cref="NotSupportedException">Thrown when API is not supported in this device</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access this method</exception>
+ public IEnumerable<Instance> GetInstances()
+ {
+ IList<Instance> instances = new List<Instance>();
+ Interop.WidgetService.ErrorCode err = Interop.WidgetService.GetInstances(Id, (widgetId, instanceId, userData) =>
+ {
+ instances.Add(new Instance(widgetId) { Id = instanceId });
+ }, IntPtr.Zero);
+
+ switch (err)
+ {
+ case Interop.WidgetService.ErrorCode.InvalidParameter:
+ throw new InvalidOperationException("Invalid parameter at unmanaged code");
+
+ case Interop.WidgetService.ErrorCode.NotSupported:
+ throw new NotSupportedException();
+
+ case Interop.WidgetService.ErrorCode.PermissionDenied:
+ throw new UnauthorizedAccessException();
+ }
+
+ return instances;
+ }
+
+ /// <summary>
+ /// Gets objects for widget scale information.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
+ /// <exception cref="InvalidOperationException">Thrown in case of failed conditions</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access this method</exception>
+ public IEnumerable<Scale> GetScales()
+ {
+ int[] w = new int[100];
+ int[] h = new int[100];
+ int[] types = new int[100];
+ int cnt1 = 100;
+ int cnt2 = 100;
+ IList<Scale> scales = new List<Scale>();
+
+ Interop.WidgetService.ErrorCode err = Interop.WidgetService.GetSupportedSizes(Id, ref cnt1, out w, out h);
+
+ switch (err)
+ {
+ case Interop.WidgetService.ErrorCode.InvalidParameter:
+ throw new InvalidOperationException("Invalid parameter at unmanaged code");
+
+ case Interop.WidgetService.ErrorCode.IoError:
+ throw new InvalidOperationException("Failed to access DB");
+
+ case Interop.WidgetService.ErrorCode.PermissionDenied:
+ throw new UnauthorizedAccessException();
+ }
+
+ err = Interop.WidgetService.GetSupportedSizeTypes(Id, ref cnt2, out types);
+
+ switch (err)
+ {
+ case Interop.WidgetService.ErrorCode.InvalidParameter:
+ throw new InvalidOperationException("Invalid parameter at unmanaged code");
+
+ case Interop.WidgetService.ErrorCode.IoError:
+ throw new InvalidOperationException("Failed to access DB");
+
+ case Interop.WidgetService.ErrorCode.PermissionDenied:
+ throw new UnauthorizedAccessException();
+ }
+
+ if (cnt1 != cnt2)
+ return null;
+
+ for (int i = 0; i < cnt1; i++)
+ {
+ string prev = Interop.WidgetService.GetPreviewImagePath(Id, types[i]);
+
+ scales.Add(new Scale()
+ {
+ Width = w[i],
+ Height = h[i],
+ PreviewImagePath = prev,
+ Type = (Scale.SizeType)types[i]
+ });
+ }
+ return scales;
+ }
+
+ /// <summary>
+ /// Gets widget name.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="lang">Language</param>
+ /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
+ /// <exception cref="ArgumentNullException">Thrown when argument is null</exception>
+ public string GetName(string lang)
+ {
+ if (lang == null)
+ throw new ArgumentNullException();
+
+ return Interop.WidgetService.GetName(Id, lang);
+ }
+
+ /// <summary>
+ /// Gets widget icon path.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="lang">Language</param>
+ /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
+ /// <exception cref="ArgumentNullException">Thrown when argument is null</exception>
+ public string GetIconPath(string lang)
+ {
+ if (lang == null)
+ throw new ArgumentNullException();
+
+ string pkgId = Interop.WidgetService.GetPkgId(Id);
+
+ return Interop.WidgetService.GetIcon(pkgId, lang);
+ }
+
+ /// <summary>
+ /// Releases all resources used by the WidgetControl class.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ if (disposing)
+ {
+ }
+
+ _created = null;
+ _resumed = null;
+ _paused = null;
+ _destroyed = null;
+ UnregisterLifecycleEvent();
+
+ _disposedValue = true;
+ }
+ }
+
+ private void RegisterLifecycleEvent()
+ {
+ if (!s_lifecycleEventRefCnt.ContainsKey(Id))
+ s_lifecycleEventRefCnt[Id] = 0;
+
+ if (_created != null || _paused != null || _resumed != null || _destroyed != null)
+ return;
+
+ if (s_lifecycleEventRefCnt[Id] == 0)
+ {
+ Interop.WidgetService.ErrorCode err = Interop.WidgetService.SetLifecycleEvent(Id, OnLifecycleEvent, IntPtr.Zero);
+
+ switch (err)
+ {
+ case Interop.WidgetService.ErrorCode.InvalidParameter:
+ throw new InvalidOperationException("Invalid parameter at unmanaged code");
+
+ case Interop.WidgetService.ErrorCode.PermissionDenied:
+ throw new UnauthorizedAccessException();
+ }
+ }
+
+ s_lifecycleEventRefCnt[Id]++;
+ s_eventObjects.Add(this);
+ }
+
+ private void UnregisterLifecycleEvent()
+ {
+ if (!s_lifecycleEventRefCnt.ContainsKey(Id))
+ return;
+
+ if (s_lifecycleEventRefCnt[Id] <= 0)
+ return;
+
+ if (_created != null || _paused != null || _resumed != null || _destroyed != null)
+ return;
+
+ if (s_lifecycleEventRefCnt[Id] == 1)
+ {
+ Interop.WidgetService.ErrorCode err = Interop.WidgetService.UnsetLifecycleEvent(Id, IntPtr.Zero);
+
+ switch (err)
+ {
+ case Interop.WidgetService.ErrorCode.InvalidParameter:
+ throw new InvalidOperationException("Invalid parameter at unmanaged code");
+
+ case Interop.WidgetService.ErrorCode.PermissionDenied:
+ throw new UnauthorizedAccessException();
+
+ case Interop.WidgetService.ErrorCode.NotExist:
+ throw new InvalidOperationException("Event handler is not exist");
+ }
+ }
+
+ s_eventObjects.Remove(this);
+ s_lifecycleEventRefCnt[Id]--;
+ }
+
+ private static void OnLifecycleEvent(string widgetId, Interop.WidgetService.LifecycleEvent e, string instanceId, IntPtr userData)
+ {
+ switch (e)
+ {
+ case Interop.WidgetService.LifecycleEvent.Created:
+ foreach (WidgetControl c in s_eventObjects)
+ {
+ if (c.Id.CompareTo(widgetId) == 0)
+ {
+ c._created?.Invoke(null, new WidgetLifecycleEventArgs()
+ {
+ WidgetId = widgetId,
+ InstanceId = instanceId,
+ Type = WidgetLifecycleEventArgs.EventType.Created
+ });
+ }
+ }
+ break;
+
+ case Interop.WidgetService.LifecycleEvent.Resumed:
+ foreach (WidgetControl c in s_eventObjects)
+ {
+ if (c.Id.CompareTo(widgetId) == 0)
+ {
+ c._resumed?.Invoke(null, new WidgetLifecycleEventArgs()
+ {
+ WidgetId = widgetId,
+ InstanceId = instanceId,
+ Type = WidgetLifecycleEventArgs.EventType.Resumed
+ });
+ }
+ }
+ break;
+
+ case Interop.WidgetService.LifecycleEvent.Paused:
+ foreach (WidgetControl c in s_eventObjects)
+ {
+ if (c.Id.CompareTo(widgetId) == 0)
+ {
+ c._paused?.Invoke(null, new WidgetLifecycleEventArgs()
+ {
+ WidgetId = widgetId,
+ InstanceId = instanceId,
+ Type = WidgetLifecycleEventArgs.EventType.Paused
+ });
+ }
+ }
+ break;
+
+ case Interop.WidgetService.LifecycleEvent.Destroyed:
+ foreach (WidgetControl c in s_eventObjects)
+ {
+ if (c.Id.CompareTo(widgetId) == 0)
+ {
+ c._destroyed?.Invoke(null, new WidgetLifecycleEventArgs()
+ {
+ WidgetId = widgetId,
+ InstanceId = instanceId,
+ Type = WidgetLifecycleEventArgs.EventType.Destroyed
+ });
+ }
+ }
+ break;
+ }
+
+ }
+ }
+}
diff --git a/src/Tizen.Applications.WidgetControl/Tizen.Applications/WidgetLifecycleEventArgs.cs b/src/Tizen.Applications.WidgetControl/Tizen.Applications/WidgetLifecycleEventArgs.cs
new file mode 100755
index 0000000..6d553f4
--- /dev/null
+++ b/src/Tizen.Applications.WidgetControl/Tizen.Applications/WidgetLifecycleEventArgs.cs
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Class for event arguments of the widget lifecycle.
+ /// </summary>
+ public class WidgetLifecycleEventArgs : EventArgs
+ {
+ internal WidgetLifecycleEventArgs()
+ {
+ }
+
+ /// <summary>
+ /// Enumeration for event type.
+ /// </summary>
+ public enum EventType
+ {
+ /// <summary>
+ /// The widget is created.
+ /// </summary>
+ Created,
+
+ /// <summary>
+ /// The widget is destroyed.
+ /// </summary>
+ Destroyed,
+
+ /// <summary>
+ /// The widget is paused.
+ /// </summary>
+ Paused,
+
+ /// <summary>
+ /// The widget is resumed.
+ /// </summary>
+ Resumed
+ }
+
+ /// <summary>
+ /// Widget ID.
+ /// </summary>
+ public string WidgetId { get; internal set; }
+
+ /// <summary>
+ /// Widget instnace ID.
+ /// </summary>
+ public string InstanceId { get; internal set; }
+
+ /// <summary>
+ /// Event type.
+ /// </summary>
+ public EventType Type { get; internal set; }
+ }
+}
diff --git a/src/Tizen.Content.Download/Interop/Interop.Download.cs b/src/Tizen.Content.Download/Interop/Interop.Download.cs
new file mode 100755
index 0000000..839ee63
--- /dev/null
+++ b/src/Tizen.Content.Download/Interop/Interop.Download.cs
@@ -0,0 +1,110 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Applications;
+
+internal static partial class Interop
+{
+ internal static partial class Download
+ {
+ // Request class
+
+ [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+ internal delegate void StateChangedCallback(int requestId, int state, IntPtr userData);
+ [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+ internal delegate void ProgressChangedCallback(int requestId, ulong receivedSize, IntPtr userData);
+
+ [DllImport(Libraries.Download, EntryPoint = "download_create")]
+ internal static extern int CreateRequest(out int requestId);
+ [DllImport(Libraries.Download, EntryPoint = "download_destroy")]
+ internal static extern int DestroyRequest(int requestId);
+ [DllImport(Libraries.Download, EntryPoint = "download_set_url")]
+ internal static extern int SetUrl(int requestId, string url);
+ [DllImport(Libraries.Download, EntryPoint = "download_get_url")]
+ internal static extern int GetUrl(int requestId, out string url);
+ [DllImport(Libraries.Download, EntryPoint = "download_set_network_type")]
+ internal static extern int SetNetworkType(int requestId, int networkType);
+ [DllImport(Libraries.Download, EntryPoint = "download_get_network_type")]
+ internal static extern int GetNetworkType(int requestId, out int networkType);
+ [DllImport(Libraries.Download, EntryPoint = "download_set_destination")]
+ internal static extern int SetDestination(int requestId, string path);
+ [DllImport(Libraries.Download, EntryPoint = "download_get_destination")]
+ internal static extern int GetDestination(int requestId, out string path);
+ [DllImport(Libraries.Download, EntryPoint = "download_set_file_name")]
+ internal static extern int SetFileName(int requestId, string fileName);
+ [DllImport(Libraries.Download, EntryPoint = "download_get_file_name")]
+ internal static extern int GetFileName(int requestId, out string path);
+ [DllImport(Libraries.Download, EntryPoint = "download_set_auto_download")]
+ internal static extern int SetAutoDownload(int requestId, bool value);
+ [DllImport(Libraries.Download, EntryPoint = "download_get_auto_download")]
+ internal static extern int GetAutoDownload(int requestId, out bool value);
+ [DllImport(Libraries.Download, EntryPoint = "download_set_temp_file_path")]
+ internal static extern int SetTempFilePath(int requestId, string tempPath);
+ [DllImport(Libraries.Download, EntryPoint = "download_get_temp_path")]
+ internal static extern int GetTempFilePath(int requestId, out string tempPath);
+ [DllImport(Libraries.Download, EntryPoint = "download_add_http_header_field")]
+ internal static extern int AddHttpHeaderField(int requestId, string field, string value);
+ [DllImport(Libraries.Download, EntryPoint = "download_get_downloaded_file_path")]
+ internal static extern int GetDownloadedPath(int requestId, out string downloadedPath);
+ [DllImport(Libraries.Download, EntryPoint = "download_get_mime_type")]
+ internal static extern int GetMimeType(int requestId, out string mimeType);
+ [DllImport(Libraries.Download, EntryPoint = "download_get_state")]
+ internal static extern int GetState(int requestId, out int downloadState);
+ [DllImport(Libraries.Download, EntryPoint = "download_get_content_name")]
+ internal static extern int GetContentName(int requestId, out string contentName);
+ [DllImport(Libraries.Download, EntryPoint = "download_get_content_size")]
+ internal static extern int GetContentSize(int requestId, out ulong size);
+ [DllImport(Libraries.Download, EntryPoint = "download_get_http_status")]
+ internal static extern int GetHttpStatus(int requestId, out int httpStatus);
+ [DllImport(Libraries.Download, EntryPoint = "download_get_etag")]
+ internal static extern int GetETag(int requestId, out string etag);
+ [DllImport(Libraries.Download, EntryPoint = "download_start")]
+ internal static extern int StartDownload(int requestId);
+ [DllImport(Libraries.Download, EntryPoint = "download_pause")]
+ internal static extern int PauseDownload(int requestId);
+ [DllImport(Libraries.Download, EntryPoint = "download_cancel")]
+ internal static extern int CancelDownload(int requestId);
+ [DllImport(Libraries.Download, EntryPoint = "download_set_state_changed_cb")]
+ internal static extern int SetStateChangedCallback(int requestId, StateChangedCallback callback, IntPtr userData);
+ [DllImport(Libraries.Download, EntryPoint = "download_unset_state_changed_cb")]
+ internal static extern int UnsetStateChangedCallback(int requestId);
+ [DllImport(Libraries.Download, EntryPoint = "download_set_progress_cb")]
+ internal static extern int SetProgressCallback(int requestId, ProgressChangedCallback callback, IntPtr userData);
+ [DllImport(Libraries.Download, EntryPoint = "download_unset_progress_cb")]
+ internal static extern int UnsetProgressCallback(int requestId);
+
+ // Notification class
+
+ [DllImport(Libraries.Download, EntryPoint = "download_set_notification_title")]
+ internal static extern int SetNotificationTitle(int requestId, string title);
+ [DllImport(Libraries.Download, EntryPoint = "download_get_notification_title")]
+ internal static extern int GetNotificationTitle(int requestId, out string title);
+ [DllImport(Libraries.Download, EntryPoint = "download_set_notification_description")]
+ internal static extern int SetNotificationDescription(int requestId, string description);
+ [DllImport(Libraries.Download, EntryPoint = "download_get_notification_description")]
+ internal static extern int GetNotificationDescription(int requestId, out string description);
+ [DllImport(Libraries.Download, EntryPoint = "download_set_notification_type")]
+ internal static extern int SetNotificationType(int requestId, int type);
+ [DllImport(Libraries.Download, EntryPoint = "download_get_notification_type")]
+ internal static extern int GetNotificationType(int requestId, out int type);
+ [DllImport(Libraries.Download, EntryPoint = "download_set_notification_app_control")]
+ internal static extern int SetNotificationAppControl(int requestId, int appControlType, SafeAppControlHandle handle);
+ [DllImport(Libraries.Download, EntryPoint = "download_get_notification_app_control")]
+ internal static extern int GetNotificationAppControl(int requestId, int appControlType, out SafeAppControlHandle handle);
+ }
+}
diff --git a/src/Tizen.Content.Download/Interop/Interop.Libraries.cs b/src/Tizen.Content.Download/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..c634bfd
--- /dev/null
+++ b/src/Tizen.Content.Download/Interop/Interop.Libraries.cs
@@ -0,0 +1,24 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string Download = "libcapi-web-url-download.so.0";
+ public const string Libc = "libc.so.6";
+ }
+}
diff --git a/src/Tizen.Content.Download/Tizen.Content.Download.csproj b/src/Tizen.Content.Download/Tizen.Content.Download.csproj
new file mode 100644
index 0000000..99f4360
--- /dev/null
+++ b/src/Tizen.Content.Download/Tizen.Content.Download.csproj
@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen.Applications.Common\Tizen.Applications.Common.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Content.Download/Tizen.Content.Download/DownloadEnumerator.cs b/src/Tizen.Content.Download/Tizen.Content.Download/DownloadEnumerator.cs
new file mode 100755
index 0000000..facfde5
--- /dev/null
+++ b/src/Tizen.Content.Download/Tizen.Content.Download/DownloadEnumerator.cs
@@ -0,0 +1,129 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+namespace Tizen.Content.Download
+{
+ /// <summary>
+ /// Enumeration for download state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum DownloadState
+ {
+ /// <summary>
+ /// Unhandled exception
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ None = 0,
+ /// <summary>
+ /// Ready to download
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Ready,
+ /// <summary>
+ /// Queued to start downloading
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Queued,
+ /// <summary>
+ /// Currently downloading
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Downloading,
+ /// <summary>
+ /// Download is paused and can be resumed
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Paused,
+ /// <summary>
+ /// The download is completed
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Completed,
+ /// <summary>
+ /// The download failed
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Failed,
+ /// <summary>
+ /// User canceled the download request
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Canceled
+ }
+
+ /// <summary>
+ /// Enumeration for network type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum NetworkType
+ {
+ /// <summary>
+ /// Download is available through data network
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ DataNetwork = 0,
+ /// <summary>
+ /// Download is available through WiFi
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Wifi,
+ /// <summary>
+ /// Download is available through WiFi-Direct
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ WifiDirect,
+ /// <summary>
+ /// Download is available through either data network or WiFi
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ All
+ }
+
+ /// <summary>
+ /// Enumeration for notification type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum NotificationType
+ {
+ /// <summary>
+ /// Do not register notification
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ None = 0,
+ /// <summary>
+ /// Completion notification for success state and failed state
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ CompleteOnly,
+ /// <summary>
+ /// All download notifications for ongoing state, success state and failed state
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ All
+ }
+
+ internal enum NotificationAppControlType
+ {
+ Downloading = 0,
+ Completed,
+ Failed
+ }
+
+ internal static class Globals
+ {
+ internal const string LogTag = "Tizen.Content.Download";
+ }
+}
diff --git a/src/Tizen.Content.Download/Tizen.Content.Download/DownloadErrorFactory.cs b/src/Tizen.Content.Download/Tizen.Content.Download/DownloadErrorFactory.cs
new file mode 100755
index 0000000..b6fd77f
--- /dev/null
+++ b/src/Tizen.Content.Download/Tizen.Content.Download/DownloadErrorFactory.cs
@@ -0,0 +1,94 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Content.Download
+{
+ internal enum DownloadError
+ {
+ DownloadErrorCommonCode = -0x02A00000,
+ None = ErrorCode.None,
+ InvalidParameter = ErrorCode.InvalidParameter,
+ OutOfMemory = ErrorCode.OutOfMemory,
+ NetworkUnreachable = ErrorCode.NetworkUnreachable,
+ ConnectionTimedOut = ErrorCode.ConnectionTimeout,
+ NoSpace = ErrorCode.FileNoSpaceOnDevice,
+ PermissionDenied = ErrorCode.PermissionDenied,
+ NotSupported = ErrorCode.NotSupported,
+ InvalidState = DownloadErrorCommonCode | 0x21,
+ ConnectionFailed = DownloadErrorCommonCode | 0x22,
+ InvalidUrl = DownloadErrorCommonCode | 0x24,
+ InvalidDestination = DownloadErrorCommonCode | 0x25,
+ TooManyDownloads = DownloadErrorCommonCode | 0x26,
+ QueueFull = DownloadErrorCommonCode | 0x27,
+ AlreadyCompleted = DownloadErrorCommonCode | 0x28,
+ FileAlreadyExists = DownloadErrorCommonCode | 0x29,
+ CannotResume = DownloadErrorCommonCode | 0x2a,
+ FieldNotFound = DownloadErrorCommonCode | 0x2b,
+ TooManyRedirects = DownloadErrorCommonCode | 0x30,
+ UnhandledHttpCode = DownloadErrorCommonCode | 0x31,
+ RequestTimeout = DownloadErrorCommonCode | 0x32,
+ ResponseTimeout = DownloadErrorCommonCode | 0x33,
+ SystemDown = DownloadErrorCommonCode | 0x34,
+ IdNotFound = DownloadErrorCommonCode | 0x35,
+ InvalidNetworkType = DownloadErrorCommonCode | 0x36,
+ NoData = ErrorCode.NoData,
+ IoError = ErrorCode.IoError
+ }
+
+ internal static class DownloadErrorFactory
+ {
+ internal static void ThrowException(int errorCode, string errorMessage = null, string paramName = null)
+ {
+ DownloadError err = (DownloadError)errorCode;
+ if (String.IsNullOrEmpty(errorMessage))
+ {
+ errorMessage = err.ToString();
+ }
+ switch ((DownloadError)errorCode)
+ {
+ case DownloadError.InvalidParameter:
+ case DownloadError.InvalidUrl:
+ case DownloadError.InvalidDestination:
+ case DownloadError.InvalidNetworkType: throw new ArgumentException(errorMessage, paramName);
+ case DownloadError.OutOfMemory:
+ case DownloadError.NetworkUnreachable:
+ case DownloadError.ConnectionTimedOut:
+ case DownloadError.NoSpace:
+ case DownloadError.InvalidState:
+ case DownloadError.ConnectionFailed:
+ case DownloadError.TooManyDownloads:
+ case DownloadError.QueueFull:
+ case DownloadError.AlreadyCompleted:
+ case DownloadError.FileAlreadyExists:
+ case DownloadError.CannotResume:
+ case DownloadError.FieldNotFound:
+ case DownloadError.TooManyRedirects:
+ case DownloadError.UnhandledHttpCode:
+ case DownloadError.RequestTimeout:
+ case DownloadError.ResponseTimeout:
+ case DownloadError.SystemDown:
+ case DownloadError.IdNotFound:
+ case DownloadError.NoData:
+ case DownloadError.IoError: throw new InvalidOperationException(errorMessage);
+ case DownloadError.NotSupported: throw new NotSupportedException(errorMessage);
+ case DownloadError.PermissionDenied: throw new UnauthorizedAccessException(errorMessage);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Content.Download/Tizen.Content.Download/Notification.cs b/src/Tizen.Content.Download/Tizen.Content.Download/Notification.cs
new file mode 100755
index 0000000..de162a6
--- /dev/null
+++ b/src/Tizen.Content.Download/Tizen.Content.Download/Notification.cs
@@ -0,0 +1,237 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using Tizen.Applications;
+
+namespace Tizen.Content.Download
+{
+ /// <summary>
+ /// The Notification class consists of all the properties required to set notifications for download operation.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class Notification
+ {
+ private int _downloadId;
+
+ internal Notification(int requestId)
+ {
+ _downloadId = requestId;
+ }
+
+ /// <summary>
+ /// Title of the notification.
+ /// If user tries to get before setting, empty string is returned.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ public string Title
+ {
+ get
+ {
+ string title;
+ int ret = Interop.Download.GetNotificationTitle(_downloadId, out title);
+ if (ret != (int)DownloadError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get Notification Title, " + (DownloadError)ret);
+ return String.Empty;
+ }
+ return title;
+ }
+ set
+ {
+ int ret = Interop.Download.SetNotificationTitle(_downloadId, value.ToString());
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Failed to set Notification Title");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Description of the notification.
+ /// If user tries to get before setting, empty string is returned.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ public string Description
+ {
+ get
+ {
+ string description;
+ int ret = Interop.Download.GetNotificationDescription(_downloadId, out description);
+ if (ret != (int)DownloadError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get Notification Description, " + (DownloadError)ret);
+ return String.Empty;
+ }
+ return description;
+ }
+ set
+ {
+ int ret = Interop.Download.SetNotificationDescription(_downloadId, value.ToString());
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Failed to set Notification Description");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Type of Notification.
+ /// If user tries to get before setting, default NotificationType None is returned.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ public NotificationType Type
+ {
+ get
+ {
+ int type;
+ int ret = Interop.Download.GetNotificationType(_downloadId, out type);
+ if (ret != (int)DownloadError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get NotificationType, " + (DownloadError)ret);
+ return 0;
+ }
+ return (NotificationType)type;
+ }
+ set
+ {
+ int ret = Interop.Download.SetNotificationType(_downloadId, (int)value);
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Failed to set NotificationType");
+ }
+ }
+ }
+
+ /// <summary>
+ /// AppControl for an ongoing download notification.
+ /// If user tries to get before setting, null is returned.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <remarks>
+ /// When the notification message is clicked, the action is decided by the app control.
+ /// </remarks>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ public AppControl AppControlOngoing
+ {
+ get
+ {
+ SafeAppControlHandle handle;
+ int ret = Interop.Download.GetNotificationAppControl(_downloadId, (int)NotificationAppControlType.Downloading, out handle);
+ if (ret != (int)DownloadError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get Ongoing type NotificationAppControl, " + (DownloadError)ret);
+ return null;
+ }
+ return new AppControl(handle);
+ }
+ set
+ {
+ int ret = Interop.Download.SetNotificationAppControl(_downloadId, (int)NotificationAppControlType.Downloading, value.SafeAppControlHandle);
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Failed to set Ongoing type NotificationAppControl");
+ }
+ }
+ }
+
+ /// <summary>
+ /// AppControl for a completed download notification.
+ /// If user tries to get before setting, null is returned.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <remarks>
+ /// When the notification message is clicked, the action is decided by the app control
+ /// </remarks>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ public AppControl AppControlCompleted
+ {
+ get
+ {
+ SafeAppControlHandle handle;
+ int ret = Interop.Download.GetNotificationAppControl(_downloadId, (int)NotificationAppControlType.Completed, out handle);
+ if (ret != (int)DownloadError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get Complete type NotificationAppControl, " + (DownloadError)ret);
+ return null;
+ }
+ return new AppControl(handle);
+ }
+ set
+ {
+ int ret = Interop.Download.SetNotificationAppControl(_downloadId, (int)NotificationAppControlType.Completed, value.SafeAppControlHandle);
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Failed to set Complete type NotificationAppControl");
+ }
+ }
+ }
+
+ /// <summary>
+ /// AppControl for a failed download notification.
+ /// If user tries to get before setting, null is returned.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <remarks>
+ /// When the notification message is clicked, the action is decided by the app control
+ /// </remarks>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ public AppControl AppControlFailed
+ {
+ get
+ {
+ SafeAppControlHandle handle;
+ int ret = Interop.Download.GetNotificationAppControl(_downloadId, (int)NotificationAppControlType.Failed, out handle);
+ if (ret != (int)DownloadError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get Fail type NotificationAppControl, " + (DownloadError)ret);
+ return null;
+ }
+ return new AppControl(handle);
+ }
+ set
+ {
+ int ret = Interop.Download.SetNotificationAppControl(_downloadId, (int)NotificationAppControlType.Failed, value.SafeAppControlHandle);
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Failed to set Fail type NotificationAppControl");
+ }
+ }
+ }
+ }
+}
+
diff --git a/src/Tizen.Content.Download/Tizen.Content.Download/ProgressChangedEventArgs.cs b/src/Tizen.Content.Download/Tizen.Content.Download/ProgressChangedEventArgs.cs
new file mode 100755
index 0000000..3e5d169
--- /dev/null
+++ b/src/Tizen.Content.Download/Tizen.Content.Download/ProgressChangedEventArgs.cs
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+
+namespace Tizen.Content.Download
+{
+ /// <summary>
+ /// An extended EventArgs class which contains the size of received data in bytes.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class ProgressChangedEventArgs : EventArgs
+ {
+ private ulong _size = 0;
+
+ internal ProgressChangedEventArgs(ulong size)
+ {
+ _size = size;
+ }
+
+ /// <summary>
+ /// Received data size in bytes.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ulong ReceivedDataSize
+ {
+ get
+ {
+ return _size;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Content.Download/Tizen.Content.Download/Request.cs b/src/Tizen.Content.Download/Tizen.Content.Download/Request.cs
new file mode 100755
index 0000000..20e2048
--- /dev/null
+++ b/src/Tizen.Content.Download/Tizen.Content.Download/Request.cs
@@ -0,0 +1,858 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Content.Download
+{
+ /// <summary>
+ /// The Request class provides functions to create and manage a single download request.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class Request : IDisposable
+ {
+ private int _downloadId;
+ private Notification _notificationProperties;
+ private IDictionary<string, string> _httpHeaders;
+ private EventHandler<StateChangedEventArgs> _downloadStateChanged;
+ private Interop.Download.StateChangedCallback _downloadStateChangedCallback;
+ private EventHandler<ProgressChangedEventArgs> _downloadProgressChanged;
+ private Interop.Download.ProgressChangedCallback _downloadProgressChangedCallback;
+ private bool _disposed = false;
+
+ /// <summary>
+ /// Creates a Request object.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="url"> URL to download</param>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ public Request(string url)
+ {
+ if (String.IsNullOrEmpty(url))
+ {
+ DownloadErrorFactory.ThrowException((int)DownloadError.InvalidParameter, "url cannot be null or empty");
+ }
+ int ret = Interop.Download.CreateRequest(out _downloadId);
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Request creation failed");
+ }
+ ret = Interop.Download.SetUrl(_downloadId, url);
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Setting Url failed");
+ }
+ _notificationProperties = new Notification(_downloadId);
+ _httpHeaders = new Dictionary<string, string>();
+ }
+
+ /// <summary>
+ /// Creates a Request object.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="url"> URL to download</param>
+ /// <param name="destinationPath"> Directory path where downloaded file is stored </param>
+ /// <param name="fileName"> Name of the downloaded file </param>
+ /// <param name="type"> Network type which the download request must adhere to </param>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <feature>http://tizen.org/feature/network.wifi.direct</feature>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="NotSupportedException">Thrown when feature is not supported.</exception>
+ public Request(string url, string destinationPath, string fileName, NetworkType type)
+ {
+ if (String.IsNullOrEmpty(url))
+ {
+ DownloadErrorFactory.ThrowException((int)DownloadError.InvalidParameter, "url cannot be null or empty");
+ }
+ int ret = Interop.Download.CreateRequest(out _downloadId);
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Request creation failed");
+ }
+
+ ret = Interop.Download.SetUrl(_downloadId, url);
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Setting Url failed");
+ }
+
+ ret = Interop.Download.SetDestination(_downloadId, destinationPath);
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Setting DestinationPath failed");
+ }
+
+ ret = Interop.Download.SetFileName(_downloadId, fileName);
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Setting FileName failed");
+ }
+
+ ret = Interop.Download.SetNetworkType(_downloadId, (int)type);
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Setting NetworkType failed");
+ }
+
+ _notificationProperties = new Notification(_downloadId);
+ _httpHeaders = new Dictionary<string, string>();
+ }
+
+ /// <summary>
+ /// Creates a Request object.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="url"> URL to download</param>
+ /// <param name="destinationPath"> Directory path where downloaded file is stored </param>
+ /// <param name="fileName"> Name of the downloaded file </param>
+ /// <param name="type"> Network type which the download request must adhere to </param>
+ /// <param name="httpHeaders"> HTTP header fields for download request </param>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <feature>http://tizen.org/feature/network.wifi.direct</feature>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="NotSupportedException">Thrown when features is not supported.</exception>
+ public Request(string url, string destinationPath, string fileName, NetworkType type, IDictionary<string, string> httpHeaders)
+ {
+ if (String.IsNullOrEmpty(url))
+ {
+ DownloadErrorFactory.ThrowException((int)DownloadError.InvalidParameter, "url cannot be null or empty");
+ }
+ int ret = Interop.Download.CreateRequest(out _downloadId);
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Request creation failed");
+ }
+
+ ret = Interop.Download.SetUrl(_downloadId, url);
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Setting Url failed");
+ }
+
+ ret = Interop.Download.SetDestination(_downloadId, destinationPath);
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Setting DestinationPath failed");
+ }
+
+ ret = Interop.Download.SetFileName(_downloadId, fileName);
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Setting FileName failed");
+ }
+
+ ret = Interop.Download.SetNetworkType(_downloadId, (int)type);
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Setting NetworkType failed");
+ }
+
+ _notificationProperties = new Notification(_downloadId);
+ _httpHeaders = httpHeaders;
+ }
+
+ ~Request()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Event that occurs when the download state changes.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ public event EventHandler<StateChangedEventArgs> StateChanged
+ {
+ add
+ {
+ if (_downloadStateChanged == null)
+ {
+ RegisterStateChangedEvent();
+ }
+ _downloadStateChanged += value;
+ }
+ remove
+ {
+ _downloadStateChanged -= value;
+ if (_downloadStateChanged == null)
+ {
+ UnregisterStateChangedEvent();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Event that occurs when the download progress changes.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ public event EventHandler<ProgressChangedEventArgs> ProgressChanged
+ {
+ add
+ {
+ if (_downloadProgressChanged == null)
+ {
+ RegisterProgressChangedEvent();
+ }
+ _downloadProgressChanged += value;
+ }
+ remove
+ {
+ _downloadProgressChanged -= value;
+ if (_downloadProgressChanged == null)
+ {
+ UnregisterProgressChangedEvent();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Absolute path where the file will be downloaded.
+ /// If you try to get this property value before calling Start(), an empty string is returned.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <remarks>
+ /// Returns empty string if download is not completed or if state has not yet changed to Completed or if any other error occurs.
+ /// </remarks>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ public string DownloadedPath
+ {
+ get
+ {
+ string path;
+ int ret = Interop.Download.GetDownloadedPath(_downloadId, out path);
+ if (ret != (int)DownloadError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get DownloadedPath, " + (DownloadError)ret);
+ return String.Empty;
+ }
+ return path;
+ }
+ }
+
+ /// <summary>
+ /// MIME type of the downloaded content.
+ /// If you try to get this property value before calling Start(), an empty string is returned.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ public string MimeType
+ {
+ get
+ {
+ string mime;
+ int ret = Interop.Download.GetMimeType(_downloadId, out mime);
+ if (ret != (int)DownloadError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get MimeType, " + (DownloadError)ret);
+ return String.Empty;
+ }
+ return mime;
+ }
+ }
+
+ /// <summary>
+ /// Current state of the download.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ public DownloadState State
+ {
+ get
+ {
+ int state;
+ int ret = Interop.Download.GetState(_downloadId, out state);
+ if (ret != (int)DownloadError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get DownloadState, " + (DownloadError)ret);
+ return DownloadState.None;
+ }
+ return (DownloadState)state;
+ }
+ }
+
+ /// <summary>
+ /// The content name of the downloaded file.
+ /// This can be defined with reference of HTTP response header data. The content name can be received when HTTP response header is received.
+ /// If you try to get this property value before calling Start(), an empty string is returned.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ public string ContentName
+ {
+ get
+ {
+ string name;
+ int ret = Interop.Download.GetContentName(_downloadId, out name);
+ if (ret != (int)DownloadError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get ContentName, " + (DownloadError)ret);
+ return String.Empty;
+ }
+ return name;
+ }
+ }
+
+ /// <summary>
+ /// Total size of downloaded content.
+ /// This information is received from the server. If the server does not send the total size of the content, the content size is set to zero.
+ /// If you try to get this property value before calling Start(), 0 is returned.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ public ulong ContentSize
+ {
+ get
+ {
+ ulong size;
+ int ret = Interop.Download.GetContentSize(_downloadId, out size);
+ if (ret != (int)DownloadError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get ContentSize, " + (DownloadError)ret);
+ return 0;
+ }
+ return size;
+ }
+ }
+
+ /// <summary>
+ /// HTTP status code when a download exception occurs.
+ /// If you try to get this property value before calling Start(), 0 is returned.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <remarks>
+ /// State of download request must be DownlodState.Failed.
+ /// </remarks>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ public int HttpStatus
+ {
+ get
+ {
+ int status;
+ int ret = Interop.Download.GetHttpStatus(_downloadId, out status);
+ if (ret != (int)DownloadError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get HttpStatus, " + (DownloadError)ret);
+ return 0;
+ }
+ return status;
+ }
+ }
+
+ /// <summary>
+ /// ETag value from the HTTP response header when making a HTTP request for resume.
+ /// If you try to get this property value before calling Start() or if any other error occurs, an empty string is returned.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <remarks>
+ /// The etag value is available or not depending on the web server. If not available, then on get of the property null is returned.
+ /// After download is started, it can get the etag value.
+ /// </remarks>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ public string ETagValue
+ {
+ get
+ {
+ string etag;
+ int ret = Interop.Download.GetETag(_downloadId, out etag);
+ if (ret != (int)DownloadError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get ETagValue, " + (DownloadError)ret);
+ return String.Empty;
+ }
+ return etag;
+ }
+ }
+
+ /// <summary>
+ /// Contains properties required for creating download notifications.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// When the notification message is clicked, the action taken by the system is decided by the app control properties of the NotificationProperties instance.
+ /// If the app control is not set, the following default operation is executed when the notification message is clicked:
+ /// 1) download completed state - the viewer application is executed according to extension name of downloaded content,
+ /// 2) download failed state and ongoing state - the client application is executed.
+ /// This property should be set before calling Start().
+ /// </remarks>
+ public Notification NotificationProperties
+ {
+ get
+ {
+ return _notificationProperties;
+ }
+ }
+
+ /// <summary>
+ /// Full path of the temporary file which stores downloaded content.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <remarks>
+ /// The download state must be one of the states after Downloading.
+ /// </remarks>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ public string TemporaryPath
+ {
+ get
+ {
+ string path;
+ int ret = Interop.Download.GetTempFilePath(_downloadId, out path);
+ if (ret != (int)DownloadError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get TemporaryPath, " + (DownloadError)ret);
+ return String.Empty;
+ }
+ return path;
+ }
+ }
+
+ /// <summary>
+ /// URL to download.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <remarks>
+ /// Should be set before calling Start().
+ /// If you try to get this property value before setting or if any other error occurs, an empty string is returned.
+ /// </remarks>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ public string Url
+ {
+ get
+ {
+ string url;
+ int ret = Interop.Download.GetUrl(_downloadId, out url);
+ if (ret != (int)DownloadError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get Url, " + (DownloadError)ret);
+ return String.Empty;
+ }
+ return url;
+ }
+ set
+ {
+ int ret = Interop.Download.SetUrl(_downloadId, value);
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Failed to set Url");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Allowed network type for downloading the file.
+ /// The file will be downloaded only under the allowed network.
+ /// If you try to get this property value before setting or if any other error occurs, default value NetworkType All is returned.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <feature>http://tizen.org/feature/network.wifi.direct</feature>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <remarks>
+ /// Should be set before calling Start().
+ /// </remarks>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="NotSupportedException">Thrown when feature is not supported.</exception>
+ public NetworkType AllowedNetworkType
+ {
+ get
+ {
+ int type;
+ int ret = Interop.Download.GetNetworkType(_downloadId, out type);
+ if (ret != (int)DownloadError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get AllowedNetworkType, " + (DownloadError)ret);
+ return NetworkType.All;
+ }
+ return (NetworkType)type;
+ }
+ set
+ {
+ int ret = Interop.Download.SetNetworkType(_downloadId, (int)value);
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Failed to set AllowedNetworkType");
+ }
+ }
+ }
+
+ /// <summary>
+ /// The file will be downloaded to the set destination file path. The downloaded file is saved to an auto-generated file name in the destination. If the destination is not specified, the file will be downloaded to default storage.
+ /// If you try to get this property value before setting or if any other error occurs, an empty string is returned.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <remarks>
+ /// Should be set before calling Start().
+ /// </remarks>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ public string DestinationPath
+ {
+ get
+ {
+ string path;
+ int ret = Interop.Download.GetDestination(_downloadId, out path);
+ if (ret != (int)DownloadError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get DestinationPath, " + (DownloadError)ret);
+ return String.Empty;
+ }
+ return path;
+ }
+ set
+ {
+ int ret = Interop.Download.SetDestination(_downloadId, value.ToString());
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Failed to set DestinationPath");
+ }
+ }
+ }
+
+ /// <summary>
+ /// The file will be saved in the specified destination or default storage with the set file name. If the file name is not specified, the downloaded file will be saved with an auto-generated file name in the destination.
+ /// If you try to get this property value before setting or if any other error occurs, an empty string is returned.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <remarks>
+ /// Should be set before calling Start().
+ /// </remarks>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ public string FileName
+ {
+ get
+ {
+ string name;
+ int ret = Interop.Download.GetFileName(_downloadId, out name);
+ if (ret != (int)DownloadError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get FileName, " + (DownloadError)ret);
+ return String.Empty;
+ }
+ return name;
+ }
+ set
+ {
+ int ret = Interop.Download.SetFileName(_downloadId, value.ToString());
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Failed to set FileName");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Enables or disables auto download.
+ /// If this option is enabled, the previous downloading item is restarted automatically as soon as the download daemon is restarted. The download progress continues after the client process is terminated.
+ /// If you try to get this property value before setting, default value false is returned.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <remarks>
+ /// The default value is false.
+ /// </remarks>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ public bool AutoDownload
+ {
+ get
+ {
+ bool value;
+ int ret = Interop.Download.GetAutoDownload(_downloadId, out value);
+ if (ret != (int)DownloadError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get AutoDownload, " + (DownloadError)ret);
+ return false;
+ }
+ return value;
+ }
+ set
+ {
+ int ret = Interop.Download.SetAutoDownload(_downloadId, value);
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Failed to set AutoDownload");
+ }
+ }
+ }
+
+ /// <summary>
+ /// HTTP header field and value pairs to the download request.
+ /// HTTP header &lt;field,value&gt; pair is the &lt;key,value&gt; pair in the Dictionary HttpHeaders
+ /// The given HTTP header field will be included with the HTTP request of the download request.
+ /// If you try to get this property value before setting, an empty dictionary is returned.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// HTTP header fields should be set before calling Start().
+ /// HTTP header fields can be removed before calling Start().
+ /// </remarks>
+ public IDictionary<string, string> HttpHeaders
+ {
+ get
+ {
+ return _httpHeaders;
+ }
+ }
+
+ /// <summary>
+ /// Sets the directory path of a temporary file used in a previous download request.
+ /// This is only useful when resuming download to make HTTP request header at the client side. Otherwise, the path is ignored.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <remarks>
+ /// If the etag value is not present in the download database, it is not useful to set the temporary file path.
+ /// When resuming the download request, the data is attached at the end of this temporary file.
+ /// </remarks>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ public void SetTemporaryFilePath(string path)
+ {
+ int ret = Interop.Download.SetTempFilePath(_downloadId, path);
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Failed to set TemporaryFilePath");
+ }
+ }
+
+ /// <summary>
+ /// Starts or resumes download.
+ /// Starts to download the current URL, or resumes the download if paused.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <remarks>
+ /// The URL is the mandatory information to start the download.
+ /// </remarks>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ public void Start()
+ {
+ int ret = (int)DownloadError.None;
+ foreach (KeyValuePair<string, string> entry in _httpHeaders)
+ {
+ ret = Interop.Download.AddHttpHeaderField(_downloadId, entry.Key, entry.Value);
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Failed to set HttpHeaders");
+ }
+ }
+
+ ret = Interop.Download.StartDownload(_downloadId);
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Failed to start download request");
+ }
+ }
+
+ /// <summary>
+ /// Pauses download request.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <remarks>
+ /// The paused download request can be restarted with Start() or canceled with Cancel().
+ /// </remarks>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ public void Pause()
+ {
+ int ret = Interop.Download.PauseDownload(_downloadId);
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Failed to pause download request");
+ }
+ }
+
+ /// <summary>
+ /// Cancels download request.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <remarks>
+ /// The canceled download can be restarted with Start().
+ /// </remarks>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ public void Cancel()
+ {
+ int ret = Interop.Download.CancelDownload(_downloadId);
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Failed to cancel download request");
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by the Request class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <remarks>
+ /// After calling this method, download request related data exists in the download database for a certain period of time. Within that time, it is possible to use other APIs with this data.
+ /// </remarks>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Deletes the corresponding download request.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/download</privilege>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects.
+ }
+ Interop.Download.DestroyRequest(_downloadId);
+ _disposed = true;
+ }
+
+ static private void IntPtrToStringArray(IntPtr unmanagedArray, int size, out string[] managedArray)
+ {
+ managedArray = new string[size];
+ IntPtr[] IntPtrArray = new IntPtr[size];
+
+ Marshal.Copy(unmanagedArray, IntPtrArray, 0, size);
+
+ for (int iterator = 0; iterator < size; iterator++)
+ {
+ managedArray[iterator] = Marshal.PtrToStringAnsi(IntPtrArray[iterator]);
+ }
+ }
+
+ private void RegisterStateChangedEvent()
+ {
+ _downloadStateChangedCallback = (int downloadId, int downloadState, IntPtr userData) =>
+ {
+ StateChangedEventArgs eventArgs = new StateChangedEventArgs((DownloadState)downloadState);
+ _downloadStateChanged?.Invoke(this, eventArgs);
+ };
+
+ int ret = Interop.Download.SetStateChangedCallback(_downloadId, _downloadStateChangedCallback, IntPtr.Zero);
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Setting StateChanged callback failed");
+ }
+ }
+
+ private void UnregisterStateChangedEvent()
+ {
+ int ret = Interop.Download.UnsetStateChangedCallback(_downloadId);
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Unsetting StateChanged callback failed");
+ }
+ }
+
+ private void RegisterProgressChangedEvent()
+ {
+ _downloadProgressChangedCallback = (int downloadId, ulong size, IntPtr userData) =>
+ {
+ ProgressChangedEventArgs eventArgs = new ProgressChangedEventArgs(size);
+ _downloadProgressChanged?.Invoke(this, eventArgs);
+ };
+
+ int ret = Interop.Download.SetProgressCallback(_downloadId, _downloadProgressChangedCallback, IntPtr.Zero);
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Setting ProgressChanged callback failed");
+ }
+ }
+
+ private void UnregisterProgressChangedEvent()
+ {
+ int ret = Interop.Download.UnsetProgressCallback(_downloadId);
+ if (ret != (int)DownloadError.None)
+ {
+ DownloadErrorFactory.ThrowException(ret, "Unsetting ProgressChanged callback failed");
+ }
+ }
+ }
+}
+
diff --git a/src/Tizen.Content.Download/Tizen.Content.Download/StateChangedEventArgs.cs b/src/Tizen.Content.Download/Tizen.Content.Download/StateChangedEventArgs.cs
new file mode 100755
index 0000000..e4c56e8
--- /dev/null
+++ b/src/Tizen.Content.Download/Tizen.Content.Download/StateChangedEventArgs.cs
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+
+namespace Tizen.Content.Download
+{
+ /// <summary>
+ /// An extended EventArgs class which contains the changed download state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class StateChangedEventArgs : EventArgs
+ {
+ private DownloadState _state;
+
+ internal StateChangedEventArgs(DownloadState downloadState)
+ {
+ _state = downloadState;
+ }
+
+ /// <summary>
+ /// Present download state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public DownloadState State
+ {
+ get
+ {
+ return _state;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Interop/Interop.AudioInformation.cs b/src/Tizen.Content.MediaContent/Interop/Interop.AudioInformation.cs
new file mode 100755
index 0000000..ccdf20c
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Interop/Interop.AudioInformation.cs
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Content.MediaContent;
+
+internal static partial class Interop
+{
+ internal static partial class AudioInformation
+ {
+ [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_destroy", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError Destroy(IntPtr media);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_clone", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError Clone(out SafeAudioInformationHandle dst, SafeAudioInformationHandle src);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_media_id", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetMediaId(SafeAudioInformationHandle audioInformationHandle, out IntPtr mediaId);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_album", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetAlbum(SafeAudioInformationHandle audioInformationHandle, out IntPtr albumName);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_artist", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetArtist(SafeAudioInformationHandle audioInformationHandle, out IntPtr artistName);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_album_artist", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetAlbumArtist(SafeAudioInformationHandle audioInformationHandle, out IntPtr albumArtistName);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_genre", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetGenre(SafeAudioInformationHandle audioInformationHandle, out IntPtr genreName);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_composer", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetComposer(SafeAudioInformationHandle audioInformationHandle, out IntPtr composerName);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_year", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetYear(SafeAudioInformationHandle audioInformationHandle, out IntPtr year);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_recorded_date", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetRecordedDate(SafeAudioInformationHandle audioInformationHandle, out IntPtr recordedDate);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_copyright", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetCopyright(SafeAudioInformationHandle audioInformationHandle, out IntPtr copyright);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_track_num", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetTrackNum(SafeAudioInformationHandle audioInformationHandle, out IntPtr trackNum);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_bit_rate", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetBitRate(SafeAudioInformationHandle audioInformationHandle, out int bitRate);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_bitpersample", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetBitPerSample(SafeAudioInformationHandle audioInformationHandle, out int bitPerSample);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_sample_rate", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetSampleRate(SafeAudioInformationHandle audioInformationHandle, out int sampleRate);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_channel", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetChannel(SafeAudioInformationHandle audioInformationHandle, out int channel);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_duration", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetDuration(SafeAudioInformationHandle audioInformationHandle, out int duration);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_played_count", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetPlayedCount(SafeAudioInformationHandle audioInformationHandle, out int playedCount);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_played_time", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetPlayedTime(SafeAudioInformationHandle audioInformationHandle, out int playedTime);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_played_position", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetPlayedPosition(SafeAudioInformationHandle audioInformationHandle, out int playedPosition);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_set_played_count", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError SetPlayedCount(SafeAudioInformationHandle audioInformationHandle, int playedCount);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_set_played_time", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError SetPlayedTime(SafeAudioInformationHandle audioInformationHandle, int playedTime);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_set_played_position", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError SetPlayedPosition(SafeAudioInformationHandle audioInformationHandle, int playedPosition);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_update_to_db", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError UpdateToDB(IntPtr audioInformationHandle);
+
+ internal sealed class SafeAudioInformationHandle : SafeHandle
+ {
+ public SafeAudioInformationHandle()
+ : base(IntPtr.Zero, true)
+ {
+ }
+
+ public override bool IsInvalid
+ {
+ get { return this.handle == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ AudioInformation.Destroy(this.handle);
+ this.SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Interop/Interop.Glib.cs b/src/Tizen.Content.MediaContent/Interop/Interop.Glib.cs
new file mode 100755
index 0000000..81afefd
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Interop/Interop.Glib.cs
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Glib
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool GSourceFunc(IntPtr userData);
+
+ [DllImport(Libraries.Glib, EntryPoint = "g_idle_add", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern uint IdleAdd(GSourceFunc d, IntPtr data);
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Interop/Interop.ImageInformation.cs b/src/Tizen.Content.MediaContent/Interop/Interop.ImageInformation.cs
new file mode 100755
index 0000000..cbcfffb
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Interop/Interop.ImageInformation.cs
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Content.MediaContent;
+
+internal static partial class Interop
+{
+ internal static partial class ImageInformation
+ {
+ [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_destroy", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError Destroy(IntPtr media);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_clone", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError Clone(out SafeImageInformationHandle dst, SafeImageInformationHandle src);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_orientation", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetOrientation(SafeImageInformationHandle imageInformationHandle, out MediaContentOrientation orientation);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_date_taken", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetDateTaken(SafeImageInformationHandle imageInformationHandle, out IntPtr dateTaken);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_burst_id", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetBurstId(SafeImageInformationHandle imageInformationHandle, out IntPtr burstId);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_exposure_time", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetExposureTime(SafeImageInformationHandle imageInformationHandle, out IntPtr exposureTime);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_fnumber", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetFNumber(SafeImageInformationHandle imageInformationHandle, out double fNumber);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_iso", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetISO(SafeImageInformationHandle imageInformationHandle, out int iso);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_model", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetModel(SafeImageInformationHandle imageInformationHandle, out IntPtr model);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_is_burst_shot", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError IsBurstShot(SafeImageInformationHandle imageInformationHandle, out bool isBurstShot);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_set_orientation", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError SetOrientation(SafeImageInformationHandle imageInformationHandle, MediaContentOrientation orientation);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_media_id", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetMediaId(SafeImageInformationHandle imageInformationHandle, out IntPtr mediaId);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_width", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetWidth(SafeImageInformationHandle imageInformationHandle, out int width);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_height", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetHeight(SafeImageInformationHandle imageInformationHandle, out int width);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_update_to_db", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError UpdateToDB(IntPtr imageInformationHandle);
+
+ internal sealed class SafeImageInformationHandle : SafeHandle
+ {
+ public SafeImageInformationHandle()
+ : base(IntPtr.Zero, true)
+ {
+ }
+
+ public override bool IsInvalid
+ {
+ get { return this.handle == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ ImageInformation.Destroy(this.handle);
+ this.SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Interop/Interop.Libc.cs b/src/Tizen.Content.MediaContent/Interop/Interop.Libc.cs
new file mode 100755
index 0000000..c9e7ff8
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Interop/Interop.Libc.cs
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Libc
+ {
+ [DllImport(Libraries.Libc, EntryPoint = "free", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int Free(IntPtr ptr);
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Interop/Interop.Libraries.cs b/src/Tizen.Content.MediaContent/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..a2d161e
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Interop/Interop.Libraries.cs
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string MediaContent = "libcapi-content-media-content.so.0";
+ public const string Glib = "libglib-2.0.so.0";
+ public const string Libc = "libc.so.6";
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Interop/Interop.MediaBookmark.cs b/src/Tizen.Content.MediaContent/Interop/Interop.MediaBookmark.cs
new file mode 100755
index 0000000..6639fbb
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Interop/Interop.MediaBookmark.cs
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Content.MediaContent;
+
+internal partial class Interop
+{
+ internal static partial class MediaBookmark
+ {
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_bookmark_insert_to_db")]
+ internal static extern MediaContentError InsertToDb(string media_id, uint time, string thumbnail_path);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_bookmark_delete_from_db")]
+ internal static extern MediaContentError DeleteFromDb(int bookmark_id);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_bookmark_get_bookmark_count_from_db")]
+ internal static extern MediaContentError GetBookmarkCountFromDb(IntPtr filter, out int bookmark_count);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_bookmark_clone")]
+ internal static extern MediaContentError Clone(out IntPtr dst, IntPtr src);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_bookmark_destroy")]
+ internal static extern MediaContentError Destroy(IntPtr bookmark);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_bookmark_get_bookmark_id")]
+ internal static extern MediaContentError GetBookmarkId(IntPtr bookmark, out int bookmark_id);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_bookmark_get_marked_time")]
+ internal static extern MediaContentError GetMarkedTime(IntPtr bookmark, out uint marked_time);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_bookmark_get_thumbnail_path")]
+ internal static extern MediaContentError GetThumbnailPath(IntPtr bookmark, out IntPtr filePath);
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Interop/Interop.MediaContent.cs b/src/Tizen.Content.MediaContent/Interop/Interop.MediaContent.cs
new file mode 100755
index 0000000..02205f1
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Interop/Interop.MediaContent.cs
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Content.MediaContent;
+
+
+internal static partial class Interop
+{
+ internal static partial class Content
+ {
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_content_connect")]
+ internal static extern MediaContentError Connect();
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_content_disconnect")]
+ internal static extern MediaContentError Disconnect();
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_content_scan_file")]
+ internal static extern MediaContentError ScanFile(string filePath);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_content_cancel_scan_folder")]
+ internal static extern MediaContentError CancelScanFolder(string folderPath);
+
+ // Callback
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MediaScanCompletedCallback(MediaContentError error, IntPtr data);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MediaContentDBUpdatedCallback(MediaContentError error, int pid, MediaContentUpdateItemType updateItem, MediaContentDBUpdateType updateType, MediaContentType mediaType, string uuid, string filePath, string mimeType, IntPtr data);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_content_scan_folder")]
+ internal static extern MediaContentError ScanFolder(string folderPath, bool is_recursive, MediaScanCompletedCallback scanCompletedCallback, IntPtr userData);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_content_add_db_updated_cb")]
+ internal static extern MediaContentError AddDbUpdatedCb(MediaContentDBUpdatedCallback mediaContentDBUpdatedCallback, IntPtr userData, out IntPtr noti_handle);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_content_remove_db_updated_cb")]
+ internal static extern MediaContentError RemoveDbUpdatedCb(IntPtr noti_handle);
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Interop/Interop.MediaFace.cs b/src/Tizen.Content.MediaContent/Interop/Interop.MediaFace.cs
new file mode 100755
index 0000000..ce88a2c
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Interop/Interop.MediaFace.cs
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Content.MediaContent;
+
+internal static partial class Interop
+{
+ internal static partial class Face
+ {
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_face_clone")]
+ internal static extern MediaContentError Clone(out IntPtr dst, IntPtr src);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_face_destroy")]
+ internal static extern MediaContentError Destroy(IntPtr face);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_face_get_face_id")]
+ internal static extern MediaContentError GetFaceId(IntPtr face, out IntPtr face_id);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_face_get_media_id")]
+ internal static extern MediaContentError GetMediaId(IntPtr face, out IntPtr media_id);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_face_get_face_rect")]
+ internal static extern MediaContentError GetFaceRect(IntPtr face, out int rect_x, out int rect_y, out int rect_w, out int IntPtr);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_face_get_orientation")]
+ internal static extern MediaContentError GetOrientation(IntPtr face, out int orientation);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_face_get_tag")]
+ internal static extern MediaContentError GetTag(IntPtr face, out IntPtr tag);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_face_create")]
+ internal static extern MediaContentError Create(string media_id, out IntPtr face);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_face_set_face_rect")]
+ internal static extern MediaContentError SetFaceRect(IntPtr face, int rect_x, int rect_y, int rect_w, int IntPtr);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_face_set_orientation")]
+ internal static extern MediaContentError SetOrientation(IntPtr face, int orientation);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_face_set_tag")]
+ internal static extern MediaContentError SetTag(IntPtr face, string tag);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_face_insert_to_db")]
+ internal static extern MediaContentError InsertToDb(IntPtr face);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_face_update_to_db")]
+ internal static extern MediaContentError UpdateToDb(IntPtr face);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_face_delete_from_db")]
+ internal static extern MediaContentError DeleteFromDb(string face_id);
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Interop/Interop.MediaFilter.cs b/src/Tizen.Content.MediaContent/Interop/Interop.MediaFilter.cs
new file mode 100755
index 0000000..f66986b
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Interop/Interop.MediaFilter.cs
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Content.MediaContent;
+
+internal static partial class Interop
+{
+ internal static partial class Filter
+ {
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_filter_create")]
+ internal static extern MediaContentError Create(out IntPtr filter);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_filter_destroy")]
+ internal static extern MediaContentError Destroy(IntPtr filter);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_filter_set_offset")]
+ internal static extern MediaContentError SetOffset(IntPtr filter, int offset, int count);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_filter_set_condition")]
+ internal static extern MediaContentError SetCondition(IntPtr filter, string condition, ContentCollation type);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_filter_set_order")]
+ internal static extern MediaContentError SetOrder(IntPtr filter, ContentOrder order, string keyword, ContentCollation type);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_filter_set_storage")]
+ internal static extern MediaContentError SetStorage(IntPtr filter, string storageId);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_filter_get_offset")]
+ internal static extern MediaContentError GetOffset(IntPtr filter, out int offset, out int count);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_filter_get_condition")]
+ internal static extern MediaContentError GetCondition(IntPtr filter, out IntPtr condition, out ContentCollation type);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_filter_get_order")]
+ internal static extern MediaContentError GetOrder(IntPtr filter, out ContentOrder order, out IntPtr keyword, out ContentCollation type);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_filter_get_storage")]
+ internal static extern MediaContentError GetStorage(IntPtr filter, out IntPtr storageId);
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Interop/Interop.MediaFolder.cs b/src/Tizen.Content.MediaContent/Interop/Interop.MediaFolder.cs
new file mode 100755
index 0000000..8ba231d
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Interop/Interop.MediaFolder.cs
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Content.MediaContent;
+
+internal static partial class Interop
+{
+ internal static partial class Folder
+ {
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_folder_get_folder_count_from_db")]
+ internal static extern MediaContentError GetFolderCountFromDb(IntPtr filter, out int folder_count);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_folder_get_media_count_from_db")]
+ internal static extern MediaContentError GetMediaCountFromDb(string folder_id, IntPtr filter, out int media_count);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_folder_clone")]
+ internal static extern MediaContentError Clone(out IntPtr dst, IntPtr src);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_folder_destroy")]
+ internal static extern MediaContentError Destroy(IntPtr folder);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_folder_get_folder_id")]
+ internal static extern MediaContentError GetFolderId(IntPtr folder, out IntPtr folder_id);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_folder_get_parent_folder_id")]
+ internal static extern MediaContentError GetParentFolderId(IntPtr folder, out IntPtr parent_folder_id);
+
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_folder_get_path")]
+ internal static extern MediaContentError GetPath(IntPtr folder, out IntPtr folderPath);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_folder_get_name")]
+ internal static extern MediaContentError GetName(IntPtr folder, out IntPtr folder_name);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_folder_get_modified_time")]
+ internal static extern MediaContentError GetModifiedTime(IntPtr folder, out DateTime date);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_folder_get_storage_type")]
+ internal static extern MediaContentError GetStorageType(IntPtr folder, out ContentStorageType storage_type);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_folder_get_storage_id")]
+ internal static extern MediaContentError GetStorageId(IntPtr folder, out IntPtr storage_id);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_folder_get_order")]
+ internal static extern MediaContentError GetOrder(IntPtr folder, out int order);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_folder_get_folder_from_db")]
+ internal static extern MediaContentError GetFolderFromDb(string folder_id, out IntPtr folder);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_folder_set_name")]
+ internal static extern MediaContentError SetName(IntPtr folder, string name);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_folder_set_order")]
+ internal static extern MediaContentError SetOrder(IntPtr folder, int order);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_folder_update_to_db")]
+ internal static extern MediaContentError UpdateToDb(IntPtr folder);
+
+ //Callbacks
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool MediaFolderCallback(IntPtr folderHandle, IntPtr data);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool MediaInfoCallback(IntPtr handle, IntPtr data);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_folder_foreach_folder_from_db")]
+ internal static extern MediaContentError ForeachFolderFromDb(IntPtr filter, MediaFolderCallback callback, IntPtr user_data);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_folder_foreach_media_from_db")]
+ internal static extern MediaContentError ForeachMediaFromDb(string folder_id, IntPtr filter, MediaInfoCallback callback, IntPtr user_data);
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Interop/Interop.MediaGroup.cs b/src/Tizen.Content.MediaContent/Interop/Interop.MediaGroup.cs
new file mode 100755
index 0000000..c879bcc
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Interop/Interop.MediaGroup.cs
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Content.MediaContent;
+
+internal static partial class Interop
+{
+ internal static partial class Group
+ {
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_album_get_album_count_from_db")]
+ internal static extern MediaContentError MediaAlbumGetAlbumCountFromDb(IntPtr filter, out int album_count);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_album_get_media_count_from_db")]
+ internal static extern MediaContentError MediaAlbumGetMediaCountFromDb(int album_id, IntPtr filter, out int media_count);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_album_destroy")]
+ internal static extern MediaContentError MediaAlbumDestroy(IntPtr album);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_album_clone")]
+ internal static extern MediaContentError MediaAlbumClone(out IntPtr dst, IntPtr src);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_album_get_album_id")]
+ internal static extern MediaContentError MediaAlbumGetAlbumId(IntPtr album, out int album_id);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_album_get_name")]
+ internal static extern MediaContentError MediaAlbumGetName(IntPtr album, out IntPtr album_name);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_album_get_artist")]
+ internal static extern MediaContentError MediaAlbumGetArtist(IntPtr album, out IntPtr artist);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_album_get_album_art")]
+ internal static extern MediaContentError MediaAlbumGetAlbumArt(IntPtr album, out IntPtr album_art);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_album_get_album_from_db")]
+ internal static extern MediaContentError MediaAlbumGetAlbumFromDb(int album_id, out IntPtr album);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_group_get_group_count_from_db")]
+ internal static extern MediaContentError GetGroupCountFromDb(IntPtr filter, MediaGroupType group, out int group_count);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_group_get_media_count_from_db")]
+ internal static extern MediaContentError GetMediaCountFromDb(string group_name, MediaGroupType group, IntPtr filter, out int media_count);
+
+ //Callbacks
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool MediaInfoCallback(IntPtr mediaInformation, IntPtr data);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool MediaGroupCallback(string groupName, IntPtr data);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool MediaAlbumCallback(IntPtr albumHandle, IntPtr data);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_album_foreach_album_from_db")]
+ internal static extern MediaContentError MediaAlbumForeachAlbumFromDb(IntPtr filter, MediaAlbumCallback callback, IntPtr user_data);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_album_foreach_media_from_db")]
+ internal static extern MediaContentError MediaAlbumForeachMediaFromDb(int albumId, IntPtr filter, MediaInfoCallback callback, IntPtr user_data);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_group_foreach_group_from_db")]
+ internal static extern MediaContentError ForeachGroupFromDb(IntPtr filter, MediaGroupType group, MediaGroupCallback callback, IntPtr user_data);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_group_foreach_media_from_db")]
+ internal static extern MediaContentError ForeachMediaFromDb(string groupName, MediaGroupType group, IntPtr filter, MediaInfoCallback callback, IntPtr user_data);
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Interop/Interop.MediaInformation.cs b/src/Tizen.Content.MediaContent/Interop/Interop.MediaInformation.cs
new file mode 100755
index 0000000..5d994fc
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Interop/Interop.MediaInformation.cs
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Content.MediaContent;
+
+internal static partial class Interop
+{
+ internal static partial class MediaInformation
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MediaThumbnailCompletedCallback(MediaContentError error, string filePath, IntPtr UserData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool MediaTagCallback(IntPtr tagHandle, IntPtr UserData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool MediaBookmarkCallback(IntPtr bookmarkHandle, IntPtr UserData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool MediaFaceCallback(IntPtr bookmarkHandle, IntPtr UserData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MediaInsertCompletedCallback(MediaContentError error, IntPtr UserData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MediaInsertBurstShotCompletedCallback(MediaContentError error, IntPtr UserData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool MediaInformationCallback(IntPtr mediaInformationHandle, IntPtr UserData);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_insert_to_db", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError Insert(string filePath, out SafeMediaInformationHandle info);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_insert_batch_to_db", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError BatchInsert(string[] filePathArray, int arrayLength, MediaInsertCompletedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_insert_burst_shot_to_db", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError BurstShotInsert(string[] filePathArray, int arrayLength, MediaInsertBurstShotCompletedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_delete_from_db", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError Delete(string mediaId);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_delete_batch_from_db", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError BatchDelete(IntPtr filter);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_destroy", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError Destroy(IntPtr mediaInformationHandle);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_clone", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError Clone(out SafeMediaInformationHandle dst, IntPtr src);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_media_count_from_db", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetMediaCount(IntPtr filter, out int mediaCount);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_foreach_media_from_db", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetAllMedia(IntPtr filter, MediaInformationCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_tag_count_from_db", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetTagCount(string mediaId, IntPtr filter, out int tagCount);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_foreach_tag_from_db", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetAllTags(string mediaId, IntPtr filter, MediaTagCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_bookmark_count_from_db", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetBookmarkCount(string mediaId, IntPtr filter, out int bookmarkCount);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_foreach_bookmark_from_db", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetAllBookmarks(string mediaId, IntPtr filter, MediaBookmarkCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_face_count_from_db", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetFaceCount(string mediaId, IntPtr filter, out int bookmarkCount);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_foreach_face_from_db", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetAllFaces(string mediaId, IntPtr filter, MediaFaceCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_image", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetImage(IntPtr mediaInformationHandle, out Interop.ImageInformation.SafeImageInformationHandle image);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_video", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetVideo(IntPtr mediaInformationHandle, out Interop.VideoInformation.SafeVideoInformationHandle video);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_audio", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetAudio(IntPtr mediaInformationHandle, out Interop.AudioInformation.SafeAudioInformationHandle audio);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_media_id", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetMediaId(SafeMediaInformationHandle mediaInformationHandle, out IntPtr mediaId);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_file_path", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetFilePath(SafeMediaInformationHandle mediaInformationHandle, out IntPtr filePath);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_display_name", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetDisplayName(SafeMediaInformationHandle mediaInformationHandle, out IntPtr name);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_media_type", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetMediaType(SafeMediaInformationHandle mediaInformationHandle, out MediaContentType type);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_mime_type", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetMimeType(SafeMediaInformationHandle mediaInformationHandle, out IntPtr mimeType);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_size", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetSize(SafeMediaInformationHandle mediaInformationHandle, out long size);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_added_time", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetAddedTime(SafeMediaInformationHandle mediaInformationHandle, out int addedTime);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_modified_time", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetModifiedTime(SafeMediaInformationHandle mediaInformationHandle, out int time);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_timeline", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetTimeline(SafeMediaInformationHandle mediaInformationHandle, out int time);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_thumbnail_path", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetThumbnailPath(SafeMediaInformationHandle mediaInformationHandle, out IntPtr filePath);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_description", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetDescription(SafeMediaInformationHandle mediaInformationHandle, out IntPtr description);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_longitude", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetLongitude(SafeMediaInformationHandle mediaInformationHandle, out double longitude);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_latitude", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetLatitude(SafeMediaInformationHandle mediaInformationHandle, out double latitude);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_altitude", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetAltitude(SafeMediaInformationHandle mediaInformationHandle, out double altitude);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_weather", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetWeather(SafeMediaInformationHandle mediaInformationHandle, out IntPtr weather);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_rating", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetRating(SafeMediaInformationHandle mediaInformationHandle, out int rating);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_favorite", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetFavorite(SafeMediaInformationHandle mediaInformationHandle, out bool favorite);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_author", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetAuthor(SafeMediaInformationHandle mediaInformationHandle, out IntPtr author);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_provider", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetProvider(SafeMediaInformationHandle mediaInformationHandle, out IntPtr provider);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_content_name", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetContentName(SafeMediaInformationHandle mediaInformationHandle, out IntPtr contentName);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_title", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetTitle(SafeMediaInformationHandle mediaInformationHandle, out IntPtr title);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_category", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetCategory(SafeMediaInformationHandle mediaInformationHandle, out IntPtr category);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_location_tag", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetLocationTag(SafeMediaInformationHandle mediaInformationHandle, out IntPtr locationTag);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_age_rating", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetAgeRating(SafeMediaInformationHandle mediaInformationHandle, out IntPtr ageRating);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_keyword", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetKeyword(SafeMediaInformationHandle mediaInformationHandle, out IntPtr keyword);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_storage_id", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetStorageId(SafeMediaInformationHandle mediaInformationHandle, out IntPtr storageId);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_is_drm", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError IsDrm(SafeMediaInformationHandle mediaInformationHandle, out bool isDrm);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_storage_type", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetStorageType(SafeMediaInformationHandle mediaInformationHandle, out ContentStorageType storageType);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_played_count", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetPlayedCount(SafeMediaInformationHandle mediaInformationHandle, out int playedCount);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_played_time", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetPlayedAt(SafeMediaInformationHandle mediaInformationHandle, out int playedTime);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_media_from_db", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetMediaFromDB(string mediaId, out SafeMediaInformationHandle mediaInformationHandle);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_increase_played_count", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError IncreasePlayedCount(SafeMediaInformationHandle mediaInformationHandle);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_played_time", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError SetPlayedAt(SafeMediaInformationHandle mediaInformationHandle);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_display_name", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError SetDisplayName(SafeMediaInformationHandle mediaInformationHandle, string displayName);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_description", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError SetDescription(SafeMediaInformationHandle mediaInformationHandle, string description);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_longitude", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError SetLongitude(SafeMediaInformationHandle mediaInformationHandle, double longitude);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_latitude", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError SetLatitude(SafeMediaInformationHandle mediaInformationHandle, double latitude);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_altitude", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError SetAltitude(SafeMediaInformationHandle mediaInformationHandle, double altitude);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_weather", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError SetWeather(SafeMediaInformationHandle mediaInformationHandle, string weather);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_rating", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError SetRating(SafeMediaInformationHandle mediaInformationHandle, int rating);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_favorite", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError SetFavorite(SafeMediaInformationHandle mediaInformationHandle, bool favorite);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_author", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError SetAuthor(SafeMediaInformationHandle mediaInformationHandle, string author);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_provider", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError SetProvider(SafeMediaInformationHandle mediaInformationHandle, string provider);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_content_name", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError SetContentName(SafeMediaInformationHandle mediaInformationHandle, string contentName);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_category", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError SetCategory(SafeMediaInformationHandle mediaInformationHandle, string category);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_location_tag", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError SetLocationTag(SafeMediaInformationHandle mediaInformationHandle, string locationTag);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_age_rating", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError SetAgeRating(SafeMediaInformationHandle mediaInformationHandle, string ageRating);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_keyword", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError SetKeyword(SafeMediaInformationHandle mediaInformationHandle, string keyword);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_update_to_db", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError UpdateToDB(IntPtr mediaInformationHandle);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_refresh_metadata_to_db", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError RefreshMetadataToDB(string mediaId);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_added_time", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError SetAddedTime(SafeMediaInformationHandle mediaInformationHandle, int addedTime);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_move_to_db", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError MoveToDB(SafeMediaInformationHandle mediaInformationHandle, string dstPath);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_create_thumbnail", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError CreateThumbnail(SafeMediaInformationHandle mediaInformationHandle, MediaThumbnailCompletedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_info_cancel_thumbnail", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError CancelThumbnail(SafeMediaInformationHandle mediaInformationHandle);
+
+ internal sealed class SafeMediaInformationHandle : SafeHandle
+ {
+ public SafeMediaInformationHandle(IntPtr handle)
+ : base(handle, true)
+ {
+ }
+ public SafeMediaInformationHandle()
+ : base(IntPtr.Zero, true)
+ {
+ }
+
+ public override bool IsInvalid
+ {
+ get { return this.handle == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ MediaInformation.Destroy(this.handle);
+ this.SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Interop/Interop.MediaPlaylist.cs b/src/Tizen.Content.MediaContent/Interop/Interop.MediaPlaylist.cs
new file mode 100755
index 0000000..25a9ccf
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Interop/Interop.MediaPlaylist.cs
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Content.MediaContent;
+
+internal static partial class Interop
+{
+ internal static partial class Playlist
+ {
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_get_playlist_count_from_db")]
+ internal static extern MediaContentError GetPlaylistCountFromDb(IntPtr filter, out int playlist_count);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_get_media_count_from_db")]
+ internal static extern MediaContentError GetMediaCountFromDb(int playlist_id, IntPtr filter, out int media_count);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_insert_to_db")]
+ internal static extern MediaContentError InsertToDb(string name, out IntPtr playlist);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_delete_from_db")]
+ internal static extern MediaContentError DeleteFromDb(int playlist_id);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_get_playlist_from_db")]
+ internal static extern MediaContentError GetPlaylistFromDb(int playlist_id, out IntPtr playlist);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_destroy")]
+ internal static extern MediaContentError Destroy(IntPtr playlist);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_clone")]
+ internal static extern MediaContentError Clone(out IntPtr dst, IntPtr src);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_get_playlist_id")]
+ internal static extern MediaContentError GetPlaylistId(IntPtr playlist, out int playlist_id);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_get_name")]
+ internal static extern MediaContentError GetName(IntPtr playlist, out IntPtr playlist_name);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_set_name")]
+ internal static extern MediaContentError SetName(IntPtr playlist, string playlist_name);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_get_thumbnail_path")]
+ internal static extern MediaContentError GetThumbnailPath(IntPtr playlist, out IntPtr filePath);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_set_thumbnail_path")]
+ internal static extern MediaContentError SetThumbnailPath(IntPtr playlist, string filePath);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_set_play_order")]
+ internal static extern MediaContentError SetPlayOrder(IntPtr playlist, int playlist_member_id, int play_order);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_add_media")]
+ internal static extern MediaContentError AddMedia(IntPtr playlist, string media_id);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_remove_media")]
+ internal static extern MediaContentError RemoveMedia(IntPtr playlist, int playlist_member_id);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_get_play_order")]
+ internal static extern MediaContentError GetPlayOrder(IntPtr playlist, int playlist_member_id, out int play_order);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_update_to_db")]
+ internal static extern MediaContentError UpdateToDb(IntPtr playlist);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_import_from_file")]
+ internal static extern MediaContentError ImportFromFile(string playlist_name, string filePath, out IntPtr playlist);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_export_to_file")]
+ internal static extern MediaContentError ExportToFile(IntPtr playlist, string filePath);
+
+ //Callbacks
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool MediaPlaylistCallback(IntPtr playListHandle, IntPtr data);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool PlaylistMemberCallback(int playListMemberId, IntPtr mediaInformation, IntPtr data);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_foreach_playlist_from_db")]
+ internal static extern MediaContentError ForeachPlaylistFromDb(IntPtr filter, MediaPlaylistCallback callback, IntPtr user_data);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_foreach_media_from_db")]
+ internal static extern MediaContentError ForeachMediaFromDb(int playlist_id, IntPtr filter, PlaylistMemberCallback callback, IntPtr user_data);
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Interop/Interop.MediaStorage.cs b/src/Tizen.Content.MediaContent/Interop/Interop.MediaStorage.cs
new file mode 100755
index 0000000..b17768e
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Interop/Interop.MediaStorage.cs
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Content.MediaContent;
+
+internal static partial class Interop
+{
+ internal static partial class Storage
+ {
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_storage_get_storage_info_from_db")]
+ internal static extern MediaContentError GetStorageInfoFromDb(string storage_id, out IntPtr storage);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_storage_get_storage_count_from_db")]
+ internal static extern MediaContentError GetStorageCountFromDb(IntPtr filter, out int storage_count);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_storage_get_media_count_from_db")]
+ internal static extern MediaContentError GetMediaCountFromDb(string storage_id, IntPtr filter, out int media_count);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_storage_destroy")]
+ internal static extern MediaContentError Destroy(IntPtr storage);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_storage_clone")]
+ internal static extern MediaContentError Clone(out IntPtr dst, IntPtr src);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_storage_get_id")]
+ internal static extern MediaContentError GetId(IntPtr storage, out IntPtr storage_id);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_storage_get_name")]
+ internal static extern MediaContentError GetName(IntPtr storage, out IntPtr storage_name);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_storage_get_path")]
+ internal static extern MediaContentError GetPath(IntPtr storage, out IntPtr storage_path);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_storage_get_type")]
+ internal static extern MediaContentError GetType(IntPtr storage, out ContentStorageType storage_type);
+
+ //Callbacks
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool MediaStorageCallback(IntPtr mediaStorageHandle, IntPtr data);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool MediaInfoCallback(IntPtr mediaInformation, IntPtr data);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_storage_foreach_storage_from_db")]
+ internal static extern MediaContentError ForeachStorageFromDb(IntPtr filter, MediaStorageCallback callback, IntPtr user_data);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_storage_foreach_media_from_db")]
+ internal static extern MediaContentError ForeachMediaFromDb(string storage_id, IntPtr filter, MediaInfoCallback callback, IntPtr user_data);
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Interop/Interop.MediaTag.cs b/src/Tizen.Content.MediaContent/Interop/Interop.MediaTag.cs
new file mode 100755
index 0000000..9895b62
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Interop/Interop.MediaTag.cs
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Content.MediaContent;
+
+internal static partial class Interop
+{
+ internal static partial class Tag
+ {
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_insert_to_db")]
+ internal static extern MediaContentError InsertToDb(string tag_name, out IntPtr tag);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_delete_from_db")]
+ internal static extern MediaContentError DeleteFromDb(int tag_id);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_get_tag_count_from_db")]
+ internal static extern MediaContentError GetTagCountFromDb(IntPtr filter, out int tag_count);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_get_media_count_from_db")]
+ internal static extern MediaContentError GetMediaCountFromDb(int tag_id, IntPtr filter, out int media_count);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_clone")]
+ internal static extern MediaContentError Clone(out IntPtr dst, IntPtr src);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_destroy")]
+ internal static extern MediaContentError Destroy(IntPtr tag);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_get_tag_id")]
+ internal static extern MediaContentError GetTagId(IntPtr tag, out int tag_id);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_get_name")]
+ internal static extern MediaContentError GetName(IntPtr tag, out IntPtr tag_name);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_get_tag_from_db")]
+ internal static extern MediaContentError GetTagFromDb(int tag_id, out IntPtr tag);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_add_media")]
+ internal static extern MediaContentError AddMedia(IntPtr tag, string media_id);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_remove_media")]
+ internal static extern MediaContentError RemoveMedia(IntPtr tag, string media_id);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_set_name")]
+ internal static extern MediaContentError SetName(IntPtr tag, string tag_name);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_update_to_db")]
+ internal static extern MediaContentError UpdateToDb(IntPtr tag);
+
+ //Callbacks
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool MediaInfoCallback(IntPtr mediaInformation, IntPtr data);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool MediaTagCallback(IntPtr tag, IntPtr data);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_foreach_tag_from_db")]
+ internal static extern MediaContentError ForeachTagFromDb(IntPtr filter, MediaTagCallback callback, IntPtr user_data);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_foreach_media_from_db")]
+ internal static extern MediaContentError ForeachMediaFromDb(int tag_id, IntPtr filter, MediaInfoCallback callback, IntPtr user_data);
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Interop/Interop.VideoInformation.cs b/src/Tizen.Content.MediaContent/Interop/Interop.VideoInformation.cs
new file mode 100755
index 0000000..8138990
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Interop/Interop.VideoInformation.cs
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Content.MediaContent;
+
+internal static partial class Interop
+{
+ internal static partial class VideoInformation
+ {
+ [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_destroy", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError Destroy(IntPtr media);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_clone", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError Clone(out SafeVideoInformationHandle dst, SafeVideoInformationHandle src);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_media_id", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetMediaId(SafeVideoInformationHandle videoInformationHandle, out IntPtr mediaId);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_album", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetAlbum(SafeVideoInformationHandle videoInformationHandle, out IntPtr albumName);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_artist", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetArtist(SafeVideoInformationHandle videoInformationHandle, out IntPtr artistName);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_album_artist", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetAlbumArtist(SafeVideoInformationHandle videoInformationHandle, out IntPtr albumArtistName);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_genre", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetGenre(SafeVideoInformationHandle videoInformationHandle, out IntPtr genreName);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_composer", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetComposer(SafeVideoInformationHandle videoInformationHandle, out IntPtr composerName);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_year", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetYear(SafeVideoInformationHandle videoInformationHandle, out IntPtr year);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_recorded_date", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetRecordedDate(SafeVideoInformationHandle videoInformationHandle, out IntPtr recordedDate);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_copyright", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetCopyright(SafeVideoInformationHandle videoInformationHandle, out IntPtr copyright);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_track_num", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetTrackNum(SafeVideoInformationHandle videoInformationHandle, out IntPtr trackNum);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_bit_rate", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetBitRate(SafeVideoInformationHandle videoInformationHandle, out int bitRate);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_duration", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetDuration(SafeVideoInformationHandle videoInformationHandle, out int duration);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_width", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetWidth(SafeVideoInformationHandle videoInformationHandle, out int width);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_height", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetHeight(SafeVideoInformationHandle videoInformationHandle, out int width);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_played_count", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetPlayedCount(SafeVideoInformationHandle videoInformationHandle, out int playedCount);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_played_time", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetPlayedTime(SafeVideoInformationHandle videoInformationHandle, out int playedTime);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_played_position", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError GetPlayedPosition(SafeVideoInformationHandle videoInformationHandle, out int playedPosition);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_set_played_count", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError SetPlayedCount(SafeVideoInformationHandle videoInformationHandle, int playedCount);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_set_played_time", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError SetPlayedTime(SafeVideoInformationHandle videoInformationHandle, int playedTime);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_set_played_position", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError SetPlayedPosition(SafeVideoInformationHandle videoInformationHandle, int playedPosition);
+
+ [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_update_to_db", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern MediaContentError UpdateToDB(IntPtr videoInformationHandle);
+
+ internal sealed class SafeVideoInformationHandle : SafeHandle
+ {
+ public SafeVideoInformationHandle()
+ : base(IntPtr.Zero, true)
+ {
+ }
+
+ public override bool IsInvalid
+ {
+ get { return this.handle == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ VideoInformation.Destroy(this.handle);
+ this.SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent.csproj b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent.csproj
new file mode 100644
index 0000000..5ed2f1f
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent.csproj
@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Album.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Album.cs
new file mode 100755
index 0000000..3763483
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Album.cs
@@ -0,0 +1,224 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+
+namespace Tizen.Content.MediaContent
+{
+ /// <summary>
+ /// An album is a logical collection or grouping of related audio files. It is also used for filtering media items.
+ /// The Media Album API allows to manage media albums which contains all video and audio items from the same album.
+ /// </summary>
+ public class Album : ContentCollection
+ {
+ private IntPtr _albumHandle = IntPtr.Zero;
+
+ private IntPtr Handle
+ {
+ get
+ {
+ if (_albumHandle == IntPtr.Zero)
+ {
+ throw new ObjectDisposedException(nameof(Album));
+ }
+
+ return _albumHandle;
+ }
+ }
+
+ /// <summary>
+ /// The media album ID
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Id
+ {
+ get
+ {
+ int id = 0;
+ MediaContentValidator.ThrowIfError(
+ Interop.Group.MediaAlbumGetAlbumId(Handle, out id), "Failed to get value");
+
+ return id;
+ }
+ }
+
+ /// <summary>
+ /// The name of the media artist
+ /// If the media content has no album info, the property returns empty string.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Artist
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Group.MediaAlbumGetArtist(Handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The path of the media album art
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Art
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Group.MediaAlbumGetAlbumArt(Handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The name of the media album
+ /// If the media content has no album info, the property returns empty string.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Name
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Group.MediaAlbumGetName(Handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ internal Album(IntPtr handle)
+ {
+ _albumHandle = handle;
+ }
+
+ /// <summary>
+ /// Gets the number of MediaInformation Items for the given album present in the media database.
+ /// If NULL is passed to the filter, no filtering is applied.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="filter">ContentFilter used to match media content from the media database.</param>
+ /// <returns>The number of media contents matching the filter passed</returns>
+ public override int GetMediaInformationCount(ContentFilter filter)
+ {
+ int mediaCount = 0;
+ IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
+
+ MediaContentValidator.ThrowIfError(
+ Interop.Group.MediaAlbumGetMediaCountFromDb(Id, handle, out mediaCount), "Failed to get count");
+
+ return mediaCount;
+ }
+
+ public override void Dispose()
+ {
+ if (_albumHandle != IntPtr.Zero)
+ {
+ Interop.Group.MediaAlbumDestroy(_albumHandle);
+ _albumHandle = IntPtr.Zero;
+ }
+ }
+
+ /// <summary>
+ /// Iterates through the media files with a filter in the given media album from the media database.
+ /// This function gets all media files associated with the given media album and meeting desired filter option.
+ /// If NULL is passed to the filter, no filtering is applied.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="filter">ContentFilter used to match media content from the media database.</param>
+ /// <returns>List of content media items matching the passed filter</returns>
+ public override IEnumerable<MediaInformation> GetMediaInformations(ContentFilter filter)
+ {
+ List<MediaInformation> mediaContents = new List<MediaInformation>();
+
+ IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
+ Interop.Group.MediaInfoCallback callback = (IntPtr mediaHandle, IntPtr data) =>
+ {
+ Interop.MediaInformation.SafeMediaInformationHandle newHandle;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.Clone(out newHandle, mediaHandle), "Failed to clone");
+
+ MediaContentType type;
+ Interop.MediaInformation.GetMediaType(newHandle, out type);
+ if (type == MediaContentType.Image)
+ {
+ Interop.ImageInformation.SafeImageInformationHandle imageInfo;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetImage(mediaHandle, out imageInfo), "Failed to get image information");
+
+ mediaContents.Add(new ImageInformation(imageInfo, newHandle));
+ }
+ else if ((type == MediaContentType.Music) || (type == MediaContentType.Sound))
+ {
+ Interop.AudioInformation.SafeAudioInformationHandle audioInfo;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetAudio(mediaHandle, out audioInfo), "Failed to get audio information");
+
+ mediaContents.Add(new AudioInformation(audioInfo, newHandle));
+ }
+ else if (type == MediaContentType.Video)
+ {
+ Interop.VideoInformation.SafeVideoInformationHandle videoInfo;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetVideo(mediaHandle, out videoInfo), "Failed to get video information");
+
+ mediaContents.Add(new VideoInformation(videoInfo, newHandle));
+ }
+ else if (type == MediaContentType.Others)
+ {
+ mediaContents.Add(new MediaInformation(newHandle));
+ }
+
+ return true;
+ };
+ MediaContentValidator.ThrowIfError(
+ Interop.Group.MediaAlbumForeachMediaFromDb(Id, handle, callback, IntPtr.Zero), "Failed to get information");
+
+ return mediaContents;
+ }
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/AudioInformation.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/AudioInformation.cs
new file mode 100755
index 0000000..e5fc8d8
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/AudioInformation.cs
@@ -0,0 +1,455 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+using System.Collections.ObjectModel;
+
+namespace Tizen.Content.MediaContent
+{
+ /// <summary>
+ /// AudioContent class API gives the information related to the audio media stored in the device
+ /// Its purpose is threefold:
+ /// - to provide information about audio content
+ /// - to organize audio content logically(grouping)
+ /// </summary>
+ public class AudioInformation : MediaInformation
+ {
+ private readonly Interop.AudioInformation.SafeAudioInformationHandle _handle;
+
+ /// <summary>
+ /// Gets the ID of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string MediaId
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.AudioInformation.GetMediaId(_handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the album name.
+ /// If the media content has no album info, the property returns empty string.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Album
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.AudioInformation.GetAlbum(_handle, out val), "Failed to get value");
+
+ return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the artist name.
+ /// If the media content has no album info, the property returns empty string.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Artist
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.AudioInformation.GetArtist(_handle, out val), "Failed to get value");
+
+ return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the album artist name.
+ /// If the media content has no album info, the property returns empty string.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string AlbumArtist
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.AudioInformation.GetAlbumArtist(_handle, out val), "Failed to get value");
+
+ return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the genre.
+ /// If the media content has no album info, the property returns empty string.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Genre
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.AudioInformation.GetGenre(_handle, out val), "Failed to get value");
+
+ return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the composer name.
+ /// If the value is an empty string, the property returns "Unknown".
+ /// If the media content has no album info, the property returns empty string.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Composer
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.AudioInformation.GetComposer(_handle, out val), "Failed to get value");
+
+ return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the year.
+ /// If the media content has no album info, the property returns empty string.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Year
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.AudioInformation.GetYear(_handle, out val), "Failed to get value");
+
+ return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the recorded date.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string RecordedDate
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.AudioInformation.GetRecordedDate(_handle, out val), "Failed to get value");
+
+ return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the copyright.
+ /// If the media content has no copyright information, the property returns empty string.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Copyright
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.AudioInformation.GetCopyright(_handle, out val), "Failed to get value");
+
+ return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the track number.
+ /// If the media content has no track information, the property returns empty string.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string TrackNumber
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.AudioInformation.GetTrackNum(_handle, out val), "Failed to get value");
+
+ return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the bitrate in bit per second [bps].
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int BitRate
+ {
+ get
+ {
+ int bitrate = 0;
+ MediaContentValidator.ThrowIfError(
+ Interop.AudioInformation.GetBitRate(_handle, out bitrate), "Failed to get value");
+
+ return bitrate;
+ }
+ }
+
+ /// <summary>
+ /// Gets bit per sample.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int BitPerSample
+ {
+ get
+ {
+ int bitPerSample = 0;
+ MediaContentValidator.ThrowIfError(
+ Interop.AudioInformation.GetBitPerSample(_handle, out bitPerSample), "Failed to get value");
+
+ return bitPerSample;
+ }
+ }
+
+ /// <summary>
+ /// Gets the sample rate in hz.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int SampleRate
+ {
+ get
+ {
+ int sampleRate = 0;
+ MediaContentValidator.ThrowIfError(
+ Interop.AudioInformation.GetSampleRate(_handle, out sampleRate), "Failed to get value");
+
+ return sampleRate;
+ }
+ }
+
+ /// <summary>
+ /// Gets the channel.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Channel
+ {
+ get
+ {
+ int channel = 0;
+ MediaContentValidator.ThrowIfError(
+ Interop.AudioInformation.GetChannel(_handle, out channel), "Failed to get value");
+
+ return channel;
+ }
+ }
+
+ /// <summary>
+ /// Gets the track duration in Milliseconds.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Duration
+ {
+ get
+ {
+ int duration = 0;
+ MediaContentValidator.ThrowIfError(
+ Interop.AudioInformation.GetDuration(_handle, out duration), "Failed to get value");
+
+ return duration;
+ }
+ }
+
+ /// <summary>
+ /// Gets the number of MediaBookmark for the passed filter in the given media ID from the media database.
+ /// If NULL is passed to the filter, no filtering is applied.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// int count</returns>
+ /// <param name="filter">The Filter for matching Bookmarks</param>
+ public int GetMediaBookmarkCount(ContentFilter filter)
+ {
+ int count = 0;
+ IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetBookmarkCount(MediaId, handle, out count), "Failed to get count");
+
+ return count;
+ }
+
+ /// <summary>
+ /// Returns the MediaBookmarks for the given media info from the media database.
+ /// If NULL is passed to the filter, no filtering is applied.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// Task to get all the Bookmarks
+ /// </returns>
+ /// <param name="filter"> filter for the Tags</param>
+ public IEnumerable<MediaBookmark> GetMediaBookmarks(ContentFilter filter)
+ {
+ Collection<MediaBookmark> coll = new Collection<MediaBookmark>();
+ IntPtr filterHandle = (filter != null) ? filter.Handle : IntPtr.Zero;
+ Interop.MediaInformation.MediaBookmarkCallback callback = (IntPtr handle, IntPtr userData) =>
+ {
+ IntPtr newHandle = IntPtr.Zero;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaBookmark.Clone(out newHandle, handle), "Failed to clone");
+
+ coll.Add(new MediaBookmark(newHandle));
+ return true;
+ };
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetAllBookmarks(MediaId, filterHandle, callback, IntPtr.Zero), "Failed to get value");
+
+ return coll;
+ }
+
+ /// <summary>
+ /// Adds a MediaBookmark to the audio
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="offset">Offset of the audio in seconds</param>
+ /// <returns>
+ /// Task with newly added MediaBookmark instance.
+ /// </returns>
+ public MediaBookmark AddBookmark(uint offset)
+ {
+ MediaBookmark result = null;
+ ContentManager.Database.Insert(MediaId, offset, null);
+ ContentFilter bookmarkfilter = new ContentFilter();
+ bookmarkfilter.Condition = ContentColumns.Bookmark.Offset + " = " + offset;
+ IEnumerable<MediaBookmark> bookmarksList = null;
+ bookmarksList = GetMediaBookmarks(bookmarkfilter);
+ foreach (MediaBookmark bookmark in bookmarksList)
+ {
+ if (bookmark.Offset == offset)
+ {
+ result = bookmark;
+ break;
+ }
+ }
+
+ bookmarkfilter.Dispose();
+ return result;
+ }
+
+ /// <summary>
+ /// Deletes a MediaBookmark item from the media database.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="bookmark">The MediaBookmark instance to be deleted</param>
+ public void DeleteBookmark(MediaBookmark bookmark)
+ {
+ ContentManager.Database.Delete(bookmark);
+ }
+
+ internal IntPtr AudioHandle
+ {
+ get
+ {
+ return _handle.DangerousGetHandle();
+ }
+ }
+
+ internal AudioInformation(Interop.AudioInformation.SafeAudioInformationHandle handle, Interop.MediaInformation.SafeMediaInformationHandle mediaInformationHandle)
+ : base(mediaInformationHandle)
+ {
+ _handle = handle;
+ }
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentCollection.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentCollection.cs
new file mode 100755
index 0000000..2e4ae7e
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentCollection.cs
@@ -0,0 +1,50 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Tizen.Content.MediaContent
+{
+ public abstract class ContentCollection : IDisposable
+ {
+ /// <summary>
+ /// Gets the media count for this content store matching the passed filter
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="filter">the media filter</param>
+ /// <returns>Media count</returns>
+ public abstract int GetMediaInformationCount(ContentFilter filter);
+
+ /// <summary>
+ /// Destroys the unmanaged handles.
+ /// Call Dispose API once Contentcollection operations are completed.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public abstract void Dispose();
+
+ /// <summary>
+ /// Gets the media matching the passed filter for this content store, asynchronously
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="filter">The media filter</param>
+ /// <returns>Task with Media Information list</returns>
+ public abstract IEnumerable<MediaInformation> GetMediaInformations(ContentFilter filter);
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentColumns.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentColumns.cs
new file mode 100755
index 0000000..6c10037
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentColumns.cs
@@ -0,0 +1,1130 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+
+namespace Tizen.Content.MediaContent
+{
+ /// <summary>
+ /// A ContentColumns class defines the keyword used for filter condition or sorting.
+ /// </summary>
+ public static class ContentColumns
+ {
+ /// <summary>
+ /// Media column set. \n
+ /// You can use this define to set the condition of media filter and order keyword.
+ /// </summary>
+ public class Media
+ {
+ /// <summary>
+ /// Media UUID
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Id
+ {
+ get
+ {
+ return "MEDIA_ID";
+ }
+ }
+
+ /// <summary>
+ /// Media path
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Path
+ {
+ get
+ {
+ return "MEDIA_PATH";
+ }
+ }
+
+ /// <summary>
+ /// Display name
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string DisplayName
+ {
+ get
+ {
+ return "MEDIA_DISPLAY_NAME";
+ }
+ }
+
+ /// <summary>
+ /// The type of media (0-image, 1-video, 2-sound, 3-music, 4-other)
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string MediaType
+ {
+ get
+ {
+ return "MEDIA_TYPE";
+ }
+ }
+
+ /// <summary>
+ /// Mime type
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string MimeType
+ {
+ get
+ {
+ return "MEDIA_MIME_TYPE";
+ }
+ }
+
+
+ /// <summary>
+ /// File size
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Size
+ {
+ get
+ {
+ return "MEDIA_SIZE";
+ }
+ }
+
+ /// <summary>
+ /// Added time
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string AddedTime
+ {
+ get
+ {
+ return "MEDIA_ADDED_TIME";
+ }
+ }
+
+ /// <summary>
+ /// Modified time
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string ModifiedTime
+ {
+ get
+ {
+ return "MEDIA_MODIFIED_TIME";
+ }
+ }
+
+ /// <summary>
+ /// Timeline. Normally, creation date of media
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Timeline
+ {
+ get
+ {
+ return "MEDIA_TIMELINE";
+ }
+ }
+
+ /// <summary>
+ /// The path of thumbnail
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string ThumbnailPath
+ {
+ get
+ {
+ return "MEDIA_THUMBNAIL_PATH";
+ }
+ }
+
+ /// <summary>
+ /// Title
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Title
+ {
+ get
+ {
+ return "MEDIA_TITLE";
+ }
+ }
+
+ /// <summary>
+ /// Album name
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Album
+ {
+ get
+ {
+ return "MEDIA_ALBUM";
+ }
+ }
+
+ /// <summary>
+ /// Artist
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Artist
+ {
+ get
+ {
+ return "MEDIA_ARTIST";
+ }
+ }
+
+ /// <summary>
+ /// Album artist
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string AlbumArtist
+ {
+ get
+ {
+ return "MEDIA_ALBUM_ARTIST";
+ }
+ }
+
+ /// <summary>
+ /// Genre
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Genre
+ {
+ get
+ {
+ return "MEDIA_GENRE";
+ }
+ }
+
+ /// <summary>
+ /// Composer
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Composer
+ {
+ get
+ {
+ return "MEDIA_COMPOSER";
+ }
+ }
+
+ /// <summary>
+ /// Release year
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Year
+ {
+ get
+ {
+ return "MEDIA_YEAR";
+ }
+ }
+
+ /// <summary>
+ /// Recorded date
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string RecordedDate
+ {
+ get
+ {
+ return "MEDIA_RECORDED_DATE";
+ }
+ }
+
+ /// <summary>
+ /// Copyright
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Copyright
+ {
+ get
+ {
+ return "MEDIA_COPYRIGHT";
+ }
+ }
+
+ /// <summary>
+ /// Track Number
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string TrackNumber
+ {
+ get
+ {
+ return "MEDIA_TRACK_NUM";
+ }
+ }
+
+ /// <summary>
+ /// Description
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Description
+ {
+ get
+ {
+ return "MEDIA_DESCRIPTION";
+ }
+ }
+
+ /// <summary>
+ /// Bitrate
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Bitrate
+ {
+ get
+ {
+ return "MEDIA_BITRATE";
+ }
+ }
+
+ /// <summary>
+ /// Bit per sample
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string BitPerSample
+ {
+ get
+ {
+ return "MEDIA_BITPERSAMPLE";
+ }
+ }
+
+ /// <summary>
+ /// Samplerate
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Samplerate
+ {
+ get
+ {
+ return "MEDIA_SAMPLERATE";
+ }
+ }
+
+ /// <summary>
+ /// Channel
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Channel
+ {
+ get
+ {
+ return "MEDIA_CHANNEL";
+ }
+ }
+
+ /// <summary>
+ /// Duration
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Duration
+ {
+ get
+ {
+ return "MEDIA_DURATION";
+ }
+ }
+
+ /// <summary>
+ /// Longitude
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Longitude
+ {
+ get
+ {
+ return "MEDIA_LONGITUDE";
+ }
+ }
+
+ /// <summary>
+ /// Latitude
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Latitude
+ {
+ get
+ {
+ return "MEDIA_LATITUDE";
+ }
+ }
+
+ /// <summary>
+ /// Altitude
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Altitude
+ {
+ get
+ {
+ return "MEDIA_ALTITUDE";
+ }
+ }
+ /// <summary>
+ /// Width
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Width
+ {
+ get
+ {
+ return "MEDIA_WIDTH";
+ }
+ }
+
+ /// <summary>
+ /// Height
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Height
+ {
+ get
+ {
+ return "MEDIA_HEIGHT";
+ }
+ }
+
+ /// <summary>
+ /// Datetaken
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Datetaken
+ {
+ get
+ {
+ return "MEDIA_DATETAKEN";
+ }
+ }
+
+ /// <summary>
+ /// Orientation
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Orientation
+ {
+ get
+ {
+ return "MEDIA_ORIENTATION";
+ }
+ }
+
+ /// <summary>
+ /// Burst shot ID
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string BurstId
+ {
+ get
+ {
+ return "BURST_ID";
+ }
+ }
+
+ /// <summary>
+ /// Played count
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string PlayedCount
+ {
+ get
+ {
+ return "MEDIA_PLAYED_COUNT";
+ }
+ }
+
+ /// <summary>
+ /// Last played time
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string PlayedTime
+ {
+ get
+ {
+ return "MEDIA_LAST_PLAYED_TIME";
+ }
+ }
+
+ /// <summary>
+ /// Last played position
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string PlayedPosition
+ {
+ get
+ {
+ return "MEDIA_LAST_PLAYED_POSITION";
+ }
+ }
+
+ /// <summary>
+ /// Rating
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Rating
+ {
+ get
+ {
+ return "MEDIA_RATING";
+ }
+ }
+
+ /// <summary>
+ /// Favourite
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Favourite
+ {
+ get
+ {
+ return "MEDIA_FAVOURITE";
+ }
+ }
+
+ /// <summary>
+ /// Author
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Author
+ {
+ get
+ {
+ return "MEDIA_AUTHOR";
+ }
+ }
+
+ /// <summary>
+ /// Provider
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Provider
+ {
+ get
+ {
+ return "MEDIA_PROVIDER";
+ }
+ }
+ /// <summary>
+ /// Content name
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string ContentName
+ {
+ get
+ {
+ return "MEDIA_CONTENT_NAME";
+ }
+ }
+
+ /// <summary>
+ /// Category
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Category
+ {
+ get
+ {
+ return "MEDIA_CATEGORY";
+ }
+ }
+ /// <summary>
+ /// Location tag
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string LocationTag
+ {
+ get
+ {
+ return "MEDIA_LOCATION_TAG";
+ }
+ }
+
+ /// <summary>
+ /// Age rating
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string AgeRating
+ {
+ get
+ {
+ return "MEDIA_AGE_RATING";
+ }
+ }
+
+ /// <summary>
+ /// Keyword
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Keyword
+ {
+ get
+ {
+ return "MEDIA_KEYWORD";
+ }
+ }
+
+ /// <summary>
+ /// Weather
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Weather
+ {
+ get
+ {
+ return "MEDIA_WEATHER";
+ }
+ }
+
+ /// <summary>
+ /// Whether DRM(1) or not(0)
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string IsDRM
+ {
+ get
+ {
+ return "MEDIA_IS_DRM";
+ }
+ }
+
+ /// <summary>
+ /// Storage type
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string StorageType
+ {
+ get
+ {
+ return "MEDIA_STORAGE_TYPE";
+ }
+ }
+
+ /// <summary>
+ /// Exposure time
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string ExposureTime
+ {
+ get
+ {
+ return "MEDIA_EXPOSURE_TIME";
+ }
+ }
+
+ /// <summary>
+ /// f-number
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string FNumber
+ {
+ get
+ {
+ return "MEDIA_FNUMBER";
+ }
+ }
+
+ /// <summary>
+ /// ISO
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Iso
+ {
+ get
+ {
+ return "MEDIA_ISO";
+ }
+ }
+
+ /// <summary>
+ /// Model
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Model
+ {
+ get
+ {
+ return "MEDIA_MODEL";
+ }
+ }
+
+ /// <summary>
+ /// 360 content
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Media360
+ {
+ get
+ {
+ return "MEDIA_360";
+ }
+ }
+
+ /// <summary>
+ /// Keyword for pinyin
+ /// </summary>
+ public class Pinyin
+ {
+ /// <summary>
+ /// File name (pinyin)
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string FileName
+ {
+ get
+ {
+ return "MEDIA_FILE_NAME_PINYIN";
+ }
+ }
+
+ /// <summary>
+ /// Title (pinyin)
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Title
+ {
+ get
+ {
+ return "MEDIA_TITLE_PINYIN";
+ }
+ }
+
+ /// <summary>
+ /// Album (pinyin)
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Album
+ {
+ get
+ {
+ return "MEDIA_ALBUM_PINYIN";
+ }
+ }
+
+ /// <summary>
+ /// Artist (pinyin)
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Artist
+ {
+ get
+ {
+ return "MEDIA_ARTIST_PINYIN";
+ }
+ }
+
+ /// <summary>
+ /// Album artist (pinyin)
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string AlbumArtist
+ {
+ get
+ {
+ return "MEDIA_ALBUM_ARTIST_PINYIN";
+ }
+ }
+
+ /// <summary>
+ /// Genre (pinyin)
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Genre
+ {
+ get
+ {
+ return "MEDIA_GENRE_PINYIN";
+ }
+ }
+
+ /// <summary>
+ /// Composer (pinyin)
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Composer
+ {
+ get
+ {
+ return "MEDIA_COMPOSER_PINYIN";
+ }
+ }
+
+ /// <summary>
+ /// Copyright (pinyin)
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Copyright
+ {
+ get
+ {
+ return "MEDIA_COPYRIGHT_PINYIN";
+ }
+ }
+
+ /// <summary>
+ /// Description (pinyin)
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Description
+ {
+ get
+ {
+ return "MEDIA_DESCRIPTION_PINYIN";
+ }
+ }
+
+ /// <summary>
+ /// Author (pinyin)
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Author
+ {
+ get
+ {
+ return "MEDIA_AUTHOR_PINYIN";
+ }
+ }
+
+ /// <summary>
+ /// Provider (pinyin)
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Provider
+ {
+ get
+ {
+ return "MEDIA_PROVIDER_PINYIN";
+ }
+ }
+
+ /// <summary>
+ /// Content name (pinyin)
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string ContentName
+ {
+ get
+ {
+ return "MEDIA_CONTENT_NAME_PINYIN";
+ }
+ }
+
+ /// <summary>
+ /// Category (pinyin)
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Category
+ {
+ get
+ {
+ return "MEDIA_CATEGORY_PINYIN";
+ }
+ }
+
+ /// <summary>
+ /// Location tag (pinyin)
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string LocationTag
+ {
+ get
+ {
+ return "MEDIA_LOCATION_TAG_PINYIN";
+ }
+ }
+
+ /// <summary>
+ /// Age rating (pinyin)
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string AgeRating
+ {
+ get
+ {
+ return "MEDIA_AGE_RATING_PINYIN";
+ }
+ }
+
+ /// <summary>
+ /// Keyword (pinyin)
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Keyword
+ {
+ get
+ {
+ return "MEDIA_KEYWORD_PINYIN";
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Folder column set. \n
+ /// You can use this define to set the condition of folder filter and order keyword.
+ /// </summary>
+ public class Folder
+ {
+
+ /// <summary>
+ ///Folder UUID
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Id
+ {
+ get
+ {
+ return "FOLDER_ID";
+ }
+ }
+
+ /// <summary>
+ /// Folder path
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Path
+ {
+ get
+ {
+ return "FOLDER_PATH";
+ }
+ }
+
+ /// <summary>
+ /// Folder name
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Name
+ {
+ get
+ {
+ return "FOLDER_NAME";
+ }
+ }
+
+ /// <summary>
+ /// Folder modified time
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string ModifiedTime
+ {
+ get
+ {
+ return "FOLDER_MODIFIED_TIME";
+ }
+ }
+
+ /// <summary>
+ /// Folder storage type
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string StorageType
+ {
+ get
+ {
+ return "FOLDER_STORAGE_TYPE";
+ }
+ }
+
+ /// <summary>
+ /// Keyword for pinyin
+ /// </summary>
+ public class Pinyin
+ {
+ /// <summary>
+ /// Folder name (pinyin)
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Name
+ {
+ get
+ {
+ return "FOLDER_NAME_PINYIN";
+ }
+ }
+
+ }
+
+ /// <summary>
+ /// Folder order. Default is 0
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Order
+ {
+ get
+ {
+ return "FOLDER_ORDER";
+ }
+ }
+
+ /// <summary>
+ /// Parent folder UUID
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string ParentId
+ {
+ get
+ {
+ return "FOLDER_PARENT_FOLDER_ID";
+ }
+ }
+ }
+
+ /// <summary>
+ /// Playlist column set. \n
+ /// You can use this define to set the condition of playlist filter and order keyword.
+ /// </summary>
+ public class Playlist
+ {
+ /// <summary>
+ /// Playlist name
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Name
+ {
+ get
+ {
+ return "PLAYLIST_NAME";
+ }
+ }
+ /// <summary>
+ /// Playlist member's play order
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Order
+ {
+ get
+ {
+ return "PLAYLIST_MEMBER_ORDER";
+ }
+ }
+
+ /// <summary>
+ /// Count of media in the playlist
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Count
+ {
+ get
+ {
+ return "PLAYLIST_MEDIA_COUNT";
+ }
+ }
+ }
+
+ /// <summary>
+ /// Tag column set. \n
+ /// You can use this define to set the condition of tag filter and order keyword.
+ /// </summary>
+ public class Tag
+ {
+ /// <summary>
+ /// Tag name
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Name
+ {
+ get
+ {
+ return "TAG_NAME";
+ }
+ }
+
+ /// <summary>
+ /// Count of media in the tag
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Count
+ {
+ get
+ {
+ return "TAG_MEDIA_COUNT";
+ }
+ }
+ }
+
+ /// <summary>
+ /// Bookmark column set. \n
+ /// You can use this define to set the condition of bookmark filter and order keyword.
+ /// </summary>
+ public class Bookmark
+ {
+ /// <summary>
+ /// Bookmarked offset
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Offset
+ {
+ get
+ {
+ return "BOOKMARK_MARKED_TIME";
+ }
+ }
+ }
+
+ /// <summary>
+ /// Storage column set. \n
+ /// You can use this define to set the condition of storage filter and order keyword.
+ /// </summary>
+ public class Storage
+ {
+ /// <summary>
+ /// Storage UUID
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Id
+ {
+ get
+ {
+ return "STORAGE_ID";
+ }
+ }
+
+ /// <summary>
+ /// Storage path
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Path
+ {
+ get
+ {
+ return "STORAGE_PATH";
+ }
+ }
+ }
+
+ /// <summary>
+ /// Face column set. \n
+ /// You can use this define to set the condition of face filter and order keyword.
+ /// </summary>
+ public class Face
+ {
+ /// <summary>
+ /// face tag
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static string Tag
+ {
+ get
+ {
+ return "MEDIA_FACE_TAG";
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentDatabase.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentDatabase.cs
new file mode 100755
index 0000000..e2389a3
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentDatabase.cs
@@ -0,0 +1,714 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+/// <summary>
+/// The Media Content API provides functions, enumerations used in the entire Content Service.
+/// </summary>
+/// <remarks>
+/// The Media Content API provides functions and enumerations used in the entire Content Service.
+/// The information about media items i.e.image, audio and video, are managed in the content database
+/// and operations that involve database requires an active connection with the media content service.
+/// During media scanning, Media Service extract media information automatically. media information
+/// include basic file info like path, size, modified time etc and some metadata like ID3tag, EXIF,
+/// thumbnail, etc. (thumbnail extracted only in Internal and SD card storage.
+/// Media content services do not manage hidden files.
+/// The API provides functions for connecting (media_content_connect()) and disconnecting(media_content_disconnect())
+/// from the media content service.
+/// </remarks>
+
+
+namespace Tizen.Content.MediaContent
+{
+ /// <summary>
+ /// ContentDatabase class is the interface class for managing the ContentCollection and MediaInformation from/to the database.
+ /// This class allows usre to access/create/update db operations for media content.
+ /// </summary>
+ public class ContentDatabase
+ {
+ private static IntPtr _updateHandle = IntPtr.Zero;
+
+ /// <summary>
+ /// Connect to the media database to search, insert, remove or modify media information.
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ /// <remarks>
+ /// For information security, disconnect() after use media database.
+ /// </remarks>
+ public static void Connect()
+ {
+ MediaContentValidator.ThrowIfError(Interop.Content.Connect(), "Connect failed");
+ }
+
+ /// <summary>
+ /// Disconnect from the media database.
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static void Disconnect()
+ {
+ MediaContentValidator.ThrowIfError(Interop.Content.Disconnect(), "Disconnect failed");
+ }
+
+ private static readonly Interop.Content.MediaContentDBUpdatedCallback s_contentUpdatedCallback = (
+ MediaContentError error,
+ int pid,
+ MediaContentUpdateItemType updateItem,
+ MediaContentDBUpdateType updateType,
+ MediaContentType mediaType,
+ string uuid,
+ string filePath,
+ string mimeType,
+ IntPtr userData) =>
+ {
+ _contentUpdated?.Invoke(
+ null, new ContentUpdatedEventArgs(error, pid, updateItem, updateType, mediaType, uuid, filePath, mimeType));
+ };
+
+ private static event EventHandler<ContentUpdatedEventArgs> _contentUpdated;
+ /// <summary>
+ /// ContentUpdated event is triggered when the media DB changes.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="sender"></param>
+ /// <param name="e">A ContentUpdatedEventArgs object that contains information about the update operation.</param>
+ public static event EventHandler<ContentUpdatedEventArgs> ContentUpdated
+ {
+ add
+ {
+ if (_contentUpdated == null)
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Content.AddDbUpdatedCb(s_contentUpdatedCallback, IntPtr.Zero, out _updateHandle), "Failed to set callback");
+ }
+
+ _contentUpdated += value;
+ }
+
+ remove
+ {
+ _contentUpdated -= value;
+ if (_contentUpdated == null)
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Content.RemoveDbUpdatedCb(_updateHandle), "Failed to unset callback");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the count of ContentCollections for the ContentCollectionType and passed filter from the media database.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="filter">The media filter</param>
+ /// <returns>The count of contents present in the media database for a ContentSourceType</returns>
+ public int GetCount<T>(ContentFilter filter) where T : class
+ {
+ int count = 0;
+ IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
+ MediaGroupType groupType = MediaGroupType.DisplayName;
+ if (handle != IntPtr.Zero)
+ {
+ groupType = filter.GroupType;
+ }
+
+ if (typeof(T) == typeof(MediaInformation))
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetMediaCount(handle, out count), "Failed to get count");
+ }
+ else if (typeof(T) == typeof(MediaBookmark))
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaBookmark.GetBookmarkCountFromDb(handle, out count), "Failed to get count");
+ }
+ else if (typeof(T) == typeof(Album))
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Group.MediaAlbumGetAlbumCountFromDb(handle, out count), "Failed to get count");
+ }
+ else if (typeof(T) == typeof(MediaFolder))
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Folder.GetFolderCountFromDb(handle, out count), "Failed to get count");
+ }
+ else if (typeof(T) == typeof(Storage))
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Storage.GetStorageCountFromDb(handle, out count), "Failed to get count");
+ }
+ else if (typeof(T) == typeof(Tag))
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Tag.GetTagCountFromDb(handle, out count), "Failed to get count");
+ }
+ else if (typeof(T) == typeof(PlayList))
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Playlist.GetPlaylistCountFromDb(handle, out count), "Failed to get count");
+ }
+ else if (typeof(T) == typeof(Group))
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Group.GetGroupCountFromDb(handle, groupType, out count), "Failed to get count");
+ }
+ else
+ {
+ throw new ArgumentException("Wrong type");
+ }
+
+ return count;
+ }
+
+ /// <summary>
+ /// Gets the MediaInformation object for the passed media Id.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="id">The media id to fetch the respective MediaInformation instance</param>
+ /// <returns>MediaInformation instance for the associated id.It throws Exception for invalid Id.</returns>
+ public MediaInformation Select(string id)
+ {
+ Interop.MediaInformation.SafeMediaInformationHandle mediaHandle;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetMediaFromDB(id, out mediaHandle), "Failed to get information");
+
+ MediaContentType type;
+ MediaInformation res;
+ Interop.MediaInformation.GetMediaType(mediaHandle, out type);
+ if (type == MediaContentType.Image)
+ {
+ Interop.ImageInformation.SafeImageInformationHandle imageInfo;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetImage(mediaHandle.DangerousGetHandle(), out imageInfo), "Failed to get image information");
+
+ res = new ImageInformation(imageInfo, mediaHandle);
+ }
+ else if ((type == MediaContentType.Music) || (type == MediaContentType.Sound))
+ {
+ Interop.AudioInformation.SafeAudioInformationHandle audioInfo;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetAudio(mediaHandle.DangerousGetHandle(), out audioInfo), "Failed to get audio information");
+
+ res = new AudioInformation(audioInfo, mediaHandle);
+ }
+ else if (type == MediaContentType.Video)
+ {
+ Interop.VideoInformation.SafeVideoInformationHandle videoInfo;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetVideo(mediaHandle.DangerousGetHandle(), out videoInfo), "Failed to get video information");
+
+ res = new VideoInformation(videoInfo, mediaHandle);
+ }
+ else
+ {
+ res = new MediaInformation(mediaHandle);
+ }
+
+ return res;
+ }
+
+ /// <summary>
+ /// Gets the ContentCollection object for the passed media Id.
+ /// Applicable for MediaFolder and Storage types.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="id">The ContentCollection id to fetch the respective MediaInformation instance</param>
+ /// <returns>ContentCollection instance for the associated id.It throws Exception for invalid Id.</returns>
+ public T Select<T>(string id) where T : ContentCollection
+ {
+ ContentCollection result = null;
+ IntPtr handle = IntPtr.Zero;
+
+ if (typeof(T) == typeof(MediaFolder))
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Folder.GetFolderFromDb(id, out handle), "Failed to get information");
+
+ if (handle != IntPtr.Zero)
+ {
+ result = new MediaFolder(handle);
+ return (T)result;
+ }
+
+ }
+ else if (typeof(T) == typeof(Storage))
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Storage.GetStorageInfoFromDb(id, out handle), "Failed to get information");
+
+ if (handle != IntPtr.Zero)
+ {
+ result = new Storage(handle);
+ return (T)result;
+ }
+ }
+
+ return null;
+ }
+
+
+ /// <summary>
+ /// Gets the ContentCollection object for the passed media Id.
+ /// Applicable for PlayList, Album and Tag types.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="id">The ContentCollection id to fetch the respective MediaInformation instance</param>
+ /// <returns>ContentCollection instance for the associated id.It throws Exception for invalid Id.</returns>
+ public T Select<T>(int id) where T : ContentCollection
+ {
+ ContentCollection result = null;
+ IntPtr handle = IntPtr.Zero;
+
+ if (typeof(T) == typeof(PlayList))
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Playlist.GetPlaylistFromDb(id, out handle), "Failed to get information");
+
+ if (handle != IntPtr.Zero)
+ {
+ result = new PlayList(handle);
+ return (T)result;
+ }
+ }
+ else if (typeof(T) == typeof(Album))
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Group.MediaAlbumGetAlbumFromDb(id, out handle), "Failed to get information");
+
+ if (handle != IntPtr.Zero)
+ {
+ result = new Album(handle);
+ return (T)result;
+ }
+ }
+ else if (typeof(T) == typeof(Tag))
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Tag.GetTagFromDb(id, out handle), "Failed to get information");
+
+ if (handle != IntPtr.Zero)
+ {
+ result = new Tag(handle);
+ return (T)result;
+ }
+ }
+
+ return null;
+ }
+
+ private static IEnumerable<MediaFolder> ForEachFolder(ContentFilter filter)
+ {
+ List<MediaFolder> result = new List<MediaFolder>();
+ Interop.Folder.MediaFolderCallback callback = (IntPtr handle, IntPtr data) =>
+ {
+ IntPtr newHandle = IntPtr.Zero;
+ MediaContentValidator.ThrowIfError(
+ Interop.Folder.Clone(out newHandle, handle), "Failed to clone");
+
+ result.Add(new MediaFolder(newHandle));
+ return true;
+ };
+ IntPtr filterHandle = filter != null ? filter.Handle : IntPtr.Zero;
+ MediaContentValidator.ThrowIfError(
+ Interop.Folder.ForeachFolderFromDb(filterHandle, callback, IntPtr.Zero), "Failed to get information");
+
+ return result;
+ }
+
+ private static IEnumerable<Album> ForEachAlbum(ContentFilter filter)
+ {
+ List<Album> result = new List<Album>();
+ Interop.Group.MediaAlbumCallback callback = (IntPtr handle, IntPtr data) =>
+ {
+ IntPtr newHandle = IntPtr.Zero;
+ MediaContentValidator.ThrowIfError(
+ Interop.Group.MediaAlbumClone(out newHandle, handle), "Failed to clone");
+
+ result.Add(new Album(newHandle));
+ return true;
+ };
+ IntPtr filterHandle = (filter != null) ? filter.Handle : IntPtr.Zero;
+ MediaContentValidator.ThrowIfError(
+ Interop.Group.MediaAlbumForeachAlbumFromDb(filterHandle, callback, IntPtr.Zero), "Failed to get information");
+
+ return result;
+ }
+
+ private static IEnumerable<Group> ForEachGroup(ContentFilter filter)
+ {
+ IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
+ MediaGroupType groupType;
+ if (filter == null)
+ {
+ groupType = MediaGroupType.DisplayName;
+ }
+ else
+ {
+ groupType = filter.GroupType;
+ }
+
+ List<Group> result = new List<Group>();
+ Interop.Group.MediaGroupCallback callback = (string groupName, IntPtr data) =>
+ {
+ result.Add(new Group(groupName, groupType));
+ return true;
+ };
+ MediaContentValidator.ThrowIfError(
+ Interop.Group.ForeachGroupFromDb(handle, groupType, callback, IntPtr.Zero), "Failed to get information");
+
+ return result;
+ }
+
+ private static IEnumerable<Storage> ForEachStorage(ContentFilter filter)
+ {
+ IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
+ List<Storage> result = new List<Storage>();
+ Interop.Storage.MediaStorageCallback callback = (IntPtr storageHandle, IntPtr data) =>
+ {
+ IntPtr newHandle = IntPtr.Zero;
+ MediaContentValidator.ThrowIfError(
+ Interop.Storage.Clone(out newHandle, storageHandle), "Failed to clone");
+
+ result.Add(new Storage(newHandle));
+ return true;
+ };
+ MediaContentValidator.ThrowIfError(
+ Interop.Storage.ForeachStorageFromDb(handle, callback, IntPtr.Zero), "Failed to get information");
+
+ return result;
+ }
+
+ private static IEnumerable<Tag> ForEachTag(ContentFilter filter)
+ {
+ IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
+
+ List<Tag> result = new List<Tag>();
+ Interop.Tag.MediaTagCallback callback = (IntPtr tagHandle, IntPtr data) =>
+ {
+ IntPtr newHandle = IntPtr.Zero;
+ MediaContentValidator.ThrowIfError(
+ Interop.Tag.Clone(out newHandle, tagHandle), "Failed to clone");
+
+ result.Add(new Tag(newHandle));
+ return true;
+ };
+ MediaContentValidator.ThrowIfError(
+ Interop.Tag.ForeachTagFromDb(handle, callback, IntPtr.Zero), "Failed to get information");
+
+ return result;
+ }
+
+ private static IEnumerable<PlayList> ForEachPlayList(ContentFilter filter)
+ {
+ IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
+
+ List<PlayList> result = new List<PlayList>();
+ Interop.Playlist.MediaPlaylistCallback callback = (IntPtr playListHandle, IntPtr data) =>
+ {
+ IntPtr newHandle = IntPtr.Zero;
+ MediaContentValidator.ThrowIfError(
+ Interop.Playlist.Clone(out newHandle, playListHandle), "Failed to clone");
+
+ result.Add(new PlayList(newHandle));
+ return true;
+ };
+ MediaContentValidator.ThrowIfError(
+ Interop.Playlist.ForeachPlaylistFromDb(handle, callback, IntPtr.Zero), "Failed to get information");
+
+ return result;
+ }
+
+ /// <summary>
+ /// Returns the ContentCollections with optional filter from the media database.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// This function gets all ContentCollections matching the given filter. If NULL is passed to the filter, no filtering is applied.
+ /// </remarks>
+ /// <param name="filter">Filter for content items</param>
+ /// <returns>
+ /// Task with the list of the ContentCollection
+ /// </returns>
+ public IEnumerable<T> SelectAll<T>(ContentFilter filter)
+ {
+ if (typeof(T) == typeof(MediaInformation))
+ {
+ IEnumerable<MediaInformation> mediaList = GetMediaInformations(filter);
+ return (IEnumerable<T>)mediaList;
+ }
+ else if (typeof(T) == typeof(Album))
+ {
+ IEnumerable<Album> collectionList = ForEachAlbum(filter);
+ return (IEnumerable<T>)collectionList;
+ }
+ else if (typeof(T) == typeof(MediaFolder))
+ {
+ IEnumerable<MediaFolder> collectionList = ForEachFolder(filter);
+ return (IEnumerable<T>)collectionList;
+ }
+ else if (typeof(T) == typeof(Group))
+ {
+ IEnumerable<Group> collectionList = ForEachGroup(filter);
+ return (IEnumerable<T>)collectionList;
+ }
+ else if (typeof(T) == typeof(Storage))
+ {
+ IEnumerable<Storage> collectionList = ForEachStorage(filter);
+ return (IEnumerable<T>)collectionList;
+ }
+ else if (typeof(T) == typeof(Tag))
+ {
+ IEnumerable<Tag> collectionList = ForEachTag(filter);
+ return (IEnumerable<T>)collectionList;
+ }
+ else if (typeof(T) == typeof(PlayList))
+ {
+ IEnumerable<PlayList> collectionList = ForEachPlayList(filter);
+ return (IEnumerable<T>)collectionList;
+ }
+
+ return null;
+ }
+
+ /// <summary>
+ /// Returns media from the media database.
+ /// This function gets all media meeting the given filter
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="filter">The media filter</param>
+ /// <returns>List of media</returns>
+ private IEnumerable<MediaInformation> GetMediaInformations(ContentFilter filter)
+ {
+ IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
+ List<MediaInformation> mediaInformationList = new List<MediaInformation>();
+ Interop.MediaInformation.MediaInformationCallback callback = (IntPtr mediaHandle, IntPtr userData) =>
+ {
+ Interop.MediaInformation.SafeMediaInformationHandle newHandle;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.Clone(out newHandle, mediaHandle), "Failed to clone");
+
+ MediaContentType type;
+ Interop.MediaInformation.GetMediaType(newHandle, out type);
+ if (type == MediaContentType.Image)
+ {
+ Interop.ImageInformation.SafeImageInformationHandle imageInfo;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetImage(mediaHandle, out imageInfo), "Failed to get image information");
+
+ mediaInformationList.Add(new ImageInformation(imageInfo, newHandle));
+ }
+ else if ((type == MediaContentType.Music) || (type == MediaContentType.Sound))
+ {
+ Interop.AudioInformation.SafeAudioInformationHandle audioInfo;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetAudio(mediaHandle, out audioInfo), "Failed to get audio information");
+
+ mediaInformationList.Add(new AudioInformation(audioInfo, newHandle));
+ }
+ else if (type == MediaContentType.Video)
+ {
+ Interop.VideoInformation.SafeVideoInformationHandle videoInfo;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetVideo(mediaHandle, out videoInfo), "Failed to get video information");
+
+ mediaInformationList.Add(new VideoInformation(videoInfo, newHandle));
+ }
+ else if (type == MediaContentType.Others)
+ {
+ mediaInformationList.Add(new MediaInformation(newHandle));
+ }
+
+ return true;
+ };
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetAllMedia(handle, callback, IntPtr.Zero), "Failed to get media information");
+
+ return mediaInformationList;
+ }
+
+ /// <summary>
+ /// Deletes a MediaInformation from the media database.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="mediaInfo">The MediaInformation to be deleted</param>
+ public void Delete(MediaInformation mediaInfo)
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.Delete(mediaInfo.MediaId), "Failed to remove information");
+ }
+
+
+ /// <summary>
+ /// Deletes a content collection from the media database.
+ /// Applicable for Tag and PlayList only.
+ /// For other types ArgumentException is thrown.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="contentcollection">The ContentCollection instance to be deleted</param>
+ public void Delete(ContentCollection contentcollection)
+ {
+ Type type = contentcollection.GetType();
+
+ if (type == typeof(Tag))
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Tag.DeleteFromDb(((Tag)contentcollection).Id), "Failed to remove information");
+ }
+ else if (type == typeof(PlayList))
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Playlist.DeleteFromDb(((PlayList)contentcollection).Id), "Failed to remove information");
+ }
+ else
+ {
+ throw new ArgumentException("The type of content collection is wrong");
+ }
+ }
+
+ internal void Delete(MediaBookmark bookmark)
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaBookmark.DeleteFromDb(bookmark.Id), "Failed to remove information");
+ }
+
+ internal void Delete(MediaFace face)
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Face.DeleteFromDb(face.Id), "Failed to remove face information");
+ }
+
+ /// <summary>
+ /// Updates a content collection in the media database
+ /// Applicable for Tag, PlayList and MediagFolder types only.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="contentCollection">The content collection to be updated</param>
+ public void Update(ContentCollection contentCollection)
+ {
+ Type type = contentCollection.GetType();
+ if (type == typeof(Tag))
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Tag.UpdateToDb(((Tag)contentCollection).Handle), "Failed to update DB");
+ }
+ else if (type == typeof(PlayList))
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Playlist.UpdateToDb(((PlayList)contentCollection).Handle), "Failed to update DB");
+ }
+ else if (type == typeof(MediaFolder))
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Folder.UpdateToDb(((MediaFolder)contentCollection).Handle), "Failed to update DB");
+ }
+ else
+ {
+ throw new ArgumentException("The type of content collection is wrong");
+ }
+ }
+
+ /// <summary>
+ /// Updates a media information instance in the media database
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="mediaInfo">The MediaInformation object to be updated</param>
+ public void Update(MediaInformation mediaInfo)
+ {
+ Type type = mediaInfo.GetType();
+ if (type == typeof(ImageInformation))
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.ImageInformation.UpdateToDB(((ImageInformation)mediaInfo).ImageHandle), "Failed to update DB");
+
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.UpdateToDB(mediaInfo.MediaHandle), "Failed to update DB");
+ }
+ else if (type == typeof(AudioInformation))
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.AudioInformation.UpdateToDB(((AudioInformation)mediaInfo).AudioHandle), "Failed to update DB");
+
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.UpdateToDB(mediaInfo.MediaHandle), "Failed to update DB");
+ }
+ else if (type == typeof(VideoInformation))
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.VideoInformation.UpdateToDB(((VideoInformation)mediaInfo).VideoHandle), "Failed to update DB");
+
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.UpdateToDB(mediaInfo.MediaHandle), "Failed to update DB");
+ }
+ else if (type == typeof(MediaInformation))
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.UpdateToDB(mediaInfo.MediaHandle), "Failed to update DB");
+ }
+ else
+ {
+ throw new ArgumentException("Invalid information type");
+ }
+ }
+
+ internal void Update(MediaFace face)
+ {
+ MediaContentValidator.ThrowIfError(Interop.Face.UpdateToDb(face.Handle), "Failed to update DB");
+ }
+
+ /// <summary>
+ /// Inserts a content collection to the media database.
+ /// Applicable for Tag and PlayList types only.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="contentCollection">The content collection to be inserted</param>
+ public void Insert(ContentCollection contentCollection)
+ {
+ Type type = contentCollection.GetType();
+ IntPtr handle = IntPtr.Zero;
+ if (type == typeof(Tag))
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Tag.InsertToDb(((Tag)contentCollection).Name, out handle), "Failed to insert collection");
+ ((Tag)contentCollection).Handle = handle;
+ }
+ else if (type == typeof(PlayList))
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Playlist.InsertToDb(((PlayList)contentCollection).Name, out handle), "Failed to insert collection");
+ ((PlayList)contentCollection).Handle = handle;
+ }
+ else
+ {
+ throw new ArgumentException("collection type is wrong");
+ }
+ }
+
+ internal void Insert(string mediaId, uint offset, string thumbnailPath)
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaBookmark.InsertToDb(mediaId, offset, thumbnailPath), "Failed to insert information");
+ }
+
+ internal void Insert(MediaFace face)
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Face.InsertToDb(((MediaFace)face).Handle), "Failed to insert information");
+ }
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentEventArgs.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentEventArgs.cs
new file mode 100755
index 0000000..283fc87
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentEventArgs.cs
@@ -0,0 +1,113 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+
+using System;
+
+namespace Tizen.Content.MediaContent
+{
+ /// <summary>
+ /// Event arguments passed when content is updated in the media database
+ /// </summary>
+ public class ContentUpdatedEventArgs : EventArgs
+ {
+ internal ContentUpdatedEventArgs(MediaContentError error, int pid, MediaContentUpdateItemType updateItem,
+ MediaContentDBUpdateType updateType, MediaContentType mediaType, string uuid, string filePath, string mimeType)
+ {
+ Error = error;
+ Pid = pid;
+ UpdateItem = updateItem;
+ UpdateType = updateType;
+ MediaType = mediaType;
+ Uuid = uuid;
+ FilePath = filePath;
+ MimeType = mimeType;
+ }
+ /// <summary>
+ /// The error code
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public MediaContentError Error
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// The PID which publishes notification
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Pid
+ {
+ get; set;
+ }
+
+ /// <summary>
+ /// The update item of notification
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public MediaContentUpdateItemType UpdateItem
+ {
+ get; set;
+ }
+
+ /// <summary>
+ /// The update type of notification
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public MediaContentDBUpdateType UpdateType
+ {
+ get; set;
+ }
+
+ /// <summary>
+ /// The type of the media content
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public MediaContentType MediaType
+ {
+ get; set;
+ }
+
+ /// <summary>
+ /// The UUID of media or directory, which is updated
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Uuid
+ {
+ get; set;
+ }
+
+ /// <summary>
+ /// The path of the media or directory
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string FilePath
+ {
+ get; set;
+ }
+
+ /// <summary>
+ /// The mime type of the media info
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string MimeType
+ {
+ get; set;
+ }
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentFilter.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentFilter.cs
new file mode 100755
index 0000000..97d4998
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentFilter.cs
@@ -0,0 +1,365 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Content.MediaContent
+{
+ /// <summary>
+ /// The Content Filter API provides functions to manage media filters.
+ /// </summary>
+ /// <remarks>
+ /// A Content filter is required for filtering information associated with Media Folder, Tag, Audio, MediaBookmark and Media Information on basis of details like offset, count, order and condition for searching.
+ /// It provide functionality to set properties associated with a given content filter.
+ /// Setting content filter properties helps to limit the number of filtered items as following:
+ /// <list>
+ /// <item><description>
+ /// Offset - Used to set starting position of the filter's search
+ /// </description></item>
+ /// <item><description>
+ /// Count - Used to set number of items to be searched from offset
+ /// </description></item>
+ /// <item><description>
+ /// Condition - Used to set keyword which user want to search
+ /// </description></item>
+ /// <item><description>
+ /// Order - Used to set type of media to be ordered by the filter
+ /// </description></item>
+ /// </list>
+ /// Searchable expression can use one of the following forms:
+ /// <list>
+ /// <item><description>
+ /// column = value
+ /// </description></item>
+ /// <item><description>
+ /// column > value
+ /// </description></item>
+ /// <item><description>
+ /// column >= value
+ /// </description></item>
+ /// <item><description>
+ /// column < value
+ /// </description></item>
+ /// <item><description>
+ /// column <= value
+ /// </description></item>
+ /// <item><description>
+ /// value = column
+ /// </description></item>
+ /// <item><description>
+ /// value >= column
+ /// </description></item>
+ /// <item><description>
+ /// value < column
+ /// </description></item>
+ /// <item><description>
+ /// value <= column
+ /// </description></item>
+ /// <item><description>
+ /// column IN (value)
+ /// </description></item>
+ /// <item><description>
+ /// column IN(value-list)
+ /// </description></item>
+ /// <item><description>
+ /// column NOT IN(value)
+ /// </description></item>
+ /// <item><description>
+ /// column NOT IN(value-list)
+ /// </description></item>
+ /// <item><description>
+ /// column LIKE value
+ /// </description></item>
+ /// <item><description>
+ /// expression1 AND expression2 OR expression3
+ /// </description></item>
+ /// </list>
+ /// Note that if you want to set qoutation(" ' " or " " ") as value of LIKE operator, you should use two times.(" '' " or " "" ") \n And the optional ESCAPE clause is supported. Both percent symbol("%") and underscore symbol("_") are used in the LIKE pattern.
+ /// If these characters are used as value of LIKE operation, then the expression following the ESCAPE caluse of sqlite.
+ /// </remarks>
+ public class ContentFilter : IDisposable
+ {
+ private IntPtr _filterHandle = IntPtr.Zero;
+ private bool _disposedValue = false;
+ private ContentCollation _conditionCollate = ContentCollation.Default;
+ private ContentCollation _orderCollate = ContentCollation.Default;
+ private ContentOrder _orderType = ContentOrder.Asc;
+ private string _orderKeyword = null;
+ private string _conditionMsg = null;
+
+ internal IntPtr Handle
+ {
+ get
+ {
+ if (_filterHandle == IntPtr.Zero)
+ {
+ throw new ObjectDisposedException(nameof(ContentFilter));
+ }
+
+ return _filterHandle;
+ }
+ }
+ /// <summary>
+ /// The start position of the given filter Starting from zero.
+ /// Please note that count value has to be set properly for correct result.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Offset
+ {
+ get
+ {
+ int offset;
+ int count;
+ MediaContentValidator.ThrowIfError(
+ Interop.Filter.GetOffset(Handle, out offset, out count), "Failed to get offset");
+
+ return offset;
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Filter.SetOffset(Handle, value, this.Count), "Failed to set offset");
+ }
+ }
+
+ public ContentFilter()
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Filter.Create(out _filterHandle), "Failed to Create Filter handle.");
+ }
+
+ /// <summary>
+ /// The number of items to be searched with respect to the offset
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Count
+ {
+ get
+ {
+ int offset;
+ int count;
+ MediaContentValidator.ThrowIfError(
+ Interop.Filter.GetOffset(Handle, out offset, out count), "Failed to get count");
+
+ return count;
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Filter.SetOffset(Handle, this.Offset, value), "Failed to set count");
+ }
+ }
+
+ /// <summary>
+ /// Gets the media filter content order and order keyword.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ContentOrder Order
+ {
+ get
+ {
+ return _orderType;
+ }
+
+ set
+ {
+ if (_orderKeyword != null)
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Filter.SetOrder(Handle, value, _orderKeyword, _orderCollate), "Failed to set order");
+ }
+
+ _orderType = value;
+ }
+ }
+
+ /// <summary>
+ /// The search order keyword
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string OrderKey
+ {
+ get
+ {
+ ContentOrder order;
+ IntPtr val = IntPtr.Zero;
+ ContentCollation type;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Filter.GetOrder(Handle, out order, out val, out type), "Failed to GetOrder for OrderKey");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Filter.SetOrder(Handle, _orderType, value, _orderCollate), "Failed to set OrderKey");
+
+ _orderKeyword = value;
+ }
+ }
+
+ /// <summary>
+ /// The collate type for comparing two strings
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ContentCollation OrderCollationType
+ {
+ get
+ {
+ return _orderCollate;
+ }
+
+ set
+ {
+ if (_orderKeyword != null)
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Filter.SetOrder(Handle, _orderType, _orderKeyword, value), "Failed to set collation");
+ }
+
+ _orderCollate = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets/Sets the condition for the given filter.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Condition
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ ContentCollation type;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Filter.GetCondition(Handle, out val, out type), "Failed to get condition");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Filter.SetCondition(Handle, value, _conditionCollate), "Failed to set condition");
+
+ _conditionMsg = value;
+ }
+ }
+
+ /// <summary>
+ /// The collate type for comparing two strings
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ContentCollation ConditionCollationType
+ {
+ get
+ {
+ return _conditionCollate;
+ }
+
+ set
+ {
+ if (_conditionMsg != null)
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Filter.SetCondition(Handle, _conditionMsg, value), "Failed to set collation");
+ }
+
+ _conditionCollate = value;
+ }
+ }
+
+ /// <summary>
+ /// Sets the storage id for the given filter.
+ /// You can use this property when you want to search items only in the specific storage
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string StorageId
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Filter.GetStorage(Handle, out val), "Failed to get condition");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Filter.SetStorage(Handle, value), "Failed to set condition");
+ }
+ }
+
+ /// <summary>
+ /// The type of the media group
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public MediaGroupType GroupType { get; set; }
+
+ /// <summary>
+ /// Dispose API for closing the internal resources.
+ /// This function can be used to stop all effects started by Vibrate().
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ if (_filterHandle != IntPtr.Zero)
+ {
+ Interop.Filter.Destroy(_filterHandle);
+ _filterHandle = IntPtr.Zero;
+ }
+
+ _disposedValue = true;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentManager.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentManager.cs
new file mode 100755
index 0000000..6044b87
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentManager.cs
@@ -0,0 +1,268 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using System.Threading;
+
+/// <summary>
+/// The Media Content API provides functions, enumerations used in the entire Content Service.
+/// </summary>
+/// <remarks>
+/// The Media Content API provides functions and enumerations used in the entire Content Service.
+/// The information about media items i.e.image, audio and video, are managed in the content database
+/// and operations that involve database requires an active connection with the media content service.
+/// During media scanning, Media Service extract media information automatically. media information
+/// include basic file info like path, size, modified time etc and some metadata like ID3tag, EXIF,
+/// thumbnail, etc. (thumbnail extracted only in Internal and SD card storage.
+/// Media content services do not manage hidden files.
+/// The API provides functions for connecting (media_content_connect()) and disconnecting(media_content_disconnect())
+/// from the media content service.
+/// </remarks>
+
+
+namespace Tizen.Content.MediaContent
+{
+ /// <summary>
+ /// ContentManager class is the interface class for accessing the ContentCollection and MediaInformation.
+ /// This class allows usre to create/update db operations for media content.
+ /// </summary>
+ public static class ContentManager
+ {
+ private static readonly ContentDatabase s_contentDB = new ContentDatabase();
+
+ /// <summary>
+ /// Database instance to do all the Database oprtions for media content management.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static ContentDatabase Database
+ {
+ get
+ {
+ return s_contentDB;
+ }
+ }
+
+ /// <summary>
+ /// Requests to scan a media file.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="filePath">File path of the media to be scanned</param>
+ /// <returns>A reference to the MediaInformation object scanned</returns>
+ /// <remarks>
+ /// This function requests to scan a media file to the media server. If media file is not registered to DB yet,
+ /// that media file information will be added to the media DB. If it is already registered to the DB,
+ /// then this tries to refresh information. If requested file does not exist on file system,
+ /// information of the media file will be removed from the media DB.
+ /// </remarks>
+ public static void Scan(string filePath)
+ {
+ MediaContentValidator.ThrowIfError(Interop.Content.ScanFile(filePath), "Failed scan");
+ }
+
+ /// <summary>
+ /// Inserts a media to the media database
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="filePath">File path of the media to be inserted</param>
+ /// <returns>the MediaInformation instance about added media path</returns>
+ public static MediaInformation AddMediaInformation(string filePath)
+ {
+ Interop.MediaInformation.SafeMediaInformationHandle mediaInformationHandle;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.Insert(filePath, out mediaInformationHandle), "Failed to Insert MediaInformation to DB");
+
+ MediaContentType type;
+ MediaInformation res;
+ Interop.MediaInformation.GetMediaType(mediaInformationHandle, out type);
+ if (type == MediaContentType.Image)
+ {
+ Interop.ImageInformation.SafeImageInformationHandle imageInfo;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetImage(mediaInformationHandle.DangerousGetHandle(), out imageInfo), "Failed to get image information");
+
+ res = new ImageInformation(imageInfo, mediaInformationHandle);
+ }
+ else if ((type == MediaContentType.Music) || (type == MediaContentType.Sound))
+ {
+ Interop.AudioInformation.SafeAudioInformationHandle audioInfo;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetAudio(mediaInformationHandle.DangerousGetHandle(), out audioInfo), "Failed to get audio information");
+
+ res = new AudioInformation(audioInfo, mediaInformationHandle);
+ }
+ else if (type == MediaContentType.Video)
+ {
+ Interop.VideoInformation.SafeVideoInformationHandle videoInfo;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetVideo(mediaInformationHandle.DangerousGetHandle(), out videoInfo), "Failed to get video information");
+
+ res = new VideoInformation(videoInfo, mediaInformationHandle);
+ }
+ else
+ {
+ res = new MediaInformation(mediaInformationHandle);
+ }
+
+ return res;
+ }
+
+ /// <summary>
+ /// Requests to scan a media folder, asynchronously.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="folderPath">The folder path</param>
+ /// <param name="recursive">Indicate sif the folder is to recursively scanned. Default value: true</param>
+ /// <remarks>
+ /// This function requests to scan a media folder to the media server with given completed callback function.
+ /// The sub folders are also scanned,if there are sub folders in that folder.
+ /// If any folder must not be scanned, a blank file ".scan_ignore" has to be created in that folder.
+ /// </remarks>
+ /// <returns>Task with scanning result</returns>
+ public static Task<MediaContentError> ScanFolderAsync(string folderPath, bool recursive = true)
+ {
+ var task = new TaskCompletionSource<MediaContentError>();
+
+ Interop.Content.MediaScanCompletedCallback scanCompleted = (MediaContentError scanResult, IntPtr data) =>
+ {
+ MediaContentValidator.ThrowIfError(scanResult, "Failed to scan");
+ task.SetResult(scanResult);
+ };
+
+ MediaContentValidator.ThrowIfError(
+ Interop.Content.ScanFolder(folderPath, recursive, scanCompleted, IntPtr.Zero), "Failed to scan");
+
+ return task.Task;
+ }
+
+ internal static Interop.Content.MediaScanCompletedCallback scanCompletedWithToken = null;
+ internal static Object l = new Object();
+ /// <summary>
+ /// Requests to scan a media folder, asynchronously.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="folderPath">The folder path</param>
+ /// <param name="cancellationToken">Cancellation token required to cancel the current scan</param>
+ /// <param name="recursive">Indicate sif the folder is to recursively scanned. Default value: true</param>
+ /// <remarks>
+ /// This function requests to scan a media folder to the media server with given completed callback function.
+ /// The sub folders are also scanned,if there are sub folders in that folder.
+ /// If any folder must not be scanned, a blank file ".scan_ignore" has to be created in that folder.
+ /// </remarks>
+ /// <returns>Task with scanning result</returns>
+ public static Task ScanFolderAsync(string folderPath, CancellationToken cancellationToken, bool recursive = true)
+ {
+ var task = new TaskCompletionSource<int>();
+ bool taskCompleted = false;
+
+ cancellationToken.Register(() =>
+ {
+ lock (l)
+ {
+ if (!taskCompleted)
+ {
+ taskCompleted = true;
+ MediaContentValidator.ThrowIfError(
+ Interop.Content.CancelScanFolder(folderPath), "Failed CancelScanFolder");
+
+ task.SetCanceled();
+ }
+ }
+ });
+ scanCompletedWithToken = (MediaContentError scanResult, IntPtr data) =>
+ {
+ lock (l)
+ {
+ if (!taskCompleted)
+ {
+ taskCompleted = true;
+ MediaContentValidator.ThrowIfError(scanResult, "Failed scan");
+ task.SetResult((int)scanResult);
+ }
+ }
+ };
+
+ MediaContentValidator.ThrowIfError(
+ Interop.Content.ScanFolder(folderPath, recursive, scanCompletedWithToken, IntPtr.Zero), "Failed to scan");
+
+ return task.Task;
+
+ }
+
+ /// <summary>
+ /// Inserts media files into the media database, asynchronously.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="filePaths">The path array to the media files</param>
+ /// <returns>
+ /// Task with the result of batch insertion
+ /// </returns>
+ public static Task AddMediaInformationBatchAsync(IEnumerable<string> filePaths)
+ {
+ var task = new TaskCompletionSource<int>();
+ string[] paths = ((List<string>)filePaths).ToArray();
+ Interop.MediaInformation.MediaInsertCompletedCallback callback = (MediaContentError error, IntPtr userData) =>
+ {
+ MediaContentValidator.ThrowIfError(error, "Failed to batch insert");
+ task.SetResult((int)error);
+ };
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.BatchInsert(paths, paths.Length, callback, IntPtr.Zero), "Failed to add batch media");
+
+ return task.Task;
+ }
+
+ /// <summary>
+ /// Inserts the burst shot images into the media database, asynchronously.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="filePaths">The path array to the burst shot images</param>
+ /// <returns>
+ /// Task with the result of the burstshot insertion
+ /// </returns>
+ public static Task AddBurstShotImagesAsync(IEnumerable<string> filePaths)
+ {
+ var task = new TaskCompletionSource<int>();
+ string[] paths = ((List<string>)filePaths).ToArray();
+ Interop.MediaInformation.MediaInsertBurstShotCompletedCallback callback = (MediaContentError error, IntPtr userData) =>
+ {
+ MediaContentValidator.ThrowIfError(error, "Failed to add burstshot");
+ task.SetResult((int)error);
+ };
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.BurstShotInsert(paths, paths.Length, callback, IntPtr.Zero), "Failed to add burst shots to db");
+
+ return task.Task;
+ }
+
+ /// <summary>
+ /// Deletes media files from the media database. The media files for deletion can be specified as a condition in a filter.
+ /// This function deletes the media items from the content storage.Normally, deleting media files in the database are done automatically by the media server,
+ /// without calling this function.This function is only called when the media server is busy and user needs to get quick result of deleting.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="filter">The content filter to which media will be matched</param>
+ public static void RemoveMediaInformationBatch(ContentFilter filter)
+ {
+ IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.BatchDelete(handle), "Failed to remove items");
+ }
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/FaceRect.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/FaceRect.cs
new file mode 100755
index 0000000..93298a9
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/FaceRect.cs
@@ -0,0 +1,59 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+
+namespace Tizen.Content.MediaContent
+{
+ /// <summary>
+ /// FaceRect represents a rectangle dimension to create a Face in an image.
+ /// It is used to create or tag a MediaFace in an image file.
+ /// </summary>
+ public class FaceRect
+ {
+ public FaceRect(int x, int y, int width, int height)
+ {
+ X = x;
+ Y = y;
+ Width = width;
+ Height = height;
+ }
+
+ /// <summary>
+ /// X coordinate of the FaceRect
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public readonly int X;
+
+ /// <summary>
+ /// Y coordinate of the FaceRect
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public readonly int Y;
+
+ /// <summary>
+ /// Width of the FaceRect
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public readonly int Width;
+
+ /// <summary>
+ /// Height of the FaceRect
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public readonly int Height;
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Group.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Group.cs
new file mode 100755
index 0000000..d037f3b
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Group.cs
@@ -0,0 +1,137 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Tizen.Content.MediaContent
+{
+ /// <summary>
+ /// A Media Group represents logical grouping of media files with respect to their group name.
+ /// It is also used for filtering media items.
+ /// </summary>
+ public class Group : ContentCollection
+ {
+ private readonly string _groupName;
+ private readonly MediaGroupType _groupType;
+ private bool _disposedValue = false;
+
+ /// <summary>
+ /// The name of the media group
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Name
+ {
+ get { return _groupName; }
+ }
+
+ internal Group(string name, MediaGroupType groupType)
+ {
+ _groupName = name;
+ _groupType = groupType;
+ }
+
+ public override void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ _disposedValue = true;
+ }
+ }
+
+ /// <summary>
+ /// Gets the count of the media info for the given media group present in the media database.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="filter">ContentFilter used to match media content from the media database.</param>
+ /// <returns>The number of media contents matching the filter passed</returns>
+ public override int GetMediaInformationCount(ContentFilter filter)
+ {
+ int mediaCount = 0;
+ IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
+ MediaContentValidator.ThrowIfError(
+ Interop.Group.GetMediaCountFromDb(Name, _groupType, handle, out mediaCount), "Failed to GetMediaCountFromDb");
+
+ return mediaCount;
+ }
+
+
+ /// <summary>
+ /// Iterates through the media files with an optional filter in the given group from the media database.
+ /// This function gets all media files associated with the given group and meeting desired filter option.
+ /// If NULL is passed to the filter, no filtering is applied.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="filter">ContentFilter used to match media content from the media database.</param>
+ /// <returns>List of content media items matching the passed filter</returns>
+ public override IEnumerable<MediaInformation> GetMediaInformations(ContentFilter filter)
+ {
+ List<MediaInformation> mediaContents = new List<MediaInformation>();
+ IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
+ Interop.Group.MediaInfoCallback callback = (IntPtr mediaHandle, IntPtr data) =>
+ {
+ Interop.MediaInformation.SafeMediaInformationHandle newHandle;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.Clone(out newHandle, mediaHandle), "Failed to clone MediaInformation instance");
+
+ MediaContentType type;
+ Interop.MediaInformation.GetMediaType(newHandle, out type);
+ if (type == MediaContentType.Image)
+ {
+ Interop.ImageInformation.SafeImageInformationHandle imageInfo;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetImage(mediaHandle, out imageInfo), "Failed to get image information");
+
+ mediaContents.Add(new ImageInformation(imageInfo, newHandle));
+ }
+ else if ((type == MediaContentType.Music) || (type == MediaContentType.Sound))
+ {
+ Interop.AudioInformation.SafeAudioInformationHandle audioInfo;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetAudio(mediaHandle, out audioInfo), "Failed to get audio information");
+
+ mediaContents.Add(new AudioInformation(audioInfo, newHandle));
+ }
+ else if (type == MediaContentType.Video)
+ {
+ Interop.VideoInformation.SafeVideoInformationHandle videoInfo;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetVideo(mediaHandle, out videoInfo), "Failed to get video information");
+
+ mediaContents.Add(new VideoInformation(videoInfo, newHandle));
+ }
+ else if (type == MediaContentType.Others)
+ {
+ mediaContents.Add(new MediaInformation(newHandle));
+ }
+
+ return true;
+ };
+ MediaContentValidator.ThrowIfError(
+ Interop.Group.ForeachMediaFromDb(Name, _groupType, handle, callback, IntPtr.Zero), "Failed to get media information for the group");
+
+ return mediaContents;
+ }
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ImageInformation.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ImageInformation.cs
new file mode 100755
index 0000000..e6922d3
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ImageInformation.cs
@@ -0,0 +1,347 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using System.Collections.ObjectModel;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Content.MediaContent
+{
+ /// <summary>
+ /// ImageContent class API gives the information related to the image media stored in the device</summary>
+ public class ImageInformation : MediaInformation
+ {
+ private readonly Interop.ImageInformation.SafeImageInformationHandle _handle;
+
+ /// <summary>
+ /// Gets the id of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string MediaId
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.ImageInformation.GetMediaId(_handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the image width in pixels.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Width
+ {
+ get
+ {
+ int width = 0;
+ MediaContentValidator.ThrowIfError(
+ Interop.ImageInformation.GetWidth(_handle, out width), "Failed to get value");
+
+ return width;
+ }
+ }
+
+ /// <summary>
+ /// Gets the image height in pixels.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Height
+ {
+ get
+ {
+ int height = 0;
+ MediaContentValidator.ThrowIfError(
+ Interop.ImageInformation.GetHeight(_handle, out height), "Failed to get value");
+
+ return height;
+ }
+ }
+
+ /// <summary>
+ /// Image orientation.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public MediaContentOrientation Orientation
+ {
+ get
+ {
+ MediaContentOrientation orientation = MediaContentOrientation.NotAvailable;
+ MediaContentValidator.ThrowIfError(
+ Interop.ImageInformation.GetOrientation(_handle, out orientation), "Failed to get value");
+
+ return orientation;
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.ImageInformation.SetOrientation(_handle, value), "Failed to set value");
+ }
+ }
+
+ /// <summary>
+ /// Gets the image creation time in seconds, since the Epoch.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string TakenDate
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.ImageInformation.GetDateTaken(_handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the burst shot ID.
+ /// If BurstId is null, this is not a burst shot
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string BurstId
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.ImageInformation.GetBurstId(_handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the exposure time from exif.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string ExposureTime
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.ImageInformation.GetExposureTime(_handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the fnumber from exif.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public double FNumber
+ {
+ get
+ {
+ double fNumber = 0.0;
+ MediaContentValidator.ThrowIfError(
+ Interop.ImageInformation.GetFNumber(_handle, out fNumber), "Failed to get value");
+
+ return fNumber;
+ }
+ }
+
+ /// <summary>
+ /// Gets the iso from exif.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Iso
+ {
+ get
+ {
+ int iso = 0;
+ MediaContentValidator.ThrowIfError(
+ Interop.ImageInformation.GetISO(_handle, out iso), "Failed to get value");
+
+ return iso;
+ }
+ }
+
+ /// <summary>
+ /// Gets the model from exif.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Model
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.ImageInformation.GetModel(_handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Checks whether the media is a burst shot image.
+ /// The value is true if the media is a burst shot image,
+ /// otherwise false if the media is not a burst shot image.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool IsBurstShot
+ {
+ get
+ {
+ bool isBurst = false;
+ MediaContentValidator.ThrowIfError(
+ Interop.ImageInformation.IsBurstShot(_handle, out isBurst), "Failed to get value");
+
+ return isBurst;
+ }
+ }
+
+ /// <summary>
+ /// Iterates through the media faces with filter in the given media file from the media database.
+ /// If NULL is passed to the filter, no filtering is applied.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// Task to get all the MediaFaces </returns>
+ /// <param name="filter"> filter for the Tags</param>
+ public IEnumerable<MediaFace> GetMediaFaces(ContentFilter filter)
+ {
+ Collection<MediaFace> coll = new Collection<MediaFace>();
+
+ Interop.MediaInformation.MediaFaceCallback callback = (IntPtr faceHandle, IntPtr userData) =>
+ {
+ IntPtr newHandle = IntPtr.Zero;
+ MediaContentValidator.ThrowIfError(
+ Interop.Face.Clone(out newHandle, faceHandle), "Failed to clone Tag");
+
+ coll.Add(new MediaFace(newHandle));
+ return true;
+ };
+ IntPtr filterHandle = (filter != null) ? filter.Handle : IntPtr.Zero;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetAllFaces(MediaId, filterHandle, callback, IntPtr.Zero), "Failed to get value");
+
+ return coll;
+ }
+
+ /// <summary>
+ /// Gets the number of faces for the passed filter in the given media ID from the media database.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// int count</returns>
+ /// <param name="filter">The Filter for matching Face</param>
+ public int GetMediaFaceCount(ContentFilter filter)
+ {
+ int count = 0;
+ IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetFaceCount(MediaId, handle, out count), "Failed to get value");
+
+ return count;
+ }
+
+
+ /// <summary>
+ /// Inserts a MediaFace item to the media database
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="image">The image on which face is to be added</param>
+ /// <param name="rect">The dimensions of the face</param>
+ /// <returns>The MediaFace instance</returns>
+ public MediaFace AddFace(ImageInformation image, FaceRect rect)
+ {
+ MediaFace face = new MediaFace(image, rect);
+ ContentManager.Database.Insert(face);
+ return face;
+ }
+
+ /// <summary>
+ /// Deletes the MediaFace from the media database.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="face">The face instance to be deleted</param>
+ public void DeleteFace(MediaFace face)
+ {
+ ContentManager.Database.Delete(face);
+ }
+
+ /// <summary>
+ /// Updates the MediaFace in the media database
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="face">The MediaFace object to be updated</param>
+ public void UpdateFace(MediaFace face)
+ {
+ ContentManager.Database.Update(face);
+ }
+
+ internal IntPtr ImageHandle
+ {
+ get
+ {
+ return _handle.DangerousGetHandle();
+ }
+ }
+
+ internal ImageInformation(Interop.ImageInformation.SafeImageInformationHandle handle, Interop.MediaInformation.SafeMediaInformationHandle mediaInformationHandle)
+ : base(mediaInformationHandle)
+ {
+ _handle = handle;
+ }
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaBookmark.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaBookmark.cs
new file mode 100755
index 0000000..07e14bb
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaBookmark.cs
@@ -0,0 +1,129 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Content.MediaContent
+{
+ /// <summary>
+ /// A MediaBookmark allows you to mark interesting moment in a media(video and audio) to enable fast searching.
+ /// The MediaBookmark Information API provides functions to get information about bookmarks associated with video and audio items.
+ /// </summary>
+ public class MediaBookmark : IDisposable
+ {
+ private IntPtr _bookmarkHandle = IntPtr.Zero;
+ private bool _disposedValue = false;
+
+ private IntPtr Handle
+ {
+ get
+ {
+ if (_bookmarkHandle == IntPtr.Zero)
+ {
+ throw new ObjectDisposedException(nameof(MediaBookmark));
+ }
+
+ return _bookmarkHandle;
+ }
+ }
+ internal MediaBookmark(IntPtr handle)
+ {
+ _bookmarkHandle = handle;
+ }
+
+ ~MediaBookmark()
+ {
+ Dispose(false);
+ }
+ /// <summary>
+ /// The media bookmark ID
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Id
+ {
+ get
+ {
+ int id;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaBookmark.GetBookmarkId(Handle, out id), "Failed to get bookmark id");
+
+ return id;
+ }
+ }
+
+ /// <summary>
+ /// The thumbnail path of media bookmark
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string ThumbnailPath
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaBookmark.GetThumbnailPath(Handle, out val), "Failed to get bookmark thumbnail");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The bookmark time offset (in milliseconds)
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public uint Offset
+ {
+ get
+ {
+ uint offset;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaBookmark.GetMarkedTime(Handle, out offset), "Failed to get bookmarked time");
+
+ return offset;
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ if (_bookmarkHandle != IntPtr.Zero)
+ {
+ Interop.MediaBookmark.Destroy(_bookmarkHandle);
+ _bookmarkHandle = IntPtr.Zero;
+ }
+
+ _disposedValue = true;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaContentEnums.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaContentEnums.cs
new file mode 100755
index 0000000..2c59329
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaContentEnums.cs
@@ -0,0 +1,411 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+
+namespace Tizen.Content.MediaContent
+{
+ /// <summary>
+ /// Enumeration for ordering
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum ContentOrder
+ {
+ /// <summary>
+ /// Ascending order
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Asc,
+ /// <summary>
+ /// Descending order
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Desc
+ }
+
+ /// <summary>
+ /// Enumeration for collations.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum ContentCollation
+ {
+ /// <summary>
+ /// Default collation BINARY
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Default,
+ /// <summary>
+ /// Collation NOCASE, not case sensitive
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Nocase,
+ /// <summary>
+ /// Collation RTRIM, trailing space characters are ignored
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Rtim,
+ /// <summary>
+ /// Collation LOCALIZATION, NOCASE also applied
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Localized
+ }
+
+ /// <summary>
+ /// Enumeration for a media group.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum MediaGroupType
+ {
+ /// <summary>
+ /// Media group ID for display name
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ DisplayName,
+ /// <summary>
+ /// Media group ID for a media type
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Type,
+ /// <summary>
+ /// Media group ID for a mime type
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ MimeType,
+ /// <summary>
+ /// Media group ID for content size
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Size,
+ /// <summary>
+ /// Media group ID for the added time
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ AddedTime,
+ /// <summary>
+ /// Media group ID for the modified time
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ ModifiedTime,
+ /// <summary>
+ /// Media group ID for a content title
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Title,
+ /// <summary>
+ /// Media group ID for an artist
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Artist,
+ /// <summary>
+ /// Media group ID for an album artist
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ AlbumArtist,
+ /// <summary>
+ /// Media group ID for a genre
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Genre,
+ /// <summary>
+ /// Media group ID for a composer
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Composer,
+ /// <summary>
+ /// Media group ID for a year
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Year,
+ /// <summary>
+ /// Media group ID for the recorded date
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ RecordedDate,
+ /// <summary>
+ /// Media group ID for the copyright
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Copyright,
+ /// <summary>
+ /// Media group ID for a track number
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Tracknum,
+ /// <summary>
+ /// Media group ID for a description
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Description,
+ /// <summary>
+ /// Media group ID for the longitude
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Longitude,
+ /// <summary>
+ /// Media group ID for the latitude
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Latitude,
+ /// <summary>
+ /// Media group ID for the altitude
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Altitude,
+ /// <summary>
+ /// Media group ID for the burst shot
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ BurstImage,
+ /// <summary>
+ /// Media group ID for a rating
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Rating,
+ /// <summary>
+ /// Media group ID for an author
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Author,
+ /// <summary>
+ /// Media group ID for a provide
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Provider,
+ /// <summary>
+ /// Media group ID for the content name
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ ContentName,
+ /// <summary>
+ /// Media group ID for a category
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Category,
+ /// <summary>
+ /// Media group ID for a location tag
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ LocationTag,
+ /// <summary>
+ /// Media group ID for an age rating
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ AgeRating,
+ /// <summary>
+ /// Media group ID for a keyword
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Keyword,
+ /// <summary>
+ /// Media group ID for the weather
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Weather,
+ /// <summary>
+ /// Invalid media group ID
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Max
+ }
+
+ /// <summary>
+ /// Enum to give the type of storage.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum ContentStorageType : int
+ {
+ /// <summary>
+ /// The device's internal storage
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Internal = 0,
+ /// <summary>
+ /// The device's external storage like sd card
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ External = 1,
+ /// <summary>
+ /// The external USB storage
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ ExternalUSB = 2
+ };
+
+ /// <summary>
+ /// Enums for media database update type
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum MediaContentDBUpdateType
+ {
+ /// <summary>
+ /// Updating the database with inserts.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Insert,
+ /// <summary>
+ /// Updating the database with removes.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Delete,
+ /// <summary>
+ /// Updating the database with updates.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Update
+ }
+
+ /// <summary>
+ /// Enums for the type of item updated in media database
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum MediaContentUpdateItemType
+ {
+ /// <summary>
+ /// The file information is updated.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ File,
+ /// <summary>
+ /// The folder information and the file information included in the folder are updated.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Directory
+ }
+
+ /// <summary>
+ /// Enums for content collection types
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum ContentCollectionType
+ {
+ /// <summary>
+ ///Content Collection type folder
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Folder,
+ /// <summary>
+ ///Content Collection type storage
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Storage,
+ /// <summary>
+ /// Content Collection type album
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Album,
+ /// <summary>
+ ///Content Collection type playlist
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ PlayList,
+ /// <summary>
+ ///Content Collection type tag
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Tag,
+ /// <summary>
+ ///Content Collection type group
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Group
+ }
+ /// <summary>
+ /// Enum to give the type of media information.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum MediaContentType : int
+ {
+ /// <summary>
+ /// The type of an image.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Image = 0,
+ /// <summary>
+ /// The type of a video.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Video = 1,
+ /// <summary>
+ /// The type of sound.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Sound = 2,
+ /// <summary>
+ /// The type of music.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Music = 3,
+ /// <summary>
+ /// The type of other.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Others = 4
+ };
+
+ /// <summary>
+ /// Enum to give the orientation type of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum MediaContentOrientation : int
+ {
+ /// <summary>
+ /// Not available.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ NotAvailable = 0,
+ /// <summary>
+ /// Normal.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Normal = 1,
+ /// <summary>
+ /// Flip horizontal.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ HFlip = 2,
+ /// <summary>
+ /// Rotate 180 degrees.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Rot180 = 3,
+ /// <summary>
+ /// Flip vertical.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ VFlip = 4,
+ /// <summary>
+ /// Transpose.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Transpose = 5,
+ /// <summary>
+ /// Rotate 90 degrees.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Rot90 = 6,
+ /// <summary>
+ /// Transverse.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Transverse = 7,
+ /// <summary>
+ /// Rotate 270 degrees.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Rot270 = 8
+ };
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaContentError.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaContentError.cs
new file mode 100755
index 0000000..421c370
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaContentError.cs
@@ -0,0 +1,79 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+using System;
+using System.IO;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Content.MediaContent
+{
+ /// <summary>
+ /// Enumeration for media content's error code
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks><paramref name="NotSupported"/> error occurs when the device does not support the function.</remarks>
+ public enum MediaContentError
+ {
+ None = ErrorCode.None,
+ InvalidParameter = ErrorCode.InvalidParameter,
+ OutOfMemory = ErrorCode.OutOfMemory,
+ InvalidOperation = ErrorCode.InvalidOperation,
+ FileNoSpaceOnDevice = ErrorCode.FileNoSpaceOnDevice,
+ PermissionDenied = ErrorCode.PermissionDenied,
+ TizenMediaContentError = -0x01610000,
+ DatabaseFailed = TizenMediaContentError | 0x01,
+ DatabaseBusy = TizenMediaContentError | 0x02,
+ NetworkFailed = TizenMediaContentError | 0x03,
+ UnsupportedContent = TizenMediaContentError | 0x04,
+ NotSupported = ErrorCode.NotSupported,
+ }
+
+ internal class MediaContentValidator
+ {
+ internal const string LogTag = "Tizen.Content.MediaContent";
+
+ internal static void ThrowIfError(MediaContentError err, string msg)
+ {
+ switch (err)
+ {
+ case MediaContentError.InvalidParameter:
+ throw new ArgumentException(msg);
+ case MediaContentError.OutOfMemory:
+ throw new OutOfMemoryException(msg);
+ case MediaContentError.InvalidOperation:
+ throw new InvalidOperationException(msg);
+ case MediaContentError.FileNoSpaceOnDevice:
+ throw new IOException(msg);
+ case MediaContentError.PermissionDenied:
+ throw new UnauthorizedAccessException(msg);
+ case MediaContentError.DatabaseFailed:
+ throw new InvalidOperationException("[DB Failed]" + msg);
+ case MediaContentError.DatabaseBusy:
+ throw new InvalidOperationException("[DB Busy]" + msg);
+ case MediaContentError.NetworkFailed:
+ throw new InvalidOperationException("[Network Error]" + msg);
+ case MediaContentError.UnsupportedContent:
+ throw new PlatformNotSupportedException(msg);
+ }
+ }
+
+ internal static string CheckString(string value)
+ {
+ return (value != null) ? value : "";
+ }
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaFace.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaFace.cs
new file mode 100755
index 0000000..134ab1f
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaFace.cs
@@ -0,0 +1,226 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Content.MediaContent
+{
+ /// <summary>
+ /// The Media Face Information API provides functions to manage the face information in the image files.
+ /// </summary>
+ public class MediaFace : IDisposable
+ {
+ private IntPtr _faceHandle = IntPtr.Zero;
+ private bool _disposedValue = false;
+ internal IntPtr Handle
+ {
+ get
+ {
+ if (_faceHandle == IntPtr.Zero)
+ {
+ throw new ObjectDisposedException(nameof(MediaFace));
+ }
+
+ return _faceHandle;
+ }
+ }
+
+
+ internal MediaFace(IntPtr handle)
+ {
+ _faceHandle = handle;
+ }
+
+ /// <summary>
+ /// Create Face for Given Image
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="image">
+ ///image item through which FaceRect has to be tagged.
+ ///</param>
+ ///<param name="rect">Position about the detacted face in the media</param>
+ internal MediaFace(MediaInformation image, FaceRect rect)
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Face.Create(image.MediaId, out _faceHandle), "Failed to create MediaFace");
+
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Face.SetFaceRect(Handle, rect.X, rect.Y, rect.Width, rect.Height), "Failed to set Rect to MediaFace");
+ }
+ catch (Exception)
+ {
+ Interop.Face.Destroy(_faceHandle);
+ throw;
+ }
+ }
+
+ ~MediaFace()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// The Media Face Information API provides functions to manage the face information in the image files.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public FaceRect Rect
+ {
+ get
+ {
+ int x;
+ int y;
+ int width;
+ int height;
+ MediaContentValidator.ThrowIfError(
+ Interop.Face.GetFaceRect(Handle, out x, out y, out width, out height), "Failed to get Rect for the Face");
+
+ return new FaceRect(x, y, width, height);
+ }
+
+ set
+ {
+ FaceRect rect = (FaceRect)value;
+ MediaContentValidator.ThrowIfError(
+ Interop.Face.SetFaceRect(Handle, rect.X, rect.Y, rect.Width, rect.Height), "Failed to set Rect for the Face");
+ }
+ }
+
+ /// <summary>
+ /// Face id.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Id
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Face.GetFaceId(Handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Media uuid from the face
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string MediaInformationId
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Face.GetMediaId(Handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+ /// <summary>
+ /// Tag name for the MediaFace.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Tag
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Face.GetTag(Handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Face.SetTag(Handle, value), "Failed to set value");
+ }
+ }
+
+ /// <summary>
+ /// Orientation Value for the face
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public MediaContentOrientation Orientation
+ {
+ get
+ {
+ int orientation;
+ MediaContentValidator.ThrowIfError(
+ Interop.Face.GetOrientation(Handle, out orientation), "Failed to value");
+
+ return (MediaContentOrientation)orientation;
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Face.SetOrientation(Handle, (int)value), "Failed to set value");
+ }
+ }
+
+ /// <summary>
+ /// Dispose API for closing the internal resources.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ if (_faceHandle != IntPtr.Zero)
+ {
+ Interop.Face.Destroy(_faceHandle);
+ _faceHandle = IntPtr.Zero;
+ }
+
+ _disposedValue = true;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaFolder.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaFolder.cs
new file mode 100755
index 0000000..af120ca
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaFolder.cs
@@ -0,0 +1,330 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+
+namespace Tizen.Content.MediaContent
+{
+ /// <summary>
+ /// A Folder is used to organize media content files i.e. image, audio, video files, in the physical storage of the device.
+ /// The Media Folder API provides functions to get basic information about existing folders e.g. folder name, path and storage type.
+ /// It also provides functions to get information related to media items present in the folder.
+ /// </summary>
+ public class MediaFolder : ContentCollection
+ {
+ private IntPtr _folderHandle = IntPtr.Zero;
+ private bool _disposedValue = false;
+ internal IntPtr Handle
+ {
+ get
+ {
+ if (_folderHandle == IntPtr.Zero)
+ {
+ throw new ObjectDisposedException(nameof(MediaFolder));
+ }
+
+ return _folderHandle;
+ }
+ }
+ /// <summary>
+ /// The ID of the media folder. For each MediaFolder this id is unique.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Id
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Folder.GetFolderId(Handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// ParentId of the MediaFolder that is the ID of the upper media folder (parent folder).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string ParentId
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Folder.GetParentFolderId(Handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The path of the media folder
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string FolderPath
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Folder.GetPath(Handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The name of the media folder
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Name
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Folder.GetName(Handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Folder.SetName(Handle, value), "Failed to set value");
+ }
+ }
+
+ /// <summary>
+ /// The storage type of the media folder.
+ /// Storage types give information about the location of storage like Internal memory, USB or External Storage etc...
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ContentStorageType StorageType
+ {
+ get
+ {
+ ContentStorageType type;
+ MediaContentValidator.ThrowIfError(
+ Interop.Folder.GetStorageType(Handle, out type), "Failed to get value");
+
+ return type;
+ }
+ }
+
+ /// <summary>
+ /// The storage id of the media folder
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string StorageId
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Folder.GetStorageId(Handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The modified date of the media folder
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public DateTime ModifiedTime
+ {
+ get
+ {
+ DateTime date;
+ MediaContentValidator.ThrowIfError(
+ Interop.Folder.GetModifiedTime(Handle, out date), "Failed to get value");
+
+ return date;
+ }
+ }
+
+ /// <summary>
+ /// The folder order value. Get/Set the folder viewing order.
+ /// Default Order value is zero.
+ /// If you set the order value for each folder, you can sort in ascending or descending order as the set order values using the filter.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Order
+ {
+ get
+ {
+ int order;
+ MediaContentValidator.ThrowIfError(
+ Interop.Folder.GetOrder(Handle, out order), "Failed to get value");
+
+ return order;
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Folder.SetOrder(Handle, value), "Failed to set value");
+ }
+ }
+
+ internal MediaFolder(IntPtr handle)
+ {
+ _folderHandle = handle;
+ }
+
+ /// <summary>
+ /// Gets the count of media files for the passed filter in the given folder from the media database.
+ /// If NULL is passed to the filter, no filtering is applied.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="filter">ContentFilter used to match media content from teh media database.</param>
+ /// <returns>The number of media contents matching the filter passed</returns>
+ public override int GetMediaInformationCount(ContentFilter filter)
+ {
+ int mediaCount;
+ IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
+ MediaContentValidator.ThrowIfError(
+ Interop.Folder.GetMediaCountFromDb(Id, handle, out mediaCount), "Failed to get count");
+
+ return mediaCount;
+ }
+
+ ~MediaFolder()
+ {
+ Dispose(false);
+ }
+
+ public override void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ if (_folderHandle != IntPtr.Zero)
+ {
+ Interop.Folder.Destroy(_folderHandle);
+ _folderHandle = IntPtr.Zero;
+ }
+
+ _disposedValue = true;
+ }
+ }
+
+ /// <summary>
+ /// Iterates through the media files with an filter in the given folder from the media database.
+ /// This function gets all media files associated with the given folder and meeting desired filter option.
+ /// If NULL is passed to the filter, no filtering is applied.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="filter">ContentFilter used to match media content from the media database.</param>
+ /// <returns>List of content media items matching the passed filter</returns>
+ public override IEnumerable<MediaInformation> GetMediaInformations(ContentFilter filter)
+ {
+ List<MediaInformation> mediaContents = new List<MediaInformation>();
+ IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
+
+ Interop.Folder.MediaInfoCallback callback = (IntPtr mediaHandle, IntPtr data) =>
+ {
+ Interop.MediaInformation.SafeMediaInformationHandle newHandle;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.Clone(out newHandle, mediaHandle), "Failed to clone");
+
+ MediaContentType type;
+ Interop.MediaInformation.GetMediaType(newHandle, out type);
+ if (type == MediaContentType.Image)
+ {
+ Interop.ImageInformation.SafeImageInformationHandle imageInfo;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetImage(mediaHandle, out imageInfo), "Failed to get image information");
+
+ mediaContents.Add(new ImageInformation(imageInfo, newHandle));
+ }
+ else if ((type == MediaContentType.Music) || (type == MediaContentType.Sound))
+ {
+ Interop.AudioInformation.SafeAudioInformationHandle audioInfo;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetAudio(mediaHandle, out audioInfo), "Failed to get audio information");
+
+ mediaContents.Add(new AudioInformation(audioInfo, newHandle));
+ }
+ else if (type == MediaContentType.Video)
+ {
+ Interop.VideoInformation.SafeVideoInformationHandle videoInfo;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetVideo(mediaHandle, out videoInfo), "Failed to get video information");
+
+ mediaContents.Add(new VideoInformation(videoInfo, newHandle));
+ }
+ else if (type == MediaContentType.Others)
+ {
+ mediaContents.Add(new MediaInformation(newHandle));
+ }
+
+ return true;
+ };
+ MediaContentValidator.ThrowIfError(
+ Interop.Folder.ForeachMediaFromDb(Id, handle, callback, IntPtr.Zero), "Failed to get information");
+
+ return mediaContents;
+ }
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaInformation.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaInformation.cs
new file mode 100755
index 0000000..49b1788
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaInformation.cs
@@ -0,0 +1,897 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Runtime.InteropServices;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Tizen.Content.MediaContent
+{
+ /// <summary>
+ /// MediaContent class API gives the information related to the media stored in the device</summary>
+ /// <remarks>
+ /// The API's provide the functionlity to insert, clone, delete, get the number and content of files from DB.
+ /// You can get and set properties and parameters such as storage type, provider, and category of media info,
+ /// handling with thumbnail and updating media info to DB.</remarks>
+ public class MediaInformation
+ {
+ private readonly Interop.MediaInformation.SafeMediaInformationHandle _handle;
+
+ /// <summary>
+ /// Gets the count of media tags for the passed filter in the given mediaId from the media database.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// int count</returns>
+ /// <param name="filter">The Filter for matching Tags</param>
+ public int GetTagCount(ContentFilter filter)
+ {
+ int count = 0;
+ IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetTagCount(MediaId, handle, out count), "Failed to get count");
+
+ return count;
+ }
+
+ /// <summary>
+ /// Moves the media info to the given destination path in the media database.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// void </returns>
+ /// <param name="destination">The Destination path</param>
+ public void Move(string destination)
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.MoveToDB(_handle, destination), "Failed to move");
+ }
+
+ /// <summary>
+ /// Refreshes the media metadata to the media database.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// void </returns>
+ public void Refresh()
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.RefreshMetadataToDB(MediaId), "Failed to refresh");
+ }
+
+ /// <summary>
+ /// Creates a thumbnail image for the given media, asynchronously
+ /// If a thumbnail already exists for the given media, then the path of thumbnail will be returned.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// Task for creation of Thumbnail </returns>
+ public Task<string> CreateThumbnailAsync()
+ {
+ var task = new TaskCompletionSource<string>();
+ Interop.MediaInformation.MediaThumbnailCompletedCallback thumbnailResult = (MediaContentError createResult, string path, IntPtr userData) =>
+ {
+ if (createResult != MediaContentError.None)
+ {
+ task.SetException(new InvalidOperationException("Failed to create thumbnail:" + createResult));
+ }
+
+ task.SetResult(path);
+ };
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.CreateThumbnail(_handle, thumbnailResult, IntPtr.Zero), "Failed to create thumbnail");
+
+ return task.Task;
+ }
+
+ /// <summary>
+ /// Creates a thumbnail image for the given media, asynchronously
+ /// which can be cancelled
+ /// If a thumbnail already exists for the given media, then the path of thumbnail will be returned.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="cancellationToken">Token to cancel the requested operation</param>
+ /// <returns>
+ /// Task for creation of Thumbnail
+ /// </returns>
+ public Task<string> CreateThumbnailAsync(CancellationToken cancellationToken)
+ {
+ var task = new TaskCompletionSource<string>();
+ cancellationToken.Register(() =>
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.CancelThumbnail(_handle), "Failed to cancel");
+
+ task.SetCanceled();
+ });
+
+ Interop.MediaInformation.MediaThumbnailCompletedCallback thumbnailResult = (MediaContentError createResult, string path, IntPtr userData) =>
+ {
+ if (createResult != MediaContentError.None)
+ {
+ task.SetException(new InvalidOperationException("Failed to create thumbnail:" + createResult));
+ }
+
+ task.SetResult(path);
+ };
+
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.CreateThumbnail(_handle, thumbnailResult, IntPtr.Zero), "Failed to create thumbnail");
+
+ return task.Task;
+ }
+
+ /// <summary>
+ /// Iterates through the media tag in the given media info from the media database.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// Task to get all the Tags </returns>
+ /// <param name="filter"> The filter for the Tags</param>
+ public IEnumerable<Tag> GetTags(ContentFilter filter)
+ {
+ Collection<Tag> coll = new Collection<Tag>();
+
+ IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
+ Interop.MediaInformation.MediaTagCallback tagsCallback = (IntPtr tagHandle, IntPtr userData) =>
+ {
+ IntPtr newHandle;
+ MediaContentValidator.ThrowIfError(
+ Interop.Tag.Clone(out newHandle, tagHandle), "Failed to clone");
+ coll.Add(new Tag(newHandle));
+
+ return true;
+ };
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetAllTags(MediaId, handle, tagsCallback, IntPtr.Zero), "Failed to get information");
+
+ return coll;
+ }
+
+ /// <summary>
+ /// Gets the ID of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public virtual string MediaId
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetMediaId(_handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the path to the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string FilePath
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetFilePath(_handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Name of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string DisplayName
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetDisplayName(_handle, out val), "Failed to get value");
+
+ return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.SetDisplayName(_handle, value), "failed to set value");
+ }
+ }
+
+ /// <summary>
+ /// Gets the content type of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public MediaContentType MediaType
+ {
+ get
+ {
+ MediaContentType contentType = MediaContentType.Others;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetMediaType(_handle, out contentType), "Failed to get value");
+
+ return contentType;
+ }
+ }
+
+ /// <summary>
+ /// Gets the MIME type from the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string MimeType
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetMimeType(_handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the media file size in bytes.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public long Size
+ {
+ get
+ {
+ long size;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetSize(_handle, out size), "Failed to get value");
+
+ return size;
+ }
+ }
+
+ /// <summary>
+ /// Addition time of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public DateTime AddedAt
+ {
+ get
+ {
+ int time;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetAddedTime(_handle, out time), "Failed to get value");
+
+ DateTime utc = DateTime.SpecifyKind(new DateTime(1970, 1, 1).AddSeconds(time), DateTimeKind.Utc);
+
+ return utc.ToLocalTime();
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.SetAddedTime(_handle, (int)value.ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds), "failed to set time");
+ }
+ }
+
+ /// <summary>
+ /// Gets the date of modification of media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public DateTime ModifiedAt
+ {
+ get
+ {
+ int time;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetModifiedTime(_handle, out time), "Failed to get value");
+
+ DateTime utc = DateTime.SpecifyKind(new DateTime(1970, 1, 1).AddSeconds(time), DateTimeKind.Utc);
+
+ return utc.ToLocalTime();
+ }
+ }
+
+ /// <summary>
+ /// Gets the timeline of media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public DateTime TimeLine
+ {
+ get
+ {
+ int time;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetTimeline(_handle, out time), "Failed to get value");
+
+ DateTime utc = DateTime.SpecifyKind(new DateTime(1970, 1, 1).AddSeconds(time), DateTimeKind.Utc);
+
+ return utc.ToLocalTime();
+ }
+ }
+
+ /// <summary>
+ /// Gets the thumbnail of media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string ThumbnailPath
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetThumbnailPath(_handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Description of media.
+ /// If the media info has no description, the property returns empty string.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Description
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetDescription(_handle, out val), "Failed to get value");
+
+ return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.SetDescription(_handle, value), "failed to set value");
+ }
+ }
+
+ /// <summary>
+ /// Longitude of media.
+ /// Default Value is 0.0.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public double Longitude
+ {
+ get
+ {
+ double longitude = 0.0;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetLongitude(_handle, out longitude), "Failed to get value");
+
+ return longitude;
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.SetLongitude(_handle, value), "failed to set value");
+ }
+ }
+
+ /// <summary>
+ /// Latitude of media.
+ /// Default Value is 0.0.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public double Latitude
+ {
+ get
+ {
+ double latitude = 0.0;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetLatitude(_handle, out latitude), "Failed to get value");
+
+ return latitude;
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.SetLatitude(_handle, value), "failed to set value");
+ }
+ }
+
+ /// <summary>
+ /// Altitude of media.
+ /// Default Value is 0.0.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public double Altitude
+ {
+ get
+ {
+ double altitude = 0.0;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetAltitude(_handle, out altitude), "Failed to get value");
+
+ return altitude;
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.SetAltitude(_handle, value), "failed to set value");
+ }
+ }
+
+ /// <summary>
+ /// Weather information of media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Weather
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetWeather(_handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.SetWeather(_handle, value), "failed to set value");
+ }
+ }
+
+ /// <summary>
+ /// Rating of media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Rating
+ {
+ get
+ {
+ int rating = 0;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetRating(_handle, out rating), "Failed to get value");
+ return rating;
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.SetRating(_handle, value), "failed to set value");
+ }
+ }
+
+ /// <summary>
+ /// Favorite status of media.
+ /// true if media info is set as favorite, otherwise false if media info is not set as favorite.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool IsFavourite
+ {
+ get
+ {
+ bool isFavourtite = false;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetFavorite(_handle, out isFavourtite), "Failed to get value");
+
+ return isFavourtite;
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.SetFavorite(_handle, value), "failed to set value");
+ }
+ }
+
+ /// <summary>
+ /// Author of media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Author
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetAuthor(_handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.SetAuthor(_handle, value), "failed to set value");
+ }
+ }
+
+ /// <summary>
+ /// Provider of media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Provider
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetProvider(_handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.SetProvider(_handle, value), "failed to set value");
+ }
+ }
+
+ /// <summary>
+ /// Content name of media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string ContentName
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetContentName(_handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.SetContentName(_handle, value), "failed to set value");
+ }
+ }
+
+ /// <summary>
+ /// Gets the title of media.
+ /// If the media content has no title, the property returns empty string.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Title
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetTitle(_handle, out val), "Failed to get value");
+
+ return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Category of media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Category
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetCategory(_handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.SetCategory(_handle, value), "failed to set value");
+ }
+ }
+
+ /// <summary>
+ /// location tag of media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string LocationTag
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetLocationTag(_handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.SetLocationTag(_handle, value), "failed to set value");
+ }
+ }
+
+ /// <summary>
+ /// Age Rating of media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string AgeRating
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetAgeRating(_handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.SetAgeRating(_handle, value), "Failed to set value");
+ }
+ }
+
+ /// <summary>
+ /// Keyword of media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Keyword
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetKeyword(_handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.SetKeyword(_handle, value), "failed to set value");
+ }
+ }
+
+ /// <summary>
+ /// Gets the storage id of media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string StorageId
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetStorageId(_handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Checks whether the media is protected via DRM.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool IsDrm
+ {
+ get
+ {
+ bool isDRM = false;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.IsDrm(_handle, out isDRM), "Failed to get value");
+
+ return isDRM;
+ }
+ }
+
+ /// <summary>
+ /// Gets the storage type of media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ContentStorageType StorageType
+ {
+ get
+ {
+ ContentStorageType storageType = ContentStorageType.Internal;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetStorageType(_handle, out storageType), "Failed to get value");
+
+ return storageType;
+ }
+ }
+
+ /// <summary>
+ /// Number which represents how many times given content has been played.
+ /// While Setting the played count, it will only be incremented by 1, the value provided will be ignored.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int PlayedCount
+ {
+ get
+ {
+ int playedCount = 0;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetPlayedCount(_handle, out playedCount), "Failed to get value");
+
+ return playedCount;
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.IncreasePlayedCount(_handle), "failed to set value");
+ }
+ }
+
+ /// <summary>
+ /// Content's latest played(opened) time of the media file.
+ /// for set the current time is automatically taken from the system, the value provided will be ignored.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public DateTime PlayedAt
+ {
+ get
+ {
+ int time;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetPlayedAt(_handle, out time), "Failed to get value");
+
+ DateTime utc = DateTime.SpecifyKind(new DateTime(1970, 1, 1).AddSeconds(time), DateTimeKind.Utc);
+
+ return utc.ToLocalTime();
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.SetPlayedAt(_handle), "failed to set value");
+ }
+ }
+
+ internal IntPtr MediaHandle
+ {
+ get
+ {
+ return _handle.DangerousGetHandle();
+ }
+ }
+
+ internal MediaInformation(Interop.MediaInformation.SafeMediaInformationHandle handle)
+ {
+ _handle = handle;
+ }
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/PlayList.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/PlayList.cs
new file mode 100755
index 0000000..e440707
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/PlayList.cs
@@ -0,0 +1,341 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+
+namespace Tizen.Content.MediaContent
+{
+ /// <summary>
+ /// The PlayList API provides functions to manage media playlists.
+ /// </summary>
+ /// <remarks>
+ /// A PlayList is a list of songs which can be played in some sequence i.e. sequential or shuffled order.
+ /// The Media PlayList API provides functions to insert, delete or updates a media playlist in the database.
+ /// </remarks>
+ public class PlayList : ContentCollection
+ {
+ private readonly IDictionary<string, int> _dictionary = new Dictionary<string, int>();
+ private IntPtr _playlistHandle = IntPtr.Zero;
+ internal IntPtr Handle
+ {
+ get
+ {
+ if (_playlistHandle == IntPtr.Zero)
+ {
+ throw new ObjectDisposedException(nameof(PlayList));
+ }
+
+ return _playlistHandle;
+ }
+
+ set
+ {
+ _playlistHandle = value;
+ }
+ }
+
+ private void RefreshPlaylistDictionary()
+ {
+ _dictionary.Clear();
+ Interop.Playlist.PlaylistMemberCallback callback = (int memberId, IntPtr mediaHandle, IntPtr data) =>
+ {
+ Interop.MediaInformation.SafeMediaInformationHandle newHandle;
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.Clone(out newHandle, mediaHandle), "Failed to clone media");
+
+ Interop.MediaInformation.GetMediaId(newHandle, out val);
+ _dictionary.Add(Marshal.PtrToStringAnsi(val), memberId);
+ return true;
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ };
+ MediaContentValidator.ThrowIfError(
+ Interop.Playlist.ForeachMediaFromDb(Id, IntPtr.Zero, callback, IntPtr.Zero), "Failed to get playlist items");
+ }
+
+ /// <summary>
+ /// The ID of the media playlist
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Id
+ {
+ get
+ {
+ int id;
+ MediaContentValidator.ThrowIfError(
+ Interop.Playlist.GetPlaylistId(Handle, out id), "Failed to get value");
+
+ return id;
+ }
+ }
+
+ internal string _playListName;
+ /// <summary>
+ /// The playlist name
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Name
+ {
+ get
+ {
+ return _playListName;
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Playlist.SetName(Handle, value), "Failed to set value");
+ _playListName = value;
+ }
+ }
+ /// <summary>
+ /// The path of the thumbnail
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string ThumbnailPath
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Playlist.GetThumbnailPath(Handle, out val), "Failed to get value");
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Playlist.SetThumbnailPath(Handle, value), "Failed to set value");
+ }
+ }
+
+ /// <summary>
+ /// The constructor to create a new playlist with the given name in the media database.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="name">The name of the inserted playlist</param>
+ public PlayList(string name)
+ {
+ _playListName = name;
+ }
+
+ internal PlayList(IntPtr handle)
+ {
+ _playlistHandle = handle;
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Playlist.GetName(handle, out val), "Failed to get value");
+ _playListName = Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+
+ /// <summary>
+ /// Adds a new media info to the playlist.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="mediaContent">The AudioContent obect to be added</param>
+ public void AddItem(MediaInformation mediaContent)
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Playlist.AddMedia(Handle, mediaContent.MediaId), "Failed to add item");
+ }
+
+ /// <summary>
+ /// Removes the playlist members related with the media from the given playlist.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="media">The AudioContent object to be removed</param>
+ public void RemoveItem(MediaInformation media)
+ {
+ int memberId = 0;
+ RefreshPlaylistDictionary();
+ _dictionary.TryGetValue(media.MediaId, out memberId);
+ MediaContentValidator.ThrowIfError(
+ Interop.Playlist.RemoveMedia(Handle, memberId), "Failed to remove item");
+ }
+
+ /// <summary>
+ /// Sets the playing order in the playlist.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="media">The playlist reference</param>
+ /// <param name="playOrder">The playing order</param>
+ public void SetPlayOrder(MediaInformation media, int playOrder)
+ {
+ int memberId;
+ RefreshPlaylistDictionary();
+ _dictionary.TryGetValue(media.MediaId, out memberId);
+ MediaContentValidator.ThrowIfError(
+ Interop.Playlist.SetPlayOrder(Handle, memberId, playOrder), "Failed to set play order");
+ }
+
+ /// <summary>
+ /// Gets the playing order in the playlist for the passed member id.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="media">The MediaInformation instance</param>
+ /// <returns>The number of play order</returns>
+ public int GetPlayOrder(MediaInformation media)
+ {
+ int playOrder;
+ int memberId;
+ RefreshPlaylistDictionary();
+ _dictionary.TryGetValue(media.MediaId, out memberId);
+ MediaContentValidator.ThrowIfError(
+ Interop.Playlist.GetPlayOrder(Handle, memberId, out playOrder), "Failed to get play order");
+
+ return playOrder;
+ }
+
+ /// <summary>
+ /// Imports the playlist from m3u playlist file.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="name">The name of the playlist to save</param>
+ /// <param name="filePath">The path to import the playlist file</param>
+ /// <returns>The imported PlayList object</returns>
+ public static PlayList Import(string name, string filePath)
+ {
+ PlayList playList = null;
+ IntPtr playlistHandle;
+
+ MediaContentValidator.ThrowIfError(
+ Interop.Playlist.ImportFromFile(name, filePath, out playlistHandle), "Failed to import");
+
+ playList = new PlayList(name);
+ playList.Handle = playlistHandle;
+ return playList;
+ }
+
+ /// <summary>
+ /// Exports the playlist to m3u playlist file.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="list">The playlist instance to export</param>
+ /// <param name="filePath">The path to save exported playlist</param>
+ /// <returns>path The path to export the playlist</returns>
+ public static void Export(PlayList list, string filePath)
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Playlist.ExportToFile(list.Handle, filePath), "Failed to export playlist:" + filePath);
+ }
+
+ /// <summary>
+ /// Gets the number of the media info for the given playlist present in the media database.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="filter">ContentFilter used to match media content from the media database.</param>
+ /// <returns>The number of media contents matching the filter passed</returns>
+ public override int GetMediaInformationCount(ContentFilter filter)
+ {
+ int mediaCount;
+ IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
+ MediaContentValidator.ThrowIfError(
+ Interop.Playlist.GetMediaCountFromDb(Id, handle, out mediaCount), "Failed to get media count");
+
+ return mediaCount;
+ }
+
+ public override void Dispose()
+ {
+ if (_playlistHandle != IntPtr.Zero)
+ {
+ Interop.Playlist.Destroy(_playlistHandle);
+ _playlistHandle = IntPtr.Zero;
+ }
+ }
+
+ /// <summary>
+ /// Iterates through the media files with an optional filter in the given audio playlist from the media database.
+ /// This function gets all media files associated with the given media playlist and meeting desired filter option.
+ /// If NULL is passed to the filter, no filtering is applied.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="filter">ContentFilter used to match media content from the media database.</param>
+ /// <returns>List of content media items matching the passed filter</returns>
+ public override IEnumerable<MediaInformation> GetMediaInformations(ContentFilter filter)
+ {
+ List<MediaInformation> mediaContents = new List<MediaInformation>();
+ IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
+ Interop.Playlist.PlaylistMemberCallback callback = (int memberId, IntPtr mediaHandle, IntPtr data) =>
+ {
+ Interop.MediaInformation.SafeMediaInformationHandle newHandle;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.Clone(out newHandle, mediaHandle), "Failed to clone media");
+
+ MediaContentType type;
+ Interop.MediaInformation.GetMediaType(newHandle, out type);
+ if (type == MediaContentType.Image)
+ {
+ Interop.ImageInformation.SafeImageInformationHandle imageInfo;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetImage(mediaHandle, out imageInfo), "Failed to get image information");
+
+ mediaContents.Add(new ImageInformation(imageInfo, newHandle));
+ }
+ else if ((type == MediaContentType.Music) || (type == MediaContentType.Sound))
+ {
+ Interop.AudioInformation.SafeAudioInformationHandle audioInfo;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetAudio(mediaHandle, out audioInfo), "Failed to get audio information");
+
+ mediaContents.Add(new AudioInformation(audioInfo, newHandle));
+ }
+ else if (type == MediaContentType.Video)
+ {
+ Interop.VideoInformation.SafeVideoInformationHandle videoInfo;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetVideo(mediaHandle, out videoInfo), "Failed to get video information");
+
+ mediaContents.Add(new VideoInformation(videoInfo, newHandle));
+ }
+ else if (type == MediaContentType.Others)
+ {
+ mediaContents.Add(new MediaInformation(newHandle));
+ }
+
+ return true;
+ };
+ MediaContentValidator.ThrowIfError(
+ Interop.Playlist.ForeachMediaFromDb(Id, handle, callback, IntPtr.Zero), "Failed to get media information");
+
+ return mediaContents;
+ }
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Storage.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Storage.cs
new file mode 100755
index 0000000..b6935ef
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Storage.cs
@@ -0,0 +1,219 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+
+namespace Tizen.Content.MediaContent
+{
+ /// <summary>
+ /// A Storage allows you to manage external storage.
+ /// The system generates the storage id when the external storage is added.And the system manages the media information in each of the storage by using storage id.
+ /// So you can get the information from the storage that you want to view.
+ /// </summary>
+ public class Storage : ContentCollection
+ {
+ private IntPtr _storageHandle = IntPtr.Zero;
+ private IntPtr Handle
+ {
+ get
+ {
+ if (_storageHandle == IntPtr.Zero)
+ {
+ throw new ObjectDisposedException(nameof(Storage));
+ }
+
+ return _storageHandle;
+ }
+ }
+ /// <summary>
+ /// The storage id of the media storage
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Id
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Storage.GetId(Handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The storage path of the media storage
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string StoragePath
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Storage.GetPath(Handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The storage name of the media storage
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Name
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Storage.GetName(Handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The storage type of the media storage
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ContentStorageType StorageType
+ {
+ get
+ {
+ ContentStorageType storageType;
+ MediaContentValidator.ThrowIfError(
+ Interop.Storage.GetType(Handle, out storageType), "Failed to get value");
+
+ return storageType;
+ }
+ }
+
+ internal Storage(IntPtr handle)
+ {
+ _storageHandle = handle;
+ }
+
+ /// <summary>
+ /// Gets the count of media files for the passed filter in the given storage from the media database.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="filter">ContentFilter used to match media content from the media database.</param>
+ /// <returns>The number of media contents matching the filter passed</returns>
+ public override int GetMediaInformationCount(ContentFilter filter)
+ {
+ int mediaCount;
+ IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
+ MediaContentValidator.ThrowIfError(
+ Interop.Storage.GetMediaCountFromDb(Id, handle, out mediaCount), "Failed to get count");
+
+ return mediaCount;
+ }
+
+ public override void Dispose()
+ {
+ if (_storageHandle != IntPtr.Zero)
+ {
+ Interop.Storage.Destroy(_storageHandle);
+ _storageHandle = IntPtr.Zero;
+ }
+ }
+
+ /// <summary>
+ /// Iterates through the media files with an optional filter in the given storage from the media database.
+ /// This function gets all media files associated with the given storage and meeting desired filter option.
+ /// If NULL is passed to the filter, no filtering is applied.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="filter">ContentFilter used to match media content from the media database.</param>
+ /// <returns>List of content media items matching the passed filter</returns>
+ public override IEnumerable<MediaInformation> GetMediaInformations(ContentFilter filter)
+ {
+ List<MediaInformation> mediaContents = new List<MediaInformation>();
+
+ IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
+ Interop.Storage.MediaInfoCallback callback = (IntPtr mediaHandle, IntPtr data) =>
+ {
+ Interop.MediaInformation.SafeMediaInformationHandle newHandle;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.Clone(out newHandle, mediaHandle), "Failed to clone media");
+
+ MediaContentType type;
+ Interop.MediaInformation.GetMediaType(newHandle, out type);
+ if (type == MediaContentType.Image)
+ {
+ Interop.ImageInformation.SafeImageInformationHandle imageInfo;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetImage(mediaHandle, out imageInfo), "Failed to get image information");
+
+ mediaContents.Add(new ImageInformation(imageInfo, newHandle));
+ }
+ else if ((type == MediaContentType.Music) || (type == MediaContentType.Sound))
+ {
+ Interop.AudioInformation.SafeAudioInformationHandle audioInfo;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetAudio(mediaHandle, out audioInfo), "Failed to get audio information");
+
+ mediaContents.Add(new AudioInformation(audioInfo, newHandle));
+ }
+ else if (type == MediaContentType.Video)
+ {
+ Interop.VideoInformation.SafeVideoInformationHandle videoInfo;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetVideo(mediaHandle, out videoInfo), "Failed to get video information");
+
+ mediaContents.Add(new VideoInformation(videoInfo, newHandle));
+ }
+ else if (type == MediaContentType.Others)
+ {
+ mediaContents.Add(new MediaInformation(newHandle));
+ }
+
+ return true;
+ };
+ MediaContentValidator.ThrowIfError(
+ Interop.Storage.ForeachMediaFromDb(Id, handle, callback, IntPtr.Zero), "Failed to get information");
+
+ return mediaContents;
+ }
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Tag.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Tag.cs
new file mode 100755
index 0000000..181b763
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Tag.cs
@@ -0,0 +1,217 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+
+namespace Tizen.Content.MediaContent
+{
+ /// <summary>
+ /// A Tag is a special piece of information that may be associated with media content items.
+ /// Tagging allows a user to organize large number of items into logical groups providing a simplified and faster way of accessing media content items.
+ /// </summary>
+ public class Tag : ContentCollection
+ {
+ private IntPtr _tagHandle = IntPtr.Zero;
+ private string _tagName = "";
+
+ internal IntPtr Handle
+ {
+ get
+ {
+ if (_tagHandle == IntPtr.Zero)
+ {
+ throw new ObjectDisposedException(nameof(Tag));
+ }
+
+ return _tagHandle;
+ }
+
+ set
+ {
+ _tagHandle = value;
+ }
+ }
+ /// <summary>
+ /// The ID of the media tag
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Id
+ {
+ get
+ {
+ int id;
+ MediaContentValidator.ThrowIfError(
+ Interop.Tag.GetTagId(Handle, out id), "Failed to get value");
+ return id;
+ }
+ }
+
+ /// <summary>
+ /// The name of the tag
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Name
+ {
+ get
+ {
+ return _tagName;
+ }
+
+ set
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Tag.SetName(Handle, value), "Failed to set value");
+ _tagName = value;
+ }
+ }
+
+ internal Tag(IntPtr tagHandle)
+ {
+ _tagHandle = tagHandle;
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Tag.GetName(Handle, out val), "Failed to get value");
+ _tagName = Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+
+ /// <summary>
+ /// Creates a Tag object which can be inserted to the media database using ContentManager:InsertToDatabaseAsync(ContentCollection)
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="tagName">The name of the media tag</param>
+ public Tag(string tagName)
+ {
+ _tagName = tagName;
+ }
+
+ /// <summary>
+ /// Adds a new media info to the tag.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="mediaContent">The media info which is added</param>
+ public void AddItem(MediaInformation mediaContent)
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Tag.AddMedia(Handle, mediaContent.MediaId), "Failed to add item");
+ }
+
+ /// <summary>
+ /// Removes the media info from the given tag.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="mediaContent">The media info which is removed</param>
+ public void RemoveItem(MediaInformation mediaContent)
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.Tag.RemoveMedia(Handle, mediaContent.MediaId), "Failed to remove item");
+ }
+
+ /// <summary>
+ /// Gets the number of media files for the passed filter in the given tag from the media database.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="filter">ContentFilter used to match media content from the media database.</param>
+ /// <returns>The number of media contents matching the filter passed</returns>
+ public override int GetMediaInformationCount(ContentFilter filter)
+ {
+ int mediaCount;
+ IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
+ MediaContentValidator.ThrowIfError(
+ Interop.Tag.GetMediaCountFromDb(Id, handle, out mediaCount), "Failed to get count");
+
+ return mediaCount;
+ }
+
+ public override void Dispose()
+ {
+ if (_tagHandle != IntPtr.Zero)
+ {
+ Interop.Tag.Destroy(_tagHandle);
+ _tagHandle = IntPtr.Zero;
+ }
+ }
+
+ /// <summary>
+ /// Iterates through media items for a given tag from the media database.
+ /// This function gets all media items associated with a given tag and meeting a desired filter.
+ /// If NULL is passed to the filter, no filtering is applied.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="filter">ContentFilter used to match media content from the media database.</param>
+ /// <returns>List of content media items matching the passed filter</returns>
+ public override IEnumerable<MediaInformation> GetMediaInformations(ContentFilter filter)
+ {
+ List<MediaInformation> mediaContents = new List<MediaInformation>();
+ IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
+
+ Interop.Tag.MediaInfoCallback callback = (IntPtr mediaHandle, IntPtr data) =>
+ {
+ Interop.MediaInformation.SafeMediaInformationHandle newHandle;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.Clone(out newHandle, mediaHandle), "Failed to clone media");
+
+ MediaContentType type;
+ Interop.MediaInformation.GetMediaType(newHandle, out type);
+ if (type == MediaContentType.Image)
+ {
+ Interop.ImageInformation.SafeImageInformationHandle imageInfo;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetImage(mediaHandle, out imageInfo), "Failed to get image information");
+
+ mediaContents.Add(new ImageInformation(imageInfo, newHandle));
+ }
+ else if ((type == MediaContentType.Music) || (type == MediaContentType.Sound))
+ {
+ Interop.AudioInformation.SafeAudioInformationHandle audioInfo;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetAudio(mediaHandle, out audioInfo), "Failed to get audio information");
+
+ mediaContents.Add(new AudioInformation(audioInfo, newHandle));
+ }
+ else if (type == MediaContentType.Video)
+ {
+ Interop.VideoInformation.SafeVideoInformationHandle videoInfo;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetVideo(mediaHandle, out videoInfo), "Failed to get video information");
+
+ mediaContents.Add(new VideoInformation(videoInfo, newHandle));
+ }
+ else if (type == MediaContentType.Others)
+ {
+ mediaContents.Add(new MediaInformation(newHandle));
+ }
+
+ return true;
+ };
+
+ MediaContentValidator.ThrowIfError(
+ Interop.Tag.ForeachMediaFromDb(Id, handle, callback, IntPtr.Zero), "Failed to get information");
+
+ return mediaContents;
+ }
+ }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/VideoInformation.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/VideoInformation.cs
new file mode 100755
index 0000000..da48d28
--- /dev/null
+++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/VideoInformation.cs
@@ -0,0 +1,431 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+using System.Collections.ObjectModel;
+
+namespace Tizen.Content.MediaContent
+{
+ /// <summary>
+ /// VideoContent class API gives the information related to the image media stored in the device
+ /// </summary>
+ public class VideoInformation : MediaInformation
+ {
+ /// <summary>
+ /// Gets the ID of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string MediaId
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.VideoInformation.GetMediaId(_handle, out val), "Failed to get value");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the album name.
+ /// If the media content has no album information, the property returns empty string.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Album
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.VideoInformation.GetAlbum(_handle, out val), "Failed to get value");
+
+ return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the artist name.
+ /// If the media content has no artist information, the property returns empty string.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Artist
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.VideoInformation.GetArtist(_handle, out val), "Failed to get value");
+
+ return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the album artist name.
+ /// If the media content has no album artist information, the property returns empty string.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string AlbumArtist
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.VideoInformation.GetAlbumArtist(_handle, out val), "Failed to get value");
+
+ return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the genre name.
+ /// If the media content has no genre information, the property returns empty string.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Genre
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.VideoInformation.GetGenre(_handle, out val), "Failed to get value");
+
+ return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the composer name.
+ /// If the media content has no composer information, the property returns empty string.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Composer
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.VideoInformation.GetComposer(_handle, out val), "Failed to get value");
+
+ return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the year.
+ /// If the media content has no year information, the property returns empty string.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Year
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.VideoInformation.GetYear(_handle, out val), "Failed to get value");
+
+ return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the recorded date.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string RecordedDate
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.VideoInformation.GetRecordedDate(_handle, out val), "Failed to get value");
+
+ return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the copyright notice.
+ /// If the media content has no copyright information, the property returns empty string.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Copyright
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.VideoInformation.GetCopyright(_handle, out val), "Failed to get value");
+
+ return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the track number.
+ /// If the media content has no track information, the property returns empty string.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string TrackNumber
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ MediaContentValidator.ThrowIfError(
+ Interop.VideoInformation.GetTrackNum(_handle, out val), "Failed to get value");
+
+ return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the bitrate in bit per second [bps].
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int BitRate
+ {
+ get
+ {
+ int bitrate = 0;
+ MediaContentValidator.ThrowIfError(
+ Interop.VideoInformation.GetBitRate(_handle, out bitrate), "Failed to get value");
+
+ return bitrate;
+ }
+ }
+
+ /// <summary>
+ /// Gets the track duration in Milliseconds.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Duration
+ {
+ get
+ {
+ int duration = 0;
+ MediaContentValidator.ThrowIfError(
+ Interop.VideoInformation.GetDuration(_handle, out duration), "Failed to get value");
+
+ return duration;
+ }
+ }
+
+ /// <summary>
+ /// Gets the video width in pixels.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Width
+ {
+ get
+ {
+ int width = 0;
+ MediaContentValidator.ThrowIfError(
+ Interop.VideoInformation.GetWidth(_handle, out width), "Failed to get value");
+
+ return width;
+ }
+ }
+
+ /// <summary>
+ /// Gets the video height in pixels.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Height
+ {
+ get
+ {
+ int height = 0;
+ MediaContentValidator.ThrowIfError(
+ Interop.VideoInformation.GetHeight(_handle, out height), "Failed to get value");
+
+ return height;
+ }
+ }
+
+ /// <summary>
+ /// Gets the number of bookmarks for the passed filter in the given media ID from the media database.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// int count</returns>
+ /// <param name="filter">The Filter for matching Bookmarks</param>
+ public int GetMediaBookmarkCount(ContentFilter filter)
+ {
+ int count = 0;
+ IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetBookmarkCount(MediaId, handle, out count), "Failed to get count");
+
+ return count;
+ }
+
+ /// <summary>
+ /// Iterates through the media bookmark in the given media info from the media database.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// Task to get all the Bookmarks </returns>
+ /// <param name="filter"> filter for the Tags</param>
+ public IEnumerable<MediaBookmark> GetMediaBookmarks(ContentFilter filter)
+ {
+ Collection<MediaBookmark> result = new Collection<MediaBookmark>();
+ IntPtr filterHandle = (filter != null) ? filter.Handle : IntPtr.Zero;
+ Interop.MediaInformation.MediaBookmarkCallback callback = (IntPtr handle, IntPtr userData) =>
+ {
+ IntPtr newHandle = IntPtr.Zero;
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaBookmark.Clone(out newHandle, handle), "Failed to clone Tag");
+ result.Add(new MediaBookmark(newHandle));
+ return true;
+ };
+ MediaContentValidator.ThrowIfError(
+ Interop.MediaInformation.GetAllBookmarks(MediaId, filterHandle, callback, IntPtr.Zero), "Failed to get value");
+
+ return result;
+ }
+
+ /// <summary>
+ /// Adds a bookmark to the video
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="offset">Offset of the video in seconds</param>
+ /// <param name="thumbnailPath">Thumbnail path for the bookmark</param>
+ /// <returns>Task with added MediaBookmark instance </returns>
+ public MediaBookmark AddBookmark(uint offset, string thumbnailPath)
+ {
+ MediaBookmark result = null;
+ ContentManager.Database.Insert(MediaId, offset, thumbnailPath);
+ ContentFilter bookmarkfilter = new ContentFilter();
+ bookmarkfilter.Condition = ContentColumns.Bookmark.Offset + " = " + offset;
+ IEnumerable<MediaBookmark> bookmarksList = null;
+ bookmarksList = GetMediaBookmarks(bookmarkfilter);
+ foreach (MediaBookmark bookmark in bookmarksList)
+ {
+ if (bookmark.Offset == offset)
+ {
+ result = bookmark;
+ break;
+ }
+ }
+
+ bookmarkfilter.Dispose();
+ return result;
+ }
+
+ /// <summary>
+ /// Deletes a bookmark from the media database.
+ /// For other types Unsupported exception is thrown.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="bookmark">The bookmark to be deleted</param>
+ public void DeleteBookmark(MediaBookmark bookmark)
+ {
+ ContentManager.Database.Delete(bookmark);
+ }
+
+ internal IntPtr VideoHandle
+ {
+ get
+ {
+ return _handle.DangerousGetHandle();
+ }
+ }
+
+ private readonly Interop.VideoInformation.SafeVideoInformationHandle _handle;
+
+ internal VideoInformation(Interop.VideoInformation.SafeVideoInformationHandle handle, Interop.MediaInformation.SafeMediaInformationHandle mediaInformationHandle)
+ : base(mediaInformationHandle)
+ {
+ _handle = handle;
+ }
+ }
+}
diff --git a/src/Tizen.Content.MimeType/Interop/Interop.Glib.cs b/src/Tizen.Content.MimeType/Interop/Interop.Glib.cs
new file mode 100755
index 0000000..576a6e2
--- /dev/null
+++ b/src/Tizen.Content.MimeType/Interop/Interop.Glib.cs
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Glib
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool GSourceFunc(IntPtr userData);
+
+ [DllImport(Libraries.Glib, EntryPoint = "g_idle_add", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern uint IdleAdd(GSourceFunc d, IntPtr data);
+ }
+}
diff --git a/src/Tizen.Content.MimeType/Interop/Interop.Libc.cs b/src/Tizen.Content.MimeType/Interop/Interop.Libc.cs
new file mode 100755
index 0000000..825599e
--- /dev/null
+++ b/src/Tizen.Content.MimeType/Interop/Interop.Libc.cs
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Libc
+ {
+ [DllImport(Libraries.Libc, EntryPoint = "free", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int Free(IntPtr ptr);
+ }
+}
diff --git a/src/Tizen.Content.MimeType/Interop/Interop.Libraries.cs b/src/Tizen.Content.MimeType/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..365b82e
--- /dev/null
+++ b/src/Tizen.Content.MimeType/Interop/Interop.Libraries.cs
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string Mime = "libcapi-content-mime-type.so.0";
+ public const string Glib = "libglib-2.0.so.0";
+ public const string Libc = "libc.so.6";
+ }
+}
diff --git a/src/Tizen.Content.MimeType/Interop/Interop.Mime.cs b/src/Tizen.Content.MimeType/Interop/Interop.Mime.cs
new file mode 100755
index 0000000..048c773
--- /dev/null
+++ b/src/Tizen.Content.MimeType/Interop/Interop.Mime.cs
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Mime
+ {
+ [DllImport(Libraries.Mime, EntryPoint = "mime_type_get_mime_type", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int GetMime(
+ [System.Runtime.InteropServices.InAttribute()]
+ [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] string file_extension
+ , out string mime_type);
+
+ [DllImport(Libraries.Mime, EntryPoint = "mime_type_get_file_extension", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int GetFile(
+ [System.Runtime.InteropServices.InAttribute()]
+ [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] string mime_type
+ , out System.IntPtr file_extension, out int length);
+ }
+}
diff --git a/src/Tizen.Content.MimeType/Tizen.Content.MimeType.csproj b/src/Tizen.Content.MimeType/Tizen.Content.MimeType.csproj
new file mode 100644
index 0000000..5ed2f1f
--- /dev/null
+++ b/src/Tizen.Content.MimeType/Tizen.Content.MimeType.csproj
@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Content.MimeType/Tizen.Content.MimeType/MimeExceptionFactory.cs b/src/Tizen.Content.MimeType/Tizen.Content.MimeType/MimeExceptionFactory.cs
new file mode 100755
index 0000000..d316198
--- /dev/null
+++ b/src/Tizen.Content.MimeType/Tizen.Content.MimeType/MimeExceptionFactory.cs
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Tizen.Content.MimeType
+{
+ internal class MimeExceptionFactory
+ {
+ internal static Exception CreateException(MimeUtil.MimeError err)
+ {
+ Exception exp;
+ switch (err)
+ {
+ case MimeUtil.MimeError.InvalidParameter:
+ {
+ exp = new ArgumentException("Invalid Parameters Provided");
+ break;
+ }
+ case MimeUtil.MimeError.IoError:
+ {
+ exp = new InvalidOperationException("I/O Error Occured");
+ break;
+ }
+ case MimeUtil.MimeError.OutOfMemory:
+ {
+ exp = new InvalidOperationException("Out Of Memory");
+ break;
+ }
+ default:
+ {
+ exp = new InvalidOperationException("");
+ break;
+ }
+ }
+ return exp;
+ }
+ }
+}
diff --git a/src/Tizen.Content.MimeType/Tizen.Content.MimeType/MimeUtil.cs b/src/Tizen.Content.MimeType/Tizen.Content.MimeType/MimeUtil.cs
new file mode 100755
index 0000000..d9be14a
--- /dev/null
+++ b/src/Tizen.Content.MimeType/Tizen.Content.MimeType/MimeUtil.cs
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Collections.Specialized;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Content.MimeType
+{
+ /// <summary>
+ /// The MimeUtil API provides functions to map MIME types to file extensions and vice versa.</summary>
+ /// <remarks>
+ /// Conversions are provided from file extensions to MIME types and from MIME types to file extensions.</remarks>
+ public static class MimeUtil
+ {
+ /// <summary>
+ /// Gets the MIME type for the given file extension.
+ /// The MIME type is 'application/octet-stream' if the given file extension is not associated with specific file formats
+ /// </summary>
+ /// <param name="fileExtension"> The file Extension</param>
+ /// <example>
+ /// <code>
+ /// string mimeType = MimeUtil.GetMimeType("png");
+ /// </code>
+ /// </example>
+ public static string GetMimeType(string fileExtension)
+ {
+ string mime;
+ int res = Interop.Mime.GetMime(fileExtension, out mime);
+ if (res != (int)MimeError.None)
+ {
+ throw MimeExceptionFactory.CreateException((MimeError)res);
+ }
+ return mime;
+ }
+
+ /// <summary>
+ /// Gets file extensions for the given MIME type. </summary>
+ /// <returns>
+ /// If Successfull, return's the list of file extension strings for the given MIME type.
+ /// The array of file extension are without the leading dot ('.')</returns>
+ /// <param name="mime"> The mime type</param>
+ /// <example>
+ /// <code>
+ /// IEnumerable<string> extColl = MimeUtil.GetFileExtension("video/mpeg");
+ /// foreach ( string obj in extColl )
+ /// {
+ /// Console.WriteLine(obj);
+ /// }
+ /// </code>
+ /// </example>
+ public static IEnumerable<string> GetFileExtension(string mime)
+ {
+ IntPtr extensionArray = IntPtr.Zero;
+ int length = -1;
+ int res = Interop.Mime.GetFile(mime, out extensionArray, out length);
+ if (res != (int)MimeError.None)
+ {
+ throw MimeExceptionFactory.CreateException((MimeError)res);
+ }
+ IntPtr[] extensionList = new IntPtr[length];
+ Marshal.Copy(extensionArray, extensionList, 0, length);
+ Collection<string> coll = new Collection<string>();
+ foreach (IntPtr extension in extensionList)
+ {
+ coll.Add(Marshal.PtrToStringAnsi(extension));
+ Interop.Libc.Free(extension);
+ }
+ Interop.Libc.Free(extensionArray);
+ return coll;
+ }
+
+ internal enum MimeError : int
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None, /**< Successful */
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter, /**< Invalid parameter */
+ OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory, /**< Out of memory */
+ IoError = Tizen.Internals.Errors.ErrorCode.IoError, /**< Internal I/O error */
+ }
+ }
+}
diff --git a/src/Tizen.Location.Geofence/Interop/Interop.Libraries.cs b/src/Tizen.Location.Geofence/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..40b8453
--- /dev/null
+++ b/src/Tizen.Location.Geofence/Interop/Interop.Libraries.cs
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ internal const string Geofence = "libcapi-geofence-manager.so.0";
+ internal const string Libc = "libc.so.6";
+ }
+}
diff --git a/src/Tizen.Location.Geofence/Interop/Interop.Location.cs b/src/Tizen.Location.Geofence/Interop/Interop.Location.cs
new file mode 100755
index 0000000..89eed6a
--- /dev/null
+++ b/src/Tizen.Location.Geofence/Interop/Interop.Location.cs
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Location.Geofence;
+
+internal static partial class Interop
+{
+ internal static partial class Geofence
+ {
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_create_geopoint")]
+ internal static extern int CreateGPSFence(int placeId, double latitude, double longitude, int radius, string address, out IntPtr handle);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_create_bluetooth")]
+ internal static extern int CreateBTFence(int placeId, string bssid, string ssid, out IntPtr handle);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_create_wifi")]
+ internal static extern int CreateWiFiFence(int placeId, string bssid, string ssid, out IntPtr handle);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_destroy")]
+ internal static extern int Destroy(IntPtr handle);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_get_type")]
+ internal static extern int FenceType(IntPtr handle, out FenceType type);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_get_place_id")]
+ internal static extern int FencePlaceID(IntPtr handle, out int placeId);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_get_latitude")]
+ internal static extern int FenceLatitude(IntPtr handle, out double latitude);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_get_longitude")]
+ internal static extern int FenceLongitude(IntPtr handle, out double longitude);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_get_radius")]
+ internal static extern int FenceRadius(IntPtr handle, out int radius);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_get_address")]
+ internal static extern int FenceAddress(IntPtr handle, out string address);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_get_bssid")]
+ internal static extern int FenceBSSID(IntPtr handle, out string bssid);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_get_ssid")]
+ internal static extern int FenceSSID(IntPtr handle, out string ssid);
+ }
+
+ internal static partial class GeofenceStatus
+ {
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_status_create")]
+ internal static extern int Create(int fenceId, out IntPtr statusHandle);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_status_destroy")]
+ internal static extern int Destroy(IntPtr statusHandle);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_status_get_state")]
+ internal static extern int State(IntPtr statusHandle, out GeofenceState state);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_status_get_duration")]
+ internal static extern int Duration(IntPtr statusHandle, out int seconds);
+ }
+
+ internal static partial class GeofenceManager
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool StateChangedCallback(int fenceId, GeofenceState state, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool ProximityStateChangedCallback(int fenceId, ProximityState state, ProximityProvider provider, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool GeofenceEventCallback(int placeId, int fenceId, GeofenceError error, GeofenceEventType eventType, IntPtr userData);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_manager_is_supported")]
+ internal static extern int IsSupported(out bool supported);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_manager_create")]
+ internal static extern int Create(out IntPtr handle);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_manager_destroy")]
+ internal static extern int Destroy(IntPtr handle);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_manager_start")]
+ internal static extern int Start(IntPtr handle, int fenceId);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_manager_stop")]
+ internal static extern int Stop(IntPtr handle, int fenceId);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_manager_set_geofence_state_changed_cb")]
+ internal static extern int SetStateChangedCB(IntPtr handle, StateChangedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_manager_unset_geofence_state_changed_cb")]
+ internal static extern int UnsetStateChangedCB(IntPtr handle);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_manager_set_geofence_proximity_state_changed_cb")]
+ internal static extern int SetProximityStateCB(IntPtr handle, ProximityStateChangedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_manager_unset_geofence_proximity_state_changed_cb")]
+ internal static extern int UnsetProximityStateCB(IntPtr handle);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_manager_set_geofence_event_cb")]
+ internal static extern int SetGeofenceEventCB(IntPtr handle, GeofenceEventCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_manager_unset_geofence_event_cb")]
+ internal static extern int UnsetGeofenceEventCB(IntPtr handle);
+ }
+
+ internal static partial class VirtualPerimeter
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool ForEachPlaceListCallback(int placeId, string placeName, int placeIndex, int placeCount, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool ForEachFenceListCallback(int fenceId, IntPtr fenceHandle, int placeIndex, int placeCount, IntPtr userData);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_manager_add_place")]
+ internal static extern int AddPlace(IntPtr handle, string placeName, out int placeId);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_manager_update_place")]
+ internal static extern int UpdatePlace(IntPtr handle, int placeId, string placeName);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_manager_remove_place")]
+ internal static extern int RemovePlace(IntPtr handle, int placeId);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_manager_add_fence")]
+ internal static extern int AddFence(IntPtr handle, IntPtr fenceHandle, out int fenceId);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_manager_remove_fence")]
+ internal static extern int RemoveFence(IntPtr handle, int fenceId);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_manager_foreach_geofence_list")]
+ internal static extern int GetForEachFenceList(IntPtr handle, ForEachFenceListCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_manager_foreach_place_geofence_list")]
+ internal static extern int GetForEachPlaceFenceList(IntPtr handle, int placeId, ForEachFenceListCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_manager_foreach_place_list")]
+ internal static extern int GetForEachPlaceList(IntPtr handle, ForEachPlaceListCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Geofence, EntryPoint = "geofence_manager_get_place_name")]
+ internal static extern int GetPlaceName(IntPtr handle, int placeId, out string placeName);
+ }
+}
diff --git a/src/Tizen.Location.Geofence/Tizen.Location.Geofence.csproj b/src/Tizen.Location.Geofence/Tizen.Location.Geofence.csproj
new file mode 100644
index 0000000..5ed2f1f
--- /dev/null
+++ b/src/Tizen.Location.Geofence/Tizen.Location.Geofence.csproj
@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Location.Geofence/Tizen.Location.Geofence/Fence.cs b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/Fence.cs
new file mode 100755
index 0000000..d22b94a
--- /dev/null
+++ b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/Fence.cs
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Location.Geofence
+{
+ /// <summary>
+ /// Geo-fence defines a virtual perimeter for a real-world geographic area.
+ /// If you create a geofence, you can trigger some activities when a device enters(or exits) the geofences defined by you.
+ /// You can create a geofence with the information of Geopoint, Wi-Fi, or BT.
+ /// <list>
+ /// <item>Geopoint: Geofence is specified by coordinates (Latitude and Longitude) and Radius</item>
+ /// <item>WIFI: Geofence is specified by BSSID of Wi-Fi access point</item>
+ /// <item>BT: Geofence is specified by Bluetooth address</item>
+ /// </list>
+ /// Basic service set identification(BSSID) The BSSID is the MAC address of the wireless access point(WAP) generated by combining the 24 bit Organization Unique Identifier(the manufacturer's identity)
+ /// and the manufacturer's assigned 24-bit identifier for the radio chipset in the WAP.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class Fence : IDisposable
+ {
+ private bool _disposed = false;
+
+ internal IntPtr Handle
+ {
+ get;
+ set;
+ }
+
+ internal Fence(IntPtr handle)
+ {
+ Handle = handle;
+ }
+
+ ~Fence()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Gets the type of geofence.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public FenceType Type
+ {
+ get
+ {
+ FenceType val;
+ GeofenceError ret = (GeofenceError)Interop.Geofence.FenceType(Handle, out val);
+ if (ret != GeofenceError.None)
+ {
+ Tizen.Log.Error(GeofenceErrorFactory.LogTag, "Failed to get GeofenceType");
+ }
+
+ return val;
+ }
+ }
+
+ /// <summary>
+ /// Gets the id of place.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public int PlaceId
+ {
+ get
+ {
+ int result = -1;
+ GeofenceError ret = (GeofenceError)Interop.Geofence.FencePlaceID(Handle, out result);
+ if (ret != GeofenceError.None)
+ {
+ Tizen.Log.Error(GeofenceErrorFactory.LogTag, "Failed to get PlaceId");
+ }
+
+ return result;
+ }
+ }
+
+ /// <summary>
+ /// Gets the longitude of geofence.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public double Longitude
+ {
+ get
+ {
+ double result = -1;
+ GeofenceError ret = (GeofenceError)Interop.Geofence.FenceLongitude(Handle, out result);
+ if (ret != GeofenceError.None)
+ {
+ Tizen.Log.Error(GeofenceErrorFactory.LogTag, "Failed to get Longitude");
+ }
+
+ return result;
+
+ }
+ }
+
+ /// <summary>
+ /// Gets the latitude of geofence.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public double Latitude
+ {
+ get
+ {
+ double result = -1;
+ GeofenceError ret = (GeofenceError)Interop.Geofence.FenceLatitude(Handle, out result);
+ if (ret != GeofenceError.None)
+ {
+ Tizen.Log.Error(GeofenceErrorFactory.LogTag, "Failed to get Latitude");
+ }
+
+ return result;
+ }
+ }
+
+ /// <summary>
+ /// Gets the radius of geofence.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public int Radius
+ {
+ get
+ {
+ int result = -1;
+ GeofenceError ret = (GeofenceError)Interop.Geofence.FenceRadius(Handle, out result);
+ if (ret != GeofenceError.None)
+ {
+ Tizen.Log.Error(GeofenceErrorFactory.LogTag, "Failed to get Radius");
+ }
+
+ return result;
+ }
+ }
+
+ /// <summary>
+ /// Gets the address of geofence.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Address
+ {
+ get
+ {
+ string result = "";
+ GeofenceError ret = (GeofenceError)Interop.Geofence.FenceAddress(Handle, out result);
+ if (ret != GeofenceError.None)
+ {
+ Tizen.Log.Error(GeofenceErrorFactory.LogTag, "Failed to get Adress");
+ }
+
+ return result;
+ }
+ }
+
+ /// <summary>
+ /// Gets the bssid of geofence.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Bssid
+ {
+ get
+ {
+ string result = "";
+ GeofenceError ret = (GeofenceError)Interop.Geofence.FenceBSSID(Handle, out result);
+ if (ret != GeofenceError.None)
+ {
+ Tizen.Log.Error(GeofenceErrorFactory.LogTag, "Failed to get Bssid");
+ }
+
+ return result;
+ }
+ }
+
+ /// <summary>
+ /// Gets the ssid of geofence.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Ssid
+ {
+ get
+ {
+ string result = "";
+ GeofenceError ret = (GeofenceError)Interop.Geofence.FenceSSID(Handle, out result);
+ if (ret != GeofenceError.None)
+ {
+ Tizen.Log.Error(GeofenceErrorFactory.LogTag, "Failed to get Ssid");
+ }
+
+ return result;
+ }
+ }
+
+ /// <summary>
+ /// Creates a geopoint type of new geofence.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="placeId">The current place id.</param>
+ /// <param name="latitude">Specifies the value of latitude of geofence [-90.0 ~ 90.0] (degrees).</param>
+ /// <param name="longitude">Specifies the value of longitude of geofence [-180.0 ~ 180.0] (degrees).</param>
+ /// <param name="radius">Specifies the value of radius of geofence [100 ~ 500](meter).</param>
+ /// <param name="address">Specifies the value of address.</param>
+ /// <returns>Newly created geofence instance.</returns>
+ /// <exception cref="ArgumentException">Incase of Invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Incase of any System error.</exception>
+ /// <exception cref="NotSupportedException">Incase of Geofence is not supported.</exception>
+ public static Fence CreateGPSFence(int placeId, int latitude, int longitude, int radius, string address)
+ {
+ IntPtr handle = IntPtr.Zero;
+ GeofenceError ret = (GeofenceError)Interop.Geofence.CreateGPSFence(placeId, latitude, longitude, radius,address, out handle);
+ if (ret != GeofenceError.None)
+ {
+ throw GeofenceErrorFactory.CreateException(ret, "Failed to create Geofence from GPS Data for " + placeId);
+ }
+
+ return new Fence(handle);
+ }
+
+ /// <summary>
+ /// Creates a Wi-Fi type of new geofence.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="placeId">The current place id.</param>
+ /// <param name="bssid">Specifies the value of BSSID of Wi-Fi MAC address.</param>
+ /// <param name="ssid"> Specifies the value of SSID of Wi-Fi Device.</param>
+ /// <returns>Newly created geofence instance.</returns>
+ /// <exception cref="ArgumentException">Incase of Invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Incase of any System error.</exception>
+ /// <exception cref="NotSupportedException">Incase of Geofence is not supported.</exception>
+ public static Fence CreateWifiFence(int placeId, string bssid, string ssid)
+ {
+ IntPtr handle = IntPtr.Zero;
+ GeofenceError ret = (GeofenceError)Interop.Geofence.CreateWiFiFence(placeId, bssid, ssid, out handle);
+ if (ret != GeofenceError.None)
+ {
+ throw GeofenceErrorFactory.CreateException(ret, "Failed to create Geofence from Wifi Data for " + placeId);
+ }
+
+ return new Fence(handle);
+ }
+
+ /// <summary>
+ /// Creates a bluetooth type of new geofence.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="placeId">The current place id.</param>
+ /// <param name="bssid">Specifies the value of BSSID of BT MAC address.</param>
+ /// <param name="ssid"> Specifies the value of SSID of BT Device.</param>
+ /// <returns>Newly created geofence instance.</returns>
+ /// <exception cref="ArgumentException">Incase of Invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Incase of any System error.</exception>
+ /// <exception cref="NotSupportedException">Incase of Geofence is not supported.</exception>
+ public static Fence CreateBTFence(int placeId, string bssid, string ssid)
+ {
+ IntPtr handle = IntPtr.Zero;
+ GeofenceError ret = (GeofenceError)Interop.Geofence.CreateBTFence(placeId, bssid, ssid, out handle);
+ if (ret != GeofenceError.None)
+ {
+ throw GeofenceErrorFactory.CreateException(ret, "Failed to create Geofence from Bluetooth Data for " + placeId);
+ }
+
+ return new Fence(handle);
+ }
+
+ /// <summary>
+ /// Overloaded Dispose API for destroying the fence Handle.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (_disposed)
+ return;
+
+ if (Handle != IntPtr.Zero)
+ {
+ Interop.Geofence.Destroy(Handle);
+ Handle = IntPtr.Zero;
+ }
+
+ _disposed = true;
+ }
+ }
+}
diff --git a/src/Tizen.Location.Geofence/Tizen.Location.Geofence/FenceData.cs b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/FenceData.cs
new file mode 100755
index 0000000..cfda8cf
--- /dev/null
+++ b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/FenceData.cs
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+namespace Tizen.Location.Geofence
+{
+ /// <summary>
+ /// Represents the Geofence list Item data.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class FenceData
+ {
+ internal FenceData(int fenceId, IntPtr handle, int index, int count)
+ {
+ GeofenceId = fenceId;
+ Fence = new Fence(handle);
+ Index = index;
+ Count = count;
+ }
+ /// <summary>
+ /// Geofence instance.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public Fence Fence
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// The geofence id.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public int GeofenceId
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// The index number of the fences in the list.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Index value starts from 1.</value>
+ public int Index
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// The total number of fences that exists for the requester.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public int Count
+ {
+ get;
+ internal set;
+ }
+ };
+
+ /// <summary>
+ /// Represents the Place list Item data.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class PlaceData
+ {
+ internal PlaceData(int id, string name, int index, int count)
+ {
+ PlaceId = id;
+ Name = name;
+ Index = index;
+ Count = count;
+ }
+ /// <summary>
+ /// The current place id.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public int PlaceId
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// The current place name.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Name
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// The index number of the places in the list.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Index value starts from 1.</value>
+ public int Index
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// The total number of places that exists for the requester.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public int Count
+ {
+ get;
+ internal set;
+ }
+ };
+}
diff --git a/src/Tizen.Location.Geofence/Tizen.Location.Geofence/FenceStatus.cs b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/FenceStatus.cs
new file mode 100644
index 0000000..46e5e66
--- /dev/null
+++ b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/FenceStatus.cs
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Location.Geofence
+{
+ /// <summary>
+ /// The geofence status describes the current state and duration of a geofence.
+ /// <list>
+ /// <item>State: State is specified by current state of fence</item>
+ /// <item>Duration: Geofence is specified by duration of current state</item>
+ /// </list>
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class FenceStatus : IDisposable
+ {
+ private bool _disposed = false;
+
+ internal IntPtr Handle
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// Creates a new geofence status.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="ArgumentException">Incase of Invalid parameter.</exception>
+ /// <exception cref="NotSupportedException">Incase of Geofence is not supported.</exception>
+ public FenceStatus(int fenceId)
+ {
+ IntPtr handle;
+ GeofenceError ret = (GeofenceError)Interop.GeofenceStatus.Create(fenceId, out handle);
+ if (ret != GeofenceError.None)
+ {
+ throw GeofenceErrorFactory.CreateException(ret, "Failed to create Geofence Status instance");
+ }
+
+ Handle = handle;
+ }
+
+ ~FenceStatus()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Gets the state of geofence.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="NotSupportedException">Incase of Geofence is not supported.</exception>
+ public GeofenceState State
+ {
+ get
+ {
+ GeofenceState state;
+ GeofenceError ret = (GeofenceError)Interop.GeofenceStatus.State(Handle, out state);
+ if (ret != GeofenceError.None)
+ {
+ Tizen.Log.Error(GeofenceErrorFactory.LogTag, "Failed to get FenceState");
+ }
+
+ return state;
+ }
+ }
+
+ /// <summary>
+ /// Gets the amount of seconds geofence is in the current state.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="NotSupportedException">Incase of Geofence is not supported.</exception>
+ public int Duration
+ {
+ get
+ {
+ int result = -1;
+ GeofenceError ret = (GeofenceError)Interop.GeofenceStatus.Duration(Handle, out result);
+ if (ret != GeofenceError.None)
+ {
+ Tizen.Log.Error(GeofenceErrorFactory.LogTag, "Failed to get FenceDuration");
+ }
+
+ return result;
+ }
+ }
+
+ /// <summary>
+ /// Overloaded Dispose API for destroying the fence Handle.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (_disposed)
+ return;
+
+ if (Handle != IntPtr.Zero)
+ {
+ Interop.GeofenceStatus.Destroy(Handle);
+ Handle = IntPtr.Zero;
+ }
+
+ _disposed = true;
+ }
+ }
+}
diff --git a/src/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceEnum.cs b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceEnum.cs
new file mode 100755
index 0000000..b5be383
--- /dev/null
+++ b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceEnum.cs
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Location.Geofence
+{
+ /// <summary>
+ /// Enumeration for geofence type.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum FenceType
+ {
+ /// <summary>
+ /// Geofence is specified by geospatial coordinate.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ GeoPoint = 1,
+
+ /// <summary>
+ /// Geofence is specified by Wi-Fi access point.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ Wifi,
+
+ /// <summary>
+ /// Geofence is specified by Bluetooth device.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ Bluetooth
+ };
+
+ /// <summary>
+ /// Enumerations for the state of geofence.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum GeofenceState
+ {
+ /// <summary>
+ /// Uncertain state of geofence.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ Uncertain = 0,
+
+ /// <summary>
+ /// Geofence In state.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ In,
+
+ /// <summary>
+ /// Geofence Out state.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ Out
+ };
+
+ /// <summary>
+ /// Enumerations for geofence management events.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum GeofenceEventType
+ {
+ /// <summary>
+ /// Geofence is added.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ FenceAdded = 0,
+
+ /// <summary>
+ /// Geofence is removed.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ FenceRemoved,
+
+ /// <summary>
+ /// Geofencing is started.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ FenceStarted,
+
+ /// <summary>
+ /// Geofencing is stopped.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ FenceStopped,
+
+ /// <summary>
+ /// Place is added.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ PlaceAdded = 0x10,
+
+ /// <summary>
+ /// Place is removed.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ PlaceRemoved,
+
+ /// <summary>
+ /// Place is updated.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ PlaceUpdated,
+
+ /// <summary>
+ /// Setting for geofencing is enabled.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ SettingEnabled = 0x20,
+
+ /// <summary>
+ /// Setting for geofencing is disabled.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ SettingDisabled
+ };
+
+ /// <summary>
+ /// Enumeration for the provider of proximity.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum ProximityProvider
+ {
+ /// <summary>
+ /// Proximity is specified by geospatial coordinate.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ Location = 0,
+
+ /// <summary>
+ /// Proximity is specified by Wi-Fi access point.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ Wifi,
+
+ /// <summary>
+ /// Proximity is specified by Bluetooth device.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ Bluetooth,
+
+ /// <summary>
+ /// Proximity is specified by Bluetooth low energy device.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ BLE,
+
+ /// <summary>
+ /// Proximity is specified by Sensor.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ Sensor
+ }
+
+ /// <summary>
+ /// Enumeration for the state of proximity.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum ProximityState
+ {
+ /// <summary>
+ /// Uncertain state of proximity.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ Uncertain = 0,
+
+ /// <summary>
+ /// Far state of proximity.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ Far,
+
+ /// <summary>
+ /// Far state of proximity.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ Near,
+
+ /// <summary>
+ /// Immediate state of proximity.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ Immediate
+ }
+}
diff --git a/src/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceErrorFactory.cs b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceErrorFactory.cs
new file mode 100755
index 0000000..e9fc3ad
--- /dev/null
+++ b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceErrorFactory.cs
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Tizen;
+
+
+namespace Tizen.Location.Geofence
+{
+ /// <summary>
+ /// Enum to give the type of error occured, if any.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum GeofenceError
+ {
+ /// <summary>
+ /// Successful.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ None = Tizen.Internals.Errors.ErrorCode.None,
+
+ /// <summary>
+ /// Out of memory.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
+
+ /// <summary>
+ /// Invalid parameter.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+
+ /// <summary>
+ /// Permission denied.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied,
+
+ /// <summary>
+ /// Not Supported.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ NotSupported = Tizen.Internals.Errors.ErrorCode.NotSupported,
+
+ /// <summary>
+ /// Geofence Manager is not initialized.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ NotInitialized = -0x02C00000 | 0x100 | 0x01,
+
+ /// <summary>
+ /// Invalid geofence ID.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ InvalidID = -0x02C00000 | 0x100 | 0x02,
+
+ /// <summary>
+ /// Exception occurs.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ Exception = -0x02C00000 | 0x100 | 0x03,
+
+ /// <summary>
+ /// Geofencing is already started.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ AlreadyStarted = -0x02C00000 | 0x100 | 0x04,
+
+ /// <summary>
+ /// Too many geofence.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ TooManyGeofence = -0x02C00000 | 0x100 | 0x05,
+
+ /// <summary>
+ /// Error in GPS, Wi-Fi, or BT.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ IPC = -0x02C00000 | 0x100 | 0x06,
+
+ /// <summary>
+ /// DB error in the server side.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ DBFailed = -0x02C00000 | 0x100 | 0x07,
+
+ /// <summary>
+ /// Access to specified place is denied.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ PlaceAccessDenied = -0x02C00000 | 0x100 | 0x08,
+
+ /// <summary>
+ /// Access to specified geofence is denied.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ GeofenceAccessDenied = -0x02C00000 | 0x100 | 0x09
+ };
+
+ internal class GeofenceErrorFactory
+ {
+ internal const string LogTag = "Tizen.Location.Geofence";
+
+ internal static Exception CreateException(GeofenceError err, string msg)
+ {
+ Log.Info(LogTag, "Got Error " + err + " throwing Exception with msg " + msg);
+ Exception exp;
+ switch (err)
+ {
+ case GeofenceError.InvalidParameter:
+ {
+ exp = new ArgumentException(msg + " Invalid Parameters Provided");
+ break;
+ }
+
+ case GeofenceError.OutOfMemory:
+ {
+ exp = new OutOfMemoryException(msg + " Out Of Memory");
+ break;
+ }
+
+ case GeofenceError.NotInitialized:
+ {
+ exp = new InvalidOperationException(msg + " Not initializded");
+ break;
+ }
+
+ case GeofenceError.NotSupported:
+ {
+ exp = new NotSupportedException(msg + " Not supported");
+ break;
+ }
+
+ case GeofenceError.PermissionDenied:
+ // fall through
+ case GeofenceError.GeofenceAccessDenied:
+ //fall through
+ case GeofenceError.PlaceAccessDenied:
+ {
+ exp = new UnauthorizedAccessException(msg + " Permission Denied");
+ break;
+ }
+
+ case GeofenceError.DBFailed:
+ {
+ exp = new InvalidOperationException(msg + " DataBase Failed");
+ break;
+ }
+
+ default:
+ {
+ exp = new InvalidOperationException(msg);
+ break;
+ }
+ }
+
+ return exp;
+ }
+ }
+}
diff --git a/src/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceEventArgs.cs b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceEventArgs.cs
new file mode 100755
index 0000000..f5ef780
--- /dev/null
+++ b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceEventArgs.cs
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Location.Geofence
+{
+ /// <summary>
+ /// Event arguments passed when Event is triggered to notify proximity state change.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class ProximityStateEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Internal constructor.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="id">The geofence id.</param>
+ /// <param name="state">The proximity state.</param>
+ /// <param name="provider">The proximity provider.</param>
+ internal ProximityStateEventArgs(int id, ProximityState state, ProximityProvider provider)
+ {
+ GeofenceId = id;
+ State = state;
+ Provider = provider;
+ }
+
+ /// <summary>
+ /// The geofence id.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public int GeofenceId
+ {
+ get;
+ }
+
+ /// <summary>
+ /// The proximity state.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public ProximityState State
+ {
+ get;
+ }
+
+ /// <summary>
+ /// The proximity provider.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public ProximityProvider Provider
+ {
+ get;
+ }
+ };
+
+ /// <summary>
+ /// Event arguments passed when Event is triggered to notify Geofence state change.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class GeofenceStateEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Internal constructor.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="fenceId">The specified geofence id.</param>
+ /// <param name="state">The geofence state.</param>
+ internal GeofenceStateEventArgs(int fenceId, GeofenceState state)
+ {
+ GeofenceId = fenceId;
+ State = state;
+ }
+
+ /// <summary>
+ /// The specified geofence id.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public int GeofenceId
+ {
+ get;
+ }
+
+ /// <summary>
+ /// The geofence state.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public GeofenceState State
+ {
+ get;
+ }
+ }
+
+ /// <summary>
+ /// Event arguments passed when Event occurs in geofence and place such as add, update, etc..
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class GeofenceResponseEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Internal constructor.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="placeId">The place id.</param>
+ /// <param name="fenceId">The specified geofence id.</param>
+ /// <param name="error">The error code for the particular action.</param>
+ /// <param name="eventType">The result code for the particular place and geofence management.</param>
+ internal GeofenceResponseEventArgs(int placeId, int fenceId, GeofenceError error, GeofenceEventType eventType)
+ {
+ PlaceId = placeId;
+ FenceId = fenceId;
+ ErrorCode = error;
+ EventType = eventType;
+ }
+
+ /// <summary>
+ /// The place id.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public int PlaceId
+ {
+ get;
+ }
+
+ /// <summary>
+ /// The specified geofence id.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public int FenceId
+ {
+ get;
+ }
+
+ /// <summary>
+ /// The error code for the particular action.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public GeofenceError ErrorCode
+ {
+ get;
+ }
+
+ /// <summary>
+ /// The result code for the particular place and geofence management.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public GeofenceEventType EventType
+ {
+ get;
+ }
+ };
+}
diff --git a/src/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceManager.cs b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceManager.cs
new file mode 100755
index 0000000..ad69b02
--- /dev/null
+++ b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceManager.cs
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Location.Geofence
+{
+ /// <summary>
+ /// This Geofence Manager API provides service related to geofence(geo-fence).
+ /// A geofence is a virtual perimeter for a real-world geographic area.
+ /// This API provides functions to set geofence with geopoint, MAC address of Wi-Fi and Bluetooth address.
+ /// And, notifications on events like changing in service status are provided.
+ /// There are two kinds of places and fences:
+ /// <list>
+ /// <item>Public places and fences that are created by MyPlace app can be used by all apps.</item>
+ /// <item>Private places and fences that are created by specified app can be used by the same app.</item>
+ /// </list>
+ /// Notifications can be received about the following events:
+ /// <list>
+ /// <item>Zone in when a device enters a specific area</item>
+ /// <item>Zone out when a device exits a specific area</item>
+ /// <item>Results and errors for each event requested to geofence module</item>
+ /// </list>
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class GeofenceManager : IDisposable
+ {
+ private bool _disposed = false;
+
+ internal IntPtr Handle
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// Creates a new geofence manager.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="OutOfMemoryException">Incase of OutOfMemory condition.</exception>
+ /// <exception cref="InvalidOperationException">Incase of any System error.</exception>
+ /// <exception cref="NotSupportedException">Incase of Geofence is not supported.</exception>
+ public GeofenceManager()
+ {
+ IntPtr handle;
+ GeofenceError ret = (GeofenceError) Interop.GeofenceManager.Create(out handle);
+ if(ret != GeofenceError.None)
+ {
+ throw GeofenceErrorFactory.CreateException(ret, "Failed to create Geofence Manager instance");
+ }
+
+ Handle = handle;
+ }
+
+ ~GeofenceManager()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Checks whether the geofence manager is available or not.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public static bool IsSupported
+ {
+ get
+ {
+ bool ret = false;
+ GeofenceError res= (GeofenceError)Interop.GeofenceManager.IsSupported(out ret);
+ if(res != GeofenceError.None)
+ {
+ Tizen.Log.Error(GeofenceErrorFactory.LogTag, "Failed to get IsSupported feature for Geofence manager");
+ }
+
+ return ret;
+ }
+ }
+
+ /// <summary>
+ /// Starts the geofencing service.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="geofenceId">The specified geofence id.</param>
+ /// <privilege>http://tizen.org/privilege/location</privilege>
+ /// <remarks>
+ /// When the location service is enabled, the StateChanged event is invoked and the service starts.
+ /// </remarks>
+ /// <exception cref="ArgumentException">Incase of Invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Incase of any System error.</exception>
+ /// <exception cref="UnauthorizedAccessException">Incase of Privileges are not defined.</exception>
+ /// <exception cref="NotSupportedException">Incase of Geofence is not supported.</exception>
+ public void Start(int geofenceId)
+ {
+ GeofenceError ret = (GeofenceError)Interop.GeofenceManager.Start(Handle, geofenceId);
+ if (ret != GeofenceError.None)
+ {
+ throw GeofenceErrorFactory.CreateException(ret, "Failed to start service for " + geofenceId);
+ }
+ }
+
+ /// <summary>
+ /// Stops the geofenceing service.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="geofenceId">The specified geofence id.</param>
+ /// <privilege>http://tizen.org/privilege/location</privilege>
+ /// <remarks>
+ /// This function initiates the process of stopping the service.
+ /// You can stop and start the geofence manager as needed.
+ /// </remarks>
+ /// <exception cref="ArgumentException">Incase of Invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Incase of any System error.</exception>
+ /// <exception cref="UnauthorizedAccessException">Incase of Privileges are not defined.</exception>
+ /// <exception cref="NotSupportedException">Incase of Geofence is not supported.</exception>
+ public void Stop(int geofenceId)
+ {
+ GeofenceError ret = (GeofenceError)Interop.GeofenceManager.Stop(Handle, geofenceId);
+ if (ret != GeofenceError.None)
+ {
+ throw GeofenceErrorFactory.CreateException(ret, "Failed to stop service for " + geofenceId);
+ }
+ }
+
+ private static readonly Interop.GeofenceManager.StateChangedCallback s_stateChangedCallback = (int fenceId, GeofenceState state, IntPtr data) =>
+ {
+ GeofenceStateEventArgs evenArgs = new GeofenceStateEventArgs(fenceId, state);
+ s_stateChanged?.Invoke(null, evenArgs);
+ return true;
+ };
+
+ private static event EventHandler<GeofenceStateEventArgs> s_stateChanged = null;
+
+ /// <summary>
+ /// Invokes when a device enters or exits the given geofence, If this event is registered.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>
+ /// Call to Start() will invoke this event.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">Incase of feature Not supported.</exception>
+ public event EventHandler<GeofenceStateEventArgs> StateChanged
+ {
+ add
+ {
+ if(s_stateChanged == null)
+ {
+ GeofenceError ret = (GeofenceError)Interop.GeofenceManager.SetStateChangedCB(Handle, s_stateChangedCallback, IntPtr.Zero);
+ if (ret != GeofenceError.None)
+ {
+ throw GeofenceErrorFactory.CreateException(ret, "Failed to register state change callback");
+ }
+ }
+ s_stateChanged += value;
+ }
+ remove
+ {
+ s_stateChanged -= value;
+ if (s_stateChanged == null)
+ {
+ GeofenceError ret = (GeofenceError)Interop.GeofenceManager.UnsetStateChangedCB(Handle);
+ if (ret != GeofenceError.None)
+ {
+ throw GeofenceErrorFactory.CreateException(ret, "Failed to unregister state change callback");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.GeofenceManager.ProximityStateChangedCallback s_proximityChangedCallback = (int fenceId, ProximityState state, ProximityProvider provider, IntPtr data) =>
+ {
+ ProximityStateEventArgs evenArgs = new ProximityStateEventArgs(fenceId, state, provider);
+ s_proximityChanged?.Invoke(null, evenArgs);
+ return true;
+ };
+
+ private static event EventHandler<ProximityStateEventArgs> s_proximityChanged;
+
+ /// <summary>
+ /// Called when a proximity state of device is changed.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>
+ /// Call to Start() will invoke this event.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">Incase of feature Not supported.</exception>
+ public event EventHandler<ProximityStateEventArgs> ProximityChanged
+ {
+ add
+ {
+ if (s_proximityChanged == null)
+ {
+ GeofenceError ret = (GeofenceError)Interop.GeofenceManager.SetProximityStateCB(Handle, s_proximityChangedCallback, IntPtr.Zero);
+ if (ret != GeofenceError.None)
+ {
+ throw GeofenceErrorFactory.CreateException(ret, "Failed to register proximity change callback");
+ }
+ s_proximityChanged += value;
+ }
+ }
+ remove
+ {
+ s_proximityChanged -= value;
+ if (s_proximityChanged == null)
+ {
+ GeofenceError ret = (GeofenceError)Interop.GeofenceManager.UnsetProximityStateCB(Handle);
+ if (ret != GeofenceError.None)
+ {
+ throw GeofenceErrorFactory.CreateException(ret, "Failed to un register proximity change callback");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.GeofenceManager.GeofenceEventCallback s_geofenceEventCallback = (int placeId, int fenceId, GeofenceError error, GeofenceEventType eventType, IntPtr data) =>
+ {
+ GeofenceResponseEventArgs evenArgs = new GeofenceResponseEventArgs(placeId, fenceId, error, eventType);
+ s_geofenceEventChanged?.Invoke(null, evenArgs);
+ return true;
+ };
+
+ private static event EventHandler<GeofenceResponseEventArgs> s_geofenceEventChanged;
+
+ /// <summary>
+ /// Called when the some event occurs in geofence and place such as add, update, etc..
+ /// The events of public geofence is also received if there are public geofences.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>
+ /// Call to Start() will invoke this event.
+ /// The value of place_id or geofence_id is -1 when the place id or geofence id is not assigned.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">Incase of feature Not supported.</exception>
+ public event EventHandler<GeofenceResponseEventArgs> GeofenceEventChanged
+ {
+ add
+ {
+ if (s_geofenceEventChanged == null)
+ {
+ GeofenceError ret = (GeofenceError)Interop.GeofenceManager.SetGeofenceEventCB(Handle, s_geofenceEventCallback, IntPtr.Zero);
+ if (ret != GeofenceError.None)
+ {
+ throw GeofenceErrorFactory.CreateException(ret, "Failed to register geofence event change callback");
+ }
+ s_geofenceEventChanged += value;
+ }
+ }
+ remove
+ {
+ s_geofenceEventChanged -= value;
+ if (s_geofenceEventChanged == null)
+ {
+ GeofenceError ret = (GeofenceError)Interop.GeofenceManager.UnsetGeofenceEventCB(Handle);
+ if (ret != GeofenceError.None)
+ {
+ throw GeofenceErrorFactory.CreateException(ret, "Failed to unregister geofence event change callback");
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Overloaded Dispose API for destroying the GeofenceManager Handle.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (_disposed)
+ return;
+
+ if (Handle != IntPtr.Zero)
+ {
+ Interop.GeofenceManager.Destroy(Handle);
+ Handle = IntPtr.Zero;
+ }
+
+ _disposed = true;
+ }
+ }
+}
diff --git a/src/Tizen.Location.Geofence/Tizen.Location.Geofence/NamespaceDoc.cs b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/NamespaceDoc.cs
new file mode 100755
index 0000000..440da97
--- /dev/null
+++ b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/NamespaceDoc.cs
@@ -0,0 +1,33 @@
+/**
+<summary>
+The Tizen.Location.Geofence namespace provides classes for virtual perimeter.
+</summary>
+
+<remarks>
+<h2>Overview</h2>
+<para>
+This API provides functions to set geofence with geopoint, MAC address of Wi-Fi, and Bluetooth address.
+And notifications on events like changing in service status are provided.<p>
+There are two kinds of places and fences:<br/>
+- Public places and fences that are created by MyPlace app can be used by all apps.<br/>
+- Private places and fences that are created by specified app can be used by the same app.<p>
+Notifications can be received about the following events:<br/>
+- Zone in when a device enters a specific area<br/>
+- Zone out when a device exits a specific area<br/>
+- Results and errors for each event requested to geofence module<p>
+The Geofence manager has the following properties:<br/>
+- geofence type<br/>
+- status<br/>
+- 'Service state change' callback
+</para>
+
+<h2>Related Features</h2>
+<para>To guarantee that the Geofence application runs on a device with Geofence profile feature,
+declare the following feature requirements in the config file:<br/>
+http://tizen.org/feature/location<br/>
+http://tizen.org/feature/location.geofence<br/>
+http://tizen.org/feature/location.wps
+</para>
+</remarks>
+*/
+namespace Tizen.Location.Geofence {}
diff --git a/src/Tizen.Location.Geofence/Tizen.Location.Geofence/VirtualPerimeter.cs b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/VirtualPerimeter.cs
new file mode 100755
index 0000000..0d5cffe
--- /dev/null
+++ b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/VirtualPerimeter.cs
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Location.Geofence
+{
+ /// <summary>
+ /// Allows to create a virtual fence as Geofence using GeofenceManager instance.
+ /// User can manage all the geofence/place related data and events.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class VirtualPerimeter
+ {
+ private IntPtr Handle;
+
+ /// <summary>
+ /// Creates a VirtualPerimeter which can be used to create virtual fence.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="manager">GeofenceManager instance.</param>
+ /// <exception cref="ArgumentException"> Incase of invlid parameter.</exception>
+ public VirtualPerimeter(GeofenceManager manager)
+ {
+ if (manager == null)
+ {
+ throw GeofenceErrorFactory.CreateException(GeofenceError.InvalidParameter, "Invalid GeofenceManager instance");
+ }
+ else
+ {
+ Handle = manager.Handle;
+ }
+ }
+
+ /// <summary>
+ /// Creates a new place for geofencing service.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="name">A place name to be created.</param>
+ /// <returns>The place id to be newly created on success.</returns>
+ /// <privilege>http://tizen.org/privilege/location</privilege>
+ /// <exception cref="ArgumentException">Incase of Invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Incase of any System error.</exception>
+ /// <exception cref="UnauthorizedAccessException">Incase of Privileges are not defined.</exception>
+ /// <exception cref="NotSupportedException">Incase of Geofence is not supported.</exception>
+ public int AddPlaceName(string name)
+ {
+ int placeId = 0;
+ GeofenceError ret = (GeofenceError)Interop.VirtualPerimeter.AddPlace(Handle, name, out placeId);
+ if (ret != GeofenceError.None)
+ {
+ throw GeofenceErrorFactory.CreateException(ret, "Failed to add place to Geofence Manager for " + name);
+ }
+
+ return placeId;
+ }
+
+ /// <summary>
+ /// Updates the place name of a given place id.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="placeId">The specified place id.</param>
+ /// <param name="name">A new place name of the place id.</param>
+ /// <privilege>http://tizen.org/privilege/location</privilege>
+ /// <exception cref="ArgumentException">Incase of Invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Incase of any System error.</exception>
+ /// <exception cref="UnauthorizedAccessException">Incase of Privileges are not defined.</exception>
+ /// <exception cref="NotSupportedException">Incase of Geofence is not supported.</exception>
+ public void UpdatePlace(int placeId, string name)
+ {
+ GeofenceError ret = (GeofenceError)Interop.VirtualPerimeter.UpdatePlace(Handle, placeId, name);
+ if (ret != GeofenceError.None)
+ {
+ throw GeofenceErrorFactory.CreateException(ret, "Failed to update place to Geofence Manager for " + placeId);
+ }
+ }
+
+ /// <summary>
+ /// Removes the specific place for geofencing service.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="placeId">The specified place id.</param>
+ /// <privilege>http://tizen.org/privilege/location</privilege>
+ /// <exception cref="ArgumentException">Incase of Invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Incase of any System error.</exception>
+ /// <exception cref="UnauthorizedAccessException">Incase of Privileges are not defined.</exception>
+ /// <exception cref="NotSupportedException">Incase of Geofence is not supported.</exception>
+ public void RemovePlace(int placeId)
+ {
+ GeofenceError ret = (GeofenceError)Interop.VirtualPerimeter.RemovePlace(Handle, placeId);
+ if (ret != GeofenceError.None)
+ {
+ throw GeofenceErrorFactory.CreateException(ret, "Failed to remove place from Geofence Manager for " + placeId);
+ }
+ }
+
+ /// <summary>
+ /// Adds a geofence for a given geofence manager.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="fence">The Geofence instance to be added.</param>
+ /// <returns>The geofence id to be newly created on success.</returns>
+ /// <remarks> The retun value will always be a number greater than zero.</remarks>
+ /// <privilege>http://tizen.org/privilege/location</privilege>
+ /// <exception cref="ArgumentException">Incase of Invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Incase of any System error.</exception>
+ /// <exception cref="UnauthorizedAccessException">Incase of Privileges are not defined.</exception>
+ /// <exception cref="NotSupportedException">Incase of Geofence is not supported.</exception>
+ public int AddGeofence(Fence fence)
+ {
+ int fenceId = 0;
+ GeofenceError ret = (GeofenceError)Interop.VirtualPerimeter.AddFence(Handle, fence.Handle, out fenceId);
+ if (ret != GeofenceError.None)
+ {
+ throw GeofenceErrorFactory.CreateException(ret, "Failed to add fence to Geofence Manager ");
+ }
+
+ return fenceId;
+ }
+
+ /// <summary>
+ /// Removes a geofence with a given geofence id.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="fenceId">The specified geofence id.</param>
+ /// <privilege>http://tizen.org/privilege/location</privilege>
+ /// <exception cref="ArgumentException">Incase of Invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Incase of any System error.</exception>
+ /// <exception cref="UnauthorizedAccessException">Incase of Privileges are not defined.</exception>
+ /// <exception cref="NotSupportedException">Incase of Geofence is not supported.</exception>
+ public void RemoveGeofence(int fenceId)
+ {
+ GeofenceError ret = (GeofenceError)Interop.VirtualPerimeter.RemoveFence(Handle, fenceId);
+ if (ret != GeofenceError.None)
+ {
+ throw GeofenceErrorFactory.CreateException(ret, "Failed to remove geofence from Geofence Manager for " + fenceId);
+ }
+ }
+
+ /// <summary>
+ /// Gets the name of place.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="placeId">The place id.</param>
+ /// <returns>The name of the place.</returns>
+ /// <privilege>http://tizen.org/privilege/location</privilege>
+ /// <exception cref="ArgumentException">Incase of Invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Incase of any System error.</exception>
+ /// <exception cref="UnauthorizedAccessException">Incase of Privileges are not defined.</exception>
+ /// <exception cref="NotSupportedException">Incase of Geofence is not supported.</exception>
+ public string GetPlaceName(int placeId)
+ {
+ string name = "";
+ GeofenceError ret = (GeofenceError)Interop.VirtualPerimeter.GetPlaceName(Handle, placeId, out name);
+ if (ret != GeofenceError.None)
+ {
+ throw GeofenceErrorFactory.CreateException(ret, "Failed to get placenamefrom Geofence Manager for " + placeId);
+ }
+
+ return name;
+ }
+
+ /// <summary>
+ /// Retrieves a list of places registered in the specified geofence manager.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <returns>list of places registered as PlaceData instance list.</returns>
+ /// <privilege>http://tizen.org/privilege/location</privilege>
+ /// <exception cref="InvalidOperationException">Incase of any System error.</exception>
+ /// <exception cref="UnauthorizedAccessException">Incase of Privileges are not defined.</exception>
+ /// <exception cref="NotSupportedException">Incase of Geofence is not supported.</exception>
+ public IEnumerable<PlaceData> GetPlaceDataList()
+ {
+ List<PlaceData> places = new List<PlaceData>();
+ Interop.VirtualPerimeter.ForEachPlaceListCallback placeCallback = (int placeId, string name, int index, int count, IntPtr data) =>
+ {
+ if (count != 0)
+ {
+ PlaceData place = new PlaceData(placeId, name, index, count);
+ places.Add(place);
+ }
+ return true;
+ };
+
+ GeofenceError ret = (GeofenceError)Interop.VirtualPerimeter.GetForEachPlaceList(Handle, placeCallback, IntPtr.Zero);
+ if (ret != GeofenceError.None)
+ {
+ throw GeofenceErrorFactory.CreateException(ret, "Failed to get Places list from Geofence Manager ");
+ }
+
+ return places;
+ }
+
+ /// <summary>
+ /// Retrieves a list of fences registered in the specified geofence manager.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <returns>list of FenceData instances registred for each Geofence.</returns>
+ /// <privilege>http://tizen.org/privilege/location</privilege>
+ /// <exception cref="InvalidOperationException">Incase of any System error.</exception>
+ /// <exception cref="UnauthorizedAccessException">Incase of Privileges are not defined.</exception>
+ /// <exception cref="NotSupportedException">Incase of Geofence is not supported.</exception>
+ public IEnumerable<FenceData> GetFenceDataList()
+ {
+ List<FenceData> fences = new List<FenceData>();
+ Interop.VirtualPerimeter.ForEachFenceListCallback callback = (int fenceId, IntPtr handle, int index, int count, IntPtr data) =>
+ {
+ if (count != 0)
+ {
+ FenceData fence = new FenceData(fenceId, handle, index, count);
+ fences.Add(fence);
+ }
+ return true;
+ };
+
+ GeofenceError ret = (GeofenceError)Interop.VirtualPerimeter.GetForEachFenceList(Handle, callback, IntPtr.Zero);
+ if (ret != GeofenceError.None)
+ {
+ throw GeofenceErrorFactory.CreateException(ret, "Failed to get Geofence list from Geofence Manager ");
+ }
+
+ return fences;
+ }
+
+ /// <summary>
+ /// Retrieves a list of fences registered in the specified place.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="placeId"> The place id.</param>
+ /// <returns>list of FenceData instances registred for each Geofence for specified place.</returns>
+ /// <privilege>http://tizen.org/privilege/location</privilege>
+ /// <exception cref="ArgumentException">Incase of Invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Incase of any System error.</exception>
+ /// <exception cref="UnauthorizedAccessException">Incase of Privileges are not defined.</exception>
+ /// <exception cref="NotSupportedException">Incase of Geofence is not supported.</exception>
+ public IEnumerable<FenceData> GetGeofenceDataListByPlaceId(int placeId)
+ {
+ List<FenceData> fences = new List<FenceData>();
+ Interop.VirtualPerimeter.ForEachFenceListCallback callback = (int fenceId, IntPtr handle, int index, int count, IntPtr data) =>
+ {
+ FenceData fence = new FenceData(fenceId, handle, index, count);
+ fences.Add(fence);
+ return true;
+ };
+
+ GeofenceError ret = (GeofenceError)Interop.VirtualPerimeter.GetForEachPlaceFenceList(Handle, placeId, callback, IntPtr.Zero);
+ if (ret != GeofenceError.None)
+ {
+ throw GeofenceErrorFactory.CreateException(ret, "Failed to get Geofence list from Geofence Manager for " + placeId);
+ }
+
+ return fences;
+ }
+ }
+}
diff --git a/src/Tizen.Location/Interop/Interop.Libraries.cs b/src/Tizen.Location/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..7fd22e0
--- /dev/null
+++ b/src/Tizen.Location/Interop/Interop.Libraries.cs
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ internal const string Location = "libcapi-location-manager.so.0";
+ internal const string Libc = "libc.so.6";
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Location/Interop/Interop.Location.cs b/src/Tizen.Location/Interop/Interop.Location.cs
new file mode 100755
index 0000000..f890450
--- /dev/null
+++ b/src/Tizen.Location/Interop/Interop.Location.cs
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Location;
+
+internal static partial class Interop
+{
+ internal static partial class Locator
+ {
+ [DllImport(Libraries.Location, EntryPoint = "location_manager_create")]
+ internal static extern int Create(int locationMethod, out IntPtr handle);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_manager_destroy")]
+ internal static extern int Destroy(IntPtr handle);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_manager_start")]
+ internal static extern int Start(IntPtr handle);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_manager_stop")]
+ internal static extern int Stop(IntPtr handle);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_manager_is_enabled_mock_location")]
+ internal static extern int IsEnabledMock(out bool status);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_manager_enable_mock_location")]
+ internal static extern int EnableMock(bool enable);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_manager_set_mock_location")]
+ internal static extern int SetMockLocation(IntPtr handle, double latitude, double longitude, double altitude, double speed, double direction, double accuracy);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_manager_clear_mock_location")]
+ internal static extern int ClearMock(IntPtr handle);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_manager_get_location")]
+ internal static extern int GetLocation(IntPtr handle, out double altitude, out double latitude, out double longitude, out double climb, out double direction, out double speed, out int level, out double horizontal, out double vertical, out int timestamp);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_manager_get_last_location")]
+ internal static extern int GetLastLocation(IntPtr handle, out double altitude, out double latitude, out double longitude, out double climb, out double direction, out double speed, out int level, out double horizontal, out double vertical, out int timestamp);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_manager_add_boundary")]
+ internal static extern int AddBoundary(IntPtr managerHandle, IntPtr boundsHandle);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_manager_remove_boundary")]
+ internal static extern int RemoveBoundary(IntPtr managerHandle, IntPtr boundsHandle);
+ }
+
+ internal static partial class LocatorHelper
+ {
+ [DllImport(Libraries.Location, EntryPoint = "location_manager_is_enabled_method")]
+ internal static extern int IsEnabled(int locationMethod, out bool status);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_manager_is_supported_method")]
+ internal static extern bool IsSupported(int locationMethod);
+ }
+
+ internal static partial class Location
+ {
+ [DllImport(Libraries.Location, EntryPoint = "location_manager_get_distance")]
+ internal static extern int GetDistanceBetween(double startLatitude, double startLongitude, double endLatitude, double endLongitude, out double distance);
+ }
+
+ internal static partial class LocatorEvent
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ServiceStatechangedCallback(ServiceState state, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ZonechangedCallback(BoundaryState state, double latitude, double longitude, double altitude, int timesatmp, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void SettingchangedCallback(LocationType method, bool enable, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void LocationchangedCallback(double latitude, double longitude, double altitude, double speed, double direction, double accuracy, int timeStamp, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void LocationUpdatedCallback(LocationError error, double latitude, double longitude, double altitude, int timestamp, double speed, double direction, double climb, IntPtr userData);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_manager_set_service_state_changed_cb")]
+ internal static extern int SetServiceStateChangedCallback(IntPtr handle, ServiceStatechangedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_manager_unset_service_state_changed_cb")]
+ internal static extern int UnSetServiceStateChangedCallback(IntPtr handle);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_manager_set_zone_changed_cb")]
+ internal static extern int SetZoneChangedCallback(IntPtr handle, ZonechangedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_manager_unset_zone_changed_cb")]
+ internal static extern int UnSetZoneChangedCallback(IntPtr handle);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_manager_set_setting_changed_cb")]
+ internal static extern int SetSettingChangedCallback(int method, SettingchangedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_manager_unset_setting_changed_cb")]
+ internal static extern int UnSetSettingChangedCallback(int method);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_manager_set_distance_based_location_changed_cb")]
+ internal static extern int SetDistanceBasedLocationChangedCallback(IntPtr handle, LocationchangedCallback callback, int interval, double distance, IntPtr userData);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_manager_unset_distance_based_location_changed_cb")]
+ internal static extern int UnSetDistanceBasedLocationChangedCallback(IntPtr handle);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_manager_set_location_changed_cb")]
+ internal static extern int SetLocationChangedCallback(IntPtr handle, LocationchangedCallback callback, int interval, IntPtr userData);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_manager_unset_location_changed_cb")]
+ internal static extern int UnSetLocationChangedCallback(IntPtr handle);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_manager_request_single_location")]
+ internal static extern int GetSingleLocation(IntPtr handle, int timeout, LocationUpdatedCallback callback, IntPtr userData);
+ }
+
+ internal static partial class LocationBoundary
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool PolygonCoordinatesCallback(Coordinate coordinates, IntPtr userData);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_bounds_create_rect")]
+ internal static extern int CreateRectangularBoundary(Coordinate topLeft, Coordinate bottomLeft, out IntPtr boundsHandle);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_bounds_create_circle")]
+ internal static extern int CreateCircleBoundary(Coordinate center, double radius, out IntPtr boundsHandle);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_bounds_create_polygon")]
+ internal static extern int CreatePolygonBoundary(IntPtr list, int listLength, out IntPtr boundsHandle);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_bounds_get_rect_coords")]
+ internal static extern int GetRectangleCoordinates(IntPtr handle, out Coordinate topLeft, out Coordinate bottomRight);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_bounds_get_circle_coords")]
+ internal static extern int GetCircleCoordinates(IntPtr handle, out Coordinate center, out double radius);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_bounds_foreach_polygon_coords")]
+ internal static extern int GetForEachPolygonCoordinates(IntPtr handle, PolygonCoordinatesCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_bounds_contains_coordinates")]
+ internal static extern bool IsValidCoordinates(IntPtr handle, Coordinate coordinate);
+
+ [DllImport(Libraries.Location, EntryPoint = "location_bounds_destroy")]
+ internal static extern int DestroyBoundary(IntPtr handle);
+ }
+
+ internal static partial class GpsSatellite
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void SatelliteStatuschangedCallback(uint numActive, uint numInView, int timeStamp, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool SatelliteStatusinfomationCallback(uint azimuth, uint elevation, uint prn, uint snr, bool active, IntPtr userData);
+
+ [DllImport(Libraries.Location, EntryPoint = "gps_status_get_nmea")]
+ internal static extern int GetNMEAData(IntPtr handle, out string nmea);
+
+ [DllImport(Libraries.Location, EntryPoint = "gps_status_get_satellite")]
+ internal static extern int GetSatelliteStatus(IntPtr handle, out uint numberOfActive, out uint numberInView, out int timestamp);
+
+ [DllImport(Libraries.Location, EntryPoint = "gps_status_set_satellite_updated_cb")]
+ internal static extern int SetSatelliteStatusChangedCallback(IntPtr handle, SatelliteStatuschangedCallback callback, int interval, IntPtr userData);
+
+ [DllImport(Libraries.Location, EntryPoint = "gps_status_unset_satellite_updated_cb")]
+ internal static extern int UnSetSatelliteStatusChangedCallback(IntPtr handle);
+
+ [DllImport(Libraries.Location, EntryPoint = "gps_status_foreach_satellites_in_view")]
+ internal static extern int GetForEachSatelliteInView(IntPtr handle, SatelliteStatusinfomationCallback callback, IntPtr userData);
+ }
+
+ internal static DateTime ConvertDateTime(int timestamp)
+ {
+ DateTime dateTime = DateTime.Now;
+
+ DateTime start = DateTime.SpecifyKind(new DateTime(1970, 1, 1).AddSeconds(timestamp), DateTimeKind.Utc);
+ dateTime = start.ToLocalTime();
+
+ return dateTime;
+ }
+}
diff --git a/src/Tizen.Location/Tizen.Location.csproj b/src/Tizen.Location/Tizen.Location.csproj
new file mode 100644
index 0000000..5ed2f1f
--- /dev/null
+++ b/src/Tizen.Location/Tizen.Location.csproj
@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Location/Tizen.Location/GpsSatellite.cs b/src/Tizen.Location/Tizen.Location/GpsSatellite.cs
new file mode 100755
index 0000000..afd68ea
--- /dev/null
+++ b/src/Tizen.Location/Tizen.Location/GpsSatellite.cs
@@ -0,0 +1,360 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Location
+{
+ /// <summary>
+ /// A class which contains the functionality for obtaining information about Gps satellites in range and in use.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class GpsSatellite
+ {
+ private int _interval = 1;
+ private Locator _locator;
+ private EventHandler<SatelliteStatusChangedEventArgs> _satelliteStatusChanged;
+ private IntPtr _handle = IntPtr.Zero;
+
+ private Interop.GpsSatellite.SatelliteStatuschangedCallback _satelliteStatuschangedCallback;
+ private Interop.GpsSatellite.SatelliteStatusinfomationCallback _satelliteStatusinfomationCallback;
+
+ /// <summary>
+ /// The time interval between callback updates.
+ /// Should be in the range [1~120] seconds.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public int Interval
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the Callback Interval");
+ return _interval;
+ }
+ set
+ {
+ Log.Info(Globals.LogTag, "Setting the Callback Interval");
+ if (value > 0 && value <= 120)
+ {
+ _interval = value;
+ }
+ else
+ {
+ Log.Error(Globals.LogTag, "Error Setting the Callback Interval");
+ throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The NMEAData from the Satellite.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the location.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public string Nmea
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting NMEAData");
+ return GetNmea();
+ }
+ }
+
+ private string GetNmea()
+ {
+ string value = null;
+ int ret = Interop.GpsSatellite.GetNMEAData(_handle, out value);
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error getting the NMEAData," + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+
+ return value;
+ }
+
+
+ /// <summary>
+ /// The Count of Active satellites.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>http://tizen.org/privilege/location</privilege>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the location.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public int ActiveCount
+ {
+ get
+ {
+ return (int)GetActiveCount();
+ }
+ }
+
+ private uint GetActiveCount()
+ {
+ Log.Info(Globals.LogTag, "Getting the ActiveCount of satellites");
+ uint numActive = 0;
+ uint numInView;
+ int timestamp;
+ int ret = Interop.GpsSatellite.GetSatelliteStatus(_handle, out numActive, out numInView, out timestamp);
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error getting the satellite" + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+ return numActive;
+ }
+
+ /// <summary>
+ /// The Count of satellites in view.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>http://tizen.org/privilege/location</privilege>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the location.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public int InViewCount
+ {
+ get
+ {
+ return (int)GetInViewCount();
+ }
+ }
+
+ private uint GetInViewCount()
+ {
+ Log.Info(Globals.LogTag, "Getting the In view count of satellites");
+ uint numActive;
+ uint numInView = 0;
+ int timestamp;
+ int ret = Interop.GpsSatellite.GetSatelliteStatus(_handle, out numActive, out numInView, out timestamp);
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error getting the satellite" + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+ return numInView;
+ }
+
+ /// <summary>
+ /// The list of satellites/last recorded satellites in view.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>http://tizen.org/privilege/location</privilege>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the location.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public IList<SatelliteInformation> Satellites
+ {
+ get
+ {
+ return GetSatellites();
+ }
+ }
+
+ private IList<SatelliteInformation> GetSatellites()
+ {
+ List<SatelliteInformation> satelliteList = new List<SatelliteInformation>();
+ Log.Info(Globals.LogTag, "Getting the list of satellites");
+
+ if (_satelliteStatusinfomationCallback == null)
+ {
+ _satelliteStatusinfomationCallback = (azimuth, elevation, prn, snr, active, userData) =>
+ {
+ SatelliteInformation satellite = new SatelliteInformation(azimuth, elevation, prn, snr, active);
+ satelliteList.Add(satellite);
+ return true;
+ };
+ }
+
+ int ret = Interop.GpsSatellite.GetForEachSatelliteInView(_handle, _satelliteStatusinfomationCallback, IntPtr.Zero);
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error getting the satellite" + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+ return satelliteList;
+ }
+
+ /// <summary>
+ /// The constructor of GpsSatellite class.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="locator"> Locator object initilized using Gps.</param>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ public GpsSatellite(Locator locator)
+ {
+ Log.Info(Globals.LogTag, "Calling GpsSatellite constructor");
+ if (locator == null)
+ {
+ Log.Error(Globals.LogTag, "locator is null");
+ throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
+ }
+
+ LocationType method = locator.LocationType;
+ if (method.Equals(LocationType.Gps) || method.Equals(LocationType.Hybrid))
+ {
+ _locator = locator;
+ _handle = _locator.GetHandle();
+ }
+ else
+ {
+ Log.Error(Globals.LogTag, "Error constructing GpsSatellite class");
+ throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
+ }
+ }
+
+ /// <summary>
+ /// (event) SatelliteStatusUpdated is raised whenever satellite information is updated.
+ /// The callback will be invoked periodically (every Interval seconds).
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>http://tizen.org/privilege/location</privilege>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the location.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public event EventHandler<SatelliteStatusChangedEventArgs> SatelliteStatusUpdated
+ {
+ add
+ {
+ Log.Info(Globals.LogTag, "SatelliteStatusUpdated Add called");
+ if (_satelliteStatusChanged == null)
+ {
+ Log.Info(Globals.LogTag, "SetSatelliteStatusChangeCallback called");
+ SetSatelliteStatusChangeCallback();
+ }
+ _satelliteStatusChanged += value;
+ }
+ remove
+ {
+ Log.Info(Globals.LogTag, "SatelliteStatusUpdated Remove called");
+ _satelliteStatusChanged -= value;
+ if (_satelliteStatusChanged == null)
+ {
+ Log.Info(Globals.LogTag, "UnSetSatelliteStatusChangeCallback called");
+ UnSetSatelliteStatusChangeCallback();
+ }
+ }
+ }
+
+ private void SetSatelliteStatusChangeCallback()
+ {
+ Log.Info(Globals.LogTag, "SetSatelliteStatusChangeCallback");
+ if (_satelliteStatuschangedCallback == null)
+ {
+ _satelliteStatuschangedCallback = (numActive, numInView, timestamp, userData) =>
+ {
+ Log.Info(Globals.LogTag, "Inside SatelliteStatusChangedCallback");
+ DateTime timeStamp = DateTime.Now;
+
+ if (timestamp != 0)
+ {
+ DateTime start = DateTime.SpecifyKind(new DateTime(1970, 1, 1).AddSeconds(timestamp), DateTimeKind.Utc);
+ timeStamp = start.ToLocalTime();
+ }
+ _satelliteStatusChanged?.Invoke(_handle, new SatelliteStatusChangedEventArgs(numActive, numInView, timeStamp));
+ };
+ }
+
+ GCHandle handle = GCHandle.Alloc(this);
+ int ret = Interop.GpsSatellite.SetSatelliteStatusChangedCallback(_handle, _satelliteStatuschangedCallback, _interval, GCHandle.ToIntPtr(handle));
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error in setting satellite status changed callback," + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+ }
+
+ private void UnSetSatelliteStatusChangeCallback()
+ {
+ Log.Info(Globals.LogTag, "UnSetSatelliteStatusChangeCallback");
+ int ret = Interop.GpsSatellite.UnSetSatelliteStatusChangedCallback(_handle);
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error in Getting Unsetting satellite status changed callback," + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+ }
+ }
+
+ /// <summary>
+ /// A class which contains the information of the Satellite under consideration.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class SatelliteInformation
+ {
+ /// <summary>
+ /// Class Constructor for SatelliteInformation class.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="azimuth"> The azimuth value of the satellite in degrees.</param>
+ /// <param name="elevation"> The elevation of the satellite in meters.</param>
+ /// <param name="prn"> The Prn value of the satellite.</param>
+ /// <param name="snr"> The SNR value of the satellite in dB.</param>
+ /// <param name="active"> The flag signaling if satellite is in use.</param>
+ public SatelliteInformation(uint azimuth, uint elevation, uint prn, uint snr, bool active)
+ {
+ Azimuth = azimuth;
+ Elevation = elevation;
+ Prn = prn;
+ Snr = snr;
+ Active = active;
+ }
+
+ /// <summary>
+ /// The Azimuth information of the Satellite.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="azimuth"> The azimuth value of the satellite in degrees.</param>
+ public uint Azimuth { get; private set; }
+
+ /// <summary>
+ /// The Elevation information of the Satellite.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="azimuth"> The azimuth value of the satellite in degrees.</param>
+ public uint Elevation { get; private set; }
+
+ /// <summary>
+ /// The PRN of the Satellite.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="azimuth"> The azimuth value of the satellite in degrees.</param>
+ public uint Prn { get; private set; }
+
+ /// <summary>
+ /// The SNR of the Satellite.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public uint Snr { get; private set; }
+
+ /// <summary>
+ /// The operational status of the Satellite.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public bool Active { get; private set; }
+ }
+}
diff --git a/src/Tizen.Location/Tizen.Location/Location.cs b/src/Tizen.Location/Tizen.Location/Location.cs
new file mode 100755
index 0000000..7127800
--- /dev/null
+++ b/src/Tizen.Location/Tizen.Location/Location.cs
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Location
+{
+ /// <summary>
+ /// A class which contains the details of the location rrequested.
+ /// Includes the functionality to get the distance between locations.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class Location
+ {
+ private double _latitude;
+ private double _longitude;
+ private double _altitude;
+ private double _speed;
+ private double _direction;
+ private double _accuracy;
+ internal int _timestamp;
+
+ /// <summary>
+ /// The default constructor of Location Class.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public Location()
+ {
+ }
+
+ /// <summary>
+ /// The parameterized constructor of Location Class.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="latitude"> Latitude component of the device co-ordinate [-90.0 ~ 90.0] (degrees).</param>
+ /// <param name="longitude"> Longitude component of the device co-ordinate[-180.0 ~ 180.0] (degrees).</param>
+ /// <param name="altitude"> Altitude value.</param>
+ /// <param name="accuracy"> Accuracy in meters.</param>
+ /// <param name="speed"> Devie Speed.</param>
+ /// <param name="direction"> Device direction with respect to north.</param>
+ /// <param name="timestamp"> Time when the measurement took place.</param>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ public Location(double latitude, double longitude, double altitude, double speed, double direction, double accuracy, int timestamp)
+ {
+ _latitude = latitude;
+ _longitude = longitude;
+ _altitude = altitude;
+ _speed = speed;
+ _direction = direction;
+ _accuracy = accuracy;
+ _timestamp = timestamp;
+ }
+
+ /// <summary>
+ /// The current latitude [-90.0 ~ 90.0] (degrees).
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public double Latitude
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the latitude");
+ return _latitude;
+ }
+ set
+ {
+ Log.Info(Globals.LogTag, "Setting the latitude");
+ if (value >= -90.0 && value <= 90.0)
+ {
+ _latitude = value;
+ }
+ else
+ {
+ Log.Error(Globals.LogTag, "Error setting latitude");
+ throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The current longitude [-180.0 ~ 180.0] (degrees).
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public double Longitude
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the longitude");
+ return _longitude;
+ }
+ set
+ {
+ Log.Info(Globals.LogTag, "Setting the longitude");
+ if (value >= -180.0 && value <= 180.0)
+ {
+ _longitude = value;
+ }
+ else
+ {
+ Log.Error(Globals.LogTag, "Error setting longitude");
+ throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The current altitude (meters).
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public double Altitude
+ {
+ get
+ {
+ return _altitude;
+ }
+ set
+ {
+ _altitude = value;
+ }
+ }
+
+ /// <summary>
+ /// The Device Speed (km/h).
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public double Speed
+ {
+ get
+ {
+ return _speed;
+ }
+ set
+ {
+ _speed = value;
+ }
+ }
+
+ /// <summary>
+ /// The direction, degrees from the north.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public double Direction
+ {
+ get
+ {
+ return _direction;
+ }
+ set
+ {
+ _direction = value;
+ }
+ }
+
+ /// <summary>
+ /// The accuracy.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public double Accuracy
+ {
+ get
+ {
+ return _accuracy;
+ }
+ set
+ {
+ _accuracy = value;
+ }
+ }
+
+ /// <summary>
+ /// The time value when the measurement was done.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public DateTime Timestamp
+ {
+ get
+ {
+ return Interop.ConvertDateTime(_timestamp);
+ }
+ internal set
+ {
+ Timestamp = value;
+ }
+
+ }
+
+ /// <summary>
+ /// Gets the distance between the two given coordinates.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="startLatitude"> The latitude of the source location [-90.0 ~ 90.0] (degrees).</param>
+ /// <param name="startLongitude"> The Longitude of the source location[-180.0 ~ 180.0] (degrees).</param>
+ /// <param name="endLatitude"> The latitude of the source location [-90.0 ~ 90.0] (degrees).</param>
+ /// <param name="endLongitude"> The longitude of the source location[-180.0 ~ 180.0] (degrees).</param>
+ /// <returns>Returns the distance between source and destination.</returns>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public static double GetDistanceBetween(double startLatitude, double startLongitude, double endLatitude, double endLongitude)
+ {
+ double result;
+ Log.Info(Globals.LogTag, "Calling GetDistanceBetween");
+ int ret = Interop.Location.GetDistanceBetween(startLatitude, startLongitude, endLatitude, endLongitude, out result);
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error getting single distance information ," + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+ return result;
+ }
+
+ /// <summary>
+ /// Gets the distance between the current and specified location.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="location"> The location object to which distance is to be calculated.</param>
+ /// <returns>Returns the distance to the specified location.</returns>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public double GetDistanceTo(Location location)
+ {
+ double result;
+ Log.Info(Globals.LogTag, "Calling GetDistanceTo");
+ int ret = Interop.Location.GetDistanceBetween(this.Latitude, this.Longitude, location.Latitude, location.Longitude, out result);
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error getting distance information to the specifed location," + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+ return result;
+ }
+ }
+}
diff --git a/src/Tizen.Location/Tizen.Location/LocationBoundary.cs b/src/Tizen.Location/Tizen.Location/LocationBoundary.cs
new file mode 100755
index 0000000..f66f609
--- /dev/null
+++ b/src/Tizen.Location/Tizen.Location/LocationBoundary.cs
@@ -0,0 +1,364 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Location
+{
+ /// <summary>
+ /// Abstract class which provides functions related to geographic bounds information.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public abstract class LocationBoundary : IDisposable
+ {
+ internal IntPtr handle;
+ private bool _disposed = false;
+
+ /// <summary>
+ /// Gets the location boundary type.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public BoundaryType BoundaryType{ get; internal set; }
+
+ internal LocationBoundary() { }
+ /// <summary>
+ /// The destructor of LocationBoundary class.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ ~LocationBoundary()
+ {
+ Log.Info(Globals.LogTag, "The destructor of LocationBoundary class");
+ Dispose(false);
+ }
+
+ internal IntPtr GetHandle()
+ {
+ return handle;
+ }
+
+ /// <summary>
+ /// Checks if the boundary contains the specified geographical coordinates.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="coordinate"> The coordinate which needs to be checked.</param>
+ /// <returns>Returns a boolean value indicating whether or not the specified coordinate lies in the geographical area.</returns>
+ public bool BoundaryContainsCoordinates(Coordinate coordinate)
+ {
+ Log.Info(Globals.LogTag, "Checking if coordinates are contained within boundary");
+ return Interop.LocationBoundary.IsValidCoordinates(handle, coordinate);
+ }
+
+ /// <summary>
+ /// The overidden Dispose method of the IDisposable class.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public void Dispose()
+ {
+ Log.Info(Globals.LogTag, "Dispose");
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ Log.Info(Globals.LogTag, "Dispose");
+ if (_disposed)
+ return;
+
+ if (disposing)
+ DestroyHandle();
+
+ _disposed = true;
+ }
+
+ private void DestroyHandle()
+ {
+ Log.Info(Globals.LogTag, "DestroyBoundaryHandle");
+ int ret = Interop.LocationBoundary.DestroyBoundary(handle);
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error in DestroyBoundary handle" + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Class representing a rectangular location boundary.
+ /// Inherits the Abstract LocationBoundary class.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class RectangleBoundary : LocationBoundary
+ {
+ /// <summary>
+ /// Constructor of the Rectangle boundary class.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="topLeft"> The coordinate which constitute the top left handside of the rectangular boundary.</param>
+ /// <param name="bottomRight"> The coordinate which constitute the bottom right handside of the rectangular boundary.</param>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public RectangleBoundary(Coordinate topLeft, Coordinate bottomRight)
+ {
+ Log.Info(Globals.LogTag, "Calling RectangleBoundary constructor");
+ BoundaryType = BoundaryType.Rectangle;
+ IntPtr boundsHandle;
+ int ret = Interop.LocationBoundary.CreateRectangularBoundary(topLeft, bottomRight, out boundsHandle);
+ if ((LocationBoundError)ret != LocationBoundError.None)
+ {
+ Log.Error(Globals.LogTag, "Error Creating Rectangular Boundary," + (LocationBoundError)ret);
+ throw LocationErrorFactory.ThrowLocationBoundaryException(ret);
+ }
+ handle = boundsHandle;
+ }
+
+ /// <summary>
+ /// Gets the Top Left handside coordinate of a rectangular boundary.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public Coordinate TopLeft
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Calling to get CoordinateItem TopLeft");
+ return GetRectangleCoordinate("TopLeft");
+ }
+ }
+
+ /// <summary>
+ /// Gets the Bottom Right handside coordinate of a rectangular boundary.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public Coordinate BottomRight
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Calling to get CoordinateItem BottomRight");
+ return GetRectangleCoordinate("BottomRight");
+ }
+ }
+
+ private Coordinate GetRectangleCoordinate(string tag)
+ {
+ Coordinate topLeft;
+ Coordinate bottomRight;
+
+ Interop.LocationBoundary.GetRectangleCoordinates(handle, out topLeft, out bottomRight);
+
+ if (tag.Equals("TopLeft"))
+ {
+ return topLeft;
+ }
+ else
+ {
+ return bottomRight;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Class representing a circular location boundary.
+ /// Inherits the Abstract LocationBoundary class.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class CircleBoundary : LocationBoundary
+ {
+ /// <summary>
+ /// Constructor of the Circular boundary class.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="coordinate"> The coordinates which constitute the center of the circular boundary.</param>
+ /// <param name="radius"> The radius value of the circular boundary.</param>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public CircleBoundary(Coordinate coordinate, double radius)
+ {
+ Log.Info(Globals.LogTag, "Calling CircleBoundary constructor");
+ BoundaryType = BoundaryType.Circle;
+ IntPtr boundsHandle;
+ int ret = Interop.LocationBoundary.CreateCircleBoundary(coordinate, radius, out boundsHandle);
+ if ((LocationBoundError)ret != LocationBoundError.None)
+ {
+ Log.Error(Globals.LogTag, "Error Creating Circular Boundary," + (LocationBoundError)ret);
+ throw LocationErrorFactory.ThrowLocationBoundaryException(ret);
+ }
+ handle = boundsHandle;
+ }
+
+ /// <summary>
+ /// Gets the coordinate of the center of a circular boundary.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public Coordinate Center
+ {
+ get
+ {
+ return GetCircleCenter();
+ }
+ }
+
+ /// <summary>
+ /// Gets the radius of a circular boundary.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public double Radius
+ {
+ get
+ {
+ return GetRadius();
+ }
+ }
+
+ private Coordinate GetCircleCenter()
+ {
+ Log.Info(Globals.LogTag, "Calling to get CoordinateItem Center");
+ Coordinate center;
+ double radius;
+ int ret = Interop.LocationBoundary.GetCircleCoordinates(handle, out center, out radius);
+ if ((LocationBoundError)ret != LocationBoundError.None)
+ {
+ Log.Error(Globals.LogTag, "Error Get Circle Center," + (LocationBoundError)ret);
+ throw LocationErrorFactory.ThrowLocationBoundaryException(ret);
+ }
+ return center;
+ }
+
+ private double GetRadius()
+ {
+ Coordinate center;
+ double radius = 0;
+ int ret = Interop.LocationBoundary.GetCircleCoordinates(handle, out center, out radius);
+ if ((LocationBoundError)ret != LocationBoundError.None)
+ {
+ Log.Error(Globals.LogTag, "Error Get Radius," + (LocationBoundError)ret);
+ throw LocationErrorFactory.ThrowLocationBoundaryException(ret);
+ }
+ return radius;
+ }
+ }
+
+ /// <summary>
+ /// Class representing a polygonal location boundary.
+ /// Inherits the Abstract LocationBoundary class.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class PolygonBoundary : LocationBoundary
+ {
+ /// <summary>
+ /// Constructor of the polygon boundary class.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="coordinates"> The coordinates which constitute the polgonal boundary.</param>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public PolygonBoundary(IList<Coordinate> coordinates)
+ {
+ Log.Info(Globals.LogTag, "Calling PolygonBoundary Constructor");
+ if (coordinates == null)
+ {
+ Log.Error(Globals.LogTag, "coordingtes list is null");
+ throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
+ }
+
+ BoundaryType = BoundaryType.Polygon;
+ IntPtr listPointer = Marshal.AllocHGlobal(Marshal.SizeOf(coordinates[0]) * coordinates.Count);
+ IntPtr boundsHandle;
+ for (int i = 0; i < coordinates.Count; i++)
+ {
+ Marshal.StructureToPtr(coordinates[i], listPointer + i * Marshal.SizeOf(coordinates[0]), false);
+ }
+ int ret = Interop.LocationBoundary.CreatePolygonBoundary(listPointer, coordinates.Count, out boundsHandle);
+ if ((LocationBoundError)ret != LocationBoundError.None)
+ {
+ Log.Error(Globals.LogTag, "Error Creating Polygon Boundary," + (LocationBoundError)ret);
+ throw LocationErrorFactory.ThrowLocationBoundaryException(ret);
+ }
+ handle = boundsHandle;
+ }
+
+ /// <summary>
+ /// Gets the list of coordinates which constitute a polygonal boundary
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public IList<Coordinate> Coordinates
+ {
+ get
+ {
+ return GetCoordinates();
+ }
+ }
+
+ private IList<Coordinate> GetCoordinates()
+ {
+ Log.Info(Globals.LogTag, "Calling to get Polygon coordinates");
+ List<Coordinate> coordinateList = new List<Coordinate>();
+ Interop.LocationBoundary.PolygonCoordinatesCallback callback = (Coordinate coordinate, IntPtr userData) =>
+ {
+ Coordinate item;
+ item.Latitude = coordinate.Latitude;
+ item.Longitude = coordinate.Longitude;
+ coordinateList.Add(item);
+ return true;
+ };
+
+ int ret = Interop.LocationBoundary.GetForEachPolygonCoordinates(handle, callback, IntPtr.Zero);
+ if ((LocationBoundError)ret != LocationBoundError.None)
+ {
+ Log.Error(Globals.LogTag, "Error Get foreach Boundary," + (LocationBoundError)ret);
+ throw LocationErrorFactory.ThrowLocationBoundaryException(ret);
+ }
+ return coordinateList;
+ }
+ }
+
+ /// <summary>
+ /// The structure which represents the co-ordinates of a geographical location.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ [StructLayout(LayoutKind.Sequential)]
+ public struct Coordinate
+ {
+ /// <summary>
+ /// Latitude component of the co-ordinate.
+ /// Should have a value between [-90.0 ~ 90.0] (degrees).
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public double Latitude;
+
+ /// <summary>
+ /// Longitude component of the co-ordinate.
+ /// Should have a value between [-180.0 ~ 180.0] (degrees).
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public double Longitude;
+ }
+}
diff --git a/src/Tizen.Location/Tizen.Location/LocationChangedEventArgs.cs b/src/Tizen.Location/Tizen.Location/LocationChangedEventArgs.cs
new file mode 100755
index 0000000..6bfe66d
--- /dev/null
+++ b/src/Tizen.Location/Tizen.Location/LocationChangedEventArgs.cs
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Location
+{
+ /// <summary>
+ /// An extended EventArgs class which contains the changed location information.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class LocationChangedEventArgs : EventArgs
+ {
+
+ /// <summary>
+ /// Class Constructor for LocationUpdatedEventArgs class.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="location"> Object of Location class.</param>
+ public LocationChangedEventArgs(Location location)
+ {
+ Location = location;
+ }
+
+ /// <summary>
+ /// Get the Location Update information.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public Location Location { get; private set; }
+ }
+}
diff --git a/src/Tizen.Location/Tizen.Location/LocationError.cs b/src/Tizen.Location/Tizen.Location/LocationError.cs
new file mode 100755
index 0000000..3254d8e
--- /dev/null
+++ b/src/Tizen.Location/Tizen.Location/LocationError.cs
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Location
+{
+ internal static class LocationManagerError
+ {
+ public const int Base = -0x02C00000;
+ public const int BoundsBase = -0x02C00000 | 0x20;
+ }
+
+ /// <summary>
+ /// Location Manager error codes.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum LocationError
+ {
+ None = ErrorCode.None,/**< Successful */
+ OutOfMemory = ErrorCode.OutOfMemory,/**< Out of memory error */
+ InvalidParameter = ErrorCode.InvalidParameter,/**< Invalid parameter */
+ AcessibilityNotallowed = ErrorCode.PermissionDenied,/**< Permission denied */
+ NotSupported = ErrorCode.NotSupported,/**< Address family not supported */
+ IncorrectMethod = LocationManagerError.Base | 0x01,/**< Location manager contains incorrect method for a given call */
+ NetworkFailed = LocationManagerError.Base | 0x02,/**< Network unavailable */
+ ServiceNotAvailable = LocationManagerError.Base | 0x03,/**< Location service is not available */
+ SettingOff = LocationManagerError.Base | 0x04,/**< GPS/WPS, or MOCK setting is not enabled */
+ SecuirtyRestricted = LocationManagerError.Base | 0x05,/**< Restricted by security system policy */
+ }
+
+ /// <summary>
+ /// Location Boundary error codes.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum LocationBoundError
+ {
+ None = ErrorCode.None,/**< Successful */
+ OutOfMemory = ErrorCode.OutOfMemory,/**< Out of memory error */
+ InvalidParameter = ErrorCode.InvalidParameter,/**< Invalid parameter */
+ NotSupported = ErrorCode.NotSupported,/**< Not supported */
+ IncorrectType = LocationManagerError.BoundsBase | 0x01,/**< Incorrect bounds type for a given call */
+ IsAdded = LocationManagerError.BoundsBase | 0x02/**< Cannot remove bounds handle from location manager */
+ }
+
+ internal static class LocationErrorFactory
+ {
+ internal static Exception ThrowLocationException(int errCode)
+ {
+ Log.Error(Globals.LogTag, "Throw Location Exception : " + errCode);
+ LocationError error = (LocationError)errCode;
+ switch (error)
+ {
+ case LocationError.OutOfMemory:
+ return new InvalidOperationException("Out of memory");
+ case LocationError.InvalidParameter:
+ return new ArgumentException("Invalid Parameter passed");
+ case LocationError.AcessibilityNotallowed:
+ return new UnauthorizedAccessException("Accesibility not allowed");
+ case LocationError.NotSupported:
+ return new NotSupportedException("Not supported");
+ case LocationError.IncorrectMethod:
+ return new InvalidOperationException("Incorrect method used");
+ case LocationError.NetworkFailed:
+ return new InvalidOperationException("Network failed");
+ case LocationError.ServiceNotAvailable:
+ return new InvalidOperationException("Service not available");
+ case LocationError.SettingOff:
+ return new InvalidOperationException("Current locationtype setting is off");
+ case LocationError.SecuirtyRestricted:
+ return new InvalidOperationException("Security Restricted");
+ default:
+ return new InvalidOperationException("Unknown Error");
+ }
+ }
+
+ internal static Exception ThrowLocationBoundaryException(int errCode)
+ {
+ LocationBoundError error = (LocationBoundError)errCode;
+ switch (error)
+ {
+ case LocationBoundError.OutOfMemory:
+ return new InvalidOperationException("Out of memory exception");
+ case LocationBoundError.InvalidParameter:
+ return new ArgumentException("Invalid parameter passed");
+ case LocationBoundError.NotSupported:
+ return new NotSupportedException("Not supported");
+ case LocationBoundError.IncorrectType:
+ return new InvalidOperationException("Incorrect type passed");
+ case LocationBoundError.IsAdded:
+ return new InvalidOperationException("Boundary is not addded");
+ default:
+ return new InvalidOperationException("Unknown Error");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Location/Tizen.Location/Locator.cs b/src/Tizen.Location/Tizen.Location/Locator.cs
new file mode 100755
index 0000000..fc3337c
--- /dev/null
+++ b/src/Tizen.Location/Tizen.Location/Locator.cs
@@ -0,0 +1,839 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Tizen.Internals.Errors;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Location
+{
+ static internal class Globals
+ {
+ internal const string LogTag = "Tizen.Location";
+ }
+
+ /// <summary>
+ /// A class which contains the functionality for obtaining geographical infomation and setting boundary condition.
+ /// Notifications on events like service becoming enabled or disabled, new position data being available
+ /// and others can also be acquired.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class Locator : IDisposable
+ {
+ private int _interval = 1;
+ private int _stayInterval = 120;
+ private int _requestId = 0;
+ private double _distance = 120.0;
+ private bool _isEnableMock = false;
+ private bool _disposed = false;
+ private bool _isStarted = false;
+ private IntPtr _handle;
+ private LocationType _locationType;
+ private Location _location = null;
+ private Dictionary<IntPtr, Interop.LocatorEvent.LocationUpdatedCallback> _callback_map = new Dictionary<IntPtr, Interop.LocatorEvent.LocationUpdatedCallback>();
+
+ private Interop.LocatorEvent.ServiceStatechangedCallback _serviceStateChangedCallback;
+ private Interop.LocatorEvent.ZonechangedCallback _zoneChangedCallback;
+ private Interop.LocatorEvent.SettingchangedCallback _settingChangedCallback;
+ private Interop.LocatorEvent.LocationchangedCallback _distanceBasedLocationChangedCallback;
+ private Interop.LocatorEvent.LocationchangedCallback _locationChangedCallback;
+
+ private EventHandler<ZoneChangedEventArgs> _zoneChanged;
+ private EventHandler<ServiceStateChangedEventArgs> _serviceStateChanged;
+ private EventHandler<SettingChangedEventArgs> _settingChanged;
+ private EventHandler<LocationChangedEventArgs> _distanceBasedLocationChanged;
+ private EventHandler<LocationChangedEventArgs> _locationChanged;
+
+ /// <summary>
+ /// The constructor of Locator class.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="locationType"> The back-end positioning method to be used for LBS.</param>
+ /// <feature>http://tizen.org/feature/location</feature>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public Locator(LocationType locationType)
+ {
+ Log.Info(Globals.LogTag, "Locator Constructor");
+ int ret = Interop.Locator.Create((int)locationType, out _handle);
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error creating Location Manager," + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+ _location = new Location();
+ _locationType = locationType;
+ }
+
+ /// <summary>
+ /// The destructor of Locator class.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ ~Locator()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// The time interval between callback updates.
+ /// Should be in the range [1~120] seconds.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public int Interval
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the Callback Interval");
+ return _interval;
+ }
+ set
+ {
+ Log.Info(Globals.LogTag, "Setting the Callback Interval");
+ if (value > 0 && value <= 120)
+ {
+ _interval = value;
+ }
+ else
+ {
+ Log.Error(Globals.LogTag, "Error setting Callback Interval");
+ throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The time interval between Distance based location callback updates.
+ /// Should be in the range [1~120] seconds.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public int StayInterval
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the StayInterval");
+ return _stayInterval;
+ }
+ set
+ {
+ Log.Info(Globals.LogTag, "Setting the StayInterval");
+ if (value > 0 && value <= 120)
+ {
+ _stayInterval = value;
+ }
+ else
+ {
+ Log.Error(Globals.LogTag, "Error Setting the StayInterval");
+ throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The distance between callback updates.
+ /// Should be in the range [1-120] meters.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public double Distance
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the Distance Interval");
+ return _distance;
+ }
+ set
+ {
+ Log.Info(Globals.LogTag, "Setting the Distance Interval");
+ if (value > 0 && value <= 120)
+ {
+ _distance = value;
+ }
+ else
+ {
+ Log.Error(Globals.LogTag, "Error Setting the Distance");
+ throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the Location object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public Location Location
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting location details");
+ return _location;
+ }
+ }
+
+ /// <summary>
+ /// Gets the type used to obtain Location data.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public LocationType LocationType
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting LocationType");
+ return _locationType;
+ }
+ }
+
+ /// <summary>
+ /// Gets the status whether mock location is enabled or not.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>http://tizen.org/privilege/location</privilege>
+ /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the location.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public bool EnableMock
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting getting Mock");
+ _isEnableMock = GetEnableMock();
+ return _isEnableMock;
+ }
+ set
+ {
+ _isEnableMock = value;
+ SetEnableMock();
+ }
+ }
+
+ internal IntPtr GetHandle()
+ {
+ return _handle;
+ }
+
+ private bool GetEnableMock()
+ {
+ bool status = false;
+ int ret = Interop.Locator.IsEnabledMock(out status);
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error Get Enable Mock Status," + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+ return status;
+ }
+
+ private void SetEnableMock()
+ {
+ int ret = Interop.Locator.EnableMock(_isEnableMock);
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error Set Enable Mock Status," + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Starts the Location Manager which has been created using the specified method.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>http://tizen.org/privilege/location</privilege>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the location.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public void Start()
+ {
+ Log.Info(Globals.LogTag, "Starting Location Manager");
+ int ret = Interop.Locator.Start(_handle);
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error Starting Location Manager," + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+ _isStarted = true;
+ }
+
+ /// <summary>
+ /// Stops the Location Manager which has been activated using the specified method.
+ /// Does not destroy the manager.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public void Stop()
+ {
+ Log.Info(Globals.LogTag, "Stopping Location Manager");
+ int ret = Interop.Locator.Stop(_handle);
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error stopping Location Manager," + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+ _isStarted = false;
+ }
+
+ /// <summary>
+ /// Sets a mock location for the given location method.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="location"> The location object containing the mock location details.</param>
+ /// <privilege>http://tizen.org/privilege/location</privilege>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the location.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public void SetMockLocation(Location location)
+ {
+ Log.Info(Globals.LogTag, "Setting mock location");
+ int ret = Interop.Locator.SetMockLocation(_handle, location.Latitude, location.Longitude, location.Altitude, location.Speed, location.Direction, location.Accuracy);
+ if (((LocationError)ret == LocationError.None))
+ {
+ _location.Latitude = location.Latitude;
+ _location.Longitude = location.Longitude;
+ _location.Altitude = location.Altitude;
+ _location.Speed = location.Speed;
+ _location.Direction = location.Direction;
+ _location.Accuracy = location.Accuracy;
+ }
+ else
+ {
+ Log.Error(Globals.LogTag, "Error in setting up location mocking," + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Clears a mock location for the given location method.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>http://tizen.org/privilege/location</privilege>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the location.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public void ClearMock()
+ {
+ Log.Info(Globals.LogTag, "Clear mock location");
+ int ret = Interop.Locator.ClearMock(_handle);
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error in clear up location mocking," + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Gets the details of the location asynchronously.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="timeout"> Timeout to stop requesting single location after(seconds).</param>
+ /// <returns> A task which contains the current location details</returns>
+ /// <privilege>http://tizen.org/privilege/location</privilege>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the location.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public Task<Location> GetLocationAsync(int timeout)
+ {
+ var task = new TaskCompletionSource<Location>();
+ IntPtr id = IntPtr.Zero;
+ lock (_callback_map)
+ {
+ id = (IntPtr)_requestId++;
+ _callback_map[id] = (LocationError error, double latitude, double longitude, double altitude, int timestamp, double speed, double direction, double climb, IntPtr userData) =>
+ {
+ if (error != LocationError.None)
+ {
+ Log.Error(Globals.LogTag, "Error in getting up location information," + (LocationError)error);
+ }
+ else
+ {
+ Log.Info(Globals.LogTag, "Creating a current location object");
+ _location = new Location(latitude, longitude, altitude, speed, direction, 0.0, timestamp);
+ task.SetResult(_location);
+ }
+ lock (_callback_map)
+ {
+ _callback_map.Remove(userData);
+ }
+ };
+ }
+
+ int ret = Interop.LocatorEvent.GetSingleLocation(_handle, timeout, _callback_map[id], id);
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error in setting up location mocking," + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+ return task.Task;
+ }
+
+
+ /// <summary>
+ /// Gets the details of the location.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <returns> which contains the current location details.</returns>
+ /// <privilege>http://tizen.org/privilege/location</privilege>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the location.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public Location GetLocation()
+ {
+ double latitude = 0;
+ double longitude = 0;
+ double altitude = 0;
+ double climb = 0;
+ double speed = 0;
+ double direction = 0;
+ int level = 0;
+ double accuracy = 0;
+ double vertical = 0;
+ int timestamp = 0;
+
+ if (_isStarted)
+ {
+ Log.Info(Globals.LogTag, "Get current location information");
+ int ret = Interop.Locator.GetLocation(_handle, out altitude, out latitude, out longitude, out climb, out direction, out speed, out level, out accuracy, out vertical, out timestamp);
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error in get current location infomation," + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+ }
+ else
+ {
+ Log.Info(Globals.LogTag, "Get last location information");
+ int ret = Interop.Locator.GetLastLocation(_handle, out altitude, out latitude, out longitude, out climb, out direction, out speed, out level, out accuracy, out vertical, out timestamp);
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error in get last location information," + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+ }
+
+ Location location = new Location(latitude, longitude, altitude, speed, direction, accuracy, timestamp);
+ _location = location;
+
+ return location;
+ }
+
+
+ /// <summary>
+ /// Adds a bounds for a given locator.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="locationBoundary"> The boundary object to be added to the locator.</param>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public void AddBoundary(LocationBoundary locationBoundary)
+ {
+ Log.Info(Globals.LogTag, "AddBoundary called");
+
+ int ret = Interop.Locator.AddBoundary(_handle, locationBoundary.GetHandle());
+ if ((LocationBoundError)ret != LocationBoundError.None)
+ {
+ Log.Error(Globals.LogTag, "Error Adding Boundary," + (LocationBoundError)ret);
+ throw LocationErrorFactory.ThrowLocationBoundaryException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Deletes a bounds for a given locator.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="locationBoundary"> The boundary object to be removed from the locator.</param>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public void RemoveBoundary(LocationBoundary locationBoundary)
+ {
+ Log.Info(Globals.LogTag, "RemoveBoundary called");
+ int ret = Interop.Locator.RemoveBoundary(_handle, locationBoundary.GetHandle());
+ if ((LocationBoundError)ret != LocationBoundError.None)
+ {
+ Log.Error(Globals.LogTag, "Error Removing Boundary," + (LocationBoundError)ret);
+ throw LocationErrorFactory.ThrowLocationBoundaryException(ret);
+ }
+ }
+
+ /// <summary>
+ /// The overidden Dispose method of the IDisposable class.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_disposed)
+ return;
+
+ if (disposing)
+ DestroyHandle();
+
+ _disposed = true;
+ }
+
+ private void DestroyHandle()
+ {
+ int ret = Interop.Locator.Destroy(_handle);
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error in Destroy handle, " + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+ }
+
+ /// <summary>
+ /// (event) ServiceStateChanged Event is invoked when the location service state is changed.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public event EventHandler<ServiceStateChangedEventArgs> ServiceStateChanged
+ {
+ add
+ {
+ Log.Info(Globals.LogTag, "ServiceStateChanged called");
+ if (_serviceStateChanged == null)
+ {
+ Log.Info(Globals.LogTag, "Calling function SetServiceStateChangedCallback");
+ SetServiceStateChangedCallback();
+ }
+ _serviceStateChanged += value;
+ }
+ remove
+ {
+ Log.Info(Globals.LogTag, "Callback removed");
+ _serviceStateChanged -= value;
+
+ if (_serviceStateChanged == null)
+ {
+ Log.Info(Globals.LogTag, "Calling function UnSetServiceStateChangedCallback");
+ UnSetServiceStateChangedCallback();
+ }
+ }
+ }
+
+ private void SetServiceStateChangedCallback()
+ {
+ Log.Info(Globals.LogTag, "Calling Interop.LocatorEvent.SetServiceStateChangedCallback");
+ if (_serviceStateChangedCallback == null)
+ {
+ _serviceStateChangedCallback = (state, userData) =>
+ {
+ Log.Info(Globals.LogTag, "Inside ServiceStateChangedCallback");
+ _serviceStateChanged?.Invoke(this, new ServiceStateChangedEventArgs(state));
+ };
+ }
+
+ int ret = Interop.LocatorEvent.SetServiceStateChangedCallback(_handle, _serviceStateChangedCallback, IntPtr.Zero);
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error in Setting Service State Changed Callback," + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+ }
+
+ private void UnSetServiceStateChangedCallback()
+ {
+ Log.Info(Globals.LogTag, "Calling Interop.LocatorEvent.UnSetServiceStateChangedCallback");
+ int ret = Interop.LocatorEvent.UnSetServiceStateChangedCallback(_handle);
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error in UnSetting Service State Changed Callback," + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+ }
+
+ /// <summary>
+ /// (event) ZoneChanged is invoked when the previously set boundary area is entered or left.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public event EventHandler<ZoneChangedEventArgs> ZoneChanged
+ {
+ add
+ {
+ Log.Info(Globals.LogTag, "ZoneChanged called");
+ if (_zoneChanged == null)
+ {
+ Log.Info(Globals.LogTag, "Calling function SetZoneChangedCallback");
+ SetZoneChangedCallback();
+ }
+ _zoneChanged += value;
+ }
+ remove
+ {
+ Log.Info(Globals.LogTag, "Callback removed");
+ _zoneChanged -= value;
+
+ if (_zoneChanged == null)
+ {
+ Log.Info(Globals.LogTag, "Calling function UnSetZoneChangedCallback");
+ UnSetZoneChangedCallback();
+ }
+ }
+ }
+
+ private void SetZoneChangedCallback()
+ {
+ Log.Info(Globals.LogTag, "Inside SetZoneChangedCallback");
+ if (_zoneChangedCallback == null)
+ {
+ _zoneChangedCallback = (state, latitude, longitude, altitude, timestamp, userData) =>
+ {
+ Log.Info(Globals.LogTag, "Inside ZoneChangedCallback");
+ DateTime timeStamp = DateTime.Now;
+ if (timestamp != 0)
+ {
+ DateTime start = DateTime.SpecifyKind(new DateTime(1970, 1, 1).AddSeconds(timestamp), DateTimeKind.Utc);
+ timeStamp = start.ToLocalTime();
+ }
+ _zoneChanged?.Invoke(this, new ZoneChangedEventArgs(state, latitude, longitude, altitude, timeStamp));
+ };
+ }
+
+ int ret = Interop.LocatorEvent.SetZoneChangedCallback(_handle, _zoneChangedCallback, IntPtr.Zero);
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error in Setting Zone Changed Callback," + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+ }
+
+ private void UnSetZoneChangedCallback()
+ {
+ Log.Info(Globals.LogTag, "Inside UnSetZoneChangedCallback");
+ int ret = Interop.LocatorEvent.UnSetZoneChangedCallback(_handle);
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error in UnSetting Zone Changed Callback," + (LocationError)ret);
+ }
+ }
+
+ /// <summary>
+ /// (event) SetttingChanged is raised when the location setting is changed.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public event EventHandler<SettingChangedEventArgs> SettingChanged
+ {
+ add
+ {
+ Log.Info(Globals.LogTag, "Adding SettingChanged EventHandler");
+ if (_settingChanged == null)
+ {
+ Log.Info(Globals.LogTag, "Calling function SetSettingChangedCallback");
+ SetSettingChangedCallback();
+ }
+ _settingChanged += value;
+ }
+ remove
+ {
+ Log.Info(Globals.LogTag, "Removing SettingChanged EventHandler");
+ _settingChanged -= value;
+
+ if (_settingChanged == null)
+ {
+ Log.Info(Globals.LogTag, "Calling function UnSetSettingChangedCallback");
+ UnSetSettingChangedCallback();
+ }
+ }
+ }
+
+ private void SetSettingChangedCallback()
+ {
+ Log.Info(Globals.LogTag, "Calling SetSettingChangedCallback");
+ if (_settingChangedCallback == null)
+ {
+ _settingChangedCallback = (method, enable, userData) =>
+ {
+ Log.Info(Globals.LogTag, "Calling SettingChangedCallback");
+ _settingChanged?.Invoke(this, new SettingChangedEventArgs(method, enable));
+ };
+ }
+
+ int ret = Interop.LocatorEvent.SetSettingChangedCallback((int)_locationType, _settingChangedCallback, IntPtr.Zero);
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error in Setting Changed Callback," + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+ }
+
+ private void UnSetSettingChangedCallback()
+ {
+ Log.Info(Globals.LogTag, "Calling UnSetSettingChangedCallback");
+ int ret = Interop.LocatorEvent.UnSetSettingChangedCallback((int)_locationType);
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error in Unsetting Setting's Callback," + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+ }
+
+ /// <summary>
+ /// (event) DistanceBasedLocationChanged is raised with updated location information.
+ /// The callback will be invoked at minimum interval or minimum distance with updated position information.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public event EventHandler<LocationChangedEventArgs> DistanceBasedLocationChanged
+ {
+ add
+ {
+ Log.Info(Globals.LogTag, "Adding DistanceBasedLocationChanged EventHandler");
+ //if (_distanceBasedLocationChanged == null)
+ {
+ Log.Info(Globals.LogTag, "Calling function SetDistanceBasedLocationChangedCallback");
+ SetDistanceBasedLocationChangedCallback();
+ }
+ _distanceBasedLocationChanged += value;
+ }
+ remove
+ {
+ Log.Info(Globals.LogTag, "Removing DistanceBasedLocationChanged EventHandler");
+ _distanceBasedLocationChanged -= value;
+
+ if (_distanceBasedLocationChanged == null)
+ {
+ Log.Info(Globals.LogTag, "Calling function UnSetDistanceBasedLocationChangedCallback");
+ UnSetDistanceBasedLocationChangedCallback();
+ }
+ }
+ }
+
+ private void SetDistanceBasedLocationChangedCallback()
+ {
+ Log.Info(Globals.LogTag, "SetDistanceBasedLocationChangedCallback");
+ if (_distanceBasedLocationChangedCallback == null) {
+ _distanceBasedLocationChangedCallback = (latitude, longitude, altitude, speed, direction, accuracy, timestamp, userData) =>
+ {
+ Log.Info(Globals.LogTag, "DistanceBasedLocationChangedCallback #1");
+ Location location = new Location(latitude, longitude, altitude, speed, direction, accuracy, timestamp);
+ Log.Info(Globals.LogTag, "DistanceBasedLocationChangedCallback #2");
+ _distanceBasedLocationChanged?.Invoke(this, new LocationChangedEventArgs(location));
+ Log.Info(Globals.LogTag, "DistanceBasedLocationChangedCallback #3");
+ };
+ }
+
+ int ret = Interop.LocatorEvent.SetDistanceBasedLocationChangedCallback(_handle, _distanceBasedLocationChangedCallback, _stayInterval, _distance, IntPtr.Zero);
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error in Setting Distance based location changed Callback," + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+ }
+
+ private void UnSetDistanceBasedLocationChangedCallback()
+ {
+ Log.Info(Globals.LogTag, "UnSetDistanceBasedLocationChangedCallback");
+ int ret = Interop.LocatorEvent.UnSetDistanceBasedLocationChangedCallback(_handle);
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error in UnSetting Distance based location changed Callback," + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+ _distanceBasedLocationChanged = null;
+ }
+
+ /// <summary>
+ /// (event)LocationUpdated is raised at defined intervals of time with updated location information.
+ /// The callback will be invoked periodically.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public event EventHandler<LocationChangedEventArgs> LocationChanged
+ {
+ add
+ {
+ Log.Info(Globals.LogTag, "Adding LocationChanged EventHandler");
+ if (_locationChanged == null)
+ {
+ Log.Info(Globals.LogTag, "Calling function SetLocationChangedCallback");
+ SetLocationChangedCallback();
+ }
+ _locationChanged += value;
+ }
+ remove
+ {
+ Log.Info(Globals.LogTag, "Adding LocationChanged EventHandler");
+ _locationChanged -= value;
+
+ if (_locationChanged == null)
+ {
+ Log.Info(Globals.LogTag, "calling function UnSetLocationChangedCallback");
+ UnSetLocationChangedCallback();
+ }
+ }
+ }
+
+ private void SetLocationChangedCallback()
+ {
+ Log.Info(Globals.LogTag, "Calling SetLocationChangedCallback");
+
+ if (_locationChangedCallback == null) {
+ _locationChangedCallback = (latitude, longitude, altitude, speed, direction, accuracy, timestamp, userData) =>
+ {
+ Log.Info(Globals.LogTag, "LocationChangedCallback has been called");
+ Location location = new Location(latitude, longitude, altitude, speed, direction, accuracy, timestamp);
+ _location = location;
+ _locationChanged?.Invoke(this, new LocationChangedEventArgs(location));
+ };
+ }
+
+ int ret = Interop.LocatorEvent.SetLocationChangedCallback(_handle, _locationChangedCallback, _interval, IntPtr.Zero);
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error in Setting location changed Callback," + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+ }
+
+ private void UnSetLocationChangedCallback()
+ {
+ Log.Info(Globals.LogTag, "Calling UnSetLocationChangedCallback");
+ int ret = Interop.LocatorEvent.UnSetLocationChangedCallback(_handle);
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error in UnSetting location changed Callback," + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Location/Tizen.Location/LocatorEnumerations.cs b/src/Tizen.Location/Tizen.Location/LocatorEnumerations.cs
new file mode 100755
index 0000000..8f04a80
--- /dev/null
+++ b/src/Tizen.Location/Tizen.Location/LocatorEnumerations.cs
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Location
+{
+ /// <summary>
+ /// Enumeration for the state of the location service.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum ServiceState
+ {
+ Disabled = 0, /**<Service is disabled.*/
+ Enabled /**<Service is enabled.*/
+ }
+
+ /// <summary>
+ /// Enumeration for the type of connection used in acquiring Location data.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum LocationType
+ {
+ Hybrid = 0, /**<This method selects the best method available at the moment.*/
+ Gps, /**<This method uses Global Positioning System.*/
+ Wps, /**<This method uses WiFi Positioning System.*/
+ Passive, /**<This method uses passive mode.*/
+ }
+
+ /// <summary>
+ /// Enumeration for the created boundary type.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum BoundaryType
+ {
+ Rectangle = 0, /**<Rectangular geographical area type. */
+ Circle, /**<Rectangular geographical area type. */
+ Polygon /**<Rectangular geographical area type. */
+ }
+
+ /// <summary>
+ /// Enumeration for error code for Location manager.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum BoundaryState
+ {
+ In = 0, /**< Boundary In (Zone In) */
+ Out /**< Boundary Out (Zone Out) */
+ }
+}
diff --git a/src/Tizen.Location/Tizen.Location/LocatorHelper.cs b/src/Tizen.Location/Tizen.Location/LocatorHelper.cs
new file mode 100755
index 0000000..5ad09ee
--- /dev/null
+++ b/src/Tizen.Location/Tizen.Location/LocatorHelper.cs
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Location
+{
+ public static class LocatorHelper
+ {
+ /// <summary>
+ /// Checks if the specified geographical positioning type is supported or not.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="locationType"> The back-end positioning method to be used for LBS.</param>
+ /// <returns>Returns a boolean value indicating whether or not the specified method is supported.</returns>
+ public static bool IsSupportedType(LocationType locationType)
+ {
+ bool status = Interop.LocatorHelper.IsSupported((int)locationType);
+ Log.Info(Globals.LogTag, "Checking if the Location Manager type is supported ," + status);
+ return status;
+ }
+
+ /// <summary>
+ /// Checks if the specified geographical positioning type is enabled or not.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="locationType"> The back-end positioning method to be used for LBS.</param>
+ /// <returns>Returns a boolean value indicating whether or not the specified method is supported.</returns>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
+ public static bool IsEnabledType(LocationType locationType)
+ {
+ Log.Info(Globals.LogTag, "Checking if the Location Manager type is Enabled");
+ bool status;
+ int ret = Interop.LocatorHelper.IsEnabled((int)locationType, out status);
+ if (((LocationError)ret != LocationError.None))
+ {
+ Log.Error(Globals.LogTag, "Error Checking the Location Manager type is Enabled," + (LocationError)ret);
+ throw LocationErrorFactory.ThrowLocationException(ret);
+ }
+ return status;
+ }
+ }
+}
diff --git a/src/Tizen.Location/Tizen.Location/NamespaceDoc.cs b/src/Tizen.Location/Tizen.Location/NamespaceDoc.cs
new file mode 100755
index 0000000..e8ba5d4
--- /dev/null
+++ b/src/Tizen.Location/Tizen.Location/NamespaceDoc.cs
@@ -0,0 +1,21 @@
+/**
+<summary>
+The Tizen.Location namespace provides classes for obtaining information related to geographical location.
+Notifications on events like service becoming enabled or disabled,
+new position data being available and others can also be acquired.
+</summary>
+<remarks>
+<h2>Overview</h2>
+<para>The Tizen.Location namespace provides classes for obtaining information related to geographical location.
+Notifications on events like service becoming enabled or disabled,
+new position data being available and others can also be acquired.</para>
+<h2>Related Features</h2>
+<para>To guarantee that the Location application runs on a device with location profile feature,
+declare the following feature requirements in the config file:<br/>
+http://tizen.org/feature/location<br/>
+http://tizen.org/feature/location.gps<br/>
+http://tizen.org/feature/location.wps
+</para>
+</remarks>
+*/
+namespace Tizen.Location {}
diff --git a/src/Tizen.Location/Tizen.Location/SatelliteStatusChangedEventArgs.cs b/src/Tizen.Location/Tizen.Location/SatelliteStatusChangedEventArgs.cs
new file mode 100755
index 0000000..c6f4ba4
--- /dev/null
+++ b/src/Tizen.Location/Tizen.Location/SatelliteStatusChangedEventArgs.cs
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Location
+{
+ public class SatelliteStatusChangedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Class Constructor for SatelliteStatusChangedEventArgs class.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="activeCount"> The number of active satellites.</param>
+ /// <param name="inviewCount"> The number of satellites in view.</param>
+ /// <param name="timestamp"> The time at which the data has been extracted.</param>
+ public SatelliteStatusChangedEventArgs(uint activeCount, uint inviewCount, DateTime timestamp)
+ {
+ ActiveCount = activeCount;
+ InViewCount = inviewCount;
+ Timestamp = timestamp;
+ }
+
+ /// <summary>
+ /// Gets the number of active satellites.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public uint ActiveCount { get; private set; }
+
+ /// <summary>
+ /// Gets the number of satellites in view.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public uint InViewCount { get; private set; }
+
+ /// <summary>
+ /// Get the timestamp.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public DateTime Timestamp { get; private set; }
+ }
+}
diff --git a/src/Tizen.Location/Tizen.Location/ServiceStateChangedEventArgs.cs b/src/Tizen.Location/Tizen.Location/ServiceStateChangedEventArgs.cs
new file mode 100755
index 0000000..35ff1a7
--- /dev/null
+++ b/src/Tizen.Location/Tizen.Location/ServiceStateChangedEventArgs.cs
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Location
+{
+ /// <summary>
+ /// An extended EventArgs class which contains the changed location service state.
+ /// </summary>
+ public class ServiceStateChangedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Class Constructor for ServiceStateChangedEventArgs class.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="state"> An enumeration of type LocationServiceState.</param>
+ public ServiceStateChangedEventArgs(ServiceState state)
+ {
+ ServiceState = state;
+ }
+
+ /// <summary>
+ /// Get the Service state.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public ServiceState ServiceState { get; private set; }
+ }
+}
diff --git a/src/Tizen.Location/Tizen.Location/SettingChangedEventArgs.cs b/src/Tizen.Location/Tizen.Location/SettingChangedEventArgs.cs
new file mode 100755
index 0000000..2869b69
--- /dev/null
+++ b/src/Tizen.Location/Tizen.Location/SettingChangedEventArgs.cs
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Location
+{
+ public class SettingChangedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Class Constructor for SettingChangedEventArgs class.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="method"> The positioing method used for Location information.</param>
+ /// <param name="enable"> Status of the method.</param>
+ public SettingChangedEventArgs(LocationType type, bool enable)
+ {
+ LocationType = type;
+ IsEnabled = enable;
+ }
+
+ /// <summary>
+ /// Gets the currently used location method.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public LocationType LocationType { get; private set; }
+
+ /// <summary>
+ /// Method to get the setting value changed.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public bool IsEnabled { get; private set; }
+ }
+}
diff --git a/src/Tizen.Location/Tizen.Location/ZoneChangedEventArgs.cs b/src/Tizen.Location/Tizen.Location/ZoneChangedEventArgs.cs
new file mode 100755
index 0000000..9bc05e4
--- /dev/null
+++ b/src/Tizen.Location/Tizen.Location/ZoneChangedEventArgs.cs
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Location
+{
+ public class ZoneChangedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Class Constructor for ZoneChangedEventArgs class.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="state"> An enumeration of type BoundaryState.</param>
+ /// <param name="latitude"> The latitude value[-90.0 ~ 90.0] (degrees).</param>
+ /// <param name="longitude"> The longitude value[-180.0 ~ 180.0] (degrees).</param>
+ /// <param name="altitude"> The altitude value.</param>
+ /// <param name="timestamp"> The timestamp value.</param>
+ public ZoneChangedEventArgs(BoundaryState state, double latitude, double longitude, double altitude, DateTime timestamp)
+ {
+ BoundState = state;
+ Latitude = latitude;
+ Longitude = longitude;
+ Altitude = altitude;
+ Timestamp = timestamp;
+ }
+
+ /// <summary>
+ /// Get the Boundary State.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public BoundaryState BoundState { get; private set; }
+
+ /// <summary>
+ /// Get the latitude.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public double Latitude { get; private set; }
+
+ /// <summary>
+ /// Get the longitude.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public double Longitude { get; private set; }
+
+ /// <summary>
+ /// Get the altitude.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public double Altitude { get; private set; }
+
+ /// <summary>
+ /// Method to get the timestamp.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public DateTime Timestamp { get; private set; }
+ }
+}
diff --git a/src/Tizen.Log/Interop/Interop.Dlog.cs b/src/Tizen.Log/Interop/Interop.Dlog.cs
new file mode 100644
index 0000000..db12535
--- /dev/null
+++ b/src/Tizen.Log/Interop/Interop.Dlog.cs
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string Dlog = "libdlog.so.0";
+ }
+
+ internal static partial class Dlog
+ {
+ internal enum LogID : int
+ {
+ LOG_ID_INVALID = -1,
+ LOG_ID_MAIN,
+ LOG_ID_RADIO,
+ LOG_ID_SYSTEM,
+ LOG_ID_APPS,
+ LOG_ID_KMSG,
+ LOG_ID_MAX
+ }
+
+ internal enum LogPriority : int
+ {
+ DLOG_UNKNOWN = 0,
+ DLOG_DEFAULT,
+ DLOG_VERBOSE,
+ DLOG_DEBUG,
+ DLOG_INFO,
+ DLOG_WARN,
+ DLOG_ERROR,
+ DLOG_FATAL,
+ DLOG_SILENT,
+ DLOG_PRIO_MAX,
+ }
+
+ [DllImport(Libraries.Dlog, EntryPoint = "dlog_print", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int Print(LogPriority prio, string tag, string fmt, string msg);
+
+ [DllImport(Libraries.Dlog, EntryPoint = "dlog_print", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int Print(LogPriority prio, string tag, string fmt, string file, string func, int line, string msg);
+
+ [DllImport(Libraries.Dlog, EntryPoint = "__dlog_print", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int InternalPrint(LogID log_id, LogPriority prio, string tag, string fmt, string msg);
+
+ [DllImport(Libraries.Dlog, EntryPoint = "__dlog_print", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int InternalPrint(LogID log_id, LogPriority prio, string tag, string fmt, string file, string func, int line, string msg);
+
+ }
+}
+
diff --git a/src/Tizen.Log/Tizen.Log.csproj b/src/Tizen.Log/Tizen.Log.csproj
new file mode 100644
index 0000000..88c3f81
--- /dev/null
+++ b/src/Tizen.Log/Tizen.Log.csproj
@@ -0,0 +1,9 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Log/Tizen/Log.cs b/src/Tizen.Log/Tizen/Log.cs
new file mode 100644
index 0000000..65126c5
--- /dev/null
+++ b/src/Tizen.Log/Tizen/Log.cs
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.IO;
+using System.Runtime.CompilerServices;
+using System.ComponentModel;
+
+namespace Tizen
+{
+ /// <summary>
+ /// Provides methods to print log messages to Tizen logging system.
+ /// </summary>
+ public class Log
+ {
+ /// <summary>
+ /// Prints a log message with the VERBOSE priority.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="tag">The tag name of the log message.</param>
+ /// <param name="message">The log message to print.</param>
+ /// <param name="file">The source file path of the caller function. This argument will be set automatically by the compiler.</param>
+ /// <param name="func">The function name of caller function. This argument will be set automatically by the compiler.</param>
+ /// <param name="line">The line number of calling position. This argument will be set automatically by the compiler.</param>
+ public static void Verbose(string tag, string message, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ Print(Interop.Dlog.LogPriority.DLOG_VERBOSE, tag, message, file, func, line);
+ }
+
+ /// <summary>
+ /// Prints a log message with the DEBUG priority.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="tag">The tag name of the log message.</param>
+ /// <param name="message">The log message to print.</param>
+ /// <param name="file">The source file path of the caller function. This argument will be set automatically by the compiler.</param>
+ /// <param name="func">The function name of caller function. This argument will be set automatically by the compiler.</param>
+ /// <param name="line">The line number of calling position. This argument will be set automatically by the compiler.</param>
+ public static void Debug(string tag, string message, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ Print(Interop.Dlog.LogPriority.DLOG_DEBUG, tag, message, file, func, line);
+ }
+
+ /// <summary>
+ /// Prints a log message with the INFO priority.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="tag">The tag name of the log message.</param>
+ /// <param name="message">The log message to print.</param>
+ /// <param name="file">The source file path of the caller function. This argument will be set automatically by the compiler.</param>
+ /// <param name="func">The function name of caller function. This argument will be set automatically by the compiler.</param>
+ /// <param name="line">The line number of calling position. This argument will be set automatically by the compiler.</param>
+ public static void Info(string tag, string message, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ Print(Interop.Dlog.LogPriority.DLOG_INFO, tag, message, file, func, line);
+ }
+
+ /// <summary>
+ /// Prints a log message with the WARNING priority.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="tag">The tag name of the log message.</param>
+ /// <param name="message">The log message to print.</param>
+ /// <param name="file">The source file path of the caller function. This argument will be set automatically by the compiler.</param>
+ /// <param name="func">The function name of caller function. This argument will be set automatically by the compiler.</param>
+ /// <param name="line">The line number of calling position. This argument will be set automatically by the compiler.</param>
+ public static void Warn(string tag, string message, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ Print(Interop.Dlog.LogPriority.DLOG_WARN, tag, message, file, func, line);
+ }
+
+ /// <summary>
+ /// Prints a log message with the ERROR priority.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="tag">The tag name of the log message.</param>
+ /// <param name="message">The log message to print.</param>
+ /// <param name="file">The source file path of the caller function. This argument will be set automatically by the compiler.</param>
+ /// <param name="func">The function name of caller function. This argument will be set automatically by the compiler.</param>
+ /// <param name="line">The line number of calling position. This argument will be set automatically by the compiler.</param>
+ public static void Error(string tag, string message, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ Print(Interop.Dlog.LogPriority.DLOG_ERROR, tag, message, file, func, line);
+ }
+
+ /// <summary>
+ /// Prints a log message with the FATAL priority.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="tag">The tag name of the log message.</param>
+ /// <param name="message">The log message to print.</param>
+ /// <param name="file">The source file path of the caller function. This argument will be set automatically by the compiler.</param>
+ /// <param name="func">The function name of caller function. This argument will be set automatically by the compiler.</param>
+ /// <param name="line">The line number of calling position. This argument will be set automatically by the compiler.</param>
+ public static void Fatal(string tag, string message, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ Print(Interop.Dlog.LogPriority.DLOG_FATAL, tag, message, file, func, line);
+ }
+
+ static void Print(Interop.Dlog.LogPriority priority, string tag, string message, string file, string func, int line)
+ {
+ if (String.IsNullOrEmpty(file))
+ {
+ Interop.Dlog.Print(priority, tag, "%s", message);
+ }
+ else
+ {
+ Uri f = new Uri("file://" + file);
+ Interop.Dlog.Print(priority, tag, "%s: %s(%d) > %s", Path.GetFileName(f.AbsolutePath), func, line, message);
+ }
+ }
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public class InternalLog
+ {
+ public static void Verbose(string tag, string message, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ // For internal dlog APIs, Verbose level log is disabled
+ // Print(Interop.Dlog.LogID.LOG_ID_MAIN, Interop.Dlog.LogPriority.DLOG_VERBOSE, tag, message, file, func, line);
+ }
+
+ public static void Debug(string tag, string message, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ Print(Interop.Dlog.LogID.LOG_ID_MAIN, Interop.Dlog.LogPriority.DLOG_DEBUG, tag, message, file, func, line);
+ }
+
+ public static void Info(string tag, string message, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ Print(Interop.Dlog.LogID.LOG_ID_MAIN, Interop.Dlog.LogPriority.DLOG_INFO, tag, message, file, func, line);
+ }
+
+ public static void Warn(string tag, string message, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ Print(Interop.Dlog.LogID.LOG_ID_MAIN, Interop.Dlog.LogPriority.DLOG_WARN, tag, message, file, func, line);
+ }
+
+ public static void Error(string tag, string message, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ Print(Interop.Dlog.LogID.LOG_ID_MAIN, Interop.Dlog.LogPriority.DLOG_ERROR, tag, message, file, func, line);
+ }
+
+ public static void Fatal(string tag, string message, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ Print(Interop.Dlog.LogID.LOG_ID_MAIN, Interop.Dlog.LogPriority.DLOG_FATAL, tag, message, file, func, line);
+ }
+
+ static void Print(Interop.Dlog.LogID log_id, Interop.Dlog.LogPriority priority, string tag, string message, string file, string func, int line)
+ {
+ if (String.IsNullOrEmpty(file))
+ {
+ Interop.Dlog.InternalPrint(log_id, priority, tag, "%s", message);
+ }
+ else
+ {
+ Uri f = new Uri("file://" + file);
+ Interop.Dlog.InternalPrint(log_id, priority, tag, "%s: %s(%d) > %s", Path.GetFileName(f.AbsolutePath), func, line, message);
+ }
+ }
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public class SecureLog
+ {
+ public static void Verbose(string tag, string message, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ // For internal dlog APIs, Verbose level log is disabled
+ // Print(Interop.Dlog.LogID.LOG_ID_MAIN, Interop.Dlog.LogPriority.DLOG_VERBOSE, tag, message, file, func, line);
+ }
+
+ public static void Debug(string tag, string message, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ Print(Interop.Dlog.LogID.LOG_ID_MAIN, Interop.Dlog.LogPriority.DLOG_DEBUG, tag, message, file, func, line);
+ }
+
+ public static void Info(string tag, string message, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ Print(Interop.Dlog.LogID.LOG_ID_MAIN, Interop.Dlog.LogPriority.DLOG_INFO, tag, message, file, func, line);
+ }
+
+ public static void Warn(string tag, string message, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ Print(Interop.Dlog.LogID.LOG_ID_MAIN, Interop.Dlog.LogPriority.DLOG_WARN, tag, message, file, func, line);
+ }
+
+ public static void Error(string tag, string message, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ Print(Interop.Dlog.LogID.LOG_ID_MAIN, Interop.Dlog.LogPriority.DLOG_ERROR, tag, message, file, func, line);
+ }
+
+ public static void Fatal(string tag, string message, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ Print(Interop.Dlog.LogID.LOG_ID_MAIN, Interop.Dlog.LogPriority.DLOG_FATAL, tag, message, file, func, line);
+ }
+
+ static void Print(Interop.Dlog.LogID log_id, Interop.Dlog.LogPriority priority, string tag, string message, string file, string func, int line)
+ {
+#if !DISABLE_SECURELOG
+ if (String.IsNullOrEmpty(file))
+ {
+ Interop.Dlog.InternalPrint(log_id, priority, tag, "[SECURE_LOG] %s", message);
+ }
+ else
+ {
+ Uri f = new Uri("file://" + file);
+ Interop.Dlog.InternalPrint(log_id, priority, tag, "%s: %s(%d) > [SECURE_LOG] %s", Path.GetFileName(f.AbsolutePath), func, line, message);
+ }
+#endif
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.Address.cs b/src/Tizen.Maps/Interop/Interop.Address.cs
new file mode 100755
index 0000000..90840c0
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.Address.cs
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ [DllImport(Libraries.MapService, EntryPoint = "maps_address_get_building_number")]
+ internal static extern ErrorCode GetBuildingNumber(this AddressHandle /* maps_address_h */ address, out string buildingNumber);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_address_set_building_number")]
+ internal static extern ErrorCode SetBuildingNumber(this AddressHandle /* maps_address_h */ address, string buildingNumber);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_address_get_street")]
+ internal static extern ErrorCode GetStreet(this AddressHandle /* maps_address_h */ address, out string street);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_address_set_street")]
+ internal static extern ErrorCode SetStreet(this AddressHandle /* maps_address_h */ address, string street);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_address_get_district")]
+ internal static extern ErrorCode GetDistrict(this AddressHandle /* maps_address_h */ address, out string district);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_address_set_district")]
+ internal static extern ErrorCode SetDistrict(this AddressHandle /* maps_address_h */ address, string district);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_address_get_city")]
+ internal static extern ErrorCode GetCity(this AddressHandle /* maps_address_h */ address, out string city);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_address_set_city")]
+ internal static extern ErrorCode SetCity(this AddressHandle /* maps_address_h */ address, string city);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_address_get_state")]
+ internal static extern ErrorCode GetState(this AddressHandle /* maps_address_h */ address, out string state);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_address_set_state")]
+ internal static extern ErrorCode SetState(this AddressHandle /* maps_address_h */ address, string state);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_address_get_country")]
+ internal static extern ErrorCode GetCountry(this AddressHandle /* maps_address_h */ address, out string country);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_address_set_country")]
+ internal static extern ErrorCode SetCountry(this AddressHandle /* maps_address_h */ address, string country);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_address_get_country_code")]
+ internal static extern ErrorCode GetCountryCode(this AddressHandle /* maps_address_h */ address, out string countryCode);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_address_set_country_code")]
+ internal static extern ErrorCode SetCountryCode(this AddressHandle /* maps_address_h */ address, string countryCode);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_address_get_county")]
+ internal static extern ErrorCode GetCounty(this AddressHandle /* maps_address_h */ address, out string county);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_address_set_county")]
+ internal static extern ErrorCode SetCounty(this AddressHandle /* maps_address_h */ address, string county);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_address_get_postal_code")]
+ internal static extern ErrorCode GetPostalCode(this AddressHandle /* maps_address_h */ address, out string postalCode);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_address_set_postal_code")]
+ internal static extern ErrorCode SetPostalCode(this AddressHandle /* maps_address_h */ address, string postalCode);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_address_get_freetext")]
+ internal static extern ErrorCode GetFreeText(this AddressHandle /* maps_address_h */ address, out string freetext);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_address_set_freetext")]
+ internal static extern ErrorCode SetFreeText(this AddressHandle /* maps_address_h */ address, string freetext);
+
+ internal class AddressHandle : SafeMapsHandle
+ {
+ [DllImport(Libraries.MapService, EntryPoint = "maps_address_create")]
+ internal static extern ErrorCode Create(out IntPtr /* maps_address_h */ address);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_address_destroy")]
+ internal static extern ErrorCode Destroy(IntPtr /* maps_address_h */ address);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_address_clone")]
+ internal static extern ErrorCode Clone(IntPtr /* maps_address_h */ origin, out IntPtr /* maps_address_h */ cloned);
+
+ internal string Building
+ {
+ get { return NativeGet(this.GetBuildingNumber); }
+ set { NativeSet(this.SetBuildingNumber, value); }
+ }
+
+ internal string Street
+ {
+ get { return NativeGet(this.GetStreet); }
+ set { NativeSet(this.SetStreet, value); }
+ }
+
+ internal string City
+ {
+ get { return NativeGet(this.GetCity); }
+ set { NativeSet(this.SetCity, value); }
+ }
+
+ internal string District
+ {
+ get { return NativeGet(this.GetDistrict); }
+ set { NativeSet(this.SetDistrict, value); }
+ }
+
+ internal string State
+ {
+ get { return NativeGet(this.GetState); }
+ set { NativeSet(this.SetState, value); }
+ }
+
+ internal string Country
+ {
+ get { return NativeGet(this.GetCountry); }
+ set { NativeSet(this.SetCountry, value); }
+ }
+
+ internal string CountryCode
+ {
+ get { return NativeGet(this.GetCountryCode); }
+ set { NativeSet(this.SetCountryCode, value); }
+ }
+
+ internal string County
+ {
+ get { return NativeGet(this.GetCounty); }
+ set { NativeSet(this.SetCounty, value); }
+ }
+
+ internal string PostalCode
+ {
+ get { return NativeGet(this.GetPostalCode); }
+ set { NativeSet(this.SetPostalCode, value); }
+ }
+
+ internal string FreeText
+ {
+ get { return NativeGet(this.GetFreeText); }
+ set { NativeSet(this.SetFreeText, value); }
+ }
+
+ internal AddressHandle(IntPtr handle, bool needToRelease) : base(handle, needToRelease, Destroy)
+ {
+ }
+
+ internal AddressHandle() : this(IntPtr.Zero, true)
+ {
+ Create(out handle).ThrowIfFailed("Failed to create native handle");
+ }
+
+ internal static AddressHandle CloneFrom(IntPtr nativeHandle)
+ {
+ IntPtr handle;
+ Clone(nativeHandle, out handle).ThrowIfFailed("Failed to clone native handle");
+ return new AddressHandle(handle, true);
+ }
+
+ internal static AddressHandle Create(IntPtr nativeHandle)
+ {
+ return new AddressHandle(nativeHandle, true);
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.AddressList.cs b/src/Tizen.Maps/Interop/Interop.AddressList.cs
new file mode 100755
index 0000000..ebbc6d3
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.AddressList.cs
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ [DllImport(Libraries.MapService, EntryPoint = "maps_address_list_append")]
+ internal static extern ErrorCode ListAppend(this AddressListHandle /* maps_address_list_h */ addressList, AddressHandle /* maps_address_h */ address);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_address_list_remove")]
+ internal static extern ErrorCode ListRemove(this AddressListHandle /* maps_address_list_h */ addressList, AddressHandle /* maps_address_h */ address);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_address_list_get_length")]
+ internal static extern ErrorCode ListGetLength(this AddressListHandle /* maps_address_list_h */ addressList, out int length);
+
+
+ internal class AddressListHandle : SafeMapsHandle
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool AddressCallback(int index, IntPtr /* maps_address_h */ addressHandle, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_address_list_create")]
+ internal static extern ErrorCode Create(out IntPtr /* maps_address_list_h */ addressList);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_address_list_destroy")]
+ internal static extern ErrorCode Destroy(IntPtr /* maps_address_list_h */ addressList);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_address_list_foreach")]
+ internal static extern ErrorCode Foreach(IntPtr /* maps_address_list_h */ addressList, AddressCallback callback, IntPtr /* void */ userData);
+
+ internal AddressListHandle() : base(IntPtr.Zero, true, Destroy)
+ {
+ Create(out handle).ThrowIfFailed("Failed to create native handle");
+ }
+
+ internal AddressListHandle(IntPtr handle, bool needToRelease) : base(handle, needToRelease, Destroy)
+ {
+ }
+
+ internal void Foreach(Action<AddressHandle> action)
+ {
+ AddressCallback callback = (index, handle, userData) =>
+ {
+ action(AddressHandle.CloneFrom(handle));
+ return true;
+ };
+
+ Foreach(handle, callback, IntPtr.Zero).WarnIfFailed("Failed to get address list from native handle");
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.Area.cs b/src/Tizen.Maps/Interop/Interop.Area.cs
new file mode 100755
index 0000000..cf56832
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.Area.cs
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal class AreaHandle : SafeMapsHandle
+ {
+ [DllImport(Libraries.MapService, EntryPoint = "maps_area_create_rectangle")]
+ internal static extern ErrorCode CreateRectangle(IntPtr /* maps_coordinates_h */ topLeft, IntPtr /* maps_coordinates_h */ bottomRight, out IntPtr /* maps_area_h */ area);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_area_create_circle")]
+ internal static extern ErrorCode CreateCircle(IntPtr /* maps_coordinates_h */ center, double radius, out IntPtr /* maps_area_h */ area);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_area_destroy")]
+ internal static extern ErrorCode Destroy(IntPtr /* maps_area_h */ area);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_area_clone")]
+ internal static extern ErrorCode Clone(IntPtr /* maps_area_h */ origin, out IntPtr /* maps_area_h */ cloned);
+
+ internal AreaHandle(IntPtr handle, bool needToRelease) : base(handle, needToRelease, Destroy)
+ {
+ }
+
+ internal AreaHandle(CoordinatesHandle topLeft, CoordinatesHandle bottomRight) : this(IntPtr.Zero, true)
+ {
+ IntPtr _topLeft = (topLeft != null ? topLeft : IntPtr.Zero);
+ IntPtr _bottomRight = (bottomRight != null ? bottomRight : IntPtr.Zero);
+ CreateRectangle(_topLeft, _bottomRight, out handle).ThrowIfFailed("Failed to create native handle");
+ }
+
+ internal AreaHandle(CoordinatesHandle center, double radius) : this(IntPtr.Zero, true)
+ {
+ IntPtr _center = (center != null ? center : IntPtr.Zero);
+ CreateCircle(_center, radius, out handle).ThrowIfFailed("Failed to create native handle");
+ }
+
+ internal static AreaHandle CloneFrom(IntPtr nativeHandle)
+ {
+ IntPtr handle;
+ Clone(nativeHandle, out handle).ThrowIfFailed("Failed to clone native handle");
+ return new AreaHandle(handle, true);
+ }
+
+ internal static AreaHandle Create(IntPtr nativeHandle)
+ {
+ return new AreaHandle(nativeHandle, true);
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.Coordinates.cs b/src/Tizen.Maps/Interop/Interop.Coordinates.cs
new file mode 100755
index 0000000..6a06431
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.Coordinates.cs
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ [DllImport(Libraries.MapService, EntryPoint = "maps_coordinates_get_latitude")]
+ internal static extern ErrorCode GetLatitude(this CoordinatesHandle /* maps_coordinates_h */ coordinates, out double latitude);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_coordinates_get_longitude")]
+ internal static extern ErrorCode GetLongitude(this CoordinatesHandle /* maps_coordinates_h */ coordinates, out double longitude);
+
+ internal class CoordinatesHandle : SafeMapsHandle
+ {
+ [DllImport(Libraries.MapService, EntryPoint = "maps_coordinates_create")]
+ internal static extern ErrorCode Create(double latitude, double longitude, out IntPtr /* maps_coordinates_h */ coordinates);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_coordinates_destroy")]
+ internal static extern ErrorCode Destroy(IntPtr /* maps_coordinates_h */ coordinates);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_coordinates_clone")]
+ internal static extern ErrorCode Clone(IntPtr /* maps_coordinates_h */ origin, out IntPtr /* maps_coordinates_h */ cloned);
+
+ internal double Latitude
+ {
+ get { return NativeGet<double>(this.GetLatitude); }
+ }
+
+ internal double Longitude
+ {
+ get { return NativeGet<double>(this.GetLongitude); }
+ }
+
+ internal CoordinatesHandle(IntPtr handle, bool needToRelease) : base(handle, needToRelease, Destroy)
+ {
+ }
+
+ internal CoordinatesHandle(double latitude, double longitude) : this(IntPtr.Zero, true)
+ {
+ Create(latitude, longitude, out handle).ThrowIfFailed("Failed to create native handle");
+ }
+
+ internal static CoordinatesHandle CloneFrom(IntPtr nativeHandle)
+ {
+ IntPtr handle;
+ Clone(nativeHandle, out handle).ThrowIfFailed("Failed to clone native handle");
+ return new CoordinatesHandle(handle, true);
+ }
+
+ internal static CoordinatesHandle Create(IntPtr nativeHandle)
+ {
+ return new CoordinatesHandle(nativeHandle, true);
+ }
+
+ public override string ToString()
+ {
+ return $"[{Latitude}, {Longitude}]";
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.CoordinatesList.cs b/src/Tizen.Maps/Interop/Interop.CoordinatesList.cs
new file mode 100755
index 0000000..5c31cf9
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.CoordinatesList.cs
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ [DllImport(Libraries.MapService, EntryPoint = "maps_coordinates_list_append")]
+ internal static extern ErrorCode Append(this CoordinatesListHandle /* maps_coordinates_list_h */ coordinatesList, IntPtr /* maps_coordinates_h */ coordinates);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_coordinates_list_remove")]
+ internal static extern ErrorCode Remove(this CoordinatesListHandle /* maps_coordinates_list_h */ coordinatesList, CoordinatesHandle /* maps_coordinates_h */ coordinates);
+
+
+ internal class CoordinatesListHandle : SafeMapsHandle
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool CoordinatesCallback(int index, IntPtr /* maps_coordinates_h */ coordinates, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_coordinates_list_create")]
+ internal static extern ErrorCode Create(out IntPtr /* maps_coordinates_list_h */ coordinatesList);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_coordinates_list_destroy")]
+ internal static extern ErrorCode Destroy(IntPtr /* maps_coordinates_list_h */ coordinatesList);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_coordinates_list_foreach")]
+ internal static extern ErrorCode Foreach(IntPtr /* maps_coordinates_list_h */ coordinatesList, CoordinatesCallback callback, IntPtr /* void */ userData);
+
+ internal CoordinatesListHandle(IntPtr handle, bool needToRelease) : base(handle, needToRelease, Destroy) { }
+
+ internal CoordinatesListHandle(bool needToRelease = true) : this(IntPtr.Zero, needToRelease)
+ {
+ Create(out handle).ThrowIfFailed("Failed to create native handle");
+ }
+
+ internal void Add(CoordinatesHandle handleToAdd)
+ {
+ using (var clonedHandle = CoordinatesHandle.CloneFrom(handleToAdd))
+ {
+ if (this.Append(clonedHandle).WarnIfFailed("Failed to add coordinates to the list"))
+ {
+ clonedHandle.HasOwnership = false;
+ }
+ }
+ }
+
+ internal void ForEach(Action<CoordinatesHandle> action)
+ {
+ CoordinatesCallback callback = (index, handle, userData) =>
+ {
+ action(CoordinatesHandle.CloneFrom(handle));
+ return true;
+ };
+
+ Foreach(handle, callback, IntPtr.Zero).WarnIfFailed("Failed to get coordinates list from native handle");
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.ErrorCode.cs b/src/Tizen.Maps/Interop/Interop.ErrorCode.cs
new file mode 100755
index 0000000..8c4eaab
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.ErrorCode.cs
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.CompilerServices;
+using Tizen;
+
+internal static partial class Interop
+{
+ internal enum ErrorCode
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None,
+ PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied,
+ OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+ NotSupported = Tizen.Internals.Errors.ErrorCode.NotSupported,
+ ConnectionTimeOut = Tizen.Internals.Errors.ErrorCode.ConnectionTimeout,
+ NetworkUnreachable = Tizen.Internals.Errors.ErrorCode.NetworkUnreachable,
+ InvalidOperation = Tizen.Internals.Errors.ErrorCode.InvalidOperation,
+ KeyNotAvailable = Tizen.Internals.Errors.ErrorCode.KeyNotAvailable,
+ ResourceBusy = Tizen.Internals.Errors.ErrorCode.ResourceBusy,
+ Canceled = Tizen.Internals.Errors.ErrorCode.Canceled,
+ Unknown = Tizen.Internals.Errors.ErrorCode.Unknown,
+ UserNotConsented = Tizen.Internals.Errors.ErrorCode.UserNotConsented,
+ ServiceNotAvailable = -0x02C20000 | 0x01, // MAPS_ERROR_SERVICE_NOT_AVAILABLE
+ NotFound = -0x02C20000 | 0x02, // MAPS_ERROR_NOT_FOUND
+ }
+}
+
+internal static class ErrorCodeExtensions
+{
+ private const string LogTag = "Tizen.Maps";
+
+ internal static bool IsSuccess(this Interop.ErrorCode err)
+ {
+ return err == Interop.ErrorCode.None;
+ }
+
+ internal static bool IsFailed(this Interop.ErrorCode err)
+ {
+ return !err.IsSuccess();
+ }
+
+ /// <summary>
+ /// Utility method to check for error, returns false if failed and print warning messages
+ /// </summary>
+ /// <returns>Returns true in case of no error, otherwise false.</returns>
+ internal static bool WarnIfFailed(this Interop.ErrorCode err, string msg, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ if (err.IsFailed())
+ {
+ Log.Debug(LogTag, $"{msg}, err: {err.ToString()}", file, func, line);
+ return false;
+ }
+ return true;
+ }
+
+ /// <summary>
+ /// Utility method to check for error, returns false if failed and throw exception
+ /// </summary>
+ /// <returns>Returns true in case of no error, otherwise false.</returns>
+ internal static bool ThrowIfFailed(this Interop.ErrorCode err, string msg, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ if (err.IsFailed())
+ {
+ Log.Error(LogTag, $"{msg}, err: {err.ToString()}", file, func, line);
+ throw err.GetException(msg);
+ }
+ return true;
+ }
+
+ internal static Exception GetException(this Interop.ErrorCode err, string message)
+ {
+ string errMessage = $"{message}, err: {err.ToString()}";
+ switch (err)
+ {
+ //case ErrorCode.None:
+ case Interop.ErrorCode.PermissionDenied: return new System.UnauthorizedAccessException(errMessage);
+ case Interop.ErrorCode.InvalidParameter: return new System.ArgumentException(errMessage);
+ case Interop.ErrorCode.OutOfMemory:
+ case Interop.ErrorCode.NotSupported:
+ case Interop.ErrorCode.ConnectionTimeOut:
+ case Interop.ErrorCode.NetworkUnreachable:
+ case Interop.ErrorCode.InvalidOperation:
+ case Interop.ErrorCode.KeyNotAvailable:
+ case Interop.ErrorCode.ResourceBusy:
+ case Interop.ErrorCode.Canceled:
+ case Interop.ErrorCode.Unknown:
+ case Interop.ErrorCode.ServiceNotAvailable:
+ case Interop.ErrorCode.NotFound:
+ default: return new System.InvalidOperationException(errMessage);
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.Libraries.cs b/src/Tizen.Maps/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..03be6b6
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.Libraries.cs
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static class Libraries
+ {
+ internal const string MapService = "capi-maps-service.so.0";
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Maps/Interop/Interop.Place.Attribute.cs b/src/Tizen.Maps/Interop/Interop.Place.Attribute.cs
new file mode 100755
index 0000000..f7e7c78
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.Place.Attribute.cs
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_attribute_get_id")]
+ internal static extern ErrorCode GetId(this PlaceAttributeHandle /* maps_place_attribute_h */ attribute, out string id);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_attribute_get_label")]
+ internal static extern ErrorCode GetLabel(this PlaceAttributeHandle /* maps_place_attribute_h */ attribute, out string label);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_attribute_get_text")]
+ internal static extern ErrorCode GetText(this PlaceAttributeHandle /* maps_place_attribute_h */ attribute, out string text);
+
+ internal class PlaceAttributeHandle : SafeMapsHandle
+ {
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_attribute_destroy")]
+ internal static extern ErrorCode Destroy(IntPtr /* maps_place_attribute_h */ attribute);
+
+ internal string Id
+ {
+ get { return NativeGet(this.GetId); }
+ }
+
+ internal string Label
+ {
+ get { return NativeGet(this.GetLabel); }
+ }
+
+ internal string Text
+ {
+ get { return NativeGet(this.GetText); }
+ }
+
+ public PlaceAttributeHandle(IntPtr handle, bool needToRelease) : base(handle, needToRelease, Destroy)
+ {
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.Place.Category.cs b/src/Tizen.Maps/Interop/Interop.Place.Category.cs
new file mode 100755
index 0000000..7265409
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.Place.Category.cs
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_category_get_id")]
+ internal static extern ErrorCode GetId(this PlaceCategoryHandle /* maps_place_category_h */ category, out string id);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_category_set_id")]
+ internal static extern ErrorCode SetId(this PlaceCategoryHandle /* maps_place_category_h */ category, string id);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_category_get_name")]
+ internal static extern ErrorCode GetName(this PlaceCategoryHandle /* maps_place_category_h */ category, out string name);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_category_set_name")]
+ internal static extern ErrorCode SetName(this PlaceCategoryHandle /* maps_place_category_h */ category, string name);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_category_get_url")]
+ internal static extern ErrorCode GetUrl(this PlaceCategoryHandle /* maps_place_category_h */ category, out string url);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_category_set_url")]
+ internal static extern ErrorCode SetUrl(this PlaceCategoryHandle /* maps_place_category_h */ category, string url);
+
+ internal class PlaceCategoryHandle : SafeMapsHandle
+ {
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_category_create")]
+ internal static extern ErrorCode Create(out IntPtr /* maps_place_category_h */ category);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_category_destroy")]
+ internal static extern ErrorCode Destroy(IntPtr /* maps_place_category_h */ category);
+
+ internal string Id
+ {
+ get { return NativeGet(this.GetId); }
+ set { NativeSet(this.SetId, value); }
+ }
+
+ internal string Name
+ {
+ get { return NativeGet(this.GetName); }
+ set { NativeSet(this.SetName, value); }
+ }
+
+ internal string Url
+ {
+ get { return NativeGet(this.GetUrl); }
+ set { NativeSet(this.SetUrl, value); }
+ }
+
+ public PlaceCategoryHandle(IntPtr handle, bool needToRelease) : base(handle, needToRelease, Destroy)
+ {
+ }
+
+ internal PlaceCategoryHandle() : this(IntPtr.Zero, true)
+ {
+ Create(out handle).ThrowIfFailed("Failed to create native handle");
+ }
+
+ internal static PlaceCategoryHandle Create(IntPtr nativeHandle)
+ {
+ return new PlaceCategoryHandle(nativeHandle, true);
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.Place.Contact.cs b/src/Tizen.Maps/Interop/Interop.Place.Contact.cs
new file mode 100755
index 0000000..bd6b61f
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.Place.Contact.cs
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_contact_get_label")]
+ internal static extern ErrorCode GetLabel(this PlaceContactHandle /* maps_place_contact_h */ contact, out string label);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_contact_get_type")]
+ internal static extern ErrorCode GetType(this PlaceContactHandle /* maps_place_contact_h */ contact, out string type);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_contact_get_value")]
+ internal static extern ErrorCode GetValue(this PlaceContactHandle /* maps_place_contact_h */ contact, out string value);
+
+ internal class PlaceContactHandle : SafeMapsHandle
+ {
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_contact_destroy")]
+ internal static extern ErrorCode Destroy(IntPtr /* maps_place_contact_h */ contact);
+
+ internal string Label
+ {
+ get { return NativeGet(this.GetLabel); }
+ }
+
+ internal string Type
+ {
+ get { return NativeGet(this.GetType); }
+ }
+
+ internal string Value
+ {
+ get { return NativeGet(this.GetValue); }
+ }
+
+ public PlaceContactHandle(IntPtr handle, bool needToRelease) : base(handle, needToRelease, Destroy)
+ {
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.Place.Editorial.cs b/src/Tizen.Maps/Interop/Interop.Place.Editorial.cs
new file mode 100755
index 0000000..6af3dba
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.Place.Editorial.cs
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_editorial_get_description")]
+ internal static extern ErrorCode GetDescription(this PlaceEditorialHandle /* maps_place_editorial_h */ editorial, out string description);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_editorial_get_language")]
+ internal static extern ErrorCode GetLanguage(this PlaceEditorialHandle /* maps_place_editorial_h */ editorial, out string language);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_editorial_get_media")]
+ internal static extern ErrorCode GetMedia(this PlaceEditorialHandle /* maps_place_editorial_h */ editorial, out IntPtr /* maps_place_media_h */ media);
+
+ internal class PlaceEditorialHandle : SafeMapsHandle
+ {
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_editorial_destroy")]
+ internal static extern ErrorCode Destroy(IntPtr /* maps_place_editorial_h */ editorial);
+
+ internal string Description
+ {
+ get { return NativeGet(this.GetDescription); }
+ }
+
+ internal string Language
+ {
+ get { return NativeGet(this.GetLanguage); }
+ }
+
+ internal PlaceMediaHandle Media
+ {
+ get { return NativeGet(this.GetMedia, PlaceMediaHandle.Create); }
+ }
+
+ public PlaceEditorialHandle(IntPtr handle, bool needToRelease) : base(handle, needToRelease, Destroy)
+ {
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.Place.Filter.cs b/src/Tizen.Maps/Interop/Interop.Place.Filter.cs
new file mode 100755
index 0000000..20dc6a9
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.Place.Filter.cs
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_filter_get")]
+ internal static extern ErrorCode Get(this PlaceFilterHandle /* maps_place_filter_h */ filter, string key, out string value);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_filter_set")]
+ internal static extern ErrorCode Set(this PlaceFilterHandle /* maps_place_filter_h */ filter, string key, string value);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_filter_get_keyword")]
+ internal static extern ErrorCode GetKeyword(this PlaceFilterHandle /* maps_place_filter_h */ filter, out string keyword);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_filter_set_keyword")]
+ internal static extern ErrorCode SetKeyword(this PlaceFilterHandle /* maps_place_filter_h */ filter, string keyword);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_filter_get_place_name")]
+ internal static extern ErrorCode GetPlaceName(this PlaceFilterHandle /* maps_place_filter_h */ filter, out string placeName);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_filter_set_place_name")]
+ internal static extern ErrorCode SetPlaceName(this PlaceFilterHandle /* maps_place_filter_h */ filter, string placeName);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_filter_get_category")]
+ internal static extern ErrorCode GetCategory(this PlaceFilterHandle /* maps_place_filter_h */ filter, out IntPtr /* maps_place_category_h */ category);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_filter_set_category")]
+ internal static extern ErrorCode SetCategory(this PlaceFilterHandle /* maps_place_filter_h */ filter, PlaceCategoryHandle /* maps_place_category_h */ category);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_filter_get_place_address")]
+ internal static extern ErrorCode GetPlaceAddress(this PlaceFilterHandle /* maps_place_filter_h */ filter, out string placeAddress);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_filter_set_place_address")]
+ internal static extern ErrorCode SetPlaceAddress(this PlaceFilterHandle /* maps_place_filter_h */ filter, string placeAddress);
+
+ internal class PlaceFilterHandle : SafeMapsHandle
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool PlaceFilterPropertiesCallback(int index, int total, string key, IntPtr /* void */ value, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_filter_foreach_property")]
+ internal static extern ErrorCode ForeachProperty(IntPtr /* maps_place_filter_h */ filter, PlaceFilterPropertiesCallback callback, IntPtr /* void */ userData);
+
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_filter_create")]
+ internal static extern ErrorCode Create(out IntPtr /* maps_place_filter_h */ filter);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_filter_destroy")]
+ internal static extern ErrorCode Destroy(IntPtr /* maps_place_filter_h */ filter);
+
+ internal string Keyword
+ {
+ get { return NativeGet(this.GetKeyword); }
+ set { NativeSet(this.SetKeyword, value); }
+ }
+
+ internal string PlaceName
+ {
+ get { return NativeGet(this.GetPlaceName); }
+ set { NativeSet(this.SetPlaceName, value); }
+ }
+
+ internal string PlaceAddress
+ {
+ get { return NativeGet(this.GetPlaceAddress); }
+ set { NativeSet(this.SetPlaceAddress, value); }
+ }
+
+ internal PlaceCategoryHandle Category
+ {
+ get { return NativeGet(this.GetCategory, PlaceCategoryHandle.Create); }
+ set { NativeSet(this.SetCategory, value); }
+ }
+
+ public PlaceFilterHandle(IntPtr handle, bool needToRelease) : base(handle, needToRelease, Destroy)
+ {
+ }
+
+ public PlaceFilterHandle() : this(IntPtr.Zero, true)
+ {
+ Create(out handle).ThrowIfFailed("Failed to create native handle");
+ }
+
+ internal void ForeachProperty(Action<string, string> action)
+ {
+ PlaceFilterPropertiesCallback callback = (index, total, key, value, userData) =>
+ {
+ action(key, Marshal.PtrToStringUni(value));
+ return true;
+ };
+
+ ForeachProperty(handle, callback, IntPtr.Zero).WarnIfFailed("Failed to get address list from native handle");
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.Place.Image.cs b/src/Tizen.Maps/Interop/Interop.Place.Image.cs
new file mode 100755
index 0000000..ff96f6b
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.Place.Image.cs
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_image_get_id")]
+ internal static extern ErrorCode GetId(this PlaceImageHandle /* maps_place_image_h */ image, out string id);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_image_get_url")]
+ internal static extern ErrorCode GetUrl(this PlaceImageHandle /* maps_place_image_h */ image, out string url);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_image_get_width")]
+ internal static extern ErrorCode GetWidth(this PlaceImageHandle /* maps_place_image_h */ image, out int width);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_image_get_height")]
+ internal static extern ErrorCode GetHeight(this PlaceImageHandle /* maps_place_image_h */ image, out int height);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_image_get_user_link")]
+ internal static extern ErrorCode GetUserLink(this PlaceImageHandle /* maps_place_image_h */ image, out IntPtr /* maps_place_link_object_h */ user);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_image_get_media")]
+ internal static extern ErrorCode GetMedia(this PlaceImageHandle /* maps_place_image_h */ image, out IntPtr /* maps_place_media_h */ media);
+
+ internal class PlaceImageHandle : SafeMapsHandle
+ {
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_image_destroy")]
+ internal static extern ErrorCode Destroy(IntPtr /* maps_place_image_h */ image);
+
+ internal string Id
+ {
+ get { return NativeGet(this.GetId); }
+ }
+
+ internal string Url
+ {
+ get { return NativeGet(this.GetUrl); }
+ }
+
+ internal int Width
+ {
+ get { return NativeGet<int>(this.GetWidth); }
+ }
+
+ internal int Height
+ {
+ get { return NativeGet<int>(this.GetHeight); }
+ }
+
+ internal PlaceLinkObjectHandle User
+ {
+ get { return NativeGet(this.GetUserLink, PlaceLinkObjectHandle.Create); }
+ }
+
+ internal PlaceMediaHandle Media
+ {
+ get { return NativeGet(this.GetMedia, PlaceMediaHandle.Create); }
+ }
+
+ public PlaceImageHandle(IntPtr handle, bool needToRelease) : base(handle, needToRelease, Destroy)
+ {
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.Place.Link.Object.cs b/src/Tizen.Maps/Interop/Interop.Place.Link.Object.cs
new file mode 100755
index 0000000..ac170b1
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.Place.Link.Object.cs
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_link_object_get_id")]
+ internal static extern ErrorCode GetId(this PlaceLinkObjectHandle /* maps_place_link_object_h */ link, out string id);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_link_object_get_name")]
+ internal static extern ErrorCode GetName(this PlaceLinkObjectHandle /* maps_place_link_object_h */ link, out string name);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_link_object_get_string")]
+ internal static extern ErrorCode GetLink(this PlaceLinkObjectHandle /* maps_place_link_object_h */ link, out string linkString);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_link_object_get_type")]
+ internal static extern ErrorCode GetType(this PlaceLinkObjectHandle /* maps_place_link_object_h */ link, out string type);
+
+ internal class PlaceLinkObjectHandle : SafeMapsHandle
+ {
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_link_object_destroy")]
+ internal static extern ErrorCode Destroy(IntPtr /* maps_place_link_object_h */ link);
+
+ internal string Id
+ {
+ get { return NativeGet(this.GetId); }
+ }
+
+ internal string Name
+ {
+ get { return NativeGet(this.GetName); }
+ }
+
+ internal string Link
+ {
+ get { return NativeGet(this.GetLink); }
+ }
+
+ internal string Type
+ {
+ get { return NativeGet(this.GetType); }
+ }
+
+ public PlaceLinkObjectHandle(IntPtr handle, bool needToRelease) : base(handle, needToRelease, Destroy)
+ {
+ }
+
+ internal static PlaceLinkObjectHandle Create(IntPtr nativeHandle)
+ {
+ return new PlaceLinkObjectHandle(nativeHandle, true);
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.Place.Media.cs b/src/Tizen.Maps/Interop/Interop.Place.Media.cs
new file mode 100755
index 0000000..14145b8
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.Place.Media.cs
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_media_get_attribution")]
+ internal static extern ErrorCode GetAttribution(this PlaceMediaHandle /* maps_place_media_h */ media, out string attribution);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_media_get_supplier")]
+ internal static extern ErrorCode GetSupplier(this PlaceMediaHandle /* maps_place_media_h */ media, out IntPtr /* maps_place_link_object_h */ supplier);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_media_get_via")]
+ internal static extern ErrorCode GetVia(this PlaceMediaHandle /* maps_place_media_h */ media, out IntPtr /* maps_place_link_object_h */ via);
+
+ internal class PlaceMediaHandle : SafeMapsHandle
+ {
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_media_destroy")]
+ internal static extern ErrorCode Destroy(IntPtr /* maps_place_media_h */ media);
+
+ internal string Attribution
+ {
+ get { return NativeGet(this.GetAttribution); }
+ }
+
+ internal PlaceLinkObjectHandle Supplier
+ {
+ get { return NativeGet(this.GetSupplier, PlaceLinkObjectHandle.Create); }
+ }
+
+ internal PlaceLinkObjectHandle Via
+ {
+ get { return NativeGet(this.GetVia, PlaceLinkObjectHandle.Create); }
+ }
+
+ public PlaceMediaHandle(IntPtr handle, bool needToRelease) : base(handle, needToRelease, Destroy)
+ {
+ }
+
+ internal static PlaceMediaHandle Create(IntPtr nativeHandle)
+ {
+ return new PlaceMediaHandle(nativeHandle, true);
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.Place.Rating.cs b/src/Tizen.Maps/Interop/Interop.Place.Rating.cs
new file mode 100755
index 0000000..acefe9e
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.Place.Rating.cs
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_rating_get_count")]
+ internal static extern ErrorCode GetCount(this PlaceRatingHandle /* maps_place_rating_h */ rating, out int count);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_rating_get_average")]
+ internal static extern ErrorCode GetAverage(this PlaceRatingHandle /* maps_place_rating_h */ rating, out double average);
+
+ internal class PlaceRatingHandle : SafeMapsHandle
+ {
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_rating_destroy")]
+ internal static extern ErrorCode Destroy(IntPtr /* maps_place_rating_h */ rating);
+
+ internal int Count
+ {
+ get { return NativeGet<int>(this.GetCount); }
+ }
+
+ internal double Average
+ {
+ get { return NativeGet<double>(this.GetAverage); }
+ }
+
+
+ public PlaceRatingHandle(IntPtr handle, bool needToRelease) : base(handle, needToRelease, Destroy)
+ {
+ }
+
+ internal static PlaceRatingHandle Create(IntPtr nativeHandle)
+ {
+ return new PlaceRatingHandle(nativeHandle, true);
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.Place.Review.cs b/src/Tizen.Maps/Interop/Interop.Place.Review.cs
new file mode 100755
index 0000000..7cb1111
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.Place.Review.cs
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_review_get_date")]
+ internal static extern ErrorCode GetDate(this PlaceReviewHandle /* maps_place_review_h */ review, out string date);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_review_get_title")]
+ internal static extern ErrorCode GetTitle(this PlaceReviewHandle /* maps_place_review_h */ review, out string title);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_review_get_rating")]
+ internal static extern ErrorCode GetRating(this PlaceReviewHandle /* maps_place_review_h */ review, out double rating);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_review_get_description")]
+ internal static extern ErrorCode GetDescription(this PlaceReviewHandle /* maps_place_review_h */ review, out string description);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_review_get_language")]
+ internal static extern ErrorCode GetLanguage(this PlaceReviewHandle /* maps_place_review_h */ review, out string language);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_review_get_media")]
+ internal static extern ErrorCode GetMedia(this PlaceReviewHandle /* maps_place_review_h */ review, out IntPtr /* maps_place_media_h */ media);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_review_get_user_link")]
+ internal static extern ErrorCode GetUserLink(this PlaceReviewHandle /* maps_place_review_h */ review, out IntPtr /* maps_place_link_object_h */ user);
+
+ internal class PlaceReviewHandle : SafeMapsHandle
+ {
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_review_destroy")]
+ internal static extern ErrorCode Destroy(IntPtr /* maps_place_review_h */ review);
+
+ internal string Date
+ {
+ get { return NativeGet(this.GetDate); }
+ }
+
+ internal string Title
+ {
+ get { return NativeGet(this.GetTitle); }
+ }
+ internal string Language
+ {
+ get { return NativeGet(this.GetLanguage); }
+ }
+ internal string Description
+ {
+ get { return NativeGet(this.GetDescription); }
+ }
+ internal double Rating
+ {
+ get { return NativeGet<double>(this.GetRating); }
+ }
+
+ internal PlaceLinkObjectHandle User
+ {
+ get { return NativeGet(this.GetUserLink, PlaceLinkObjectHandle.Create); }
+ }
+
+ internal PlaceMediaHandle Media
+ {
+ get { return NativeGet(this.GetMedia, PlaceMediaHandle.Create); }
+ }
+
+ public PlaceReviewHandle(IntPtr handle, bool needToRelease) : base(handle, needToRelease, Destroy)
+ {
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.Place.cs b/src/Tizen.Maps/Interop/Interop.Place.cs
new file mode 100755
index 0000000..9d8a898
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.Place.cs
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_get_id")]
+ internal static extern ErrorCode GetId(this PlaceHandle /* maps_place_h */ place, out string id);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_get_name")]
+ internal static extern ErrorCode GetName(this PlaceHandle /* maps_place_h */ place, out string name);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_get_uri")]
+ internal static extern ErrorCode GetUri(this PlaceHandle /* maps_place_h */ place, out string uri);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_get_distance")]
+ internal static extern ErrorCode GetDistance(this PlaceHandle /* maps_place_h */ place, out int distance);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_get_location")]
+ internal static extern ErrorCode GetLocation(this PlaceHandle /* maps_place_h */ place, out IntPtr /* maps_coordinates_h */ location);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_get_address")]
+ internal static extern ErrorCode GetAddress(this PlaceHandle /* maps_place_h */ place, out IntPtr /* maps_address_h */ address);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_get_rating")]
+ internal static extern ErrorCode GetRating(this PlaceHandle /* maps_place_h */ place, out IntPtr /* maps_place_rating_h */ rating);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_get_supplier_link")]
+ internal static extern ErrorCode GetSupplierLink(this PlaceHandle /* maps_place_h */ place, out IntPtr /* maps_place_link_object_h */ supplier);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_get_related_link")]
+ internal static extern ErrorCode GetRelatedLink(this PlaceHandle /* maps_place_h */ place, out IntPtr /* maps_place_link_object_h */ related);
+
+ internal class PlaceHandle : SafeMapsHandle
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool PropertiesCallback(int index, int total, string key, string /* void */ value, IntPtr /* void */ userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool CategoriesCallback(int index, int total, IntPtr /* maps_place_category_h */ category, IntPtr /* void */ userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool AttributesCallback(int index, int total, IntPtr /* maps_place_attribute_h */ attribute, IntPtr /* void */ userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool ContactsCallback(int index, int total, IntPtr /* maps_place_contact_h */ contact, IntPtr /* void */ userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool EditorialsCallback(int index, int total, IntPtr /* maps_place_editorial_h */ editorial, IntPtr /* void */ userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool ImagesCallback(int index, int total, IntPtr /* maps_place_image_h */ image, IntPtr /* void */ userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool ReviewsCallback(int index, int total, IntPtr /* maps_place_review_h */ review, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_foreach_property")]
+ internal static extern ErrorCode ForeachProperty(IntPtr /* maps_place_h */ place, PropertiesCallback callback, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_foreach_category")]
+ internal static extern ErrorCode ForeachCategory(IntPtr /* maps_place_h */ place, CategoriesCallback callback, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_foreach_attribute")]
+ internal static extern ErrorCode ForeachAttribute(IntPtr /* maps_place_h */ place, AttributesCallback callback, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_foreach_contact")]
+ internal static extern ErrorCode ForeachContact(IntPtr /* maps_place_h */ place, ContactsCallback callback, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_foreach_editorial")]
+ internal static extern ErrorCode ForeachEditorial(IntPtr /* maps_place_h */ place, EditorialsCallback callback, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_foreach_image")]
+ internal static extern ErrorCode ForeachImage(IntPtr /* maps_place_h */ place, ImagesCallback callback, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_foreach_review")]
+ internal static extern ErrorCode ForeachReview(IntPtr /* maps_place_h */ place, ReviewsCallback callback, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_destroy")]
+ internal static extern ErrorCode Destroy(IntPtr /* maps_place_h */ place);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_clone")]
+ internal static extern ErrorCode Clone(IntPtr /* maps_place_h */ origin, out IntPtr /* maps_place_h */ cloned);
+
+ internal string Id
+ {
+ get { return NativeGet(this.GetId); }
+ }
+
+ internal string Name
+ {
+ get { return NativeGet(this.GetName); }
+ }
+
+ internal string Uri
+ {
+ get { return NativeGet(this.GetUri); }
+ }
+
+ internal int Distance
+ {
+ get { return NativeGet<int>(this.GetDistance); }
+ }
+
+ internal CoordinatesHandle Coordinates
+ {
+ get { return NativeGet(this.GetLocation, CoordinatesHandle.Create); }
+ }
+
+ internal AddressHandle Address
+ {
+ get { return NativeGet(this.GetAddress, AddressHandle.Create); }
+ }
+
+ internal PlaceRatingHandle Rating
+ {
+ get { return NativeGet(this.GetRating, PlaceRatingHandle.Create); }
+ }
+
+ internal PlaceLinkObjectHandle Supplier
+ {
+ get { return NativeGet(this.GetSupplierLink, PlaceLinkObjectHandle.Create); }
+ }
+
+ internal PlaceLinkObjectHandle Related
+ {
+ get { return NativeGet(this.GetRelatedLink, PlaceLinkObjectHandle.Create); }
+ }
+
+ public PlaceHandle(IntPtr handle, bool needToRelease) : base(handle, needToRelease, Destroy)
+ {
+ }
+
+ internal static PlaceHandle CloneFrom(IntPtr nativeHandle)
+ {
+ IntPtr handle;
+ Clone(nativeHandle, out handle).ThrowIfFailed("Failed to clone native handle");
+ return new PlaceHandle(handle, true);
+ }
+
+
+ internal void ForeachProperty(Action<string, string> action)
+ {
+ PropertiesCallback callback = (index, total, key, value, userData) =>
+ {
+ action(key, value);
+ return true;
+ };
+
+ ForeachProperty(handle, callback, IntPtr.Zero).WarnIfFailed("Failed to get property list from native handle");
+ }
+
+ internal void ForeachCategory(Action<PlaceCategoryHandle> action)
+ {
+ // PlaceCategoryHandle is valid only in this callback and users should not keep its reference
+ CategoriesCallback callback = (index, total, handle, userData) =>
+ {
+ action(new PlaceCategoryHandle(handle, true));
+ return true;
+ };
+
+ ForeachCategory(handle, callback, IntPtr.Zero).WarnIfFailed("Failed to get category list from native handle");
+ }
+
+ internal void ForeachAttribute(Action<PlaceAttributeHandle> action)
+ {
+ // PlaceAttributeHandle is valid only in this callback and users should not keep its reference
+ AttributesCallback callback = (index, total, handle, userData) =>
+ {
+ action(new PlaceAttributeHandle(handle, true));
+ return true;
+ };
+
+ ForeachAttribute(handle, callback, IntPtr.Zero).WarnIfFailed("Failed to get attributes list from native handle");
+ }
+
+ internal void ForeachContact(Action<PlaceContactHandle> action)
+ {
+ // PlaceContactHandle is valid only in this callback and users should not keep its reference
+ ContactsCallback callback = (index, total, handle, userData) =>
+ {
+ action(new PlaceContactHandle(handle, true));
+ return true;
+ };
+
+ ForeachContact(handle, callback, IntPtr.Zero).WarnIfFailed("Failed to get contacts list from native handle");
+ }
+
+ internal void ForeachEditorial(Action<PlaceEditorialHandle> action)
+ {
+ // PlaceEditorialHandle is valid only in this callback and users should not keep its reference
+ EditorialsCallback callback = (index, total, handle, userData) =>
+ {
+ action(new PlaceEditorialHandle(handle, true));
+ return true;
+ };
+
+ ForeachEditorial(handle, callback, IntPtr.Zero).WarnIfFailed("Failed to get editorial list from native handle");
+ }
+
+ internal void ForeachImage(Action<PlaceImageHandle> action)
+ {
+ // PlaceImageHandle is valid only in this callback and users should not keep its reference
+ ImagesCallback callback = (index, total, handle, userData) =>
+ {
+ action(new PlaceImageHandle(handle, true));
+ return true;
+ };
+
+ ForeachImage(handle, callback, IntPtr.Zero).WarnIfFailed("Failed to get image list from native handle");
+ }
+
+ internal void ForeachReview(Action<PlaceReviewHandle> action)
+ {
+ // PlaceReviewHandle is valid only in this callback and users should not keep its reference
+ ReviewsCallback callback = (index, total, handle, userData) =>
+ {
+ action(new PlaceReviewHandle(handle, true));
+ return true;
+ };
+
+ ForeachReview(handle, callback, IntPtr.Zero).WarnIfFailed("Failed to get review list from native handle");
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.PlaceList.cs b/src/Tizen.Maps/Interop/Interop.PlaceList.cs
new file mode 100755
index 0000000..8edf5b8
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.PlaceList.cs
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal class PlaceListHandle : SafeMapsHandle
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool PlaceCallback(int index, IntPtr /* maps_place_h */ place, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_list_destroy")]
+ internal static extern ErrorCode Destroy(IntPtr /* maps_place_list_h */ placeList);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_place_list_foreach")]
+ internal static extern ErrorCode Foreach(IntPtr /* maps_place_list_h */ placeList, PlaceCallback callback, IntPtr /* void */ userData);
+
+ public PlaceListHandle(IntPtr handle, bool needToRelease) : base(handle, needToRelease, Destroy) { }
+
+ internal void Foreach(Action<PlaceHandle> action)
+ {
+ PlaceCallback callback = (index, handle, userData) =>
+ {
+ action(PlaceHandle.CloneFrom(handle));
+ return true;
+ };
+
+ Foreach(handle, callback, IntPtr.Zero).WarnIfFailed("Failed to get place list from native handle");
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.Preference.cs b/src/Tizen.Maps/Interop/Interop.Preference.cs
new file mode 100755
index 0000000..f309cad
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.Preference.cs
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal enum DistanceUnit
+ {
+ Meter, // MAPS_DISTANCE_UNIT_M
+ Kilometer, // MAPS_DISTANCE_UNIT_KM
+ Foot, // MAPS_DISTANCE_UNIT_FT
+ Yard, // MAPS_DISTANCE_UNIT_YD
+ }
+
+ internal enum RouteOptimization
+ {
+ Fastest, // MAPS_ROUTE_TYPE_FASTEST
+ Shortest, // MAPS_ROUTE_TYPE_SHORTEST
+ Economic, // MAPS_ROUTE_TYPE_ECONOMIC
+ Scenic, // MAPS_ROUTE_TYPE_SCENIC
+ FastestNow, // MAPS_ROUTE_TYPE_FASTESTNOW
+ DirectDrive, // MAPS_ROUTE_TYPE_DIRECTDRIVE
+ }
+
+ internal enum RouteTransportMode
+ {
+ Car, // MAPS_ROUTE_TRANSPORT_MODE_CAR
+ Pedestrian, // MAPS_ROUTE_TRANSPORT_MODE_PEDESTRIAN
+ Bicycle, // MAPS_ROUTE_TRANSPORT_MODE_BICYCLE
+ PublicTransit, // MAPS_ROUTE_TRANSPORT_MODE_PUBLICTRANSIT
+ Truck, // MAPS_ROUTE_TRANSPORT_MODE_TRUCK
+ }
+
+ internal enum RouteFeatureWeight
+ {
+ Normal, // MAPS_ROUTE_FEATURE_WEIGHT_NORMAL
+ Prefer, // MAPS_ROUTE_FEATURE_WEIGHT_PREFER
+ Avoid, // MAPS_ROUTE_FEATURE_WEIGHT_AVOID
+ SoftExclude, // MAPS_ROUTE_FEATURE_WEIGHT_SOFTEXCLUDE
+ StrictExclude, // MAPS_ROUTE_FEATURE_WEIGHT_STRICTEXCLUDE
+ }
+
+ internal enum RouteRequestFeature
+ {
+ None, // MAPS_ROUTE_FEATURE_NO
+ Toll, // MAPS_ROUTE_FEATURE_TOLL
+ MotorWay, // MAPS_ROUTE_FEATURE_MOTORWAY
+ BoatFerry, // MAPS_ROUTE_FEATURE_BOATFERRY
+ RailFerry, // MAPS_ROUTE_FEATURE_RAILFERRY
+ PublicTransit, // MAPS_ROUTE_FEATURE_PUBLICTTRANSIT
+ Tunnel, // MAPS_ROUTE_FEATURE_TUNNEL
+ DirtRoad, // MAPS_ROUTE_FEATURE_DIRTROAD
+ Parks, // MAPS_ROUTE_FEATURE_PARKS
+ Hovlane, // MAPS_ROUTE_FEATURE_HOVLANE
+ Stairs, // MAPS_ROUTE_FEATURE_STAIRS
+ }
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_preference_get_distance_unit")]
+ internal static extern ErrorCode GetDistanceUnit(this PreferenceHandle /* maps_preference_h */ preference, out DistanceUnit /* maps_distance_unit_e */ unit);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_preference_set_distance_unit")]
+ internal static extern ErrorCode SetDistanceUnit(this PreferenceHandle /* maps_preference_h */ preference, DistanceUnit /* maps_distance_unit_e */ unit);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_preference_get_language")]
+ internal static extern ErrorCode GetLanguage(this PreferenceHandle /* maps_preference_h */ preference, out string language);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_preference_set_language")]
+ internal static extern ErrorCode SetLanguage(this PreferenceHandle /* maps_preference_h */ preference, string language);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_preference_get_max_results")]
+ internal static extern ErrorCode GetMaxResults(this PreferenceHandle /* maps_preference_h */ preference, out int maxResults);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_preference_set_max_results")]
+ internal static extern ErrorCode SetMaxResults(this PreferenceHandle /* maps_preference_h */ preference, int maxResults);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_preference_get_country_code")]
+ internal static extern ErrorCode GetCountryCode(this PreferenceHandle /* maps_preference_h */ preference, out string countryCode);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_preference_set_country_code")]
+ internal static extern ErrorCode SetCountryCode(this PreferenceHandle /* maps_preference_h */ preference, string countryCode);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_preference_get_route_optimization")]
+ internal static extern ErrorCode GetRouteOptimization(this PreferenceHandle /* maps_preference_h */ preference, out RouteOptimization /* maps_route_optimization_e */ optimization);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_preference_set_route_optimization")]
+ internal static extern ErrorCode SetRouteOptimization(this PreferenceHandle /* maps_preference_h */ preference, RouteOptimization /* maps_route_optimization_e */ optimization);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_preference_get_route_transport_mode")]
+ internal static extern ErrorCode GetRouteTransportMode(this PreferenceHandle /* maps_preference_h */ preference, out RouteTransportMode /* maps_route_transport_mode_e */ transportMode);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_preference_set_route_transport_mode")]
+ internal static extern ErrorCode SetRouteTransportMode(this PreferenceHandle /* maps_preference_h */ preference, RouteTransportMode /* maps_route_transport_mode_e */ transportMode);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_preference_get_route_feature_weight")]
+ internal static extern ErrorCode GetRouteFeatureWeight(this PreferenceHandle /* maps_preference_h */ preference, out RouteFeatureWeight /* maps_route_feature_weight_e */ featureWeight);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_preference_set_route_feature_weight")]
+ internal static extern ErrorCode SetRouteFeatureWeight(this PreferenceHandle /* maps_preference_h */ preference, RouteFeatureWeight /* maps_route_feature_weight_e */ featureWeight);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_preference_get_route_feature")]
+ internal static extern ErrorCode GetRouteFeature(this PreferenceHandle /* maps_preference_h */ preference, out RouteRequestFeature /* maps_route_feature_e */ feature);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_preference_set_route_feature")]
+ internal static extern ErrorCode SetRouteFeature(this PreferenceHandle /* maps_preference_h */ preference, RouteRequestFeature /* maps_route_feature_e */ feature);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_preference_get_route_alternatives_enabled")]
+ internal static extern ErrorCode GetRouteAlternativesEnabled(this PreferenceHandle /* maps_preference_h */ preference, out bool enable);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_preference_set_route_alternatives_enabled")]
+ internal static extern ErrorCode SetRouteAlternativesEnabled(this PreferenceHandle /* maps_preference_h */ preference, bool enable);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_preference_get")]
+ internal static extern ErrorCode GetProperty(this PreferenceHandle /* maps_preference_h */ preference, string key, out string value);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_preference_set_property")]
+ internal static extern ErrorCode SetProperty(this PreferenceHandle /* maps_preference_h */ preference, string key, string value);
+
+ internal class PreferenceHandle : SafeMapsHandle
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool PropertiesCallback(int index, int total, string key, string value, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_preference_foreach_property")]
+ internal static extern ErrorCode ForeachProperty(IntPtr /* maps_preference_h */ preference, PropertiesCallback callback, IntPtr /* void */ userData);
+
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_preference_create")]
+ internal static extern ErrorCode Create(out IntPtr /* maps_preference_h */ preference);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_preference_destroy")]
+ internal static extern ErrorCode Destroy(IntPtr /* maps_preference_h */ preference);
+
+ internal DistanceUnit Unit
+ {
+ get { return NativeGet<DistanceUnit>(this.GetDistanceUnit); }
+ set { NativeSet(this.SetDistanceUnit, value); }
+ }
+
+ internal string Language
+ {
+ get { return NativeGet(this.GetLanguage); }
+ set { NativeSet(this.SetLanguage, value); }
+ }
+
+ internal int MaxResult
+ {
+ get { return NativeGet<int>(this.GetMaxResults); }
+ set { NativeSet(this.SetMaxResults, value); }
+ }
+
+ internal string CountryCode
+ {
+ get { return NativeGet(this.GetCountryCode); }
+ set { NativeSet(this.SetCountryCode, value); }
+ }
+
+ internal RouteOptimization Optimization
+ {
+ get { return NativeGet<RouteOptimization>(this.GetRouteOptimization); }
+ set { NativeSet(this.SetRouteOptimization, value); }
+ }
+
+ internal RouteTransportMode TransportMode
+ {
+ get { return NativeGet<RouteTransportMode>(this.GetRouteTransportMode); }
+ set { NativeSet(this.SetRouteTransportMode, value); }
+ }
+
+ internal RouteRequestFeature Feature
+ {
+ get { return NativeGet<RouteRequestFeature>(this.GetRouteFeature); }
+ set { NativeSet(this.SetRouteFeature, value); }
+ }
+
+ internal RouteFeatureWeight FeatureWeight
+ {
+ get { return NativeGet<RouteFeatureWeight>(this.GetRouteFeatureWeight); }
+ set { NativeSet(this.SetRouteFeatureWeight, value); }
+ }
+
+ internal bool AlternativesEnabled
+ {
+ get { return NativeGet<bool>(this.GetRouteAlternativesEnabled); }
+ set { NativeSet(this.SetRouteAlternativesEnabled, value); }
+ }
+
+ internal PreferenceHandle(IntPtr handle, bool needToRelease) : base(handle, needToRelease, Destroy)
+ {
+ }
+
+ internal PreferenceHandle() : this(IntPtr.Zero, true)
+ {
+ Create(out handle).ThrowIfFailed("Failed to create native handle");
+ }
+
+ internal void ForeachProperty(Action<string, string> action)
+ {
+ PropertiesCallback callback = (index, total, key, value, userData) =>
+ {
+ action(key, value);
+ return true;
+ };
+
+ ForeachProperty(handle, callback, IntPtr.Zero).WarnIfFailed("Failed to get property list from native handle");
+ }
+
+ internal static PreferenceHandle Create(IntPtr nativeHandle)
+ {
+ return new PreferenceHandle(nativeHandle, true);
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.Route.Maneuver.cs b/src/Tizen.Maps/Interop/Interop.Route.Maneuver.cs
new file mode 100755
index 0000000..a2c6216
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.Route.Maneuver.cs
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal enum RouteDirection
+ {
+ None, // MAPS_ROUTE_DIRECTION_NONE
+ North, // MAPS_ROUTE_DIRECTION_NORTH
+ NorthWest, // MAPS_ROUTE_DIRECTION_NORTHWEST
+ NorthEast, // MAPS_ROUTE_DIRECTION_NORTHEAST
+ South, // MAPS_ROUTE_DIRECTION_SOUTH
+ SouthEast, // MAPS_ROUTE_DIRECTION_SOUTHEAST
+ SouthWest, // MAPS_ROUTE_DIRECTION_SOUTHWEST
+ West, // MAPS_ROUTE_DIRECTION_WEST
+ East, // MAPS_ROUTE_DIRECTION_EAST
+ }
+
+ internal enum RouteTurnType
+ {
+ None, // MAPS_ROUTE_TURN_TYPE_NONE
+ Straight, // MAPS_ROUTE_TURN_TYPE_STRAIGHT
+ BearRight, // MAPS_ROUTE_TURN_TYPE_BEAR_RIGHT
+ LightRight, // MAPS_ROUTE_TURN_TYPE_LIGHT_RIGHT
+ Right, // MAPS_ROUTE_TURN_TYPE_RIGHT
+ HardRight, // MAPS_ROUTE_TURN_TYPE_HARD_RIGHT
+ UturnRight, // MAPS_ROUTE_TURN_TYPE_UTURN_RIGHT
+ UturnLeft, // MAPS_ROUTE_TURN_TYPE_UTURN_LEFT
+ HardLeft, // MAPS_ROUTE_TURN_TYPE_HARD_LEFT
+ Left, // MAPS_ROUTE_TURN_TYPE_LEFT
+ LightLeft, // MAPS_ROUTE_TURN_TYPE_LIGHT_LEFT
+ BearLeft, // MAPS_ROUTE_TURN_TYPE_BEAR_LEFT
+ RightFork, // MAPS_ROUTE_TURN_TYPE_RIGHT_FORK
+ LeftFork, // MAPS_ROUTE_TURN_TYPE_LEFT_FORK
+ StraightFork, // MAPS_ROUTE_TURN_TYPE_STRAIGHT_FORK
+ }
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_maneuver_get_direction_id")]
+ internal static extern ErrorCode GetDirectionId(this RouteManeuverHandle /* maps_route_maneuver_h */ maneuver, out RouteDirection /* maps_route_direction_e */ directionId);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_maneuver_get_turn_type")]
+ internal static extern ErrorCode GetTurnType(this RouteManeuverHandle /* maps_route_maneuver_h */ maneuver, out RouteTurnType /* maps_route_turn_type_e */ turnType);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_maneuver_get_position")]
+ internal static extern ErrorCode GetPosition(this RouteManeuverHandle /* maps_route_maneuver_h */ maneuver, out IntPtr /* maps_coordinates_h */ position);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_maneuver_get_road_name")]
+ internal static extern ErrorCode GetRoadName(this RouteManeuverHandle /* maps_route_maneuver_h */ maneuver, out string roadName);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_maneuver_get_instruction_text")]
+ internal static extern ErrorCode GetInstructionText(this RouteManeuverHandle /* maps_route_maneuver_h */ maneuver, out string instructionText);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_maneuver_get_locale")]
+ internal static extern ErrorCode GetLocale(this RouteManeuverHandle /* maps_route_maneuver_h */ maneuver, out string locale);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_maneuver_get_time_to_next_instruction")]
+ internal static extern ErrorCode GetTimeToNextInstruction(this RouteManeuverHandle /* maps_route_maneuver_h */ maneuver, out int timeToNextInstruction);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_maneuver_get_distance_to_next_instruction")]
+ internal static extern ErrorCode GetDistanceToNextInstruction(this RouteManeuverHandle /* maps_route_maneuver_h */ maneuver, out double distanceToNextInstruction);
+
+ internal class RouteManeuverHandle : SafeMapsHandle
+ {
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_maneuver_destroy")]
+ internal static extern ErrorCode Destroy(IntPtr /* maps_route_maneuver_h */ maneuver);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_maneuver_clone")]
+ internal static extern ErrorCode Clone(IntPtr /* maps_route_maneuver_h */ origin, out IntPtr /* maps_route_maneuver_h */ cloned);
+
+ internal string RoadName
+ {
+ get { return NativeGet(this.GetRoadName); }
+ }
+
+ internal string Instruction
+ {
+ get { return NativeGet(this.GetInstructionText); }
+ }
+
+ internal string Locale
+ {
+ get { return NativeGet(this.GetLocale); }
+ }
+
+ internal int TimeToNextInstruction
+ {
+ get { return NativeGet<int>(this.GetTimeToNextInstruction); }
+ }
+
+ internal double DistanceToNextInstruction
+ {
+ get { return NativeGet<double>(this.GetDistanceToNextInstruction); }
+ }
+
+ internal RouteDirection Direction
+ {
+ get { return NativeGet<RouteDirection>(this.GetDirectionId); }
+ }
+
+ internal RouteTurnType TurnType
+ {
+ get { return NativeGet<RouteTurnType>(this.GetTurnType); }
+ }
+
+ internal CoordinatesHandle Coordinates
+ {
+ get { return NativeGet(this.GetPosition, CoordinatesHandle.Create); }
+ }
+
+ public RouteManeuverHandle(IntPtr handle, bool needToRelease) : base(handle, needToRelease, Destroy)
+ {
+ }
+
+ internal static RouteManeuverHandle CloneFrom(IntPtr nativeHandle)
+ {
+ IntPtr handle;
+ Clone(nativeHandle, out handle).ThrowIfFailed("Failed to clone native handle");
+ return new RouteManeuverHandle(handle, true);
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.Route.Segment.cs b/src/Tizen.Maps/Interop/Interop.Route.Segment.cs
new file mode 100755
index 0000000..7aa6493
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.Route.Segment.cs
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_segment_get_origin")]
+ internal static extern ErrorCode GetOrigin(this RouteSegmentHandle /* maps_route_segment_h */ segment, out IntPtr /* maps_coordinates_h */ origin);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_segment_get_destination")]
+ internal static extern ErrorCode GetDestination(this RouteSegmentHandle /* maps_route_segment_h */ segment, out IntPtr /* maps_coordinates_h */ destination);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_segment_get_bounding_box")]
+ internal static extern ErrorCode GetBoundingBox(this RouteSegmentHandle /* maps_route_segment_h */ segment, out IntPtr /* maps_area_h */ boundingBox);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_segment_get_distance")]
+ internal static extern ErrorCode GetDistance(this RouteSegmentHandle /* maps_route_segment_h */ segment, out double distance);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_segment_get_duration")]
+ internal static extern ErrorCode GetDuration(this RouteSegmentHandle /* maps_route_segment_h */ segment, out long duration);
+
+ internal class RouteSegmentHandle : SafeMapsHandle
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool PathCallback(int index, int total, IntPtr /* maps_coordinates_h */ coordinates, IntPtr /* void */ userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool ManeuverCallback(int index, int total, IntPtr /* maps_route_maneuver_h */ maneuver, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_segment_foreach_path")]
+ internal static extern ErrorCode ForeachPath(IntPtr /* maps_route_segment_h */ segment, PathCallback callback, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_segment_foreach_maneuver")]
+ internal static extern ErrorCode ForeachManeuver(IntPtr /* maps_route_segment_h */ segment, ManeuverCallback callback, IntPtr /* void */ userData);
+
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_segment_destroy")]
+ internal static extern ErrorCode Destroy(IntPtr /* maps_route_segment_h */ segment);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_segment_clone")]
+ internal static extern ErrorCode Clone(IntPtr /* maps_route_segment_h */ origin, out IntPtr /* maps_route_segment_h */ cloned);
+
+ internal double Distance
+ {
+ get { return NativeGet<double>(this.GetDistance); }
+ }
+
+ internal long Duration
+ {
+ get { return NativeGet<long>(this.GetDuration); }
+ }
+
+ internal CoordinatesHandle Origin
+ {
+ get { return NativeGet(this.GetOrigin, CoordinatesHandle.Create); }
+ }
+
+ internal CoordinatesHandle Destination
+ {
+ get { return NativeGet(this.GetDestination, CoordinatesHandle.Create); }
+ }
+
+ internal AreaHandle BoundingBox
+ {
+ get { return NativeGet(this.GetBoundingBox, AreaHandle.Create); }
+ }
+
+ public RouteSegmentHandle(IntPtr handle, bool needToRelease) : base(handle, needToRelease, Destroy)
+ {
+ }
+
+ internal static RouteSegmentHandle CloneFrom(IntPtr nativeHandle)
+ {
+ IntPtr handle;
+ Clone(nativeHandle, out handle).ThrowIfFailed("Failed to clone native handle");
+ return new RouteSegmentHandle(handle, true);
+ }
+
+ internal void ForeachPath(Action<CoordinatesHandle> action)
+ {
+ PathCallback callback = (index, total, nativeHandle, userData) =>
+ {
+ if (handle != IntPtr.Zero)
+ {
+ action(CoordinatesHandle.CloneFrom(nativeHandle));
+ //Destroy(nativeHandle);
+ }
+ return true;
+ };
+
+ ForeachPath(handle, callback, IntPtr.Zero).WarnIfFailed("Failed to get path coordinates list from native handle");
+ }
+
+ internal void ForeachManeuver(Action<RouteManeuverHandle> action)
+ {
+ ManeuverCallback callback = (index, total, nativeHandle, userData) =>
+ {
+ if (handle != IntPtr.Zero)
+ {
+ action(RouteManeuverHandle.CloneFrom(nativeHandle));
+ //Destroy(nativeHandle);
+ }
+ return true;
+ };
+
+ ForeachManeuver(handle, callback, IntPtr.Zero).WarnIfFailed("Failed to get segment list from native handle");
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.Route.cs b/src/Tizen.Maps/Interop/Interop.Route.cs
new file mode 100755
index 0000000..52eac7d
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.Route.cs
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_get_route_id")]
+ internal static extern ErrorCode GetRouteId(this RouteHandle /* maps_route_h */ route, out string routeId);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_get_origin")]
+ internal static extern ErrorCode GetOrigin(this RouteHandle /* maps_route_h */ route, out IntPtr /* maps_coordinates_h */ origin);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_get_destination")]
+ internal static extern ErrorCode GetDestination(this RouteHandle /* maps_route_h */ route, out IntPtr /* maps_coordinates_h */ destination);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_get_bounding_box")]
+ internal static extern ErrorCode GetBoundingBox(this RouteHandle /* maps_route_h */ route, out IntPtr /* maps_area_h */ boundingBox);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_get_transport_mode")]
+ internal static extern ErrorCode GetTransportMode(this RouteHandle /* maps_route_h */ route, out RouteTransportMode /* maps_route_transport_mode_e */ transportMode);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_get_total_distance")]
+ internal static extern ErrorCode GetTotalDistance(this RouteHandle /* maps_route_h */ route, out double totalDistance);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_get_total_duration")]
+ internal static extern ErrorCode GetTotalDuration(this RouteHandle /* maps_route_h */ route, out long totalDuration);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_get_distance_unit")]
+ internal static extern ErrorCode GetDistanceUnit(this RouteHandle /* maps_route_h */ route, out DistanceUnit /* maps_distance_unit_e */ distanceUnit);
+
+ internal class RouteHandle : SafeMapsHandle
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool PropertiesCallback(int index, int total, string key, string /* void */ value, IntPtr /* void */ userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool PathCallback(int index, int total, IntPtr /* maps_coordinates_h */ coordinates, IntPtr /* void */ userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool SegmentCallback(int index, int total, IntPtr /* maps_route_segment_h */ segment, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_foreach_property")]
+ internal static extern ErrorCode ForeachProperty(IntPtr /* maps_route_h */ route, PropertiesCallback callback, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_foreach_path")]
+ internal static extern ErrorCode ForeachPath(IntPtr /* maps_route_h */ route, PathCallback callback, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_foreach_segment")]
+ internal static extern ErrorCode ForeachSegment(IntPtr /* maps_route_h */ route, SegmentCallback callback, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_route_destroy")]
+ internal static extern ErrorCode Destroy(IntPtr /* maps_route_h */ route);
+
+ internal string Id
+ {
+ get { return NativeGet(this.GetRouteId); }
+ }
+
+ internal double Distance
+ {
+ get { return NativeGet<double>(this.GetTotalDistance); }
+ }
+
+ internal long Duration
+ {
+ get { return NativeGet<long>(this.GetTotalDuration); }
+ }
+
+ internal DistanceUnit Unit
+ {
+ get { return NativeGet<DistanceUnit>(this.GetDistanceUnit); }
+ }
+
+ internal RouteTransportMode TransportMode
+ {
+ get { return NativeGet<RouteTransportMode>(this.GetTransportMode); }
+ }
+
+ internal CoordinatesHandle Origin
+ {
+ get { return NativeGet(this.GetOrigin, CoordinatesHandle.Create); }
+ }
+
+ internal CoordinatesHandle Destination
+ {
+ get { return NativeGet(this.GetDestination, CoordinatesHandle.Create); }
+ }
+
+ internal AreaHandle BoundingBox
+ {
+ get { return NativeGet(this.GetBoundingBox, AreaHandle.Create); }
+ }
+
+ public RouteHandle(IntPtr handle, bool needToRelease) : base(handle, needToRelease, Destroy)
+ {
+ }
+
+ internal void ForeachProperty(Action<string, string> action)
+ {
+ PropertiesCallback callback = (index, total, key, value, userData) =>
+ {
+ action(key, value);
+ return true;
+ };
+
+ ForeachProperty(handle, callback, IntPtr.Zero).WarnIfFailed("Failed to get property list from native handle");
+ }
+
+ internal void ForeachPath(Action<CoordinatesHandle> action)
+ {
+ PathCallback callback = (index, total, nativeHandle, userData) =>
+ {
+ if (handle != IntPtr.Zero)
+ {
+ action(CoordinatesHandle.CloneFrom(nativeHandle));
+ //Destroy(nativeHandle);
+ }
+ return true;
+ };
+
+ ForeachPath(handle, callback, IntPtr.Zero).WarnIfFailed("Failed to get path coordinates list from native handle");
+ }
+
+ internal void ForeachSegment(Action<RouteSegmentHandle> action)
+ {
+ SegmentCallback callback = (index, total, nativeHandle, userData) =>
+ {
+ if (handle != IntPtr.Zero)
+ {
+ action(RouteSegmentHandle.CloneFrom(nativeHandle));
+ //Destroy(nativeHandle);
+ }
+ return true;
+ };
+
+ ForeachSegment(handle, callback, IntPtr.Zero).WarnIfFailed("Failed to get segment list from native handle");
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.SafeMapsHandle.cs b/src/Tizen.Maps/Interop/Interop.SafeMapsHandle.cs
new file mode 100755
index 0000000..6f915cc
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.SafeMapsHandle.cs
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+
+internal static partial class Interop
+{
+ private const string LogTag = "Tizen.Maps";
+
+ public delegate ErrorCode GetterMethod<T>(out T value);
+ public delegate ErrorCode GetterPtrMethod(out IntPtr value);
+ public delegate ErrorCode SetterMethod<T>(T value);
+
+ internal static T NativeGet<T>(GetterMethod<T> getter, [CallerMemberName] string propertyName = "")
+ {
+ T value;
+ var err = getter(out value);
+ if (err.IsSuccess())
+ {
+ return value;
+ }
+
+ //err.WarnIfFailed($"Native getter for {propertyName} failed");
+ return default(T);
+ }
+
+ internal static T NativeGet<T>(GetterMethod<IntPtr> getter, Func<IntPtr, T> ctor, [CallerMemberName] string propertyName = "") where T : SafeMapsHandle
+ {
+ return ctor(NativeGet(getter, propertyName));
+ }
+
+ internal static T NativeGet<T>(GetterMethod<IntPtr> getter, Func<IntPtr, bool, T> ctor, bool hasOwnership, [CallerMemberName] string propertyName = "") where T : SafeMapsHandle
+ {
+ return ctor(NativeGet(getter, propertyName), hasOwnership);
+ }
+
+ internal static string NativeGet(GetterMethod<string> getter, [CallerMemberName] string propertyName = "")
+ {
+ string value;
+ var err = getter(out value);
+ if (err.IsSuccess())
+ {
+ return value;
+ }
+
+ //err.WarnIfFailed($"Native getter for {propertyName} failed");
+ return string.Empty;
+ }
+
+ internal static void NativeSet<T>(SetterMethod<T> setter, T value, [CallerMemberName] string propertyName = "")
+ {
+ setter(value).WarnIfFailed($"Native setter for {propertyName} failed");
+ }
+
+ internal abstract class SafeMapsHandle : SafeHandle
+ {
+ protected delegate ErrorCode DestroyNativeHandleMethod(IntPtr handle);
+ protected DestroyNativeHandleMethod DestroyHandle;
+
+ protected SafeMapsHandle(IntPtr handle, bool needToRelease, DestroyNativeHandleMethod destroy) : base(handle, true)
+ {
+ HasOwnership = needToRelease;
+ DestroyHandle = destroy;
+ }
+
+ internal bool HasOwnership { get; set; }
+
+ public override bool IsInvalid { get { return handle == IntPtr.Zero; } }
+
+ protected override bool ReleaseHandle()
+ {
+ if (HasOwnership)
+ {
+ var err = DestroyHandle(handle);
+ err.WarnIfFailed($"Failed to delete native {GetType()} handle");
+ }
+
+ SetHandle(IntPtr.Zero);
+ return true;
+ }
+
+ public static implicit operator IntPtr(SafeMapsHandle otherHandle)
+ {
+ return otherHandle.handle;
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.Service.cs b/src/Tizen.Maps/Interop/Interop.Service.cs
new file mode 100755
index 0000000..0cd154f
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.Service.cs
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal enum ServiceType
+ {
+ Geocode, // MAPS_SERVICE_GEOCODE
+ GeocodeInsideArea, // MAPS_SERVICE_GEOCODE_INSIDE_AREA
+ GeocodeByStructuredAddress, // MAPS_SERVICE_GEOCODE_BY_STRUCTURED_ADDRESS
+ ReverseGeocode, // MAPS_SERVICE_REVERSE_GEOCODE
+ SearchPlace, // MAPS_SERVICE_SEARCH_PLACE
+ SearchPlaceByArea, // MAPS_SERVICE_SEARCH_PLACE_BY_AREA
+ SearchPlaceByAddress, // MAPS_SERVICE_SEARCH_PLACE_BY_ADDRESS
+ SearchRoute, // MAPS_SERVICE_SEARCH_ROUTE
+ SearchRouteWaypoints, // MAPS_SERVICE_SEARCH_ROUTE_WAYPOINTS
+ CancelRequest, // MAPS_SERVICE_CANCEL_REQUEST
+ MultiReverseGeocode, // MAPS_SERVICE_MULTI_REVERSE_GEOCODE
+ SearchPlaceList, // MAPS_SERVICE_SEARCH_PLACE_LIST
+ SearchGetPlaceDetails, // MAPS_SERVICE_SEARCH_GET_PLACE_DETAILS
+ View = 0x100, // MAPS_SERVICE_VIEW
+ ViewSnapshot, // MAPS_SERVICE_VIEW_SNAPSHOT
+ }
+
+ internal enum ServiceData
+ {
+ PlaceAddress, // MAPS_PLACE_ADDRESS
+ PlaceRating, // MAPS_PLACE_RATING
+ PlaceCategories, // MAPS_PLACE_CATEGORIES
+ PlaceAttributes, // MAPS_PLACE_ATTRIBUTES
+ PlaceContacts, // MAPS_PLACE_CONTACTS
+ PlaceEditorials, // MAPS_PLACE_EDITORIALS
+ PlaceReviews, // MAPS_PLACE_REVIEWS
+ PlaceImage, // MAPS_PLACE_IMAGE
+ PlaceSupplier, // MAPS_PLACE_SUPPLIER
+ PlaceRelated, // MAPS_PLACE_RELATED
+ RoutePath, // MAPS_ROUTE_PATH
+ RouteSegmentsPath, // MAPS_ROUTE_SEGMENTS_PATH
+ RouteSegmentsManeuvers, // MAPS_ROUTE_SEGMENTS_MANEUVERS
+ ViewTraffic = 0x100, // MAPS_VIEW_TRAFFIC
+ ViewPublicTransit, // MAPS_VIEW_PUBLIC_TRANSIT
+ ViewBuilding, // MAPS_VIEW_BUILDING
+ ViewScaleBar, // MAPS_VIEW_SCALEBAR
+ }
+
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool GeocodeCallback(ErrorCode /* maps_error_e */ result, int requestId, int index, int total, IntPtr /* maps_coordinates_h */ coordinates, IntPtr /* void */ userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ReverseGeocodeCallback(ErrorCode /* maps_error_e */ result, int requestId, int index, int total, IntPtr /* maps_address_h */ address, IntPtr /* void */ userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool MultiReverseGeocodeCallback(ErrorCode /* maps_error_e */ result, int requestId, int total, IntPtr /* maps_address_list_h */ addressList, IntPtr /* void */ userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool SearchPlaceCallback(ErrorCode /* maps_error_e */ error, int requestId, int index, int total, IntPtr /* maps_place_h */ place, IntPtr /* void */ userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void SearchPlaceListCallback(ErrorCode /* maps_error_e */ error, int requestId, int total, IntPtr /* maps_place_list_h */ placeList, IntPtr /* void */ userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void GetPlaceDetailsCallback(ErrorCode /* maps_error_e */ error, int requestId, IntPtr /* maps_place_h */ place, IntPtr /* void */ userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool SearchRouteCallback(ErrorCode /* maps_error_e */ error, int requestId, int index, int total, IntPtr /* maps_route_h */ route, IntPtr /* void */ userData);
+
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_service_cancel_request")]
+ internal static extern ErrorCode CancelRequest(this ServiceHandle /* maps_service_h */ maps, int requestId);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_service_geocode")]
+ internal static extern ErrorCode Geocode(this ServiceHandle /* maps_service_h */ maps, string address, PreferenceHandle /* maps_preference_h */ preference, GeocodeCallback callback, IntPtr /* void */ userData, out int requestId);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_service_geocode_inside_area")]
+ internal static extern ErrorCode GeocodeInsideArea(this ServiceHandle /* maps_service_h */ maps, string address, AreaHandle /* maps_area_h */ bounds, PreferenceHandle /* maps_preference_h */ preference, GeocodeCallback callback, IntPtr /* void */ userData, out int requestId);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_service_geocode_by_structured_address")]
+ internal static extern ErrorCode GeocodeByStructuredAddress(this ServiceHandle /* maps_service_h */ maps, AddressHandle /* maps_address_h */ address, PreferenceHandle /* maps_preference_h */ preference, GeocodeCallback callback, IntPtr /* void */ userData, out int requestId);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_service_reverse_geocode")]
+ internal static extern ErrorCode ReverseGeocode(this ServiceHandle /* maps_service_h */ maps, double latitude, double longitude, PreferenceHandle /* maps_preference_h */ preference, ReverseGeocodeCallback callback, IntPtr /* void */ userData, out int requestId);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_service_multi_reverse_geocode")]
+ internal static extern ErrorCode MultiReverseGeocode(this ServiceHandle /* maps_service_h */ maps, CoordinatesListHandle /* maps_coordinates_list_h */ coordinatesList, PreferenceHandle /* maps_preference_h */ preference, MultiReverseGeocodeCallback callback, IntPtr /* void */ userData, out int requestId);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_service_search_place")]
+ internal static extern ErrorCode SearchPlace(this ServiceHandle /* maps_service_h */ maps, CoordinatesHandle /* maps_coordinates_h */ position, int distance, PlaceFilterHandle /* maps_place_filter_h */ filter, PreferenceHandle /* maps_preference_h */ preference, SearchPlaceCallback callback, IntPtr /* void */ userData, out int requestId);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_service_search_place_by_area")]
+ internal static extern ErrorCode SearchPlaceByArea(this ServiceHandle /* maps_service_h */ maps, AreaHandle /* maps_area_h */ boundary, PlaceFilterHandle /* maps_place_filter_h */ filter, PreferenceHandle /* maps_preference_h */ preference, SearchPlaceCallback callback, IntPtr /* void */ userData, out int requestId);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_service_search_place_by_address")]
+ internal static extern ErrorCode SearchPlaceByAddress(this ServiceHandle /* maps_service_h */ maps, string address, AreaHandle /* maps_area_h */ boundary, PlaceFilterHandle /* maps_place_filter_h */ filter, PreferenceHandle /* maps_preference_h */ preference, SearchPlaceCallback callback, IntPtr /* void */ userData, out int requestId);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_service_search_place_list")]
+ internal static extern ErrorCode SearchPlaceList(this ServiceHandle /* maps_service_h */ maps, AreaHandle /* maps_area_h */ boundary, PlaceFilterHandle /* maps_place_filter_h */ filter, PreferenceHandle /* maps_preference_h */ preference, SearchPlaceListCallback callback, IntPtr /* void */ userData, out int requestId);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_service_get_place_details")]
+ internal static extern ErrorCode GetPlaceDetails(this ServiceHandle /* maps_service_h */ maps, string uri, GetPlaceDetailsCallback callback, IntPtr /* void */ userData, out int requestId);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_service_search_route")]
+ internal static extern ErrorCode SearchRoute(this ServiceHandle /* maps_service_h */ maps, CoordinatesHandle /* maps_coordinates_h */ origin, CoordinatesHandle /* maps_coordinates_h */ destination, PreferenceHandle /* maps_preference_h */ preference, SearchRouteCallback callback, IntPtr /* void */ userData, out int requestId);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_service_search_route_waypoints")]
+ internal static extern ErrorCode SearchRouteWaypoints(this ServiceHandle /* maps_service_h */ maps, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] [In] IntPtr[] /* maps_coordinates_h */ waypointList, int waypointNum, PreferenceHandle /* maps_preference_h */ preference, SearchRouteCallback callback, IntPtr /* void */ userData, out int requestId);
+
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_service_set_provider_key")]
+ internal static extern ErrorCode SetProviderKey(this ServiceHandle /* maps_service_h */ maps, string providerKey);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_service_get_provider_key")]
+ internal static extern ErrorCode GetProviderKey(this ServiceHandle /* maps_service_h */ maps, out string providerKey);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_service_set_preference")]
+ internal static extern ErrorCode SetPreference(this ServiceHandle /* maps_service_h */ maps, PreferenceHandle /* maps_preference_h */ preference);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_service_get_preference")]
+ internal static extern ErrorCode GetPreference(this ServiceHandle /* maps_service_h */ maps, out IntPtr /* maps_preference_h */ preference);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_service_provider_is_service_supported")]
+ internal static extern ErrorCode IsServiceSupported(this ServiceHandle /* maps_service_h */ maps, ServiceType /* maps_service_e */ service, out bool supported);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_service_provider_is_data_supported")]
+ internal static extern ErrorCode IsDataSupported(this ServiceHandle /* maps_service_h */ maps, ServiceData /* maps_service_data_e */ data, out bool supported);
+
+ internal class ServiceHandle : SafeMapsHandle
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void RequestUserConsentCallback(bool consented, string provider, IntPtr /* void */ userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool ProviderInfoCallback(string mapsProvider, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_service_request_user_consent")]
+ internal static extern ErrorCode RequestUserConsent(string provider, RequestUserConsentCallback callback, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_service_foreach_provider")]
+ internal static extern ErrorCode ForeachProvider(ProviderInfoCallback callback, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_service_create")]
+ internal static extern ErrorCode Create(string provider, out IntPtr /* maps_service_h */ maps);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_service_destroy")]
+ internal static extern ErrorCode Destroy(IntPtr /* maps_service_h */ maps);
+
+ internal string ProviderKey
+ {
+ get { return NativeGet(this.GetProviderKey); }
+ set { NativeSet(this.SetProviderKey, value); }
+ }
+
+ internal PreferenceHandle Preferences
+ {
+ get { return NativeGet(this.GetPreference, PreferenceHandle.Create); }
+ set { NativeSet(this.SetPreference, value); }
+ }
+
+ public ServiceHandle(IntPtr handle, bool needToRelease) : base(handle, needToRelease, Destroy)
+ {
+ }
+
+ public ServiceHandle(string serviceProvider) : this(IntPtr.Zero, true)
+ {
+ Create(serviceProvider, out handle).ThrowIfFailed($"Failed to create native handle for {serviceProvider}");
+ }
+
+ internal static void ForeachProvider(Action<string> action)
+ {
+ ProviderInfoCallback callback = (provider, userData) =>
+ {
+ action(provider);
+ return true;
+ };
+
+ ForeachProvider(callback, IntPtr.Zero).WarnIfFailed("Failed to get provider list from native handle");
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.View.Event.Data.cs b/src/Tizen.Maps/Interop/Interop.View.Event.Data.cs
new file mode 100755
index 0000000..dd5fd6a
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.View.Event.Data.cs
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using ElmSharp;
+
+internal static partial class Interop
+{
+ internal enum ViewAction
+ {
+ None, // MAPS_VIEW_ACTION_NONE
+ Scroll, // MAPS_VIEW_ACTION_SCROLL
+ Zoom, // MAPS_VIEW_ACTION_ZOOM
+ ZoomIn, // MAPS_VIEW_ACTION_ZOOM_IN
+ ZoomOut, // MAPS_VIEW_ACTION_ZOOM_OUT
+ ZoomAndScroll, // MAPS_VIEW_ACTION_ZOOM_AND_SCROLL
+ Rotate, // MAPS_VIEW_ACTION_ROTATE
+ }
+
+ internal enum ViewGesture
+ {
+ None, // MAPS_VIEW_GESTURE_NONE
+ Scroll, // MAPS_VIEW_GESTURE_SCROLL
+ Zoom, // MAPS_VIEW_GESTURE_ZOOM
+ Click, // MAPS_VIEW_GESTURE_TAP
+ DoubleClick, // MAPS_VIEW_GESTURE_DOUBLE_TAP
+ TwoFingerClick, // MAPS_VIEW_GESTURE_2_FINGER_TAP
+ Rotation, // MAPS_VIEW_GESTURE_ROTATE
+ LongPress, // MAPS_VIEW_GESTURE_LONG_PRESS
+ }
+
+ internal enum ViewEventType
+ {
+ Gesture, // MAPS_VIEW_EVENT_GESTURE
+ Action, // MAPS_VIEW_EVENT_ACTION
+ Object, // MAPS_VIEW_EVENT_OBJECT
+ Ready, // MAPS_VIEW_EVENT_READY
+ }
+
+ internal static partial class ViewEventData
+ {
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_event_data_clone")]
+ internal static extern ErrorCode Clone(IntPtr /* maps_view_event_data_h */ origin, out IntPtr /* maps_view_event_data_h */ cloned);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_event_data_get_center")]
+ internal static extern ErrorCode GetCenter(IntPtr /* maps_view_event_data_h */ viewEvent, out IntPtr /* maps_coordinates_h */ center);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_event_data_get_delta")]
+ internal static extern ErrorCode GetDelta(IntPtr /* maps_view_event_data_h */ viewEvent, out int deltaX, out int deltaY);
+ }
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_event_data_get_type")]
+ internal static extern ErrorCode GetType(this EventDataHandle /* maps_view_event_data_h */ viewEvent, out ViewEventType /* maps_view_event_type_e */ eventType);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_event_data_get_gesture_type")]
+ internal static extern ErrorCode GetGestureType(this EventDataHandle /* maps_view_event_data_h */ viewEvent, out ViewGesture /* maps_view_gesture_e */ gestureType);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_event_data_get_action_type")]
+ internal static extern ErrorCode GetActionType(this EventDataHandle /* maps_view_event_data_h */ viewEvent, out ViewAction /* maps_view_action_e */ actionType);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_event_data_get_position")]
+ internal static extern ErrorCode GetPosition(this EventDataHandle /* maps_view_event_data_h */ viewEvent, out int x, out int y);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_event_data_get_fingers")]
+ internal static extern ErrorCode GetFingers(this EventDataHandle /* maps_view_event_data_h */ viewEvent, out int fingers);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_event_data_get_object")]
+ internal static extern ErrorCode GetObject(this EventDataHandle /* maps_view_event_data_h */ viewEvent, out IntPtr /* maps_view_object_h */ viewEventDataObject);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_event_data_get_coordinates")]
+ internal static extern ErrorCode GetCoordinates(this EventDataHandle /* maps_view_event_data_h */ viewEvent, out IntPtr /* maps_coordinates_h */ coordinates);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_event_data_get_zoom_factor")]
+ internal static extern ErrorCode GetZoomFactor(this EventDataHandle /* maps_view_event_data_h */ viewEvent, out double zoomFactor);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_event_data_get_rotation_angle")]
+ internal static extern ErrorCode GetRotationAngle(this EventDataHandle /* maps_view_event_data_h */ viewEvent, out double rotationAngle);
+
+ internal static ErrorCode GetPosition(this EventDataHandle /* maps_view_event_data_h */ viewEvent, out Point position)
+ {
+ position = new Point();
+ return GetPosition(viewEvent, out position.X, out position.Y);
+ }
+
+ internal class EventDataHandle : SafeMapsHandle
+ {
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_event_data_destroy")]
+ internal static extern ErrorCode Destroy(IntPtr /* maps_view_event_data_h */ viewEvent);
+
+ internal ViewEventType Type
+ {
+ get { return NativeGet<ViewEventType>(this.GetType); }
+ }
+
+ // event_data will be released automatically after this callback is terminated.
+ internal EventDataHandle(IntPtr handle) : base(handle, false, Destroy)
+ {
+ }
+ }
+
+ internal class ObjectEventDataHandle : EventDataHandle
+ {
+ internal ViewGesture GestureType
+ {
+ get { return NativeGet<ViewGesture>(this.GetGestureType); }
+ }
+
+ internal Point Position
+ {
+ get { return NativeGet<Point>(this.GetPosition); }
+ }
+
+ internal int FingerCount
+ {
+ get { return NativeGet<int>(this.GetFingers); }
+ }
+
+ internal ViewObjectHandle ViewObject
+ {
+ get { return NativeGet(this.GetObject, ViewObjectHandle.Create, false ); }
+ }
+
+ // event_data will be released automatically after this callback is terminated.
+ internal ObjectEventDataHandle(IntPtr handle) : base(handle)
+ {
+ }
+ }
+
+ internal class GestureEventDataHandle : EventDataHandle
+ {
+ internal ViewGesture GestureType
+ {
+ get { return NativeGet<ViewGesture>(this.GetGestureType); }
+ }
+
+ internal Point Position
+ {
+ get { return NativeGet<Point>(this.GetPosition); }
+ }
+
+ internal int FingerCount
+ {
+ get { return NativeGet<int>(this.GetFingers); }
+ }
+
+ internal double ZoomFactor
+ {
+ get { return NativeGet<double>(this.GetZoomFactor); }
+ }
+
+ internal double RotationAngle
+ {
+ get { return NativeGet<double>(this.GetRotationAngle); }
+ }
+
+ internal CoordinatesHandle Coordinates
+ {
+ get { return NativeGet(this.GetCoordinates, CoordinatesHandle.Create); }
+ }
+
+ internal GestureEventDataHandle(IntPtr handle) : base(handle)
+ {
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.View.Marker.cs b/src/Tizen.Maps/Interop/Interop.View.Marker.cs
new file mode 100755
index 0000000..f92ef87
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.View.Marker.cs
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using ElmSharp;
+
+internal static partial class Interop
+{
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_marker_get_type")]
+ internal static extern ErrorCode GetType(this MarkerHandle /* maps_view_object_h */ marker, out ViewMarkerType /* maps_view_marker_type_e */ type);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_marker_get_coordinates")]
+ internal static extern ErrorCode GetCoordinates(this MarkerHandle /* maps_view_object_h */ marker, out IntPtr /* maps_coordinates_h */ coordinates);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_marker_set_coordinates")]
+ internal static extern ErrorCode SetCoordinates(this MarkerHandle /* maps_view_object_h */ marker, CoordinatesHandle /* maps_coordinates_h */ coordinates);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_marker_get_image_file")]
+ internal static extern ErrorCode GetImageFile(this MarkerHandle /* maps_view_object_h */ marker, out string filePath);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_marker_set_image_file")]
+ internal static extern ErrorCode SetImageFile(this MarkerHandle /* maps_view_object_h */ marker, string filePath);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_marker_get_z_order")]
+ internal static extern ErrorCode GetZOrder(this MarkerHandle /* maps_view_object_h */ marker, out int zOrder);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_marker_set_z_order")]
+ internal static extern ErrorCode SetZOrder(this MarkerHandle /* maps_view_object_h */ marker, int zOrder);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_marker_get_size")]
+ internal static extern ErrorCode GetSize(this MarkerHandle /* maps_view_object_h */ marker, out int width, out int height);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_marker_resize")]
+ internal static extern ErrorCode Resize(this MarkerHandle /* maps_view_object_h */ marker, int width, int height);
+
+ internal static ErrorCode GetSize(this MarkerHandle /* maps_view_object_h */ marker, out Size size)
+ {
+ size = new Size(0, 0);
+ return GetSize(marker, out size.Width, out size.Height);
+ }
+
+ internal static ErrorCode SetSize(this MarkerHandle /* maps_view_object_h */ marker, Size size)
+ {
+ return Resize(marker, size.Width, size.Height);
+ }
+
+ internal class MarkerHandle : ViewObjectHandle
+ {
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_create_marker")]
+ internal static extern ErrorCode CreateMarker(CoordinatesHandle /* maps_coordinates_h */ coordinates, string imageFilePath, ViewMarkerType /* maps_view_marker_type_e */ type, out IntPtr /* maps_view_object_h */ marker);
+
+ internal ViewMarkerType Type
+ {
+ get { return NativeGet<ViewMarkerType>(this.GetType); }
+ }
+
+ internal string ImageFile
+ {
+ get { return NativeGet(this.GetImageFile); }
+ set { NativeSet(this.SetImageFile, value); }
+ }
+
+ internal int ZOrder
+ {
+ get { return NativeGet<int>(this.GetZOrder); }
+ set { NativeSet(this.SetZOrder, value); }
+ }
+
+ internal Size MarkerSize
+ {
+ get { return NativeGet<Size>(this.GetSize); }
+ set { NativeSet(this.SetSize, value); }
+ }
+
+ internal CoordinatesHandle Coordinates
+ {
+ get { return NativeGet(this.GetCoordinates, CoordinatesHandle.Create); }
+ set { NativeSet(this.SetCoordinates, value); }
+ }
+
+ internal MarkerHandle(CoordinatesHandle coordinates, string imagePath, ViewMarkerType type) : base(IntPtr.Zero, true)
+ {
+ var clonedCoordinatesHandle = CoordinatesHandle.CloneFrom(coordinates);
+ CreateMarker(clonedCoordinatesHandle, imagePath, type, out handle).ThrowIfFailed("Failed to create native handle for marker");
+ clonedCoordinatesHandle.HasOwnership = false;
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.View.Object.cs b/src/Tizen.Maps/Interop/Interop.View.Object.cs
new file mode 100755
index 0000000..af2834f
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.View.Object.cs
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using ElmSharp;
+
+internal static partial class Interop
+{
+ internal enum ViewObjectType
+ {
+ Polyline, // MAPS_VIEW_OBJECT_POLYLINE
+ Polygon, // MAPS_VIEW_OBJECT_POLYGON
+ Marker, // MAPS_VIEW_OBJECT_MARKER
+ Overlay, // MAPS_VIEW_OBJECT_OVERLAY
+ }
+
+ internal enum ViewMarkerType
+ {
+ Pin, // MAPS_VIEW_MARKER_PIN
+ Sticker, // MAPS_VIEW_MARKER_STICKER
+ }
+
+ internal enum ViewOverlayType
+ {
+ Normal, // MAPS_VIEW_OVERLAY_NORMAL
+ Bubble, // MAPS_VIEW_OVERLAY_BUBBLE
+ Box, // MAPS_VIEW_OVERLAY_BOX
+ }
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_get_type")]
+ internal static extern ErrorCode GetType(this ViewObjectHandle /* maps_view_object_h */ viewObject, out ViewObjectType /* maps_view_object_type_e */ type);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_set_visible")]
+ internal static extern ErrorCode SetVisible(this ViewObjectHandle /* maps_view_object_h */ viewObject, bool visible);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_get_visible")]
+ internal static extern ErrorCode GetVisible(this ViewObjectHandle /* maps_view_object_h */ viewObject, out bool visible);
+
+ internal class ViewObjectHandle : SafeMapsHandle
+ {
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_destroy")]
+ internal static extern ErrorCode Destroy(IntPtr /* maps_view_object_h */ viewObject);
+
+ internal bool IsVisible
+ {
+ get { return NativeGet<bool>(this.GetVisible); }
+ set { NativeSet(this.SetVisible, value); }
+ }
+
+ public ViewObjectHandle(IntPtr handle, bool needToRelease) : base(handle, needToRelease, Destroy)
+ {
+ }
+
+ internal static ViewObjectHandle Create(IntPtr nativeHandle, bool needToRelease)
+ {
+ return new ViewObjectHandle(nativeHandle, needToRelease);
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.View.Overlay.cs b/src/Tizen.Maps/Interop/Interop.View.Overlay.cs
new file mode 100755
index 0000000..27ed8b7
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.View.Overlay.cs
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using ElmSharp;
+
+internal static partial class Interop
+{
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_overlay_set_coordinates")]
+ internal static extern ErrorCode SetCoordinates(this OverlayHandle /* maps_view_object_h */ overlay, CoordinatesHandle /* maps_coordinates_h */ coordinates);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_overlay_get_coordinates")]
+ internal static extern ErrorCode GetCoordinates(this OverlayHandle /* maps_view_object_h */ overlay, out IntPtr /* maps_coordinates_h */ coordinates);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_overlay_set_min_zoom_level")]
+ internal static extern ErrorCode SetMinZoomLevel(this OverlayHandle /* maps_view_object_h */ overlay, int zoom);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_overlay_get_min_zoom_level")]
+ internal static extern ErrorCode GetMinZoomLevel(this OverlayHandle /* maps_view_object_h */ overlay, out int zoom);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_overlay_set_max_zoom_level")]
+ internal static extern ErrorCode SetMaxZoomLevel(this OverlayHandle /* maps_view_object_h */ overlay, int zoom);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_overlay_get_max_zoom_level")]
+ internal static extern ErrorCode GetMaxZoomLevel(this OverlayHandle /* maps_view_object_h */ overlay, out int zoom);
+
+ internal class OverlayHandle : ViewObjectHandle
+ {
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_create_overlay")]
+ internal static extern ErrorCode CreateOverlay(CoordinatesHandle /* maps_coordinates_h */ coordinates, IntPtr viewObject, ViewOverlayType /* maps_view_overlay_type_e */ type, out IntPtr /* maps_view_object_h */ overlay);
+
+ internal int MinZoomLevel
+ {
+ get { return NativeGet<int>(this.GetMinZoomLevel); }
+ set { NativeSet(this.SetMinZoomLevel, value); }
+ }
+
+ internal int MaxZoomLevel
+ {
+ get { return NativeGet<int>(this.GetMaxZoomLevel); }
+ set { NativeSet(this.SetMaxZoomLevel, value); }
+ }
+
+
+ internal CoordinatesHandle Coordinates
+ {
+ get { return NativeGet(this.GetCoordinates, CoordinatesHandle.Create); }
+ set { NativeSet(this.SetCoordinates, value); }
+ }
+
+ internal OverlayHandle(CoordinatesHandle coordinates, EvasObject viewObject, ViewOverlayType type) : base(IntPtr.Zero, true)
+ {
+ var clonedCoordinatesHandle = CoordinatesHandle.CloneFrom(coordinates);
+ CreateOverlay(clonedCoordinatesHandle, viewObject, type, out handle).ThrowIfFailed("Failed to create native overlay handle");
+ clonedCoordinatesHandle.HasOwnership = false;
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.View.Polygon.cs b/src/Tizen.Maps/Interop/Interop.View.Polygon.cs
new file mode 100755
index 0000000..5699b0e
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.View.Polygon.cs
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using ElmSharp;
+
+internal static partial class Interop
+{
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_polygon_set_polygon")]
+ internal static extern ErrorCode SetPolygon(this PolygonHandle /* maps_view_object_h */ polygon, CoordinatesListHandle /* maps_coordinates_list_h */ points);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_polygon_get_fill_color")]
+ internal static extern ErrorCode GetFillColor(this PolygonHandle /* maps_view_object_h */ polygon, out byte r, out byte g, out byte b, out byte a);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_polygon_set_fill_color")]
+ internal static extern ErrorCode SetFillColor(this PolygonHandle /* maps_view_object_h */ polygon, byte r, byte g, byte b, byte a);
+
+ internal static ErrorCode GetFillColor(this PolygonHandle /* maps_view_object_h */ polygon, out Color color)
+ {
+ byte r, g, b, a;
+ var err = polygon.GetFillColor(out r, out g, out b, out a);
+ color = new Color(r, g, b, a);
+ return err;
+ }
+
+ internal static ErrorCode SetFillColor(this PolygonHandle /* maps_view_object_h */ polygon, Color color)
+ {
+ return polygon.SetFillColor((byte)color.R, (byte)color.G, (byte)color.B, (byte)color.A);
+ }
+
+ internal class PolygonHandle : ViewObjectHandle
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool CoordinatesCallback(int index, IntPtr /* maps_coordinates_h */ coordinates, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_polygon_foreach_point")]
+ internal static extern ErrorCode ForeachPoint(IntPtr /* maps_view_object_h */ polygon, CoordinatesCallback callback, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_create_polygon")]
+ internal static extern ErrorCode CreatePolygon(CoordinatesListHandle /* maps_coordinates_list_h */ coordinates, byte r, byte g, byte b, byte a, out IntPtr /* maps_view_object_h */ polygon);
+
+ internal Color FillColor
+ {
+ get { return NativeGet<Color>(this.GetFillColor); }
+ set { NativeSet(this.SetFillColor, value); }
+ }
+
+ internal PolygonHandle(CoordinatesListHandle coordinates, Color color) : base(IntPtr.Zero, true)
+ {
+ CreatePolygon(coordinates, (byte)color.R, (byte)color.G, (byte)color.B, (byte)color.A, out handle).ThrowIfFailed("Failed to create native polygon handle");
+ coordinates.HasOwnership = false;
+ }
+
+ internal void ForeachPoint(Action<CoordinatesHandle> action)
+ {
+ CoordinatesCallback callback = (index, handle, userData) =>
+ {
+ action(CoordinatesHandle.CloneFrom(handle));
+ return true;
+ };
+
+ ForeachPoint(handle, callback, IntPtr.Zero).WarnIfFailed("Failed to get coordinates list from native handle");
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.View.Polyline.cs b/src/Tizen.Maps/Interop/Interop.View.Polyline.cs
new file mode 100755
index 0000000..0ceae65
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.View.Polyline.cs
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using ElmSharp;
+
+internal static partial class Interop
+{
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_polyline_set_polyline")]
+ internal static extern ErrorCode SetPolyline(this PolylineHandle /* maps_view_object_h */ polyline, CoordinatesListHandle /* maps_coordinates_list_h */ points);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_polyline_set_color")]
+ internal static extern ErrorCode SetColor(this PolylineHandle /* maps_view_object_h */ polyline, byte r, byte g, byte b, byte a);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_polyline_get_color")]
+ internal static extern ErrorCode GetColor(this PolylineHandle /* maps_view_object_h */ polyline, out byte r, out byte g, out byte b, out byte a);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_polyline_set_width")]
+ internal static extern ErrorCode SetWidth(this PolylineHandle /* maps_view_object_h */ polyline, int width);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_polyline_get_width")]
+ internal static extern ErrorCode GetWidth(this PolylineHandle /* maps_view_object_h */ polyline, out int width);
+
+ internal static ErrorCode GetColor(this PolylineHandle /* maps_view_object_h */ polyline, out Color color)
+ {
+ byte r, g, b, a;
+ var err = polyline.GetColor(out r, out g, out b, out a);
+ color = new Color(r, g, b, a);
+ return err;
+ }
+
+ internal static ErrorCode SetColor(this PolylineHandle /* maps_view_object_h */ polyline, Color color)
+ {
+ return polyline.SetColor((byte)color.R, (byte)color.G, (byte)color.B, (byte)color.A);
+ }
+
+ internal class PolylineHandle : ViewObjectHandle
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool CoordinatesCallback(int index, IntPtr /* maps_coordinates_h */ coordinates, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_create_polyline")]
+ internal static extern ErrorCode CreatePolyline(CoordinatesListHandle /* maps_coordinates_list_h */ coordinates, byte r, byte g, byte b, byte a, int width, out IntPtr /* maps_view_object_h */ polyline);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_object_polyline_foreach_point")]
+ internal static extern ErrorCode ForeachPoint(IntPtr /* maps_view_object_h */ polyline, CoordinatesCallback callback, IntPtr /* void */ userData);
+
+ internal Color LineColor
+ {
+ get { return NativeGet<Color>(this.GetColor); }
+ set { NativeSet(this.SetColor, value); }
+ }
+
+ internal int LineWidth
+ {
+ get { return NativeGet<int>(this.GetWidth); }
+ set { NativeSet(this.SetWidth, value); }
+ }
+
+ internal PolylineHandle(CoordinatesListHandle coordinates, Color color, int width) : base(IntPtr.Zero, true)
+ {
+ CreatePolyline(coordinates, (byte)color.R, (byte)color.G, (byte)color.B, (byte)color.A, width, out handle).ThrowIfFailed("Failed to create native polyline handle");
+ coordinates.HasOwnership = false;
+ }
+
+ internal void ForeachPoint(Action<CoordinatesHandle> action)
+ {
+ CoordinatesCallback callback = (index, handle, userData) =>
+ {
+ action(CoordinatesHandle.CloneFrom(handle));
+ return true;
+ };
+
+ ForeachPoint(handle, callback, IntPtr.Zero).WarnIfFailed("Failed to get coordinates list from native handle");
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.View.Snapshot.cs b/src/Tizen.Maps/Interop/Interop.View.Snapshot.cs
new file mode 100755
index 0000000..d6403c6
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.View.Snapshot.cs
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal enum ViewSnapshotFormatType
+ {
+ ViewSnapshotBmp, // MAPS_VIEW_SNAPSHOT_BMP
+ ViewSnapshotJpeg, // MAPS_VIEW_SNAPSHOT_JPEG
+ }
+
+ internal static partial class ViewSnapshot
+ {
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_capture_snapshot")]
+ internal static extern ErrorCode ViewCaptureSnapshot(ViewHandle /* maps_view_h */ view, ViewSnapshotFormatType /* maps_view_snapshot_format_type_e */ type, int quality, string path);
+ }
+}
diff --git a/src/Tizen.Maps/Interop/Interop.View.cs b/src/Tizen.Maps/Interop/Interop.View.cs
new file mode 100755
index 0000000..c48224a
--- /dev/null
+++ b/src/Tizen.Maps/Interop/Interop.View.cs
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using ElmSharp;
+
+internal static partial class Interop
+{
+ internal enum ViewType
+ {
+ Normal, // MAPS_VIEW_TYPE_NORMAL
+ Satellite, // MAPS_VIEW_TYPE_SATELLITE
+ Terrain, // MAPS_VIEW_TYPE_TERRAIN
+ Hybrid, // MAPS_VIEW_TYPE_HYBRID
+ }
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ViewOnEventCallback(ViewEventType /* maps_view_event_type_e */ type, IntPtr /* maps_view_event_data_h */ eventData, IntPtr /* void */ userData);
+
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_get_zoom_level")]
+ internal static extern ErrorCode GetZoomLevel(this ViewHandle /* maps_view_h */ view, out int level);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_set_zoom_level")]
+ internal static extern ErrorCode SetZoomLevel(this ViewHandle /* maps_view_h */ view, int level);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_get_min_zoom_level")]
+ internal static extern ErrorCode GetMinZoomLevel(this ViewHandle /* maps_view_h */ view, out int minZoomLevel);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_set_min_zoom_level")]
+ internal static extern ErrorCode SetMinZoomLevel(this ViewHandle /* maps_view_h */ view, int minZoomLevel);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_get_max_zoom_level")]
+ internal static extern ErrorCode GetMaxZoomLevel(this ViewHandle /* maps_view_h */ view, out int maxZoomLevel);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_set_max_zoom_level")]
+ internal static extern ErrorCode SetMaxZoomLevel(this ViewHandle /* maps_view_h */ view, int maxZoomLevel);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_get_orientation")]
+ internal static extern ErrorCode GetOrientation(this ViewHandle /* maps_view_h */ view, out double rotationAngle);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_set_orientation")]
+ internal static extern ErrorCode SetOrientation(this ViewHandle /* maps_view_h */ view, double rotationAngle);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_get_language")]
+ internal static extern ErrorCode GetLanguage(this ViewHandle /* maps_view_h */ view, out string language);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_set_language")]
+ internal static extern ErrorCode SetLanguage(this ViewHandle /* maps_view_h */ view, string language);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_set_type")]
+ internal static extern ErrorCode SetMapType(this ViewHandle /* maps_view_h */ view, ViewType /* maps_view_type_e */ type);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_get_type")]
+ internal static extern ErrorCode GetMapType(this ViewHandle /* maps_view_h */ view, out ViewType /* maps_view_type_e */ type);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_get_buildings_enabled")]
+ internal static extern ErrorCode GetBuildingsEnabled(this ViewHandle /* maps_view_h */ view, out bool enable);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_set_buildings_enabled")]
+ internal static extern ErrorCode SetBuildingsEnabled(this ViewHandle /* maps_view_h */ view, bool enable);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_get_traffic_enabled")]
+ internal static extern ErrorCode GetTrafficEnabled(this ViewHandle /* maps_view_h */ view, out bool enable);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_set_traffic_enabled")]
+ internal static extern ErrorCode SetTrafficEnabled(this ViewHandle /* maps_view_h */ view, bool enable);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_get_public_transit_enabled")]
+ internal static extern ErrorCode GetPublicTransitEnabled(this ViewHandle /* maps_view_h */ view, out bool enable);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_set_public_transit_enabled")]
+ internal static extern ErrorCode SetPublicTransitEnabled(this ViewHandle /* maps_view_h */ view, bool enable);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_get_scalebar_enabled")]
+ internal static extern ErrorCode GetScaleBarEnabled(this ViewHandle /* maps_view_h */ view, out bool enabled);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_set_scalebar_enabled")]
+ internal static extern ErrorCode SetScaleBarEnabled(this ViewHandle /* maps_view_h */ view, bool enable);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_get_screen_location")]
+ internal static extern ErrorCode GetScreenLocation(this ViewHandle /* maps_view_h */ view, out int x, out int y, out int width, out int height);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_set_screen_location")]
+ internal static extern ErrorCode SetScreenLocation(this ViewHandle /* maps_view_h */ view, int x, int y, int width, int height);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_get_visibility")]
+ internal static extern ErrorCode GetVisibility(this ViewHandle /* maps_view_h */ view, out bool visible);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_set_visibility")]
+ internal static extern ErrorCode SetVisibility(this ViewHandle /* maps_view_h */ view, bool visible);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_get_viewport")]
+ internal static extern ErrorCode GetViewport(this ViewHandle /* maps_view_h */ view, out IntPtr viewport);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_get_center")]
+ internal static extern ErrorCode GetCenter(this ViewHandle /* maps_view_h */ view, out IntPtr /* maps_coordinates_h */ coordinates);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_set_center")]
+ internal static extern ErrorCode SetCenter(this ViewHandle /* maps_view_h */ view, CoordinatesHandle /* maps_coordinates_h */ coordinates);
+
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_get_gesture_enabled")]
+ internal static extern ErrorCode GetGestureEnabled(this ViewHandle /* maps_view_h */ view, ViewGesture /* maps_view_gesture_e */ gesture, out bool enabled);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_set_gesture_enabled")]
+ internal static extern ErrorCode SetGestureEnabled(this ViewHandle /* maps_view_h */ view, ViewGesture /* maps_view_gesture_e */ gesture, bool enabled);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_set_event_cb")]
+ internal static extern ErrorCode SetEventCb(this ViewHandle /* maps_view_h */ view, ViewEventType /* maps_view_event_type_e */ type, ViewOnEventCallback callback, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_unset_event_cb")]
+ internal static extern ErrorCode UnsetEventCb(this ViewHandle /* maps_view_h */ view, ViewEventType /* maps_view_event_type_e */ type);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_screen_to_geolocation")]
+ internal static extern ErrorCode ScreenToGeolocation(this ViewHandle /* maps_view_h */ view, int x, int y, out IntPtr /* maps_coordinates_h */ coordinates);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_geolocation_to_screen")]
+ internal static extern ErrorCode GeolocationToScreen(this ViewHandle /* maps_view_h */ view, CoordinatesHandle /* maps_coordinates_h */ coordinates, out int x, out int y);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_move")]
+ internal static extern ErrorCode Move(this ViewHandle /* maps_view_h */ view, int x, int y);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_resize")]
+ internal static extern ErrorCode Resize(this ViewHandle /* maps_view_h */ view, int width, int height);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_add_object")]
+ internal static extern ErrorCode AddObject(this ViewHandle /* maps_view_h */ view, ViewObjectHandle /* maps_view_object_h */ viewObject);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_remove_object")]
+ internal static extern ErrorCode RemoveObject(this ViewHandle /* maps_view_h */ view, ViewObjectHandle /* maps_view_object_h */ viewObject);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_remove_all_objects")]
+ internal static extern ErrorCode RemoveAllObjects(this ViewHandle /* maps_view_h */ view);
+
+ internal class ViewHandle : SafeMapsHandle
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool ViewObjectCallback(int index, int total, IntPtr /* maps_view_object_h */ viewObject, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_foreach_object")]
+ internal static extern ErrorCode ForeachObject(ViewHandle /* maps_view_h */ view, ViewObjectCallback callback, IntPtr /* void */ userData);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_create")]
+ internal static extern ErrorCode Create(ServiceHandle /* maps_service_h */ maps, IntPtr obj, out IntPtr /* maps_view_h */ view);
+
+ [DllImport(Libraries.MapService, EntryPoint = "maps_view_destroy")]
+ internal static extern ErrorCode Destroy(IntPtr /* maps_view_h */ view);
+
+ internal int ZoomLevel
+ {
+ get { return NativeGet<int>(this.GetZoomLevel); }
+ set { NativeSet(this.SetZoomLevel, value); }
+ }
+
+ internal int MinimumZoomLevel
+ {
+ get { return NativeGet<int>(this.GetMinZoomLevel); }
+ set { NativeSet(this.SetMinZoomLevel, value); }
+ }
+
+ internal int MaximumZoomLevel
+ {
+ get { return NativeGet<int>(this.GetMaxZoomLevel); }
+ set { NativeSet(this.SetMaxZoomLevel, value); }
+ }
+
+ internal double Orientation
+ {
+ get { return NativeGet<double>(this.GetOrientation); }
+ set { NativeSet(this.SetOrientation, value); }
+ }
+
+ internal ViewType MapType
+ {
+ get { return NativeGet<ViewType>(this.GetMapType); }
+ set { NativeSet(this.SetMapType, value); }
+ }
+
+ internal bool BuildingsEnabled
+ {
+ get { return NativeGet<bool>(this.GetBuildingsEnabled); }
+ set { NativeSet(this.SetBuildingsEnabled, value); }
+ }
+
+ internal bool TrafficEnabled
+ {
+ get { return NativeGet<bool>(this.GetTrafficEnabled); }
+ set { NativeSet(this.SetTrafficEnabled, value); }
+ }
+
+ internal bool PublicTransitEnabled
+ {
+ get { return NativeGet<bool>(this.GetPublicTransitEnabled); }
+ set { NativeSet(this.SetPublicTransitEnabled, value); }
+ }
+ internal bool ScaleBarEnabled
+ {
+ get { return NativeGet<bool>(this.GetScaleBarEnabled); }
+ set { NativeSet(this.SetScaleBarEnabled, value); }
+ }
+
+ internal string Language
+ {
+ get { return NativeGet(this.GetLanguage); }
+ set { NativeSet(this.SetLanguage, value); }
+ }
+
+ internal bool IsVisible
+ {
+ get { return NativeGet<bool>(this.GetVisibility); }
+ set { NativeSet(this.SetVisibility, value); }
+ }
+
+ internal CoordinatesHandle Center
+ {
+ get { return NativeGet(this.GetCenter, CoordinatesHandle.Create); }
+ set { NativeSet(this.SetCenter, value); }
+ }
+
+ public ViewHandle(IntPtr handle, bool needToRelease) : base(handle, needToRelease, Destroy)
+ {
+ }
+
+ public ViewHandle(ServiceHandle maps, IntPtr evasObject) : this(IntPtr.Zero, true)
+ {
+ Create(maps, evasObject, out handle).ThrowIfFailed("Failed to create native handle");
+ }
+
+ internal CoordinatesHandle ScreenToGeolocation(Point position)
+ {
+ IntPtr coordinates;
+ this.ScreenToGeolocation(position.X, position.Y, out coordinates).WarnIfFailed("Failed to convert screen position to geocoordinates");
+ return CoordinatesHandle.Create(coordinates);
+ }
+
+ internal Point GeolocationToScreen(CoordinatesHandle coordinates)
+ {
+ int x, y;
+ this.GeolocationToScreen(coordinates, out x, out y).WarnIfFailed("Failed to convert geocoordinates to screen position");
+ return new Point() { X = x, Y = y };
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps.csproj b/src/Tizen.Maps/Tizen.Maps.csproj
new file mode 100644
index 0000000..27b3fdc
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps.csproj
@@ -0,0 +1,16 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\ElmSharp\ElmSharp.csproj" />
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
+
diff --git a/src/Tizen.Maps/Tizen.Maps/Area.cs b/src/Tizen.Maps/Tizen.Maps/Area.cs
new file mode 100755
index 0000000..9e19368
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/Area.cs
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Class representing geographical area
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class Area : IDisposable
+ {
+ internal Interop.AreaHandle handle;
+
+ /// <summary>
+ /// Constructs rectangular area.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="topLeft">Top-left coordinates of the area</param>
+ /// <param name="bottomRight">Bottom-left coordinate of the area</param>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when input coordinates are invalid</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when native operation failed to allocate memory.</exception>
+ public Area(Geocoordinates topLeft, Geocoordinates bottomRight)
+ {
+ handle = new Interop.AreaHandle(topLeft?.handle, bottomRight?.handle);
+ }
+
+ /// <summary>
+ /// Constructs circular area.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="center">Coordinates for center of the area</param>
+ /// <param name="radius">Radius of the area</param>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when input coordinates are invalid</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when native operation failed to allocate memory.</exception>
+ public Area(Geocoordinates center, double radius)
+ {
+ handle = new Interop.AreaHandle(center?.handle, radius);
+ }
+
+ internal Area(Interop.AreaHandle nativeHandle)
+ {
+ handle = nativeHandle;
+ }
+
+ #region IDisposable Support
+ private bool _disposedValue = false;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ handle.Dispose();
+ _disposedValue = true;
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/Direction.cs b/src/Tizen.Maps/Tizen.Maps/Direction.cs
new file mode 100755
index 0000000..61c924f
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/Direction.cs
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Direction types for route maneuver
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum DirectionType
+ {
+ /// <summary>
+ /// Indicates unknown direction.
+ /// </summary>
+ None = Interop.RouteDirection.None,
+ /// <summary>
+ /// Indicates north direction.
+ /// </summary>
+ North = Interop.RouteDirection.North,
+ /// <summary>
+ /// Indicates north-west direction.
+ /// </summary>
+ NorthWest = Interop.RouteDirection.NorthWest,
+ /// <summary>
+ /// Indicates north-east direction.
+ /// </summary>
+ NorthEast = Interop.RouteDirection.NorthEast,
+ /// <summary>
+ /// Indicates south direction.
+ /// </summary>
+ South = Interop.RouteDirection.South,
+ /// <summary>
+ /// Indicates south-East direction.
+ /// </summary>
+ SouthEast = Interop.RouteDirection.SouthEast,
+ /// <summary>
+ /// Indicates south-West direction.
+ /// </summary>
+ SouthWest = Interop.RouteDirection.SouthWest,
+ /// <summary>
+ /// Indicates west direction.
+ /// </summary>
+ West = Interop.RouteDirection.West,
+ /// <summary>
+ /// Indicates east direction.
+ /// </summary>
+ East = Interop.RouteDirection.East,
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/DistanceUnit.cs b/src/Tizen.Maps/Tizen.Maps/DistanceUnit.cs
new file mode 100755
index 0000000..addc926
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/DistanceUnit.cs
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Allowed distance units
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum DistanceUnit
+ {
+ /// <summary>
+ /// Indicates meter unit.
+ /// </summary>
+ Meter = Interop.DistanceUnit.Meter,
+ /// <summary>
+ /// Indicates kilometer unit.
+ /// </summary>
+ Kilometer = Interop.DistanceUnit.Kilometer,
+ /// <summary>
+ /// Indicates foot unit.
+ /// </summary>
+ Foot = Interop.DistanceUnit.Foot,
+ /// <summary>
+ /// Indicates yard unit.
+ /// </summary>
+ Yard = Interop.DistanceUnit.Yard,
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/GeocodeRequest.cs b/src/Tizen.Maps/Tizen.Maps/GeocodeRequest.cs
new file mode 100755
index 0000000..f39452c
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/GeocodeRequest.cs
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Geocode request for map service
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class GeocodeRequest : MapServiceRequest<Geocoordinates>
+ {
+ private Interop.GeocodeCallback _geocodeCallback;
+ private List<Geocoordinates> _coordinateList = new List<Geocoordinates>();
+
+ internal GeocodeRequest(MapService service, string address) : this(service, ServiceRequestType.Geocode)
+ {
+ startExecutionAction = new Action(() =>
+ {
+ int requestID;
+ errMessage = $"Failed to get coordinates for given address {address}";
+ errorCode = _service.handle.Geocode(address, _service.Preferences.handle, _geocodeCallback, IntPtr.Zero, out requestID);
+ if (errorCode.IsFailed() && errorCode != Interop.ErrorCode.Canceled)
+ {
+ _requestTask?.TrySetException(errorCode.GetException(errMessage));
+ }
+ _requestID = requestID;
+ });
+ }
+
+ internal GeocodeRequest(MapService service, string address, Area boundry) : this(service, ServiceRequestType.GeocodeInsideArea)
+ {
+ startExecutionAction = new Action(() =>
+ {
+ int requestID;
+ errMessage = $"Failed to get coordinates for given address {address}";
+ errorCode = _service.handle.GeocodeInsideArea(address, boundry.handle, _service.Preferences.handle, _geocodeCallback, IntPtr.Zero, out requestID);
+ if (errorCode.IsFailed() && errorCode != Interop.ErrorCode.Canceled)
+ {
+ _requestTask?.TrySetException(errorCode.GetException(errMessage));
+ }
+ _requestID = requestID;
+ });
+ }
+
+ internal GeocodeRequest(MapService service, PlaceAddress address) : this(service, ServiceRequestType.GeocodeByStructuredAddress)
+ {
+ startExecutionAction = new Action(() =>
+ {
+ int requestID;
+ errMessage = $"Failed to get coordinates for given address {address}";
+ errorCode = _service.handle.GeocodeByStructuredAddress(address.handle, _service.Preferences.handle, _geocodeCallback, IntPtr.Zero, out requestID);
+ if (errorCode.IsFailed() && errorCode != Interop.ErrorCode.Canceled)
+ {
+ _requestTask?.TrySetException(errorCode.GetException(errMessage));
+ }
+ _requestID = requestID;
+ });
+ }
+
+ private GeocodeRequest(MapService service, ServiceRequestType type) : base(service, type)
+ {
+ // The Maps Service invokes this callback while iterating through the list of obtained coordinates of the specified place.
+ _geocodeCallback = (result, id, index, total, coordinates, userData) =>
+ {
+ errorCode = result;
+ if (result.IsSuccess())
+ {
+ // The parameter coordinates must be released using maps_coordinates_destroy()
+ var coordinatesHandle = new Interop.CoordinatesHandle(coordinates, needToRelease: true);
+ _coordinateList.Add(new Geocoordinates(coordinatesHandle));
+ if (_coordinateList.Count == total)
+ {
+ _requestTask?.TrySetResult(_coordinateList);
+ }
+ return true;
+ }
+ else
+ {
+ // If search is failed, the value of total is 0 and coordinates is NULL
+ _requestTask?.TrySetException(result.GetException(errMessage));
+ return false;
+ }
+ };
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/Geocoordinates.cs b/src/Tizen.Maps/Tizen.Maps/Geocoordinates.cs
new file mode 100755
index 0000000..fb891ac
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/Geocoordinates.cs
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Class representing geographical coordinates.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class Geocoordinates : IDisposable
+ {
+ internal Interop.CoordinatesHandle handle;
+
+ /// <summary>
+ /// Constructs map coordinates object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="latitude">Latitude value, must be between (-90.0 ~ 90.0) degrees</param>
+ /// <param name="longitude">Longitude value, must be between (-180.0 ~ 180.0) degrees</param>
+ /// <exception cref="System.ArgumentException">Thrown when values for latitude and longitude are not valid.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when native operation failed to allocate memory.</exception>
+ public Geocoordinates(double latitude, double longitude)
+ {
+ handle = new Interop.CoordinatesHandle(latitude, longitude);
+ }
+
+ internal Geocoordinates(Interop.CoordinatesHandle nativeHandle)
+ {
+ handle = nativeHandle;
+ }
+
+ /// <summary>
+ /// Gets latitude of the coordinates.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public double Latitude
+ {
+ get
+ {
+ return handle.Latitude;
+ }
+ }
+
+ /// <summary>
+ /// Gets longitude of the coordinates.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public double Longitude
+ {
+ get
+ {
+ return handle.Longitude;
+ }
+ }
+
+ /// <summary>
+ /// Returns a string that represents this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <returns>Returns a string which presents this object.</returns>
+ public override string ToString()
+ {
+ return $"[{Latitude}, {Longitude}]";
+ }
+
+ #region IDisposable Support
+ private bool _disposedValue = false;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ handle.Dispose();
+ _disposedValue = true;
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/GeocoordinatesList.cs b/src/Tizen.Maps/Tizen.Maps/GeocoordinatesList.cs
new file mode 100755
index 0000000..50ae012
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/GeocoordinatesList.cs
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// List of <see cref="Geocoordinates"/> objects to be used in <see cref="MapService"/> APIs
+ /// </summary>
+ internal class GeocoordinatesList : IDisposable
+ {
+ internal Interop.CoordinatesListHandle handle;
+
+ internal GeocoordinatesList(IEnumerable<Geocoordinates> coordinateList, bool ownerShip = false)
+ {
+ handle = new Interop.CoordinatesListHandle(ownerShip);
+ foreach (var coordinates in coordinateList)
+ {
+ handle.Add(coordinates.handle);
+ }
+ }
+
+ /// <summary>
+ /// Iterator for coordinates in this list
+ /// </summary>
+ internal IEnumerable<Geocoordinates> Coordinates
+ {
+ get
+ {
+ List<Geocoordinates> list = new List<Geocoordinates>();
+ handle.ForEach(coordinateHandle => list.Add(new Geocoordinates(coordinateHandle)));
+ return list;
+ }
+ }
+
+ #region IDisposable Support
+ private bool _disposedValue = false;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ handle.Dispose();
+ _disposedValue = true;
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/GestureType.cs b/src/Tizen.Maps/Tizen.Maps/GestureType.cs
new file mode 100755
index 0000000..f5ab43d
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/GestureType.cs
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Enumeration of user gestures over map view
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum GestureType
+ {
+ /// <summary>
+ /// Indicates empty gesture.
+ /// </summary>
+ None = Interop.ViewGesture.None,
+ /// <summary>
+ /// Indicates the move map user gesture.
+ /// </summary>
+ Scroll = Interop.ViewGesture.Scroll,
+ /// <summary>
+ /// Indicates the zoom user gesture.
+ /// </summary>
+ Zoom = Interop.ViewGesture.Zoom,
+ /// <summary>
+ /// Indicates the click user gesture
+ /// </summary>
+ Click = Interop.ViewGesture.Click,
+ /// <summary>
+ /// Indicates the double click user gesture
+ /// </summary>
+ DoubleClick = Interop.ViewGesture.DoubleClick,
+ /// <summary>
+ /// Indicates the two-finger click user gesture
+ /// </summary>
+ TwoFingerClick = Interop.ViewGesture.TwoFingerClick,
+ /// <summary>
+ /// Indicates the rotation user gesture.
+ /// </summary>
+ Rotation = Interop.ViewGesture.Rotation,
+ /// <summary>
+ /// Indicates the long press user gesture.
+ /// </summary>
+ LongPress = Interop.ViewGesture.LongPress,
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/IGeocodePreference.cs b/src/Tizen.Maps/Tizen.Maps/IGeocodePreference.cs
new file mode 100755
index 0000000..fb0d8a5
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/IGeocodePreference.cs
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Preferences for geocode searches
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public interface IGeocodePreference
+ {
+ /// <summary>
+ /// Gets or sets a string that presents preferred language.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>Language should be specified as an ISO 3166 alpha-2 two letter country-code
+ /// followed by ISO 639-1 for the two-letter language code.<br/>e.g. "ko-KR", "en-US".</remarks>
+ string Language { get; set; }
+
+ /// <summary>
+ /// Gets or sets the maximum number of results.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>Setting negative value will not have any effect on MaxResults value.</remarks>
+ int MaxResults { get; set; }
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/IPlaceSearchPreference.cs b/src/Tizen.Maps/Tizen.Maps/IPlaceSearchPreference.cs
new file mode 100755
index 0000000..e32b44d
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/IPlaceSearchPreference.cs
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System.Collections.Generic;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Preferences for place searches
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public interface IPlaceSearchPreference
+ {
+ /// <summary>
+ /// Gets or sets distance unit.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ DistanceUnit Unit { get; set; }
+
+ /// <summary>
+ /// Gets or sets preferred language.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>Language should be specified as an ISO 3166 alpha-2 two letter country-code
+ /// followed by ISO 639-1 for the two-letter language code.<br/>e.g. "ko-KR", "en-US".</remarks>
+ string Language { get; set; }
+
+ /// <summary>
+ /// Gets or sets the maximum number of results.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ int MaxResults { get; set; }
+
+ /// <summary>
+ /// Gets or sets a string that represents code of preferred country.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ string CountryCode { get; set; }
+
+ /// <summary>
+ /// Gets or sets search properties as key value pair.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ IReadOnlyDictionary<string, string> Properties { get; set; }
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/IRouteSearchPreference.cs b/src/Tizen.Maps/Tizen.Maps/IRouteSearchPreference.cs
new file mode 100755
index 0000000..e7eedbc
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/IRouteSearchPreference.cs
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Preferences for route searches
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public interface IRouteSearchPreference
+ {
+ /// <summary>
+ /// Gets or sets distance unit.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ DistanceUnit Unit { get; set; }
+
+ /// <summary>
+ /// Gets or sets route optimization.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ RouteOptimization Optimization { get; set; }
+
+ /// <summary>
+ /// Gets or sets route transport mode.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ TransportMode Mode { get; set; }
+
+ /// <summary>
+ /// Gets or sets route feature weight.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ RouteFeatureWeight RouteFeatureWeight { get; set; }
+
+ /// <summary>
+ /// Gets or sets route feature.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ RouteFeature RouteFeature { get; set; }
+
+ /// <summary>
+ /// Gets or sets if searching for alternative routes is enabled.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ bool SearchAlternativeRoutes { get; set; }
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/Log.cs b/src/Tizen.Maps/Tizen.Maps/Log.cs
new file mode 100755
index 0000000..8340d2e
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/Log.cs
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.CompilerServices;
+
+namespace Tizen.Maps
+{
+ internal static class Log
+ {
+ private static String tag = "Tizen.Maps";
+
+ public static void Debug(string message, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ Tizen.Log.Debug(tag, message, file, func, line);
+ }
+
+ public static void Error(string message, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ Tizen.Log.Error(tag, message, file, func, line);
+ }
+
+ public static void Fatal(string message, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ Tizen.Log.Fatal(tag, message, file, func, line);
+ }
+
+ public static void Info(string message, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ Tizen.Log.Info(tag, message, file, func, line);
+ }
+
+ public static void Verbose(string message, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ Tizen.Log.Verbose(tag, message, file, func, line);
+ }
+
+ public static void Warn(string message, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ Tizen.Log.Warn(tag, message, file, func, line);
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/MapGestureEventArgs.cs b/src/Tizen.Maps/Tizen.Maps/MapGestureEventArgs.cs
new file mode 100755
index 0000000..111ce73
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/MapGestureEventArgs.cs
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using ElmSharp;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Event arguments for gesture type map events
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class MapGestureEventArgs : EventArgs
+ {
+ internal MapGestureEventArgs(IntPtr nativeHandle)
+ {
+ using (var handle = new Interop.GestureEventDataHandle(nativeHandle))
+ {
+ GestureType = (GestureType)handle.GestureType;
+ Position = handle.Position;
+ TouchCount = handle.FingerCount;
+ ZoomFactor = handle.ZoomFactor;
+ RotationAngle = handle.RotationAngle;
+ Geocoordinates = new Geocoordinates(handle.Coordinates);
+ }
+ }
+
+ /// <summary>
+ /// Gets type of gesture event.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public GestureType GestureType { get; }
+
+ /// <summary>
+ /// Gets screen coordinates in the event.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public Point Position { get; }
+
+ /// <summary>
+ /// Gets the number of fingers detected in the event.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public int TouchCount { get; }
+
+ /// <summary>
+ /// Gets zoom factor for zoom gesture event.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public double ZoomFactor { get; }
+
+ /// <summary>
+ /// Gets angle of rotation for rotate gesture event.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public double RotationAngle { get; }
+
+ /// <summary>
+ /// Gets geographical coordinates for the event.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public Geocoordinates Geocoordinates { get; }
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/MapObject.cs b/src/Tizen.Maps/Tizen.Maps/MapObject.cs
new file mode 100755
index 0000000..936552a
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/MapObject.cs
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Map object
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public abstract class MapObject
+ {
+ internal MapObject() { }
+
+ /// <summary>
+ /// Gets or sets visibility of the map object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public abstract bool IsVisible { get; set; }
+
+ internal abstract void HandleClickedEvent();
+
+ internal abstract void InvalidateMapObject();
+
+ internal abstract Interop.ViewObjectHandle GetHandle();
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/MapService.cs b/src/Tizen.Maps/Tizen.Maps/MapService.cs
new file mode 100755
index 0000000..3d737da
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/MapService.cs
@@ -0,0 +1,373 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Map service class for service request
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public partial class MapService : IDisposable
+ {
+ internal Interop.ServiceHandle handle;
+
+ private PlaceFilter _filter;
+ private SearchPreference _searchPreference;
+
+ private static List<string> s_providers;
+ private string _serviceProvider;
+
+
+ /// <summary>
+ /// Creates a new Maps Service object for given service provider.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="serviceProvider">A string which representing name of map service provider</param>
+ /// <param name="serviceProviderKey">A string which representing certificate key to use the map service provider</param>
+ /// <privilege>http://tizen.org/privilege/mapservice</privilege>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when parameters are invalid.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when native operation failed to allocate memory, connect to service.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when application does not have some privilege to access this method.</exception>
+ public MapService(string serviceProvider, string serviceProviderKey)
+ {
+ _serviceProvider = serviceProvider;
+ handle = new Interop.ServiceHandle(serviceProvider);
+ ProviderKey = serviceProviderKey;
+ PlaceSearchFilter = new PlaceFilter();
+ Preferences = new SearchPreference();
+ }
+
+ /// <summary>
+ /// Gets list of available map service providers.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The list of map service providers.</value>
+ /// <privilege>http://tizen.org/privilege/mapservice</privilege>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when application does not have privileges to access this property.</exception>
+ public static IEnumerable<string> Providers
+ {
+ get
+ {
+ if (s_providers != null) return s_providers;
+
+ s_providers = new List<string>();
+ Interop.ServiceHandle.ForeachProvider(provider => s_providers.Add(provider));
+ return s_providers;
+ }
+ }
+
+ /// <summary>
+ /// Gets name of map service provider.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Provider { get { return _serviceProvider; } }
+
+ /// <summary>
+ /// Gets and sets a string representing keys for map service provider
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>Typically, the provider key is issued by each maps provider, after signing up for a plan in the web site.
+ /// Depending on the plan and its provider which you have signed, you might pay for the network traffic.</remarks>
+ public string ProviderKey
+ {
+ get
+ {
+ return handle.ProviderKey;
+ }
+ set
+ {
+ handle.ProviderKey = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets and sets a filter used for place search result.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public PlaceFilter PlaceSearchFilter
+ {
+ get
+ {
+ return _filter;
+ }
+ set
+ {
+ if (value != null)
+ {
+ _filter = value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets search preferences used for <see cref="GeocodeRequest"/> or <see cref="ReverseGeocodeRequest"/>.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public IGeocodePreference GeocodePreferences
+ {
+ get
+ {
+ return Preferences as IGeocodePreference;
+ }
+ }
+
+ /// <summary>
+ /// Gets search preferences used for <see cref="PlaceSearchRequest"/>.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public IPlaceSearchPreference PlaceSearchPreferences
+ {
+ get
+ {
+ return Preferences as IPlaceSearchPreference;
+ }
+ }
+
+ /// <summary>
+ /// Gets search preferences used for <see cref="RouteSearchRequest"/>.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public IRouteSearchPreference RouteSearchPreferences
+ {
+ get
+ {
+ return Preferences as IRouteSearchPreference;
+ }
+ }
+
+ /// <summary>
+ /// Gets and sets search preferences.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public SearchPreference Preferences
+ {
+ get
+ {
+ if (_searchPreference == null)
+ {
+ _searchPreference = new SearchPreference(handle.Preferences);
+ }
+ return _searchPreference;
+ }
+ set
+ {
+ if (value != null)
+ {
+ handle.Preferences = value.handle;
+ _searchPreference = value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the user's consent to use maps data.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="provider">A string which representing the name of maps provider</param>
+ /// <returns>Returns true if user agreed that the application can use maps data, otherwise false.</returns>
+ /// <privilege>http://tizen.org/privilege/mapservice</privilege>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when application does not have some privilege to access this method.</exception>
+ public static async Task<bool> RequestUserConsent(string provider)
+ {
+ TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
+ Interop.ServiceHandle.RequestUserConsentCallback cb = (consented, serviceProvider, userData) =>
+ {
+ tcs.TrySetResult(consented);
+ };
+
+ var err = Interop.ServiceHandle.RequestUserConsent(provider, cb, IntPtr.Zero);
+ if (err.IsFailed())
+ {
+ tcs.TrySetException(err.GetException("Failed to get user consent"));
+ }
+ return await tcs.Task.ConfigureAwait(false);
+ }
+
+ /// <summary>
+ /// Checks if the Maps Service supports given request.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="type">Request type to check</param>
+ /// <returns>Returns true if the Maps Service supports a request, otherwise false.</returns>
+ /// <privilege>http://tizen.org/privilege/mapservice</privilege>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when application does not have some privilege to access this method.</exception>
+ public bool IsSupported(ServiceRequestType type)
+ {
+ bool result;
+ var err = handle.IsServiceSupported((Interop.ServiceType)type, out result);
+ err.WarnIfFailed($"Failed to get if {type} is supported");
+ return (err.IsSuccess()) ? result : false;
+ }
+
+ /// <summary>
+ /// Checks if the Maps Service supports given data feature.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="data">Data feature to check</param>
+ /// <returns>Returns true if the Maps Service supports a data feature, otherwise false.</returns>
+ /// <privilege>http://tizen.org/privilege/mapservice</privilege>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when application does not have some privilege to access this method.</exception>
+ public bool IsSupported(ServiceData data)
+ {
+ bool result;
+ var err = handle.IsDataSupported((Interop.ServiceData)data, out result);
+ err.WarnIfFailed($"Failed to get if {data} data is supported");
+ return (err.IsSuccess()) ? result : false;
+ }
+
+ /// <summary>
+ /// Creates geocode search request for given free-formed address string.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="address">A string which representing free-formed address</param>
+ /// <returns>GeocodeRequest object created with address string</returns>
+ public GeocodeRequest CreateGeocodeRequest(string address)
+ {
+ return new GeocodeRequest(this, address);
+ }
+
+ /// <summary>
+ /// Creates geocode search request for given free-formed address string, within the specified boundary.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="address">A string which representing free-formed address</param>
+ /// <param name="boundary">An instance of Area object which representing interested area</param>
+ /// <seealso cref="Area"/>
+ /// <returns>GeocodeRequest object created with address string and specified boundary</returns>
+ public GeocodeRequest CreateGeocodeRequest(string address, Area boundary)
+ {
+ return new GeocodeRequest(this, address, boundary);
+ }
+
+ /// <summary>
+ /// Creates geocode search request for given structured address.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="address">A string which representing address of interest</param>
+ /// <returns>Returns GeocodeRequest object created with structured address</returns>
+ public GeocodeRequest CreateGeocodeRequest(PlaceAddress address)
+ {
+ return new GeocodeRequest(this, address);
+ }
+
+ /// <summary>
+ /// Creates a reverse geocode search request for given latitude and longitude.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="latitude">Latitude of interested place</param>
+ /// <param name="longitude">Longitude of interested place</param>
+ /// <returns>Returns ReverseGeocodeRequest object created with location coordinates</returns>
+ public ReverseGeocodeRequest CreateReverseGeocodeRequest(double latitude, double longitude)
+ {
+ return new ReverseGeocodeRequest(this, latitude, longitude);
+ }
+
+ /// <summary>
+ /// Creates a reverse geocode search request for given position coordinates list.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="coordinates">Coordinates list with [2 ~ 100] coordinates</param>
+ /// <returns>Returns MultiReverseGeocodeRequest object created with list of location coordinates</returns>
+ public MultiReverseGeocodeRequest CreateMultiReverseGeocodeRequest(IEnumerable<Geocoordinates> coordinates)
+ {
+ return new MultiReverseGeocodeRequest(this, coordinates);
+ }
+
+ /// <summary>
+ /// Creates a route search request for origin and destination points.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="from">Starting point</param>
+ /// <param name="to">Destination</param>
+ /// <returns>Returns RouteSearchRequest object created with origin and destination coordinates</returns>
+ public RouteSearchRequest CreateRouteSearchRequest(Geocoordinates from, Geocoordinates to)
+ {
+ return new RouteSearchRequest(this, from, to);
+ }
+
+ /// <summary>
+ /// Creates a place search request for specified search radius around a given coordinates position.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="coordinates">A geographical coordinates of center</param>
+ /// <param name="distance">A double value which representing radius of area to search places</param>
+ /// <returns>Returns PlaceSearchRequest object created with location coordinates and search radius</returns>
+ public PlaceSearchRequest CreatePlaceSearchRequest(Geocoordinates coordinates, int distance)
+ {
+ return new PlaceSearchRequest(this, coordinates, distance);
+ }
+
+ /// <summary>
+ /// Creates a place search request for places within specified boundary.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="boundary">An instance of Area object which representing area to search interested places</param>
+ /// <returns>Returns PlaceSearchRequest object created with specified boundary</returns>
+ public PlaceSearchRequest CreatePlaceSearchRequest(Area boundary)
+ {
+ return new PlaceSearchRequest(this, boundary);
+ }
+
+ /// <summary>
+ /// Creates a place search request for free-formed address within boundary.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="address">A string which representing free-formed address</param>
+ /// <param name="boundary">An instance of Area object which representing area to search interested places</param>
+ /// <returns>Returns PlaceSearchRequest object created with address string and specified boundary</returns>
+ public PlaceSearchRequest CreatePlaceSearchRequest(string address, Area boundary)
+ {
+ return new PlaceSearchRequest(this, address, boundary);
+ }
+
+ #region IDisposable Support
+ private bool _disposedValue = false;
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ if (disposing)
+ {
+ _filter.Dispose();
+ _searchPreference.Dispose();
+ }
+ handle.Dispose();
+ _disposedValue = true;
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/MapServiceRequest.cs b/src/Tizen.Maps/Tizen.Maps/MapServiceRequest.cs
new file mode 100755
index 0000000..ce216b4
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/MapServiceRequest.cs
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Base class for map service request
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <typeparam name="T"></typeparam>
+ public abstract class MapServiceRequest<T> : IDisposable
+ {
+ protected TaskCompletionSource<IEnumerable<T>> _requestTask;
+ protected string errMessage;
+ protected int? _requestID;
+ protected ServiceRequestType _type;
+
+ internal Action startExecutionAction;
+ internal Interop.ErrorCode errorCode;
+
+ internal MapService _service;
+
+ /// <summary>
+ /// Creates a map service request.
+ /// </summary>
+ /// <param name="service">map service object</param>
+ /// <param name="type">Request type</param>
+ internal MapServiceRequest(MapService service, ServiceRequestType type)
+ {
+ _service = service;
+ _type = type;
+ }
+
+ /// <summary>
+ /// Sends a request to map service provider.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <returns>Response from map service provider</returns>
+ /// <privilege>http://tizen.org/privilege/mapservice</privilege>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when application does not have some privilege to access this method.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when the result is invalid.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when arguments are invalid</exception>
+ public async Task<IEnumerable<T>> GetResponseAsync()
+ {
+ IEnumerable<T> task = null;
+ if (_requestTask == null || _requestTask.Task.IsCanceled)
+ {
+ _requestTask = new TaskCompletionSource<IEnumerable<T>>();
+ startExecutionAction();
+ task = await _requestTask.Task;
+ }
+ errorCode.WarnIfFailed(errMessage);
+ return task;
+ }
+
+ internal void Cancel()
+ {
+ if (_requestTask?.Task.IsCompleted == false)
+ {
+ _requestTask?.SetCanceled();
+ if (_requestID != null)
+ {
+ var err = Interop.CancelRequest(_service.handle, (int)_requestID);
+ err.ThrowIfFailed($"Unable to cancel service request, Type: {_type}, ID: {_requestID}");
+ }
+
+ errorCode = Interop.ErrorCode.Canceled;
+ }
+ }
+
+ #region IDisposable Support
+ private bool _disposedValue = false;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ if (disposing)
+ {
+ Cancel();
+ _service.Dispose();
+ }
+ _disposedValue = true;
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/MapTypes.cs b/src/Tizen.Maps/Tizen.Maps/MapTypes.cs
new file mode 100755
index 0000000..e10448f
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/MapTypes.cs
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Map View Type (theme)
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum MapTypes
+ {
+ /// <summary>
+ /// Indicates normal street theme.
+ /// </summary>
+ Normal = Interop.ViewType.Normal,
+ /// <summary>
+ /// Indicates satellite theme.
+ /// </summary>
+ Satellite = Interop.ViewType.Satellite,
+ /// <summary>
+ /// Indicates terrain theme.
+ /// </summary>
+ Terrain = Interop.ViewType.Terrain,
+ /// <summary>
+ /// Indicates hybrid theme, has both satellite and normal theme.
+ /// </summary>
+ Hybrid = Interop.ViewType.Hybrid,
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/MapView.cs b/src/Tizen.Maps/Tizen.Maps/MapView.cs
new file mode 100755
index 0000000..318874d
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/MapView.cs
@@ -0,0 +1,780 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using ElmSharp;
+using Layout = ElmSharp.Layout;
+using EvasObject = ElmSharp.EvasObject;
+using System.Collections.Generic;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Map View class to show a map on the screen.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class MapView : Layout, IDisposable
+ {
+ internal Interop.ViewHandle handle;
+ private MapService _service;
+
+ private Dictionary<IntPtr, MapObject> _handleToObjectTable = new Dictionary<IntPtr, MapObject>();
+
+ private Interop.ViewOnEventCallback _gestureEventCallback;
+ private Interop.ViewOnEventCallback _objectEventCallback;
+ private Interop.ViewOnEventCallback _viewReadyEventCallback;
+
+ private event EventHandler<MapGestureEventArgs> _scrolledEventHandler;
+ private event EventHandler<MapGestureEventArgs> _twoFingerZoomedEventHandler;
+ private event EventHandler<MapGestureEventArgs> _clickedEventHandler;
+ private event EventHandler<MapGestureEventArgs> _doubleClickedEventHandler;
+ private event EventHandler<MapGestureEventArgs> _twoFingerClickedEventHandler;
+ private event EventHandler<MapGestureEventArgs> _twoFingerRotatedEventHandler;
+ private event EventHandler<MapGestureEventArgs> _longPressedEventHandler;
+ private event EventHandler _viewReadyEventHandler;
+
+ /// <summary>
+ /// Creates the view and link it to the instance of map service.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="parent">An instance of <see cref="EvasObject"/> object which map view will be drawn</param>
+ /// <param name="service">An instance of <see cref="MapService"/> object</param>
+ /// <privilege>http://tizen.org/privilege/mapservice</privilege>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when application does not have some privilege to access this method.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when parameters are invalid</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when native operation failed to allocate memory, connect to service</exception>
+ public MapView(EvasObject parent, MapService service) : base(parent)
+ {
+ handle = new Interop.ViewHandle(service.handle, this);
+ Log.Info(string.Format("MapView is created"));
+
+ _service = service;
+ this.Resize(1, 1);
+
+ // We need to keep Gesture Tap event enabled for object event to work
+ handle.SetGestureEnabled(Interop.ViewGesture.Click, true);
+ SetObjectEventCallback();
+ }
+
+ /// <summary>
+ /// Adds or removes event handlers to deliver scrolled gesture event.
+ /// </summary>
+ /// <value>Event handlers to get scrolled gesture event</value>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ public event EventHandler<MapGestureEventArgs> Scrolled
+ {
+ add
+ {
+ SetGestureEventCallback();
+ handle.SetGestureEnabled(Interop.ViewGesture.Scroll, true);
+ _scrolledEventHandler += value;
+ Log.Info(string.Format("Scrolled event handler is added"));
+ }
+ remove
+ {
+ _scrolledEventHandler -= value;
+ Log.Info(string.Format("Scrolled event handler is removed"));
+ if (_scrolledEventHandler == null)
+ {
+ handle.SetGestureEnabled(Interop.ViewGesture.Scroll, false);
+ UnsetGestureEventCallback();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Adds or removes event handlers to deliver zoomed gesture event.
+ /// </summary>
+ /// <value>Event handlers to get zoomed gesture event</value>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ public event EventHandler<MapGestureEventArgs> TwoFingerZoomed
+ {
+ add
+ {
+ SetGestureEventCallback();
+ handle.SetGestureEnabled(Interop.ViewGesture.Zoom, true);
+ _twoFingerZoomedEventHandler += value;
+ Log.Info(string.Format("TwoFingerZoomed event handler is added"));
+ }
+ remove
+ {
+ _twoFingerZoomedEventHandler -= value;
+ Log.Info(string.Format("TwoFingerZoomed event handler is removed"));
+ if (_twoFingerZoomedEventHandler == null)
+ {
+ handle.SetGestureEnabled(Interop.ViewGesture.Zoom, false);
+ UnsetGestureEventCallback();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Adds or removes event handlers to deliver clicked gesture event.
+ /// </summary>
+ /// <value>Event handlers to get clicked gesture event</value>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ public event EventHandler<MapGestureEventArgs> Clicked
+ {
+ add
+ {
+ SetGestureEventCallback();
+ //handle.SetGestureEnabled(Interop.ViewGesture.Click, true);
+ _clickedEventHandler += value;
+ Log.Info(string.Format("Clicked event handler is added"));
+ }
+ remove
+ {
+ _clickedEventHandler -= value;
+ Log.Info(string.Format("Clicked event handler is removed"));
+ if (_clickedEventHandler == null)
+ {
+ //handle.SetGestureEnabled(Interop.ViewGesture.Click, false);
+ UnsetGestureEventCallback();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Adds or removes event handlers to deliver double-clicked gesture event.
+ /// </summary>
+ /// <value>Event handlers to get double-clicked gesture event</value>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ public event EventHandler<MapGestureEventArgs> DoubleClicked
+ {
+ add
+ {
+ SetGestureEventCallback();
+ handle.SetGestureEnabled(Interop.ViewGesture.DoubleClick, true);
+ _doubleClickedEventHandler += value;
+ Log.Info(string.Format("DoubleClicked event handler is removed"));
+ }
+ remove
+ {
+ _doubleClickedEventHandler -= value;
+ Log.Info(string.Format("DoubleClicked event handler is removed"));
+ if (_doubleClickedEventHandler == null)
+ {
+ handle.SetGestureEnabled(Interop.ViewGesture.DoubleClick, false);
+ UnsetGestureEventCallback();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Adds or removes event handlers to deliver clicked gesture event with two-fingers.
+ /// </summary>
+ /// <value>Event handlers to get clicked gesture event</value>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ public event EventHandler<MapGestureEventArgs> TwoFingerClicked
+ {
+ add
+ {
+ SetGestureEventCallback();
+ handle.SetGestureEnabled(Interop.ViewGesture.TwoFingerClick, true);
+ _twoFingerClickedEventHandler += value;
+ Log.Info(string.Format("TwoFingerClicked event handler is added"));
+ }
+ remove
+ {
+ _twoFingerClickedEventHandler -= value;
+ Log.Info(string.Format("TwoFingerClicked event handler is removed"));
+ if (_twoFingerClickedEventHandler == null)
+ {
+ handle.SetGestureEnabled(Interop.ViewGesture.TwoFingerClick, false);
+ UnsetGestureEventCallback();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Adds or removes event handlers to deliver rotated gesture event.
+ /// </summary>
+ /// <value>Event handlers to get rotated gesture event</value>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ public event EventHandler<MapGestureEventArgs> TwoFingerRotated
+ {
+ add
+ {
+ SetGestureEventCallback();
+ handle.SetGestureEnabled(Interop.ViewGesture.Rotation, true);
+ _twoFingerRotatedEventHandler += value;
+ Log.Info(string.Format("Rotated event handler is added"));
+ }
+ remove
+ {
+ _twoFingerRotatedEventHandler -= value;
+ Log.Info(string.Format("Rotated event handler is removed"));
+ if (_twoFingerRotatedEventHandler == null)
+ {
+ handle.SetGestureEnabled(Interop.ViewGesture.Rotation, false);
+ UnsetGestureEventCallback();
+ }
+ }
+ }
+
+
+ /// <summary>
+ /// Adds or removes event handlers to deliver long-pressed gesture event.
+ /// </summary>
+ /// <value>Event handlers to get long-pressed gesture event</value>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ public event EventHandler<MapGestureEventArgs> LongPressed
+ {
+ add
+ {
+ SetGestureEventCallback();
+ handle.SetGestureEnabled(Interop.ViewGesture.LongPress, true);
+ _longPressedEventHandler += value;
+ Log.Info(string.Format("LongPressed event handler is added"));
+ }
+ remove
+ {
+ _longPressedEventHandler -= value;
+ Log.Info(string.Format("LongPressed event handler is removed"));
+ if (_longPressedEventHandler == null)
+ {
+ handle.SetGestureEnabled(Interop.ViewGesture.LongPress, false);
+ UnsetGestureEventCallback();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Adds or removes event handlers to deliver a event representing the view is ready to be used.
+ /// </summary>
+ /// <value>Event handlers to get view ready event</value>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ public event EventHandler ViewReady
+ {
+ add
+ {
+ SetViewReadyEventCallback();
+ _viewReadyEventHandler += value;
+ Log.Info(string.Format("ViewReady event handler is added"));
+ }
+ remove
+ {
+ _viewReadyEventHandler -= value;
+ Log.Info(string.Format("ViewReady event handler is removed"));
+ UnsetGestureEventCallback();
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets current zoom level.
+ /// </summary>
+ /// <value>It is an integer value that representing current zoom level.</value>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>http://tizen.org/privilege/mapservice</privilege>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when application does not have some privilege to access this method.</exception>
+ public int ZoomLevel
+ {
+ get
+ {
+ return handle.ZoomLevel;
+ }
+ set
+ {
+ Log.Info(string.Format("ZoomLevel is changed from {0} to {1}", handle.ZoomLevel, value));
+ handle.ZoomLevel = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets minimum zoom level.
+ /// </summary>
+ /// <value>It is an integer value that limits minimal zoom level within range of current map plug-in supported.</value>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>http://tizen.org/privilege/mapservice</privilege>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when application does not have some privilege to access this method.</exception>
+ public int MinimumZoomLevel
+ {
+ get
+ {
+ return handle.MinimumZoomLevel;
+ }
+ set
+ {
+ Log.Info(string.Format("MinimumZoomLevel is changed from {0} to {1}", handle.MinimumZoomLevel, value));
+ handle.MinimumZoomLevel = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets maximum zoom level.
+ /// </summary>
+ /// <value>It is an integer value that limits maximum zoom level within range of current map plug-in supported.</value>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>http://tizen.org/privilege/mapservice</privilege>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when application does not have some privilege to access this method.</exception>
+ public int MaximumZoomLevel
+ {
+ get
+ {
+ return handle.MaximumZoomLevel;
+ }
+ set
+ {
+ Log.Info(string.Format("MaximumZoomLevel is changed from {0} to {1}", handle.MaximumZoomLevel, value));
+ handle.MaximumZoomLevel = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets orientation on the map view.
+ /// </summary>
+ /// <value>It is an integer value from 0 to 360 that indicates orientation of the map view</value>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>http://tizen.org/privilege/mapservice</privilege>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when application does not have some privilege to access this method.</exception>
+ public double Orientation
+ {
+ get
+ {
+ return handle.Orientation;
+ }
+ set
+ {
+ Log.Info(string.Format("Orientation is changed from {0} to {1}", handle.Orientation, value));
+ handle.Orientation = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets theme type of the map view.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>http://tizen.org/privilege/mapservice</privilege>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when application does not have some privilege to access this method.</exception>
+ public MapTypes MapType
+ {
+ get
+ {
+ return (MapTypes)handle.MapType;
+ }
+ set
+ {
+ Log.Info(string.Format("MapType is changed from {0} to {1}", handle.MapType, value));
+ handle.MapType = (Interop.ViewType)value;
+ }
+ }
+
+ /// <summary>
+ /// Indicates whether the map should show the 3D buildings layer.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>http://tizen.org/privilege/mapservice</privilege>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when application does not have some privilege to access this method.</exception>
+ public bool BuildingsEnabled
+ {
+ get
+ {
+ return handle.BuildingsEnabled;
+ }
+ set
+ {
+ Log.Info(string.Format("Showing the 3D buildings is {0}", (value ? "enabled" : "disabled")));
+ handle.BuildingsEnabled = value;
+ }
+ }
+
+ /// <summary>
+ /// Indicates whether the map should show the traffic layer.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>http://tizen.org/privilege/mapservice</privilege>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when application does not have some privilege to access this method.</exception>
+ public bool TrafficEnabled
+ {
+ get
+ {
+ return handle.TrafficEnabled;
+ }
+ set
+ {
+ Log.Info(string.Format("Showing the traffic is {0}", (value ? "enabled" : "disabled")));
+ handle.TrafficEnabled = value;
+ }
+ }
+
+ /// <summary>
+ /// Indicates whether the map should show the public transit layer.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>http://tizen.org/privilege/mapservice</privilege>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when application does not have some privilege to access this method.</exception>
+ public bool PublicTransitEnabled
+ {
+ get
+ {
+ return handle.PublicTransitEnabled;
+ }
+ set
+ {
+ Log.Info(string.Format("Showing the public transit is {0}", (value ? "enabled" : "disabled")));
+ handle.PublicTransitEnabled = value;
+ }
+ }
+
+ /// <summary>
+ /// Indicates whether the scale-bar is enabled or not.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>http://tizen.org/privilege/mapservice</privilege>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when application does not have some privilege to access this method.</exception>
+ public bool ScaleBarEnabled
+ {
+ get
+ {
+ return handle.ScaleBarEnabled;
+ }
+ set
+ {
+ Log.Info(string.Format("Showing the scale-bar is {0}", (value ? "enabled" : "disabled")));
+ handle.ScaleBarEnabled = value;
+ }
+ }
+
+ /// <summary>
+ /// Sets language of map view.
+ /// </summary>
+ /// <value>The display language in the map.
+ /// A language is specified as an ISO 3166 alpha-2 two letter country-code
+ /// followed by ISO 639-1 for the two-letter language code.
+ /// Each language tag is composed of one or more "subtags" separated by hyphens (-).
+ /// Each subtag is composed of basic Latin letters or digits only.
+ /// For example, "ko-KR" for Korean, "en-US" for American English.</value>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>http://tizen.org/privilege/mapservice</privilege>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when application does not have some privilege to access this method.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when the value is invalid.</exception>
+ public string Language
+ {
+ get
+ {
+ return handle.Language;
+ }
+ set
+ {
+ Log.Info(string.Format("Language is changed from {0} to {1}", handle.Language, value));
+ handle.Language = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets geographical coordinates for map view's center.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>http://tizen.org/privilege/mapservice</privilege>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when application does not have some privilege to access this method.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when the value is invalid.</exception>
+ public Geocoordinates Center
+ {
+ get
+ {
+ return new Geocoordinates(handle.Center);
+ }
+ set
+ {
+ Log.Info(string.Format("Center is changed from {0} to {1}", handle.Center.ToString(), value.ToString()));
+ handle.Center = value.handle;
+ }
+ }
+
+ /// <summary>
+ /// Gets a list of map object added to map view.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public IEnumerable<MapObject> Children
+ {
+ get
+ {
+ return _handleToObjectTable.Values;
+ }
+ }
+
+ /// <summary>
+ /// Changes geographical coordinates to screen coordinates.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="coordinates">Geographical coordinates</param>
+ /// <returns>Returns an instance of screen coordinates on the current screen</returns>
+ /// <privilege>http://tizen.org/privilege/mapservice</privilege>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when application does not have some privilege to access this method.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when the value is invalid.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when native operation failed to allocate memory, connect to service.</exception>
+ public Point GeolocationToScreen(Geocoordinates coordinates)
+ {
+ return handle.GeolocationToScreen(coordinates.handle);
+ }
+
+ /// <summary>
+ /// Changes screen coordinates to geographical coordinates.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="screenCoordinates">Screen coordinates</param>
+ /// <returns>Returns an instance of geographical coordinates object.</returns>
+ /// <privilege>http://tizen.org/privilege/mapservice</privilege>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when application does not have some privilege to access this method.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when the value is invalid.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when native operation failed to allocate memory, connect to service.</exception>
+ public Geocoordinates ScreenToGeolocation(Point screenCoordinates)
+ {
+ return new Geocoordinates(handle.ScreenToGeolocation(screenCoordinates));
+ }
+
+ /// <summary>
+ /// Adds a map object to map view.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="child">An instance of map object to be added</param>
+ /// <privilege>http://tizen.org/privilege/mapservice</privilege>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when application does not have some privilege to access this method.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when the value is invalid.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when native operation failed to allocate memory, connect to service.</exception>
+ public void Add(MapObject child)
+ {
+ Log.Info(string.Format("Add a object"));
+ var objectHandle = child.GetHandle();
+ if (!_handleToObjectTable.ContainsKey(objectHandle))
+ {
+ _handleToObjectTable[objectHandle] = child;
+ handle.AddObject(objectHandle);
+
+ // MapView take ownership of added map objects
+ objectHandle.HasOwnership = false;
+ }
+ }
+
+ /// <summary>
+ /// Removes a map object from map view.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="child">An instance of map object to be removed</param>
+ /// <remarks>Once removed, the child object will be become invalid</remarks>
+ /// <privilege>http://tizen.org/privilege/mapservice</privilege>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when application does not have some privilege to access this method.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when the value is invalid.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when native operation failed to allocate memory, connect to service.</exception>
+ public void Remove(MapObject child)
+ {
+ Log.Info(string.Format("Remove a object"));
+ var objectHandle = child.GetHandle();
+ if (_handleToObjectTable.Remove(objectHandle))
+ {
+ handle.RemoveObject(child.GetHandle());
+
+ // The object handle will be released automatically by the View, once RemoveObject call is successful
+ child.InvalidateMapObject();
+ }
+ }
+
+ /// <summary>
+ /// Removes all map objects from map view.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>http://tizen.org/privilege/mapservice</privilege>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when application does not have some privilege to access this method.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when native operation failed to allocate memory, connect to service.</exception>
+ public void RemoveAll()
+ {
+ Log.Info(string.Format("Remove all of objects"));
+ foreach (var child in _handleToObjectTable.Values)
+ {
+ child.InvalidateMapObject();
+ }
+ _handleToObjectTable.Clear();
+ handle.RemoveAllObjects();
+ }
+
+ /// <summary>
+ /// Captures a snapshot of map view
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="type">Type of file format</param>
+ /// <param name="quality">A integer value which representing quality for encoding, from 1 to 100</param>
+ /// <param name="path">A string which representing The file path for snapshot</param>
+ /// <privilege>http://tizen.org/privilege/mapservice</privilege>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when application does not have some privilege to access this method.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when the value is invalid.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when native operation failed to allocate memory, connect to service.</exception>
+ public void CaptureSnapshot(SnapshotType type, int quality, string path)
+ {
+ var err = Interop.ViewSnapshot.ViewCaptureSnapshot(handle, (Interop.ViewSnapshotFormatType)type, quality, path);
+ err.ThrowIfFailed("Failed to create snapshot for the view");
+ }
+
+ private void SetGestureEventCallback()
+ {
+ if (_gestureEventCallback == null)
+ {
+ _gestureEventCallback = (type, eventData, userData) =>
+ {
+ if (type != Interop.ViewEventType.Gesture) return;
+ var eventArg = new MapGestureEventArgs(eventData);
+ switch (eventArg.GestureType)
+ {
+ case GestureType.Scroll: _scrolledEventHandler?.Invoke(this, eventArg); break;
+ case GestureType.Zoom: _twoFingerZoomedEventHandler?.Invoke(this, eventArg); break;
+ case GestureType.Click: _clickedEventHandler?.Invoke(this, eventArg); break;
+ case GestureType.DoubleClick: _doubleClickedEventHandler?.Invoke(this, eventArg); break;
+ case GestureType.TwoFingerClick: _twoFingerClickedEventHandler?.Invoke(this, eventArg); break;
+ case GestureType.Rotation: _twoFingerRotatedEventHandler?.Invoke(this, eventArg); break;
+ case GestureType.LongPress: _longPressedEventHandler?.Invoke(this, eventArg); break;
+ }
+ };
+ handle.SetEventCb(Interop.ViewEventType.Gesture, _gestureEventCallback, IntPtr.Zero);
+ Log.Info(string.Format("Gesture event callback is set"));
+ }
+ }
+
+ private void UnsetGestureEventCallback()
+ {
+ if (_scrolledEventHandler != null || _twoFingerZoomedEventHandler != null
+ || _clickedEventHandler != null || _doubleClickedEventHandler != null
+ || _twoFingerClickedEventHandler != null || _twoFingerRotatedEventHandler != null
+ || _longPressedEventHandler != null)
+ {
+ return;
+ }
+
+ handle.UnsetEventCb(Interop.ViewEventType.Gesture);
+ _gestureEventCallback = null;
+ Log.Info(string.Format("Gesture event callback is unset"));
+ }
+
+ private void SetObjectEventCallback()
+ {
+ if (_objectEventCallback == null)
+ {
+ _objectEventCallback = (type, eventData, userData) =>
+ {
+ if (type != Interop.ViewEventType.Object) return;
+ var eventArg = new Interop.ObjectEventDataHandle(eventData);
+ switch (eventArg.GestureType)
+ {
+ case Interop.ViewGesture.Click:
+ {
+ var mapObject = _handleToObjectTable[eventArg.ViewObject];
+ mapObject?.HandleClickedEvent();
+ break;
+ }
+ }
+ };
+ handle.SetEventCb(Interop.ViewEventType.Object, _objectEventCallback, IntPtr.Zero);
+ Log.Info(string.Format("Object event callback is set"));
+ }
+ }
+
+ private void SetViewReadyEventCallback()
+ {
+ if (_viewReadyEventCallback == null)
+ {
+ _viewReadyEventCallback = (type, eventData, userData) =>
+ {
+ _viewReadyEventHandler?.Invoke(this, EventArgs.Empty);
+ };
+ handle.SetEventCb(Interop.ViewEventType.Ready, _viewReadyEventCallback, IntPtr.Zero);
+ Log.Info(string.Format("ViewReady event callback is set"));
+ }
+ }
+
+ private void UnsetViewReadyEventCallback()
+ {
+ if (_viewReadyEventHandler == null)
+ {
+ handle.UnsetEventCb(Interop.ViewEventType.Ready);
+ _viewReadyEventCallback = null;
+ Log.Info(string.Format("ViewReady event callback is unset"));
+ }
+ }
+
+ #region IDisposable Support
+ private bool _disposedValue = false;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ if (disposing)
+ {
+ _service.Dispose();
+ }
+ handle.Dispose();
+ _disposedValue = true;
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/Marker.cs b/src/Tizen.Maps/Tizen.Maps/Marker.cs
new file mode 100755
index 0000000..1655e65
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/Marker.cs
@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using ElmSharp;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Marker map object
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class Marker : MapObject, IDisposable
+ {
+ internal Interop.MarkerHandle handle;
+
+ internal Marker(Geocoordinates coordinates, string imagePath, Interop.ViewMarkerType type)
+ {
+ var err = Interop.ErrorCode.InvalidParameter;
+ if (coordinates == null || imagePath == null)
+ {
+ err.ThrowIfFailed("given coordinates or imagePath is null");
+ }
+ handle = new Interop.MarkerHandle(coordinates.handle, imagePath, type);
+ }
+
+ /// <summary>
+ /// Gets or sets clicked event handlers.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public event EventHandler Clicked;
+
+ /// <summary>
+ /// Gets or sets marker's visibility.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public override bool IsVisible
+ {
+ get
+ {
+ return handle.IsVisible;
+ }
+ set
+ {
+ handle.IsVisible = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets geographical coordinates for this marker.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public Geocoordinates Coordinates
+ {
+ get
+ {
+ return new Geocoordinates(handle.Coordinates);
+ }
+ set
+ {
+ handle.Coordinates = value.handle;
+
+ // Marker takes ownership of the native handle.
+ value.handle.HasOwnership = false;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a string representing image file path for this marker.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string ImagePath
+ {
+ get
+ {
+ return handle.ImageFile;
+ }
+ set
+ {
+ handle.ImageFile = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets screen size for this marker.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public Size MarkerSize
+ {
+ get
+ {
+ return handle.MarkerSize;
+ }
+ set
+ {
+ handle.MarkerSize = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets z-order for this marker.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The integer value is 0 in default, and must be in range of from -100 to 100.</value>
+ public int ZOrder
+ {
+ get
+ {
+ return handle.ZOrder;
+ }
+ set
+ {
+ handle.ZOrder = value;
+ }
+ }
+
+ /// <summary>
+ /// Changes marker size.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="newSize">New size</param>
+ public void Resize(Size newSize)
+ {
+ MarkerSize = newSize;
+ }
+
+ /// <summary>
+ /// Changes marker coordinates.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="newPosition">New position for marker</param>
+ public void Move(Geocoordinates newPosition)
+ {
+ Coordinates = newPosition;
+ }
+
+ internal override void HandleClickedEvent()
+ {
+ Clicked?.Invoke(this, EventArgs.Empty);
+ }
+
+ internal override void InvalidateMapObject()
+ {
+ handle = null;
+ }
+
+ internal override Interop.ViewObjectHandle GetHandle()
+ {
+ return handle;
+ }
+
+ #region IDisposable Support
+ private bool _disposedValue = false;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ handle.Dispose();
+ _disposedValue = true;
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+
+ #endregion
+ }
+
+ /// <summary>
+ /// Pin type marker map object
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class Pin : Marker
+ {
+ private const string defaultImagePath = "/usr/share/dotnet.tizen/framework/res/maps_marker_pin_48.png";
+
+ /// <summary>
+ /// Creates a Pin type marker.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="coordinates">Marker coordinates</param>
+ /// <exception cref="System.ArgumentException">Thrown when input coordinates are invalid.</exception>
+ public Pin(Geocoordinates coordinates)
+ : base(coordinates, defaultImagePath, Interop.ViewMarkerType.Pin)
+ {
+ }
+
+ /// <summary>
+ /// Creates a Pin type marker.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="coordinates">Marker coordinates</param>
+ /// <param name="imagePath">Image file path for Marker</param>
+ /// <remarks>
+ /// http://tizen.org/privilege/mediastorage is needed if the file path are relevant to media storage.
+ /// http://tizen.org/privilege/externalstorage is needed if the file path are relevant to external storage.
+ /// </remarks>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when application does not have some privilege to access this method.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when input coordinates or imagePath are invalid.</exception>
+ public Pin(Geocoordinates coordinates, string imagePath)
+ : base(coordinates, imagePath, Interop.ViewMarkerType.Pin)
+ {
+ }
+ }
+
+ /// <summary>
+ /// Sticker type marker map object
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class Sticker : Marker
+ {
+ private const string defaultImagePath = "/usr/share/dotnet.tizen/framework/res/maps_marker_sticker_48.png";
+
+ /// <summary>
+ /// Creates a Sticker type marker.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="coordinates">Marker coordinates</param>
+ /// <exception cref="System.ArgumentException">Thrown when input coordinates are invalid.</exception>
+ public Sticker(Geocoordinates coordinates)
+ : base(coordinates, defaultImagePath, Interop.ViewMarkerType.Sticker)
+ {
+ }
+
+ /// <summary>
+ /// Creates a Sticker type marker.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="coordinates">Marker coordinates</param>
+ /// <param name="imagePath">Image file path for Marker</param>
+ /// <remarks>
+ /// http://tizen.org/privilege/mediastorage is needed if input or output path are relevant to media storage.
+ /// http://tizen.org/privilege/externalstorage is needed if input or output path are relevant to external storage.
+ /// </remarks>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when application does not have some privilege to access this method.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when input coordinates or imagePath are invalid.</exception>
+ public Sticker(Geocoordinates coordinates, string imagePath)
+ : base(coordinates, imagePath, Interop.ViewMarkerType.Sticker)
+ {
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/MultiReverseGeocodeRequest.cs b/src/Tizen.Maps/Tizen.Maps/MultiReverseGeocodeRequest.cs
new file mode 100755
index 0000000..2794961
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/MultiReverseGeocodeRequest.cs
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Multiple Reverse geocode Request for Tizen map service
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class MultiReverseGeocodeRequest : MapServiceRequest<PlaceAddress>
+ {
+ private Interop.MultiReverseGeocodeCallback _geocodeCallback;
+ private List<PlaceAddress> _addressesList = new List<PlaceAddress>();
+
+ internal MultiReverseGeocodeRequest(MapService service, IEnumerable<Geocoordinates> coordinates) : base(service, ServiceRequestType.ReverseGeocode)
+ {
+ // The Maps Service invokes this callback once when gets the response from map service provider
+ // The value of total is same with requested coordinates list size. Even though one of address is not provided valid address handle is retrieved.
+ _geocodeCallback = (result, id, total, handle, userData) =>
+ {
+ errorCode = result;
+ if (result.IsSuccess())
+ {
+ var addressListHandle = new Interop.AddressListHandle(handle, needToRelease: true);
+ var addressList = new PlaceAddressList(addressListHandle);
+ _addressesList = addressList.Addresses as List<PlaceAddress>;
+ _requestTask?.TrySetResult(_addressesList);
+ return true;
+ }
+ else
+ {
+ _requestTask?.TrySetException(errorCode.GetException(errMessage));
+ return false;
+ }
+ };
+
+ var coordinateList = new GeocoordinatesList(coordinates);
+ startExecutionAction = new Action(() =>
+ {
+ int requestID;
+ errMessage = "Failed to get address list for given co-ordinate list";
+ errorCode = _service.handle.MultiReverseGeocode(coordinateList.handle, _service.Preferences.handle, _geocodeCallback, IntPtr.Zero, out requestID);
+ if (errorCode.IsFailed() && errorCode != Interop.ErrorCode.Canceled)
+ {
+ _requestTask?.TrySetException(errorCode.GetException(errMessage));
+ }
+ _requestID = requestID;
+ });
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/NamespaceDoc.cs b/src/Tizen.Maps/Tizen.Maps/NamespaceDoc.cs
new file mode 100755
index 0000000..2c9fe11
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/NamespaceDoc.cs
@@ -0,0 +1,132 @@
+/**
+<summary>
+The Tizen.Maps namespace provides classes to get the information of Place, Geocoding, Route by querying,
+or to show them on the map view with interactive gestural interface.
+</summary>
+
+
+
+<remarks>
+
+<h2>Overview</h2>
+<para>
+Maps API provides a developer with a set of functions, helping to create Maps aware applications.<p/>
+
+Maps API comprises of following features:<br/>
+- Geocoding and reverse Geocoding<br/>
+- Discoverying Place information<br/>
+- Calculating Route<br/>
+- View
+</para>
+
+
+<para>
+Maps API allows a Developer to choose one of Map Providers which are being included as plugins.<p/>
+
+<para>
+<h3>Geocoding</h3>
+The Maps Geocoding API allows translating an address to its geographical
+location defined in terms of latitude and longitude; the input can be a
+qualified and structured address or a free-formed search text with full or
+partial address information.<p/>
+
+The example below shows a structured address:<br/>
+ - housenumber=117,<br/>
+ - street=Invaliden street<br/>
+ - city=Berlin,<br/>
+ - postalcode=10115,<br/>
+ - country=Germany,<br/>
+ - state=Berlin
+</para>
+
+
+<para>
+<h3>Reverse Geocoding</h3>
+The Maps Reverse Geocoding API allows to inverse translating a geographical
+location (longitude, latitude) to an address; it can be used to answer the
+question "Where am I?".
+</para>
+
+
+<para>
+<h3>Route</h3>
+The Maps Route API provides ways to calculate a route that defines a path
+between a start and a destination and may, optionally, pass through specific
+intermediate locations.<p/>
+
+Route Preferences:<br/>
+ - Travel Mode (car, pedestrian, public transit, truck),<br/>
+ - Optimization (fastest, shortest),<br/>
+ - Avoid/Prefer Preferences (toll road, motorway, ferry, public transit,
+ tunnel, dirt road, parks, car-pool lane).<br/>
+ - Route Calculations<br/>
+ - Way points and preferences as input values,<br/>
+ - Route geometry and maneuver (instructions for guidance) as result values:
+ Geometry consists of points that visually represent the determined route,
+ Maneuver contains turn-by-turn instruction and position.
+</para>
+
+
+<para>
+<h3>Places</h3>
+The Maps Place API allows you to find place information.<p/>
+
+Place search<br/>
+ - Depending on the location context, the number of relevant places might
+ be large. Therefore this query may not only return places, but also
+ suggestions for additional filter criteria that allow users to interactively
+ refine the classes of places they are interested in.<br/>
+ - Nearby Search: search for places within a specified area.
+ You can refine your search request by supplying keywords, Name of Points
+ of Interests, or Proximity.<br/>
+ - Category Search: search for popular places for the given location context and matching the category filter criteria.
+ You can refine your search request by specifying the categories of place you are searching for.<br/>
+Result item type of searching<br/>
+ - ID, name, location, distance, URI, rating, category.<br/>
+Place information allows to fetch details about a place. The following place content is supported:<br/>
+ - Base Attribute includes name, location, categories, contacts, ID, ratings, icon path,
+ image content, review content, and editorial content.<br/>
+ - Extended Attribute refers to opening hours, payment methods, annual closings, disabled access.
+</para>
+
+
+<para>
+<h3>View</h3>
+The Maps View API provides a developer with a set of functions, bringing
+basic interactive visual user interface in maps applications.<p/>
+
+View widget: Drawing a map image on the map port, the specified rectangular
+area of the maps application GUI.<p/>
+
+Zoom and rotation: Changing zoom and orientation of the view in response
+to user gestures, such as scrolling, tapping, zooming, rotating, etc.<p/>
+
+Conversion of screen coordinates to geographical and vise versa.<p/>
+
+User's gesture support:<br/>
+ - Receive the event of the user gesture.<br/>
+ - Enable or disable the specified gesture.<br/>
+ - Re-assign the action, which should be taken in response to the user's gesture.<p/>
+
+Various Properties:<br/>
+ - Visibility and size on the screen.<br/>
+ - Theme: Day, satellite, or terrain.<br/>
+ - Language: English, Russian, Chinese, Italian, German, Spanish, etc.
+</para>
+</para>
+
+
+
+<h2>Related Features</h2>
+<para>
+To guarantee that the Maps application runs on a device with Maps profile feature,
+declare the following feature requirements in the config file:<br/>
+http://tizen.org/feature/maps<br/>
+http://tizen.org/feature/internet
+</para>
+
+</remarks>
+*/
+
+namespace Tizen.Maps {}
+
diff --git a/src/Tizen.Maps/Tizen.Maps/Overlay.cs b/src/Tizen.Maps/Tizen.Maps/Overlay.cs
new file mode 100755
index 0000000..9a9e7f0
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/Overlay.cs
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using EvasObject = ElmSharp.EvasObject;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Overlay map object
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class Overlay : MapObject, IDisposable
+ {
+ internal Interop.OverlayHandle handle;
+
+ /// <summary>
+ /// Creates a normal overlay map object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="coordinates"></param>
+ /// <param name="objectToContain"></param>
+ /// <exception cref="ArgumentException">Thrown when input coordinates or objectToContain are invalid</exception>
+ public Overlay(Geocoordinates coordinates, EvasObject objectToContain)
+ : this(coordinates, objectToContain, Interop.ViewOverlayType.Normal)
+ {
+ }
+
+ internal Overlay(Geocoordinates coordinates, EvasObject objectToContain, Interop.ViewOverlayType type)
+ {
+ var err = Interop.ErrorCode.InvalidParameter;
+ if (coordinates == null || objectToContain == null)
+ {
+ err.ThrowIfFailed("given coordinates or parent evas object is null");
+ }
+ handle = new Interop.OverlayHandle(coordinates.handle, objectToContain, type);
+ }
+
+ /// <summary>
+ /// Gets or sets visibility of overlay map object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public override bool IsVisible
+ {
+ get { return handle.IsVisible; }
+ set { handle.IsVisible = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets geographical coordinates for overlay map object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public Geocoordinates Coordinates
+ {
+ get
+ {
+ return new Geocoordinates(handle.Coordinates);
+ }
+ set
+ {
+ // Overlay takes ownership of the native handle.
+ handle.Coordinates = value.handle;
+ value.handle.HasOwnership = false;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets minimum zoom level for overlay map object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public int MinimumZoomLevel
+ {
+ get
+ {
+ return handle.MinZoomLevel;
+ }
+ set
+ {
+ handle.MinZoomLevel = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets maximum zoom lever for overlay map object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public int MaximumZoomLevel
+ {
+ get
+ {
+ return handle.MaxZoomLevel;
+ }
+ set
+ {
+ handle.MaxZoomLevel = value;
+ }
+ }
+
+ // Overlay object does not support click events
+ internal override void HandleClickedEvent()
+ {
+ throw new NotSupportedException("Overlay object does not support click events");
+ }
+
+ internal override void InvalidateMapObject()
+ {
+ handle = null;
+ }
+
+ internal override Interop.ViewObjectHandle GetHandle()
+ {
+ return handle;
+ }
+
+ #region IDisposable Support
+ private bool _disposedValue = false;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ handle.Dispose();
+ _disposedValue = true;
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+
+ /// <summary>
+ /// Bubble overlay map object
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class BubbleOverlay : Overlay
+ {
+ /// <summary>
+ /// Creates a Bubble overlay.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="coordinates">The geographical coordinates to be pointed</param>
+ /// <param name="objectToContain">The EvasObject to be shown</param>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown when input coordinates or objectToContain are invalid</exception>
+ public BubbleOverlay(Geocoordinates coordinates, EvasObject objectToContain)
+ : base(coordinates, objectToContain, Interop.ViewOverlayType.Bubble)
+ {
+ }
+ }
+
+ /// <summary>
+ /// Box Overlay map object
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class BoxOverlay : Overlay
+ {
+ /// <summary>
+ /// Creates a Box overlay.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="coordinates">The geographical coordinates to be pointed</param>
+ /// <param name="objectToContain">The EvasObject to be shown</param>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown when input coordinates or objectToContain are invalid</exception>
+ public BoxOverlay(Geocoordinates coordinates, EvasObject objectToContain)
+ : base(coordinates, objectToContain, Interop.ViewOverlayType.Box)
+ {
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/Place.cs b/src/Tizen.Maps/Tizen.Maps/Place.cs
new file mode 100755
index 0000000..70f6bf6
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/Place.cs
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Place information, used in Place Discovery and Search
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class Place : IDisposable
+ {
+ internal Interop.PlaceHandle handle;
+
+ internal Place(Interop.PlaceHandle nativeHandle)
+ {
+ handle = nativeHandle;
+ }
+
+ /// <summary>
+ /// Gets ID string for the place.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Id
+ {
+ get
+ {
+ return handle.Id;
+ }
+ }
+
+ /// <summary>
+ /// Gets name string for the place.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Name
+ {
+ get
+ {
+ return handle.Name;
+ }
+ }
+
+ /// <summary>
+ /// Gets view URI for the place.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Uri
+ {
+ get
+ {
+ return handle.Uri;
+ }
+ }
+
+ /// <summary>
+ /// Gets distance for the place from the center.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public int Distance
+ {
+ get
+ {
+ return handle.Distance;
+ }
+ }
+
+ /// <summary>
+ /// Gets geographical location for the place.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public Geocoordinates Coordinates
+ {
+ get
+ {
+ return new Geocoordinates(handle.Coordinates);
+ }
+ }
+
+ /// <summary>
+ /// Gets address for the place.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public PlaceAddress Address
+ {
+ get
+ {
+ return new PlaceAddress(handle.Address);
+ }
+ }
+
+ /// <summary>
+ /// Gets rating for the place.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public PlaceRating Rating
+ {
+ get
+ {
+ return new PlaceRating(handle.Rating);
+ }
+ }
+
+ /// <summary>
+ /// Gets supplier link for the place.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public PlaceLink Supplier
+ {
+ get
+ {
+ return new PlaceLink(handle.Supplier);
+ }
+ }
+
+ /// <summary>
+ /// Gets related link for the place.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public PlaceLink Related
+ {
+ get
+ {
+ return new PlaceLink(handle.Related);
+ }
+ }
+
+ /// <summary>
+ /// Gets all properties attached to this place.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public IDictionary<string, string> Properties
+ {
+ get
+ {
+ var properties = new Dictionary<string, string>();
+ handle.ForeachProperty((key, value) => properties[key] = value);
+ return properties;
+ }
+ }
+
+ /// <summary>
+ /// Gets all categories attached to this place.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public IEnumerable<PlaceCategory> Categories
+ {
+ get
+ {
+ var categories = new List<PlaceCategory>();
+ handle.ForeachCategory((categoryHandle) => categories.Add(new PlaceCategory(categoryHandle)));
+ return categories;
+ }
+ }
+
+ /// <summary>
+ /// Gets all attributes attached to this place.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public IEnumerable<PlaceAttribute> Attributes
+ {
+ get
+ {
+ var attributes = new List<PlaceAttribute>();
+ handle.ForeachAttribute((attributeHandle) => attributes.Add(new PlaceAttribute(attributeHandle)));
+ return attributes;
+ }
+ }
+
+ /// <summary>
+ /// Gets all contacts attached to this place.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public IEnumerable<PlaceContact> Contacts
+ {
+ get
+ {
+ var contacts = new List<PlaceContact>();
+ handle.ForeachContact((contactHandle) => contacts.Add(new PlaceContact(contactHandle)));
+ return contacts;
+ }
+ }
+
+ /// <summary>
+ /// Gets all editorials attached to this place.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public IEnumerable<PlaceEditorial> Editorials
+ {
+ get
+ {
+ var editorials = new List<PlaceEditorial>();
+ handle.ForeachEditorial((editorialHandle) => editorials.Add(new PlaceEditorial(editorialHandle)));
+ return editorials;
+ }
+ }
+
+ /// <summary>
+ /// Gets all images attached to this place.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public IEnumerable<PlaceImage> Images
+ {
+ get
+ {
+ var images = new List<PlaceImage>();
+ handle.ForeachImage((imageHandle) => images.Add(new PlaceImage(imageHandle)));
+ return images;
+ }
+ }
+
+ /// <summary>
+ /// Gets all reviews attached to this place.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public IEnumerable<PlaceReview> Reviews
+ {
+ get
+ {
+ var reviews = new List<PlaceReview>();
+ handle.ForeachReview((reviewHandle) => reviews.Add(new PlaceReview(reviewHandle)));
+ return reviews;
+ }
+ }
+
+ #region IDisposable Support
+ private bool _disposedValue = false;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ handle.Dispose();
+ _disposedValue = true;
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/PlaceAddress.cs b/src/Tizen.Maps/Tizen.Maps/PlaceAddress.cs
new file mode 100755
index 0000000..657fce9
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/PlaceAddress.cs
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Address information for the map point used in Geocode and Reverse Geocode requests.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class PlaceAddress : IDisposable
+ {
+ internal Interop.AddressHandle handle;
+
+ /// <summary>
+ /// Constructs map address object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="System.InvalidOperationException">Thrown when native operation failed to allocate memory.</exception>
+ public PlaceAddress()
+ {
+ handle = new Interop.AddressHandle();
+ }
+
+ internal PlaceAddress(Interop.AddressHandle nativeHandle)
+ {
+ handle = nativeHandle;
+ }
+
+ /// <summary>
+ /// Gets a building number for this address.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Building
+ {
+ get
+ {
+ return handle.Building;
+ }
+ set
+ {
+ handle.Building = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets a city name for this address.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string City
+ {
+ get
+ {
+ return handle.City;
+ }
+ set
+ {
+ handle.City = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets a country name for this address.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Country
+ {
+ get
+ {
+ return handle.Country;
+ }
+ set
+ {
+ handle.Country = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets a country code for this address.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string CountryCode
+ {
+ get
+ {
+ return handle.CountryCode;
+ }
+ set
+ {
+ handle.CountryCode = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets a county for this address.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string County
+ {
+ get
+ {
+ return handle.County;
+ }
+ set
+ {
+ handle.County = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets a district name for this address.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string District
+ {
+ get
+ {
+ return handle.District;
+ }
+ set
+ {
+ handle.District = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets a free text associated with this address.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string FreeText
+ {
+ get
+ {
+ return handle.FreeText;
+ }
+ set
+ {
+ handle.FreeText = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets a postal code for this address.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string PostalCode
+ {
+ get
+ {
+ return handle.PostalCode;
+ }
+ set
+ {
+ handle.PostalCode = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets a state name for this address.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string State
+ {
+ get
+ {
+ return handle.State;
+ }
+ set
+ {
+ handle.State = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets a street name for this address.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Street
+ {
+ get
+ {
+ return handle.Street;
+ }
+ set
+ {
+ handle.Street = value;
+ }
+ }
+
+ /// <summary>
+ /// Returns a string that represents this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <returns>Returns a string which presents this object.</returns>
+ public override string ToString()
+ {
+ return $"{FreeText}";
+ }
+
+ #region IDisposable Support
+ private bool _disposedValue = false;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ handle.Dispose();
+ _disposedValue = true;
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/PlaceAddressList.cs b/src/Tizen.Maps/Tizen.Maps/PlaceAddressList.cs
new file mode 100755
index 0000000..86ba5f3
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/PlaceAddressList.cs
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// List of <see cref="PlaceAddress"/> objects to be used in <see cref="MapService"/> APIs
+ /// </summary>
+ internal class PlaceAddressList : IDisposable
+ {
+ internal Interop.AddressListHandle handle;
+ private List<PlaceAddress> _list;
+
+ /// <summary>
+ /// Constructs a map address list object.
+ /// </summary>
+ /// <exception cref="System.NotSupportedException">Thrown when the required feature is not supported.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when native operation failed to allocate memory.</exception>
+ public PlaceAddressList()
+ {
+ handle = new Interop.AddressListHandle();
+ }
+
+ internal PlaceAddressList(Interop.AddressListHandle nativeHandle)
+ {
+ handle = nativeHandle;
+ }
+
+ /// <summary>
+ /// Gets an iterator for addresses in this list.
+ /// </summary>
+ public IEnumerable<PlaceAddress> Addresses
+ {
+ get
+ {
+ if (_list == null)
+ {
+ _list = new List<PlaceAddress>();
+ handle.Foreach(addressHandle => _list.Add(new PlaceAddress(addressHandle)));
+ }
+ return _list;
+ }
+ }
+
+ #region IDisposable Support
+ private bool _disposedValue = false;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ handle.Dispose();
+ _disposedValue = true;
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/PlaceAttribute.cs b/src/Tizen.Maps/Tizen.Maps/PlaceAttribute.cs
new file mode 100755
index 0000000..a6307fa
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/PlaceAttribute.cs
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Place Attributes information, used in Place Discovery and Search requests
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class PlaceAttribute
+ {
+ private string _id;
+ private string _label;
+ private string _text;
+
+ internal PlaceAttribute(Interop.PlaceAttributeHandle nativeHandle)
+ {
+ _id = nativeHandle.Id;
+ _label = nativeHandle.Label;
+ _text = nativeHandle.Text;
+ }
+
+ internal PlaceAttribute(IntPtr nativeHandle, bool needToRelease)
+ : this(new Interop.PlaceAttributeHandle(nativeHandle, needToRelease))
+ {
+ }
+
+ /// <summary>
+ /// Gets an ID for the place attribute.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Id { get { return _id; } }
+
+ /// <summary>
+ /// Gets a label for the place attribute.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Label { get { return _label; } }
+
+ /// <summary>
+ /// Gets a text for the place attribute.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Text { get { return _text; } }
+
+ /// <summary>
+ /// Returns a string that represents this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <returns>Returns a string which presents this object.</returns>
+ public override string ToString()
+ {
+ return $"{Label}: {Text}";
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/PlaceCategory.cs b/src/Tizen.Maps/Tizen.Maps/PlaceCategory.cs
new file mode 100755
index 0000000..16ce43c
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/PlaceCategory.cs
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Place Category information, used in Place Discovery and Search requests
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class PlaceCategory : IDisposable
+ {
+ internal Interop.PlaceCategoryHandle handle;
+
+ /// <summary>
+ /// Constructs search category object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="System.InvalidOperationException">Thrown when native operation failed to allocate memory.</exception>
+ public PlaceCategory()
+ {
+ handle = new Interop.PlaceCategoryHandle();
+ }
+
+ internal PlaceCategory(Interop.PlaceCategoryHandle nativeHandle)
+ {
+ handle = nativeHandle;
+ }
+
+
+ /// <summary>
+ /// Gets or sets an ID for this category.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Id
+ {
+ get { return handle.Id; }
+ set { handle.Id = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets a name for this category.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Name
+ {
+ get { return handle.Name; }
+ set { handle.Name = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets an URL for this category.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Url
+ {
+ get { return handle.Url; }
+ set { handle.Url = value; }
+ }
+
+ /// <summary>
+ /// Returns a string that represents this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <returns>Returns a string which presents this object.</returns>
+ public override string ToString()
+ {
+ return $"{Name}";
+ }
+
+ #region IDisposable Support
+ private bool _disposedValue = false;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ handle.Dispose();
+ _disposedValue = true;
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/PlaceContact.cs b/src/Tizen.Maps/Tizen.Maps/PlaceContact.cs
new file mode 100755
index 0000000..8d6c467
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/PlaceContact.cs
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Place Contact information, used in Place Discovery and Search requests
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class PlaceContact
+ {
+ private string _label;
+ private string _type;
+ private string _value;
+
+ internal PlaceContact(Interop.PlaceContactHandle handle)
+ {
+ _label = handle.Label;
+ _type = handle.Type;
+ _value = handle.Value;
+ }
+
+ internal PlaceContact(IntPtr nativeHandle, bool needToRelease) : this(new Interop.PlaceContactHandle(nativeHandle, needToRelease))
+ {
+ }
+
+ /// <summary>
+ /// Gets an ID for this place contact.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Id { get { return _type; } }
+
+ /// <summary>
+ /// Gets a label for this place contact.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Label { get { return _label; } }
+
+ /// <summary>
+ /// Gets a value for this place contact.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Value { get { return _value; } }
+
+ /// <summary>
+ /// Returns a string that represents this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <returns>Returns a string which presents this object.</returns>
+ public override string ToString()
+ {
+ return $"{Label}: {Value}";
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/PlaceEditorial.cs b/src/Tizen.Maps/Tizen.Maps/PlaceEditorial.cs
new file mode 100755
index 0000000..ba4ff6a
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/PlaceEditorial.cs
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Place Editorial information, used in Place Discovery and Search requests
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class PlaceEditorial
+ {
+ private string _description;
+ private string _language;
+ private PlaceMedia _media;
+
+ internal PlaceEditorial(Interop.PlaceEditorialHandle handle)
+ {
+ _description = handle.Description;
+ _language = handle.Language;
+ _media = new PlaceMedia(handle.Media);
+ }
+
+ internal PlaceEditorial(IntPtr nativeHandle, bool needToRelease) : this(new Interop.PlaceEditorialHandle(nativeHandle, needToRelease))
+ {
+ }
+
+ /// <summary>
+ /// Gets a description for this place editorial.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Description { get { return _description; } }
+
+ /// <summary>
+ /// Gets a language for this place editorial.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Language { get { return _language; } }
+
+ /// <summary>
+ /// Gets an instance of <see cref="PlaceMedia"/> object which representing media for this place editorial.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public PlaceMedia Media { get { return _media; } }
+
+ /// <summary>
+ /// Returns a string that represents this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <returns>Returns a string which presents this object.</returns>
+ public override string ToString()
+ {
+ return $"{Description}";
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/PlaceFilter.cs b/src/Tizen.Maps/Tizen.Maps/PlaceFilter.cs
new file mode 100755
index 0000000..747c0d7
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/PlaceFilter.cs
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Place Filter information, used in Place Discovery and Search requests
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class PlaceFilter : IDisposable
+ {
+ internal Interop.PlaceFilterHandle handle;
+
+ /// <summary>
+ /// Constructs new place filter.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="System.InvalidOperationException">Thrown when native operation failed to allocate memory.</exception>
+ public PlaceFilter()
+ {
+ handle = new Interop.PlaceFilterHandle();
+ }
+
+ /// <summary>
+ /// Gets or sets an free-formed address string for this place filter.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>Depending on maps provider which the application has selected,
+ /// it may treat <see cref="PlaceFilter.Name"/>, <see cref="PlaceFilter.Keyword"/> and <see cref="PlaceFilter.Address"/>
+ /// as same kind of strings to search places.</remarks>
+ public string Address
+ {
+ get
+ {
+ return handle.PlaceAddress;
+ }
+ set
+ {
+ handle.PlaceAddress = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets an instance of <see cref="PlaceCategory"/> object for this place filter.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public PlaceCategory Category
+ {
+ get
+ {
+ return new PlaceCategory(handle.Category);
+ }
+ set
+ {
+ handle.Category = value.handle;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a keyword for this place filter.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>Depending on maps provider which the application has selected,
+ /// it may treat <see cref="PlaceFilter.Name"/>, <see cref="PlaceFilter.Keyword"/> and <see cref="PlaceFilter.Address"/>
+ /// as same kind of strings to search places.</remarks>
+ public string Keyword
+ {
+ get
+ {
+ return handle.Keyword;
+ }
+ set
+ {
+ handle.Keyword = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a name for this place filter.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>Depending on maps provider which the application has selected,
+ /// it may treat <see cref="PlaceFilter.Name"/>, <see cref="PlaceFilter.Keyword"/> and <see cref="PlaceFilter.Address"/>
+ /// as same kind of strings to search places.</remarks>
+ public string Name
+ {
+ get
+ {
+ return handle.PlaceName;
+ }
+ set
+ {
+ handle.PlaceName = value;
+ }
+ }
+
+ #region IDisposable Support
+ private bool _disposedValue = false;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ handle.Dispose();
+ _disposedValue = true;
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/PlaceImage.cs b/src/Tizen.Maps/Tizen.Maps/PlaceImage.cs
new file mode 100755
index 0000000..220a199
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/PlaceImage.cs
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Place Image information, used in Place Discovery and Search requests
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class PlaceImage
+ {
+ private string _id;
+ private string _url;
+ private int _width;
+ private int _height;
+ private PlaceLink _userLink;
+ private PlaceMedia _media;
+
+ internal PlaceImage(Interop.PlaceImageHandle handle)
+ {
+ _id = handle.Id;
+ _url = handle.Url;
+ _width = handle.Width;
+ _height = handle.Height;
+ _userLink = new PlaceLink(handle.User);
+ _media = new PlaceMedia(handle.Media);
+ }
+
+ /// <summary>
+ /// Gets an ID for this place image.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Id { get { return _id; } }
+
+ /// <summary>
+ /// Gets an URL for this place image.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Url { get { return _url; } }
+
+ /// <summary>
+ /// Gets width for this place image.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public int Width { get { return _width; } }
+
+ /// <summary>
+ /// Gets height for this place image.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public int Height { get { return _height; } }
+
+ /// <summary>
+ /// Gets an object which representing user link for this place image.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public PlaceLink UserLink { get { return _userLink; } }
+
+ /// <summary>
+ /// Gets an object which representing image media for this place image.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public PlaceMedia ImageMedia { get { return _media; } }
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/PlaceLink.cs b/src/Tizen.Maps/Tizen.Maps/PlaceLink.cs
new file mode 100755
index 0000000..bdc6a06
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/PlaceLink.cs
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Place Link Object information, used in Place Discovery and Search requests
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class PlaceLink
+ {
+ private string _id;
+ private string _name;
+ private string _link;
+ private string _type;
+
+ internal PlaceLink(Interop.PlaceLinkObjectHandle handle)
+ {
+ _id = handle.Id;
+ _name = handle.Name;
+ _link = handle.Link;
+ _type = handle.Type;
+ }
+
+ /// <summary>
+ /// Gets a string which representing ID for this place link.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Id { get { return _id; } }
+
+ /// <summary>
+ /// Gets a string which representing name for this place link.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Name { get { return _name; } }
+
+ /// <summary>
+ /// Gets a string which representing link for this place link.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Link { get { return _link; } }
+
+ /// <summary>
+ /// Gets a string which representing type for this place link.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Type { get { return _type; } }
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/PlaceList.cs b/src/Tizen.Maps/Tizen.Maps/PlaceList.cs
new file mode 100755
index 0000000..c46bbdb
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/PlaceList.cs
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// List of <see cref="Place"/> objects to be used in <see cref="MapService"/> APIs
+ /// </summary>
+ internal class PlaceList : IDisposable
+ {
+ internal Interop.PlaceListHandle handle;
+ private List<Place> _list;
+
+ internal PlaceList(Interop.PlaceListHandle nativeHandle)
+ {
+ handle = nativeHandle;
+ }
+
+ /// <summary>
+ /// Gets an iterator for addresses in this list.
+ /// </summary>
+ public IEnumerable<Place> Places
+ {
+ get
+ {
+ if (_list == null)
+ {
+ _list = new List<Place>();
+ handle.Foreach(placeHandle => _list.Add(new Place(placeHandle)));
+ }
+ return _list;
+ }
+ }
+
+ #region IDisposable Support
+ private bool _disposedValue = false;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ handle.Dispose();
+ _disposedValue = true;
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/PlaceMedia.cs b/src/Tizen.Maps/Tizen.Maps/PlaceMedia.cs
new file mode 100755
index 0000000..370de73
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/PlaceMedia.cs
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Place Media information, used in Place Discovery and Search requests
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class PlaceMedia
+ {
+ private string _attribution;
+ private PlaceLink _supplier;
+ private PlaceLink _via;
+
+ internal PlaceMedia(Interop.PlaceMediaHandle handle)
+ {
+ _attribution = handle.Attribution;
+ _supplier = new PlaceLink(handle.Supplier);
+ _via = new PlaceLink(handle.Via);
+ }
+
+ /// <summary>
+ /// Gets a string which representing attribution for this place media.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Attribution { get { return _attribution; } }
+
+ /// <summary>
+ /// Gets an instance of <see cref="PlaceLink"/> object which representing supplier for this place media.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public PlaceLink Supplier { get { return _supplier; } }
+
+ /// <summary>
+ /// Gets an instance of <see cref="PlaceLink"/> object which representing via data for this place media.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public PlaceLink Via { get { return _via; } }
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/PlaceRating.cs b/src/Tizen.Maps/Tizen.Maps/PlaceRating.cs
new file mode 100755
index 0000000..a829fc4
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/PlaceRating.cs
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Place Rating information, used in Place Discovery and Search requests
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class PlaceRating
+ {
+ private int _count;
+ private double _average;
+
+ internal PlaceRating(Interop.PlaceRatingHandle handle)
+ {
+ _count = handle.Count;
+ _average = handle.Average;
+ }
+
+ /// <summary>
+ /// Gets the number of users rated for this place rating.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public int UserCount { get { return _count; } }
+
+ /// <summary>
+ /// Gets average value of this place rating.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public double Average { get { return _average; } }
+
+ /// <summary>
+ /// Returns a string that represents this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <returns>Returns a string which presents this object.</returns>
+ public override string ToString()
+ {
+ return $"{Average}({UserCount} reviews)";
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/PlaceReview.cs b/src/Tizen.Maps/Tizen.Maps/PlaceReview.cs
new file mode 100755
index 0000000..210b307
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/PlaceReview.cs
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Place Review information, used in Place Discovery and Search requests
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class PlaceReview
+ {
+ private DateTime _date;
+ private string _title;
+ private double _rating;
+ private string _description;
+ private string _language;
+ private PlaceMedia _media;
+ private PlaceLink _userLink;
+
+ internal PlaceReview(Interop.PlaceReviewHandle handle)
+ {
+ string date = handle.Date;
+ if (DateTime.TryParse(date, out _date) == false)
+ {
+ Interop.ErrorCode.InvalidParameter.WarnIfFailed($"Wrong date format: {date}");
+ }
+
+ _title = handle.Title;
+ _rating = handle.Rating;
+ _description = handle.Description;
+ _language = handle.Language;
+ _media = new PlaceMedia(handle.Media);
+ _userLink = new PlaceLink(handle.User);
+ }
+
+ /// <summary>
+ /// Gets an instance of <see cref="DateTime"/> object which representing time of this review.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public DateTime Date { get { return _date; } }
+
+ /// <summary>
+ /// Gets a string which representing title of this review.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Title { get { return _title; } }
+
+ /// <summary>
+ /// Gets a value which representing rating of this review.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public double Rating { get { return _rating; } }
+
+ /// <summary>
+ /// Gets a string which representing description of this review.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Description { get { return _description; } }
+
+ /// <summary>
+ /// Gets a string which representing language of this review.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Language { get { return _language; } }
+
+ /// <summary>
+ /// Gets an instance of <see cref="PlaceMedia"/> object which representing review media of this review.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public PlaceMedia ReviewMedia { get { return _media; } }
+
+ /// <summary>
+ /// Gets an instance of <see cref="PlaceLink"/> object which representing user link of this review.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public PlaceLink UserLink { get { return _userLink; } }
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/PlaceSearchRequest.cs b/src/Tizen.Maps/Tizen.Maps/PlaceSearchRequest.cs
new file mode 100755
index 0000000..92bd555
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/PlaceSearchRequest.cs
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Place search request for Tizen map service
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class PlaceSearchRequest : MapServiceRequest<Place>
+ {
+ private Interop.SearchPlaceCallback _placeCallback;
+ private List<Place> _placeList = new List<Place>();
+
+ internal PlaceSearchRequest(MapService service, Geocoordinates position, int distance) : this(service, ServiceRequestType.SearchPlace)
+ {
+ startExecutionAction = new Action(() =>
+ {
+ int requestID;
+ errMessage = $"Failed to get place list for given co-ordinate {position} and distance {distance}";
+ errorCode = _service.handle.SearchPlace(position.handle, distance, _service.PlaceSearchFilter.handle, _service.Preferences.handle, _placeCallback, IntPtr.Zero, out requestID);
+ if (errorCode.IsFailed() && errorCode != Interop.ErrorCode.Canceled)
+ {
+ _requestTask?.TrySetException(errorCode.GetException(errMessage));
+ }
+ _requestID = requestID;
+ });
+ }
+
+ internal PlaceSearchRequest(MapService service, Area boundary) : this(service, ServiceRequestType.SearchPlaceByArea)
+ {
+ startExecutionAction = new Action(() =>
+ {
+ int requestID;
+ errMessage = $"Failed to get place list for given boundary";
+ errorCode = _service.handle.SearchPlaceByArea(boundary.handle, _service.PlaceSearchFilter.handle, _service.Preferences.handle, _placeCallback, IntPtr.Zero, out requestID);
+ if (errorCode.IsFailed() && errorCode != Interop.ErrorCode.Canceled)
+ {
+ _requestTask?.TrySetException(errorCode.GetException(errMessage));
+ }
+ _requestID = requestID;
+ });
+ }
+
+ internal PlaceSearchRequest(MapService service, string address, Area boundary) : this(service, ServiceRequestType.SearchPlaceByAddress)
+ {
+ startExecutionAction = new Action(() =>
+ {
+ int requestID;
+ errMessage = $"Failed to get coordinates for address {address} in given boundary";
+ errorCode = _service.handle.SearchPlaceByAddress(address, boundary.handle, _service.PlaceSearchFilter.handle, _service.Preferences.handle, _placeCallback, IntPtr.Zero, out requestID);
+ if (errorCode.IsFailed() && errorCode != Interop.ErrorCode.Canceled)
+ {
+ _requestTask?.TrySetException(errorCode.GetException(errMessage));
+ }
+ _requestID = requestID;
+ });
+ }
+
+ private PlaceSearchRequest(MapService service, ServiceRequestType type) : base(service, type)
+ {
+ // The Maps Service invokes this callback while iterating through the set of obtained Place data.
+ _placeCallback = (result, id, index, total, place, userData) =>
+ {
+ errorCode = result;
+ if (result.IsSuccess())
+ {
+ // The parameter place must be released using maps_place_destroy().
+ var placeHandle = new Interop.PlaceHandle(place, needToRelease: true);
+ _placeList.Add(new Place(placeHandle));
+ if (_placeList.Count == total)
+ {
+ _requestTask?.TrySetResult(_placeList);
+ }
+ return true;
+ }
+ else
+ {
+ // If search is failed, the value of total is 0 and place is NULL
+ _requestTask?.TrySetException(errorCode.GetException(errMessage));
+ return false;
+ }
+ };
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/Polygon.cs b/src/Tizen.Maps/Tizen.Maps/Polygon.cs
new file mode 100755
index 0000000..1503b63
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/Polygon.cs
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+using Color = ElmSharp.Color;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Polygon map object
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class Polygon : MapObject, IDisposable
+ {
+ internal Interop.PolygonHandle handle;
+ private List<Geocoordinates> _coordinateList;
+
+ /// <summary>
+ /// Creates a polygon visual object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="coordinates">List of geographical coordinates</param>
+ /// <param name="color">Background color</param>
+ /// <exception cref="ArgumentException">Thrown when input values are invalid.</exception>
+ public Polygon(IEnumerable<Geocoordinates> coordinates, Color color) : base()
+ {
+ var err = Interop.ErrorCode.InvalidParameter;
+ if (coordinates == null || coordinates.Count() < 3)
+ {
+ err.ThrowIfFailed("given coordinates list should contain at least 3 coordinates");
+ }
+ _coordinateList = coordinates.ToList();
+ var geocoordinateList = new GeocoordinatesList(_coordinateList, false);
+ handle = new Interop.PolygonHandle(geocoordinateList.handle, color);
+ }
+
+ /// <summary>
+ /// Adds or removes clicked event handlers.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public event EventHandler Clicked;
+
+ /// <summary>
+ /// Gets or sets visibility for the polygon.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public override bool IsVisible
+ {
+ get { return handle.IsVisible; }
+ set { handle.IsVisible = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets a list of geographical coordinates of polygon vertices.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public IEnumerable<Geocoordinates> Coordinates
+ {
+ get
+ {
+ return _coordinateList;
+ }
+ set
+ {
+ var coordinates = value.ToList();
+ var err = Interop.ErrorCode.InvalidParameter;
+ if (coordinates == null || coordinates.Count() < 3)
+ {
+ err.ThrowIfFailed("given coordinates list should contain at least 3 coordinates");
+ }
+
+ var geocoordinateList = new GeocoordinatesList(coordinates, false);
+ if (handle.SetPolygon(geocoordinateList.handle).IsSuccess())
+ {
+ _coordinateList = coordinates;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets background color to fill the polygon.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public Color FillColor
+ {
+ get
+ {
+ return handle.FillColor;
+ }
+ set
+ {
+ handle.FillColor = value;
+ }
+ }
+
+ internal override void HandleClickedEvent()
+ {
+ Clicked?.Invoke(this, EventArgs.Empty);
+ }
+
+ internal override void InvalidateMapObject()
+ {
+ handle = null;
+ }
+
+ internal override Interop.ViewObjectHandle GetHandle()
+ {
+ return handle;
+ }
+
+ #region IDisposable Support
+ private bool _disposedValue = false;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ if (disposing)
+ {
+ _coordinateList.Clear();
+ }
+ handle.Dispose();
+ _disposedValue = true;
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/Polyline.cs b/src/Tizen.Maps/Tizen.Maps/Polyline.cs
new file mode 100755
index 0000000..9c743c2
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/Polyline.cs
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+using Color = ElmSharp.Color;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Polyline map object
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class Polyline : MapObject, IDisposable
+ {
+ internal Interop.PolylineHandle handle;
+ private List<Geocoordinates> _coordinateList;
+
+ /// <summary>
+ /// Creates polyline visual object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="coordinates">List of geographical coordinates</param>
+ /// <param name="color">Line color</param>
+ /// <param name="width">The width of line [1 ~ 100] (pixels)</param>
+ /// <exception cref="ArgumentException">Thrown when input values are invalid</exception>
+ public Polyline(List<Geocoordinates> coordinates, Color color, int width) : base()
+ {
+ var err = Interop.ErrorCode.InvalidParameter;
+ if (coordinates == null || coordinates.Count() < 2)
+ {
+ err.ThrowIfFailed("given coordinates list should contain at least 2 coordinates");
+ }
+ _coordinateList = coordinates.ToList();
+ var geocoordinateList = new GeocoordinatesList(_coordinateList);
+ handle = new Interop.PolylineHandle(geocoordinateList.handle, color, width);
+ }
+
+ /// <summary>
+ /// Adds or removes clicked event handlers.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public event EventHandler Clicked;
+
+ /// <summary>
+ /// Gets or sets visibility for the polyline.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public override bool IsVisible
+ {
+ get { return handle.IsVisible; }
+ set { handle.IsVisible = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets a list of geographical coordinates for polyline vertices.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public IEnumerable<Geocoordinates> Coordinates
+ {
+ get
+ {
+ return _coordinateList;
+ }
+ set
+ {
+ var coordinates = value.ToList();
+ var err = Interop.ErrorCode.InvalidParameter;
+ if (coordinates == null || coordinates.Count() < 2)
+ {
+ err.ThrowIfFailed("given coordinates list should contain at least 2 coordinates");
+ }
+
+ var geocoordinateList = new GeocoordinatesList(coordinates, false);
+ if (handle.SetPolyline(geocoordinateList.handle).IsSuccess())
+ {
+ _coordinateList = coordinates;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets line color.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public Color LineColor
+ {
+ get
+ {
+ return handle.LineColor;
+ }
+ set
+ {
+ handle.LineColor = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets line width from 1 to 100 pixels.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public int Width
+ {
+ get
+ {
+ return handle.LineWidth;
+ }
+ set
+ {
+ handle.LineWidth = value;
+ }
+ }
+
+ internal override void HandleClickedEvent()
+ {
+ Clicked?.Invoke(this, EventArgs.Empty);
+ }
+
+ internal override void InvalidateMapObject()
+ {
+ handle = null;
+ }
+
+ internal override Interop.ViewObjectHandle GetHandle()
+ {
+ return handle;
+ }
+
+ #region IDisposable Support
+ private bool _disposedValue = false;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ if (disposing)
+ {
+ _coordinateList.Clear();
+ }
+ handle.Dispose();
+ _disposedValue = true;
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/ReverseGeocodeRequest.cs b/src/Tizen.Maps/Tizen.Maps/ReverseGeocodeRequest.cs
new file mode 100755
index 0000000..af2533d
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/ReverseGeocodeRequest.cs
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Reverse geocode request for map service.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class ReverseGeocodeRequest : MapServiceRequest<PlaceAddress>
+ {
+ private Interop.ReverseGeocodeCallback _geocodeCallback;
+ private List<PlaceAddress> _addressList = new List<PlaceAddress>();
+
+ internal ReverseGeocodeRequest(MapService service, double latitude, double longitute) : base(service, ServiceRequestType.ReverseGeocode)
+ {
+ // The Maps Service invokes this callback when the address is obtained from the specified coordinates.
+ _geocodeCallback = (result, id, index, total, address, userData) =>
+ {
+ errorCode = result;
+ if (result.IsSuccess())
+ {
+ // The parameter address must be released using maps_address_destroy().
+ var addressHandle = new Interop.AddressHandle(address, needToRelease: true);
+ _addressList.Add(new PlaceAddress(addressHandle));
+ if (_addressList.Count == total)
+ {
+ _requestTask?.TrySetResult(_addressList);
+ }
+ }
+ else
+ {
+ // If search is failed, the value of total is 0 and address is NULL
+ _requestTask?.TrySetException(errorCode.GetException(errMessage));
+ }
+ };
+
+ startExecutionAction = new Action(() =>
+ {
+ int requestID;
+ errMessage = $"Failed to get coordinates for given coordinates: {latitude}:{longitute}";
+ errorCode = _service.handle.ReverseGeocode(latitude, longitute, _service.Preferences.handle, _geocodeCallback, IntPtr.Zero, out requestID);
+ if (errorCode.IsFailed() && errorCode != Interop.ErrorCode.Canceled)
+ {
+ _requestTask?.TrySetException(errorCode.GetException(errMessage));
+ }
+ _requestID = requestID;
+ });
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/Route.cs b/src/Tizen.Maps/Tizen.Maps/Route.cs
new file mode 100755
index 0000000..bc5aa4c
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/Route.cs
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Route information, used in Route Search requests.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class Route : IDisposable
+ {
+ internal Interop.RouteHandle handle;
+
+ internal Route(Interop.RouteHandle nativeHandle)
+ {
+ handle = nativeHandle;
+ }
+
+ /// <summary>
+ /// Gets an instance of <see cref="Geocoordinates"/> object which representing destination coordinates for this route.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public Geocoordinates Destination
+ {
+ get
+ {
+ return new Geocoordinates(handle.Destination);
+ }
+ }
+
+ /// <summary>
+ /// Gets total distance for this route.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public double Distance
+ {
+ get
+ {
+ return handle.Distance;
+ }
+ }
+
+ /// <summary>
+ /// Get total duration to cover this route.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public double Duration
+ {
+ get
+ {
+ return handle.Duration;
+ }
+ }
+
+ /// <summary>
+ /// Gets an ID for this route.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Id
+ {
+ get
+ {
+ return handle.Id;
+ }
+ }
+
+ /// <summary>
+ /// Gets transport mode for this route.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public TransportMode Mode
+ {
+ get
+ {
+ return (TransportMode)handle.TransportMode;
+ }
+ }
+
+ /// <summary>
+ /// Gets origin coordinates for this route.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public Geocoordinates Origin
+ {
+ get
+ {
+ return new Geocoordinates(handle.Origin);
+ }
+ }
+
+ /// <summary>
+ /// Gets a coordinates list for this route.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public IEnumerable<Geocoordinates> Path
+ {
+ get
+ {
+ var path = new List<Geocoordinates>();
+ handle.ForeachPath(coordinateHandle => path.Add(new Geocoordinates(coordinateHandle)));
+ return path;
+ }
+ }
+
+ /// <summary>
+ /// Gets a segment list for this route.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public IEnumerable<RouteSegment> Segments
+ {
+ get
+ {
+ var segments = new List<RouteSegment>();
+ handle.ForeachSegment(segmentHandle => segments.Add(new RouteSegment(segmentHandle)));
+ return segments;
+ }
+ }
+
+ /// <summary>
+ /// Gets distance unit for this route.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public DistanceUnit Unit
+ {
+ get
+ {
+ return (DistanceUnit)handle.Unit;
+ }
+ }
+
+ /// <summary>
+ /// Gets an instance of <see cref="Area"/> object which representing bounding area for this route.
+ /// </summary>
+ private Area BoundingBox
+ {
+ get
+ {
+ return new Area(handle.BoundingBox);
+ }
+ }
+
+ #region IDisposable Support
+ private bool _disposedValue = false;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ handle.Dispose();
+ _disposedValue = true;
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/RouteFeature.cs b/src/Tizen.Maps/Tizen.Maps/RouteFeature.cs
new file mode 100755
index 0000000..4f44d36
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/RouteFeature.cs
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Route features, used for route search requests
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum RouteFeature
+ {
+ /// <summary>
+ /// Indicates no route features (are selected).
+ /// </summary>
+ None = Interop.RouteRequestFeature.None,
+ /// <summary>
+ /// Indicates toll roads (toll gates/booths).
+ /// </summary>
+ Toll = Interop.RouteRequestFeature.Toll,
+ /// <summary>
+ /// Indicates motorway.
+ /// </summary>
+ Motorway = Interop.RouteRequestFeature.MotorWay,
+ /// <summary>
+ /// Indicates a boat ferry.
+ /// </summary>
+ BoatFerry = Interop.RouteRequestFeature.BoatFerry,
+ /// <summary>
+ /// Indicates rail (train) ferry.
+ /// </summary>
+ RailFerry = Interop.RouteRequestFeature.RailFerry,
+ /// <summary>
+ /// Indicates public transport.
+ /// </summary>
+ PublicTransit = Interop.RouteRequestFeature.PublicTransit,
+ /// <summary>
+ /// Indicates tunnel.
+ /// </summary>
+ Tunnel = Interop.RouteRequestFeature.Tunnel,
+ /// <summary>
+ /// Indicates dirt road.
+ /// </summary>
+ DirtRoad = Interop.RouteRequestFeature.DirtRoad,
+ /// <summary>
+ /// Indicates park.
+ /// </summary>
+ Parks = Interop.RouteRequestFeature.Parks,
+ /// <summary>
+ /// Indicates a high-occupancy vehicle lane.
+ /// </summary>
+ Hovlane = Interop.RouteRequestFeature.Hovlane,
+ /// <summary>
+ /// Indicates stairs.
+ /// </summary>
+ Stairs = Interop.RouteRequestFeature.Stairs,
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/RouteFeatureWeight.cs b/src/Tizen.Maps/Tizen.Maps/RouteFeatureWeight.cs
new file mode 100755
index 0000000..03a557e
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/RouteFeatureWeight.cs
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Route feature weights used in route search requests
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum RouteFeatureWeight
+ {
+ /// <summary>
+ /// Indicates normal weighting.
+ /// </summary>
+ Normal = Interop.RouteFeatureWeight.Normal,
+ /// <summary>
+ /// Indicates that a feature is preferred.
+ /// </summary>
+ Prefer = Interop.RouteFeatureWeight.Prefer,
+ /// <summary>
+ /// Indicates that a feature is to be avoided.
+ /// </summary>
+ Avoid = Interop.RouteFeatureWeight.Avoid,
+ /// <summary>
+ /// Indicates that soft-exclude applies to the feature.
+ /// </summary>
+ SoftExclude = Interop.RouteFeatureWeight.SoftExclude,
+ /// <summary>
+ /// Indicates that the feature is to be strictly excluded.
+ /// </summary>
+ StrictExclude = Interop.RouteFeatureWeight.StrictExclude,
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/RouteManeuver.cs b/src/Tizen.Maps/Tizen.Maps/RouteManeuver.cs
new file mode 100755
index 0000000..ea1ceeb
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/RouteManeuver.cs
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Route Maneuver information, used in Route Search requests
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class RouteManeuver
+ {
+ private Interop.RouteDirection _direction;
+ private Interop.RouteTurnType _turntype;
+ private Geocoordinates _coordinates;
+ private string _road;
+ private string _instruction;
+ private string _locale;
+ private int _timeToNextInstruction;
+ private double _distanceToNextInstruction;
+
+ internal RouteManeuver(Interop.RouteManeuverHandle handle)
+ {
+ _direction = handle.Direction;
+ _turntype = handle.TurnType;
+ _coordinates = new Geocoordinates(handle.Coordinates);
+ _road = handle.RoadName;
+ _instruction = handle.Instruction;
+ _locale = handle.Locale;
+ _timeToNextInstruction = handle.TimeToNextInstruction;
+ _distanceToNextInstruction = handle.DistanceToNextInstruction;
+ }
+
+ /// <summary>
+ /// Gets direction type for this maneuver.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public DirectionType Direction { get { return (DirectionType)_direction; } }
+
+ /// <summary>
+ /// Gets turn type for this maneuver.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public TurnInstruction Turn { get { return (TurnInstruction)_turntype; } }
+
+ /// <summary>
+ /// Gets a geographical coordinates position for this maneuver.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public Geocoordinates Position { get { return _coordinates; } }
+
+ /// <summary>
+ /// Gets a name of the road for this maneuver.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Road { get { return _road; } }
+
+ /// <summary>
+ /// Gets an instruction text for this maneuver.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Instruction { get { return _instruction; } }
+
+ /// <summary>
+ /// Gets a locale for this maneuver.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string Locale { get { return _locale; } }
+
+ /// <summary>
+ /// Gets time to next instruction for this maneuver.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public int TimeToNextInstruction { get { return _timeToNextInstruction; } }
+
+ /// <summary>
+ /// Gets distance to next instruction for this maneuver.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public double DistanceToNextInstruction { get { return _distanceToNextInstruction; } }
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/RouteOptimization.cs b/src/Tizen.Maps/Tizen.Maps/RouteOptimization.cs
new file mode 100755
index 0000000..e7932a0
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/RouteOptimization.cs
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Allowed route optimization option used in route search requests
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>
+ /// Depending on loaded maps plug-in using <see cref="MapService"/>, some features may have no effect or differences with descriptions.
+ /// </remarks>
+ public enum RouteOptimization
+ {
+ /// <summary>
+ /// Indicates that searching for fastest routes.
+ /// </summary>
+ Fastest = Interop.RouteOptimization.Fastest,
+ /// <summary>
+ /// Indicates that searching for shortest routes (car mode only).
+ /// </summary>
+ Shortest = Interop.RouteOptimization.Shortest,
+ /// <summary>
+ /// Indicates that searching for most economic routes (car mode only).
+ /// </summary>
+ Economic = Interop.RouteOptimization.Economic,
+ /// <summary>
+ /// Indicates that searching for most scenic routes.
+ /// </summary>
+ Scenic = Interop.RouteOptimization.Scenic,
+ /// <summary>
+ /// Indicates that searching for most fastest routes now, based on current traffic condition.
+ /// </summary>
+ FastestNow = Interop.RouteOptimization.FastestNow,
+ /// <summary>
+ /// Indicates that searching for direct drive routes.
+ /// </summary>
+ DirectDrive = Interop.RouteOptimization.DirectDrive,
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/RouteSearchRequest.cs b/src/Tizen.Maps/Tizen.Maps/RouteSearchRequest.cs
new file mode 100755
index 0000000..95d48cf
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/RouteSearchRequest.cs
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Route search request for Tizen map service requests
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class RouteSearchRequest : MapServiceRequest<Route>
+ {
+ private Interop.SearchRouteCallback _routeCallback;
+ private List<Route> _routeList = new List<Route>();
+
+ private Geocoordinates _to;
+ private Geocoordinates _from;
+ private List<Geocoordinates> _waypoints = new List<Geocoordinates>();
+
+ internal RouteSearchRequest(MapService service, Geocoordinates from, Geocoordinates to) : this(service, ServiceRequestType.SearchRoute)
+ {
+ _to = to;
+ _from = from;
+ startExecutionAction = new Action(() =>
+ {
+ int requestID;
+ errMessage = $"Failed to get route list for given origin {_from} and destination {_to}";
+ if (_waypoints?.Count == 0)
+ {
+ _type = ServiceRequestType.SearchRoute;
+ errorCode = _service.handle.SearchRoute(_from.handle, _to.handle, _service.Preferences.handle, _routeCallback, IntPtr.Zero, out requestID);
+ if (errorCode.IsFailed() && errorCode != Interop.ErrorCode.Canceled)
+ {
+ _requestTask?.TrySetException(errorCode.GetException(errMessage));
+ }
+ }
+ else
+ {
+ _type = ServiceRequestType.SearchRouteWithWaypoints;
+
+ var waypoints = GetCoordinateListForWaypoints();
+ errorCode = _service.handle.SearchRouteWaypoints(waypoints, waypoints.Length, _service.Preferences.handle, _routeCallback, IntPtr.Zero, out requestID);
+ if (errorCode.IsFailed() && errorCode != Interop.ErrorCode.Canceled)
+ {
+ _requestTask?.TrySetException(errorCode.GetException(errMessage));
+ }
+ }
+ _requestID = requestID;
+ });
+ }
+
+
+ private RouteSearchRequest(MapService service, ServiceRequestType type) : base(service, type)
+ {
+ // The Maps Service invokes this callback while iterating through the set of obtained Routes.
+ _routeCallback = (result, id, index, total, route, userData) =>
+ {
+ errorCode = result;
+ if (result.IsSuccess())
+ {
+ // The parameter route must be released using maps_route_destroy().
+ var routeHandle = new Interop.RouteHandle(route, needToRelease: true);
+ _routeList.Add(new Route(routeHandle));
+ if (_routeList.Count == total)
+ {
+ _requestTask?.TrySetResult(_routeList);
+ }
+ return true;
+ }
+ else
+ {
+ // If search is failed, the value of total is 0 and route is NULL.
+ _requestTask?.TrySetException(errorCode.GetException(errMessage));
+ return false;
+ }
+ };
+ }
+
+ /// <summary>
+ /// Gets or sets a list of way-points to cover between origin and destination.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public IEnumerable<Geocoordinates> Waypoints
+ {
+ get
+ {
+ return _waypoints;
+ }
+ set
+ {
+ _waypoints = value.ToList();
+ }
+ }
+
+ private IntPtr[] GetCoordinateListForWaypoints()
+ {
+ var waypoints = new IntPtr[_waypoints.Count + 2];
+ waypoints[0] = _from.handle;
+ for (int i = 0; i < _waypoints.Count; ++i)
+ {
+ waypoints[i + 1] = _waypoints[i].handle;
+ }
+ waypoints[waypoints.Length - 1] = _to.handle;
+ return waypoints;
+ }
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/RouteSegment.cs b/src/Tizen.Maps/Tizen.Maps/RouteSegment.cs
new file mode 100755
index 0000000..347466f
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/RouteSegment.cs
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Place Segment information, used in Route Search requests
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class RouteSegment
+ {
+ private Geocoordinates _origin;
+ private Geocoordinates _destination;
+ private double _distance;
+ private double _duration;
+ private Area _boundingBox;
+
+ private List<RouteManeuver> _maneuvers = new List<RouteManeuver>();
+ private List<Geocoordinates> _path = new List<Geocoordinates>();
+
+ internal RouteSegment(Interop.RouteSegmentHandle handle)
+ {
+ _origin = new Geocoordinates(handle.Origin);
+ _destination = new Geocoordinates(handle.Destination);
+ _distance = handle.Distance;
+ _duration = handle.Duration;
+ _boundingBox = new Area(handle.BoundingBox);
+
+ handle.ForeachManeuver(maneuverHandle => _maneuvers.Add(new RouteManeuver(maneuverHandle)));
+ handle.ForeachPath(pathHandle => _path.Add(new Geocoordinates(pathHandle)));
+ }
+
+ /// <summary>
+ /// Gets an origin coordinates for this segment.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public Geocoordinates Origin { get { return _origin; } }
+
+ /// <summary>
+ /// Gets a destination coordinates for this segment.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public Geocoordinates Destination { get { return _destination; } }
+
+ /// <summary>
+ /// Gets total distance for this segment.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public double Distance { get { return _distance; } }
+
+ /// <summary>
+ /// Gets total duration to cover this segment.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public double Duration { get { return _duration; } }
+
+ /// <summary>
+ /// Gets a maneuver list for this segment.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public IEnumerable<RouteManeuver> Maneuvers { get { return _maneuvers; } }
+
+ /// <summary>
+ /// Gets a coordinates list for this segment.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public IEnumerable<Geocoordinates> Path { get { return _path; } }
+
+ private Area BoundingBox { get { return _boundingBox; } }
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/SearchPreference.cs b/src/Tizen.Maps/Tizen.Maps/SearchPreference.cs
new file mode 100755
index 0000000..fc7da53
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/SearchPreference.cs
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Preferences for route search requests
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class SearchPreference : IGeocodePreference, IPlaceSearchPreference, IRouteSearchPreference, IDisposable
+ {
+ internal Interop.PreferenceHandle handle;
+ private IDictionary<string, string> _properties = new Dictionary<string, string>();
+
+ /// <summary>
+ /// Constructors a new search preference.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public SearchPreference()
+ {
+ handle = new Interop.PreferenceHandle();
+ }
+
+ /// <summary>
+ /// Constructors a new search preference.
+ /// </summary>
+ internal SearchPreference(Interop.PreferenceHandle nativeHandle)
+ {
+ handle = nativeHandle;
+ }
+
+ /// <summary>
+ /// Gets or sets preferred language.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>Language should be specified as an ISO 3166 alpha-2 two letter country-code
+ /// followed by ISO 639-1 for the two-letter language code.<br/>e.g. "ko-KR", "en-US".</remarks>
+ public string Language
+ {
+ get
+ {
+ return handle.Language;
+ }
+ set
+ {
+ Log.Info(string.Format("Language is changed from {0} to {1}", handle.Language, value));
+ handle.Language = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the maximum result count for each service request.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>Setting negative value will not have any effect on MaxResults value</remarks>
+ public int MaxResults
+ {
+ get
+ {
+ return handle.MaxResult;
+ }
+ set
+ {
+ Log.Info(string.Format("MaxResult is changed from {0} to {1}", handle.MaxResult, value));
+ handle.MaxResult = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets distance unit.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public DistanceUnit Unit
+ {
+ get
+ {
+ return (DistanceUnit)handle.Unit;
+ }
+ set
+ {
+ Log.Info(string.Format("Unit is changed from {0} to {1}", handle.Unit, value));
+ handle.Unit = (Interop.DistanceUnit)value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets preferred country.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public string CountryCode
+ {
+ get
+ {
+ return handle.CountryCode;
+ }
+ set
+ {
+ Log.Info(string.Format("CountryCode is changed from {0} to {1}", handle.CountryCode, value));
+ handle.CountryCode = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets search properties as key value pair.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public IReadOnlyDictionary<string, string> Properties
+ {
+ get
+ {
+ Action<string, string> action = (key, value) =>
+ {
+ _properties[key] = value;
+ };
+
+ handle.ForeachProperty(action);
+ return (IReadOnlyDictionary<string, string>)_properties;
+ }
+ set
+ {
+ foreach (var prop in value)
+ {
+ _properties[prop.Key] = prop.Value;
+ handle.SetProperty(prop.Key, prop.Value);
+ Log.Info(string.Format("Properties is changed to [{0}, {1}]", prop.Key, prop.Value));
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets route optimization.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public RouteOptimization Optimization
+ {
+ get
+ {
+ return (RouteOptimization)handle.Optimization;
+ }
+ set
+ {
+ Log.Info(string.Format("Optimization is changed from {0} to {1}", handle.Optimization, value));
+ handle.Optimization = (Interop.RouteOptimization)value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets route transport mode.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public TransportMode Mode
+ {
+ get
+ {
+ return (TransportMode)handle.TransportMode;
+ }
+ set
+ {
+ Log.Info(string.Format("TransportMode is changed from {0} to {1}", handle.TransportMode, value));
+ handle.TransportMode = (Interop.RouteTransportMode)value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets route feature weight.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public RouteFeatureWeight RouteFeatureWeight
+ {
+ get
+ {
+ return (RouteFeatureWeight)handle.FeatureWeight;
+ }
+ set
+ {
+ Log.Info(string.Format("RouteFeatureWeight is changed from {0} to {1}", handle.FeatureWeight, value));
+ handle.FeatureWeight = (Interop.RouteFeatureWeight)value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets route feature.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public RouteFeature RouteFeature
+ {
+ get
+ {
+ return (RouteFeature)handle.Feature;
+ }
+ set
+ {
+ Log.Info(string.Format("RouteFeature is changed from {0} to {1}", handle.Feature, value));
+ handle.Feature = (Interop.RouteRequestFeature)value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets if searching for alternative routes is enabled.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public bool SearchAlternativeRoutes
+ {
+ get
+ {
+ return handle.AlternativesEnabled;
+ }
+ set
+ {
+ Log.Info(string.Format("SearchAlternativeRoutes is {0}", (value ? "enabled" : "disabled")));
+ handle.AlternativesEnabled = value;
+ }
+ }
+
+ #region IDisposable Support
+ private bool _disposedValue = false;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ handle.Dispose();
+ _disposedValue = true;
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/ServiceData.cs b/src/Tizen.Maps/Tizen.Maps/ServiceData.cs
new file mode 100755
index 0000000..511a562
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/ServiceData.cs
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Features available in the Map Service
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum ServiceData
+ {
+ /// <summary>
+ /// Indicates availability of address value in the Place data.
+ /// </summary>
+ PlaceAddress = Interop.ServiceData.PlaceAddress,
+ /// <summary>
+ /// Indicates availability of rating value in the Place data.
+ /// </summary>
+ PlaceRating = Interop.ServiceData.PlaceRating,
+ /// <summary>
+ /// Indicates availability of place category list in the Place data.
+ /// </summary>
+ PlaceCategories = Interop.ServiceData.PlaceCategories,
+ /// <summary>
+ /// Indicates availability of place attribute list in the Place data.
+ /// </summary>
+ PlaceAttributes = Interop.ServiceData.PlaceAttributes,
+ /// <summary>
+ /// Indicates availability of place contact list in the Place data.
+ /// </summary>
+ PlaceContacts = Interop.ServiceData.PlaceContacts,
+ /// <summary>
+ /// Indicates availability of place editorial list in the Place data.
+ /// </summary>
+ PlaceEditorials = Interop.ServiceData.PlaceEditorials,
+ /// <summary>
+ /// Indicates availability of place review list in the Place data.
+ /// </summary>
+ PlaceReviews = Interop.ServiceData.PlaceReviews,
+ /// <summary>
+ /// Indicates availability of place image in Place the data.
+ /// </summary>
+ PlaceImage = Interop.ServiceData.PlaceImage,
+ /// <summary>
+ /// Indicates availability of place supplier link value in the Place data.
+ /// </summary>
+ PlaceSupplier = Interop.ServiceData.PlaceSupplier,
+ /// <summary>
+ /// Indicates availability of related place link in the Place data.
+ /// </summary>
+ PlaceRelated = Interop.ServiceData.PlaceRelated,
+
+ /// <summary>
+ /// Indicates that the Route Data Structure is defined as a Path (a list of geographical coordinates).
+ /// </summary>
+ RoutePath = Interop.ServiceData.RoutePath,
+ /// <summary>
+ /// Indicates that the Route Data Structure is defined as a list of Segments while each segment is defined as a Path.
+ /// </summary>
+ RouteSegmentsPath = Interop.ServiceData.RouteSegmentsPath,
+ /// <summary>
+ /// Indicates that the Route Data Structure is defined as a list of Segments while each segment is defined as a list of Maneuvers.
+ /// </summary>
+ RouteSegmentsManeuvers = Interop.ServiceData.RouteSegmentsManeuvers,
+
+ /// <summary>
+ /// Indicates availability of traffic information on the Map.
+ /// </summary>
+ ViewTraffic = Interop.ServiceData.ViewTraffic,
+ /// <summary>
+ /// Indicates availability of public transit information on the Map.
+ /// </summary>
+ ViewPublicTransit = Interop.ServiceData.ViewPublicTransit,
+ /// <summary>
+ /// Indicates availability of 3D building drawable on the Map.
+ /// </summary>
+ ViewBuilding = Interop.ServiceData.ViewBuilding,
+ /// <summary>
+ /// Indicates availability of scale bar on the Map.
+ /// </summary>
+ ViewScaleBar = Interop.ServiceData.ViewScaleBar,
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/ServiceRequestType.cs b/src/Tizen.Maps/Tizen.Maps/ServiceRequestType.cs
new file mode 100755
index 0000000..5855b52
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/ServiceRequestType.cs
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Service Requests available in the Maps Service
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum ServiceRequestType
+ {
+ /// <summary>
+ /// Indicates that service request to get position <see cref="Geocoordinates"/> for a given free-formed address string is allowed.
+ /// </summary>
+ Geocode = Interop.ServiceType.Geocode,
+ /// <summary>
+ /// Indicates that service request to get position <see cref="Geocoordinates"/> for a given address, within the specified bounding <see cref="Area"/>, is allowed.
+ /// </summary>
+ GeocodeInsideArea = Interop.ServiceType.GeocodeInsideArea,
+ /// <summary>
+ /// Indicates that service request to get position <see cref="Geocoordinates"/> for a given <see cref="PlaceAddress"/> is allowed.
+ /// </summary>
+ GeocodeByStructuredAddress = Interop.ServiceType.GeocodeByStructuredAddress,
+ /// <summary>
+ /// Indicates that service request to get <see cref="PlaceAddress"/> for a given <see cref="Geocoordinates"/> is allowed.
+ /// </summary>
+ ReverseGeocode = Interop.ServiceType.ReverseGeocode,
+ /// <summary>
+ /// Indicates that service request to get <see cref="PlaceAddress"/> for a given <see cref="GeocoordinatesList"/> is allowed.
+ /// </summary>
+ MultiReverseGeocode = Interop.ServiceType.MultiReverseGeocode,
+
+ /// <summary>
+ /// Indicates that service request to query <see cref="Place"/> information for a given <see cref="Geocoordinates"/> is allowed.
+ /// </summary>
+ SearchPlace = Interop.ServiceType.SearchPlace,
+ /// <summary>
+ /// Indicates that service request to query <see cref="Place"/> information for a given <see cref="Area"/> is allowed.
+ /// </summary>
+ SearchPlaceByArea = Interop.ServiceType.SearchPlaceByArea,
+ /// <summary>
+ /// Indicates that service request to query <see cref="Place"/> information for a given free-formed address string is allowed.
+ /// </summary>
+ SearchPlaceByAddress = Interop.ServiceType.SearchPlaceByAddress,
+ /// <summary>
+ /// Indicates that service request to query <see cref="Place"/> information list for all places in a given <see cref="Area"/> is allowed.
+ /// </summary>
+ SearchPlaceList = Interop.ServiceType.SearchPlaceList,
+ /// <summary>
+ /// Indicates that service request to get detailed <see cref="Place"/> information for a given <see cref="PlaceList"/> is allowed.
+ /// </summary>
+ SearchGetPlaceDetails = Interop.ServiceType.SearchGetPlaceDetails,
+
+ /// <summary>
+ /// Indicates that service request to query <see cref="Route"/> information from a given origin <see cref="Geocoordinates"/> and destination <see cref="Geocoordinates"/> is allowed.
+ /// </summary>
+ SearchRoute = Interop.ServiceType.SearchRoute,
+ /// <summary>
+ /// Indicates that service request to query <see cref="Route"/> information passing through specified way-points <see cref="GeocoordinatesList"/> is allowed.
+ /// </summary>
+ SearchRouteWithWaypoints = Interop.ServiceType.SearchRouteWaypoints,
+
+ /// <summary>
+ /// Indicates that map view service is allowed.
+ /// </summary>
+ View = Interop.ServiceType.View,
+ /// <summary>
+ /// Indicates that map view snapshot service is allowed.
+ /// </summary>
+ ViewSnapshot = Interop.ServiceType.ViewSnapshot,
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/SnapshotType.cs b/src/Tizen.Maps/Tizen.Maps/SnapshotType.cs
new file mode 100755
index 0000000..03c7952
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/SnapshotType.cs
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Enumeration for snapshot file formats
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum SnapshotType
+ {
+ /// <summary>
+ /// Indicates BMP file format.
+ /// </summary>
+ BMP = Interop.ViewSnapshotFormatType.ViewSnapshotBmp,
+ /// <summary>
+ /// Indicates JPEG file format.
+ /// </summary>
+ JPEG = Interop.ViewSnapshotFormatType.ViewSnapshotJpeg,
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/TransportMode.cs b/src/Tizen.Maps/Tizen.Maps/TransportMode.cs
new file mode 100755
index 0000000..762e31e
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/TransportMode.cs
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Route types
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum TransportMode
+ {
+ /// <summary>
+ /// Indicates that route is to be traveled by car.
+ /// </summary>
+ Car = Interop.RouteTransportMode.Car,
+ /// <summary>
+ /// Indicates that route is for a pedestrian.
+ /// </summary>
+ Pedestrian = Interop.RouteTransportMode.Pedestrian,
+ /// <summary>
+ /// Indicates that route is for a cyclist.
+ /// </summary>
+ Bicycle = Interop.RouteTransportMode.Bicycle,
+ /// <summary>
+ /// Indicates that route is to be traveled using public transport.
+ /// </summary>
+ PublicTransit = Interop.RouteTransportMode.PublicTransit,
+ /// <summary>
+ /// Indicates that route is for a truck.
+ /// </summary>
+ Truck = Interop.RouteTransportMode.Truck,
+ }
+}
diff --git a/src/Tizen.Maps/Tizen.Maps/TurnInstruction.cs b/src/Tizen.Maps/Tizen.Maps/TurnInstruction.cs
new file mode 100755
index 0000000..d01de95
--- /dev/null
+++ b/src/Tizen.Maps/Tizen.Maps/TurnInstruction.cs
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Maps
+{
+ /// <summary>
+ /// Turn Instruction type for route maneuver
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum TurnInstruction
+ {
+ /// <summary>
+ /// Indicates unknown instruction.
+ /// </summary>
+ None = Interop.RouteTurnType.None,
+ /// <summary>
+ /// Indicates instruction to move straight.
+ /// </summary>
+ Straight = Interop.RouteTurnType.Straight,
+ /// <summary>
+ /// Indicates instruction to bear right.
+ /// </summary>
+ BearRight = Interop.RouteTurnType.BearRight,
+ /// <summary>
+ /// Indicates instruction to turn slightly to the right.
+ /// </summary>
+ LightRight = Interop.RouteTurnType.LightRight,
+ /// <summary>
+ /// Indicates instruction to turn right.
+ /// </summary>
+ Right = Interop.RouteTurnType.Right,
+ /// <summary>
+ /// Indicates instruction to turn hard to the right.
+ /// </summary>
+ HardRight = Interop.RouteTurnType.HardRight,
+ /// <summary>
+ /// Indicates instruction to u-turn to the right.
+ /// </summary>
+ UturnRight = Interop.RouteTurnType.UturnRight,
+ /// <summary>
+ /// Indicates instruction to u-turn to the left.
+ /// </summary>
+ UturnLeft = Interop.RouteTurnType.UturnLeft,
+ /// <summary>
+ /// Indicates instruction to turn hard to the left.
+ /// </summary>
+ HardLeft = Interop.RouteTurnType.HardLeft,
+ /// <summary>
+ /// Indicates instruction to turn left.
+ /// </summary>
+ Left = Interop.RouteTurnType.Left,
+ /// <summary>
+ /// Indicates instruction to turn slightly to the left.
+ /// </summary>
+ LightLeft = Interop.RouteTurnType.LightLeft,
+ /// <summary>
+ /// Indicates instruction to bear left.
+ /// </summary>
+ BearLeft = Interop.RouteTurnType.BearLeft,
+ /// <summary>
+ /// Indicates instruction to take right fork.
+ /// </summary>
+ RightFork = Interop.RouteTurnType.RightFork,
+ /// <summary>
+ /// Indicates instruction to take left fork.
+ /// </summary>
+ LeftFork = Interop.RouteTurnType.LeftFork,
+ /// <summary>
+ /// Indicates instruction to take straight fork.
+ /// </summary>
+ StraightFork = Interop.RouteTurnType.StraightFork,
+ }
+}
diff --git a/src/Tizen.Maps/res/maps_marker_pin_48.png b/src/Tizen.Maps/res/maps_marker_pin_48.png
new file mode 100755
index 0000000..a07d693
--- /dev/null
+++ b/src/Tizen.Maps/res/maps_marker_pin_48.png
Binary files differ
diff --git a/src/Tizen.Maps/res/maps_marker_pin_72.png b/src/Tizen.Maps/res/maps_marker_pin_72.png
new file mode 100755
index 0000000..bc09c65
--- /dev/null
+++ b/src/Tizen.Maps/res/maps_marker_pin_72.png
Binary files differ
diff --git a/src/Tizen.Maps/res/maps_marker_sticker_48.png b/src/Tizen.Maps/res/maps_marker_sticker_48.png
new file mode 100755
index 0000000..93d3fb6
--- /dev/null
+++ b/src/Tizen.Maps/res/maps_marker_sticker_48.png
Binary files differ
diff --git a/src/Tizen.Maps/res/maps_marker_sticker_72.png b/src/Tizen.Maps/res/maps_marker_sticker_72.png
new file mode 100755
index 0000000..c2e2060
--- /dev/null
+++ b/src/Tizen.Maps/res/maps_marker_sticker_72.png
Binary files differ
diff --git a/src/Tizen.Messaging.Push/Interop/Interop.Glib.cs b/src/Tizen.Messaging.Push/Interop/Interop.Glib.cs
new file mode 100644
index 0000000..ace5ae2
--- /dev/null
+++ b/src/Tizen.Messaging.Push/Interop/Interop.Glib.cs
@@ -0,0 +1,30 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Glib
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool GSourceFunc(IntPtr userData);
+
+ [DllImport(Libraries.Glib, EntryPoint = "g_idle_add", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern uint IdleAdd(GSourceFunc d, IntPtr data);
+ }
+}
diff --git a/src/Tizen.Messaging.Push/Interop/Interop.Libc.cs b/src/Tizen.Messaging.Push/Interop/Interop.Libc.cs
new file mode 100644
index 0000000..109ec1c
--- /dev/null
+++ b/src/Tizen.Messaging.Push/Interop/Interop.Libc.cs
@@ -0,0 +1,27 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Libc
+ {
+ [DllImport(Libraries.Libc, EntryPoint = "free", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int Free(IntPtr ptr);
+ }
+}
diff --git a/src/Tizen.Messaging.Push/Interop/Interop.Libraries.cs b/src/Tizen.Messaging.Push/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..bde641a
--- /dev/null
+++ b/src/Tizen.Messaging.Push/Interop/Interop.Libraries.cs
@@ -0,0 +1,25 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string Push = "libpush.so.0";
+ public const string Glib = "libglib-2.0.so.0";
+ public const string Libc = "libc.so.6";
+ }
+}
diff --git a/src/Tizen.Messaging.Push/Interop/Interop.PushClient.cs b/src/Tizen.Messaging.Push/Interop/Interop.PushClient.cs
new file mode 100644
index 0000000..9149db7
--- /dev/null
+++ b/src/Tizen.Messaging.Push/Interop/Interop.PushClient.cs
@@ -0,0 +1,113 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class PushClient
+ {
+ internal static string LogTag = "Tizen.Messaging.Push";
+
+ internal enum Result
+ {
+ Success = 0,
+ Timeout = 1,
+ ServerError = 2,
+ SystemError = 3
+ };
+
+ internal enum ServiceError
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None,
+ OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+ NotConnected = Tizen.Internals.Errors.ErrorCode.EndpointNotConnected,
+ NoData = Tizen.Internals.Errors.ErrorCode.NoData,
+ OpearationFailed = Tizen.Internals.Errors.ErrorCode.Unknown,
+ PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied,
+ NotSupported = Tizen.Internals.Errors.ErrorCode.NotSupported
+ };
+
+ internal enum State
+ {
+ Registered,
+ Unregistered,
+ ProvisioningIPChange,
+ PingChange,
+ StateError
+ };
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void VoidStateChangedCallback(int state, string err, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void VoidNotifyCallback(IntPtr notification, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void VoidResultCallback(Result result, IntPtr msg, IntPtr userData);
+
+ [DllImport(Libraries.Push, EntryPoint = "push_service_connect", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern Interop.PushClient.ServiceError ServiceConnect(string pushAppID, VoidStateChangedCallback stateCallback, VoidNotifyCallback notifyCallback, IntPtr userData, out IntPtr connection);
+
+ [DllImport(Libraries.Push, EntryPoint = "push_service_disconnect", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void ServiceDisconnect(IntPtr connection);
+
+ [DllImport(Libraries.Push, EntryPoint = "push_service_register", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern Interop.PushClient.ServiceError ServiceRegister(IntPtr connection, VoidResultCallback callback, IntPtr UserData);
+
+ [DllImport(Libraries.Push, EntryPoint = "push_service_deregister", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern Interop.PushClient.ServiceError ServiceDeregister(IntPtr connection, VoidResultCallback callback, IntPtr UserData);
+
+ [DllImport(Libraries.Push, EntryPoint = "push_service_app_control_to_noti_data", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern string AppControlToNotiData(IntPtr appControl, string operation);
+
+ [DllImport(Libraries.Push, EntryPoint = "push_service_app_control_to_notification", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern Interop.PushClient.ServiceError AppControlToNotification(IntPtr appControl, string operation, out IntPtr noti);
+
+ [DllImport(Libraries.Push, EntryPoint = "push_service_get_notification_data", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern Interop.PushClient.ServiceError GetNotificationData(IntPtr notification, out string data);
+
+ [DllImport(Libraries.Push, EntryPoint = "push_service_get_notification_message", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern Interop.PushClient.ServiceError GetNotificationMessage(IntPtr notification, out string data);
+
+ [DllImport(Libraries.Push, EntryPoint = "push_service_get_notification_time", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern Interop.PushClient.ServiceError GetNotificationTime(IntPtr notification, out int receivedTime);
+
+ [DllImport(Libraries.Push, EntryPoint = "push_service_get_notification_sender", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern Interop.PushClient.ServiceError GetNotificationSender(IntPtr notification, out string sender);
+
+ [DllImport(Libraries.Push, EntryPoint = "push_service_get_notification_session_info", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern Interop.PushClient.ServiceError GetNotificationSessionInfo(IntPtr notification, out string sessionInfo);
+
+ [DllImport(Libraries.Push, EntryPoint = "push_service_get_notification_request_id", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern Interop.PushClient.ServiceError GetNotificationRequestId(IntPtr notification, out string requestID);
+
+ [DllImport(Libraries.Push, EntryPoint = "push_service_get_notification_type", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern Interop.PushClient.ServiceError GetNotificationType(IntPtr notification, out int type);
+
+ [DllImport(Libraries.Push, EntryPoint = "push_service_get_unread_notification", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern Interop.PushClient.ServiceError GetUnreadNotification(IntPtr connection, out IntPtr noti);
+
+ [DllImport(Libraries.Push, EntryPoint = "push_service_request_unread_notification", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern Interop.PushClient.ServiceError RequestUnreadNotification(IntPtr connection);
+
+ [DllImport(Libraries.Push, EntryPoint = "push_service_get_registration_id", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern Interop.PushClient.ServiceError GetRegistrationId(IntPtr connection, out string regID);
+
+ [DllImport(Libraries.Push, EntryPoint = "push_service_free_notification", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern Interop.PushClient.ServiceError FreeNotification(IntPtr connection);
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Messaging.Push/Tizen.Messaging.Push.csproj b/src/Tizen.Messaging.Push/Tizen.Messaging.Push.csproj
new file mode 100644
index 0000000..d5717a4
--- /dev/null
+++ b/src/Tizen.Messaging.Push/Tizen.Messaging.Push.csproj
@@ -0,0 +1,15 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
+
diff --git a/src/Tizen.Messaging.Push/Tizen.Messaging.Push/PushClient.cs b/src/Tizen.Messaging.Push/Tizen.Messaging.Push/PushClient.cs
new file mode 100644
index 0000000..af0dfcc
--- /dev/null
+++ b/src/Tizen.Messaging.Push/Tizen.Messaging.Push/PushClient.cs
@@ -0,0 +1,189 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Threading.Tasks;
+
+namespace Tizen.Messaging.Push
+{
+ /// <summary>
+ /// The PushClient API provides functions to connect to push service for receiving push messages.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// The PushClient API provides the way to connect with the push service.
+ /// It provides api's to connect/disconnect from the push service.
+ /// Api's are provided so that an application can register itself
+ /// with the push server along with api's to request push message.
+ /// </remarks>
+ /// <example>
+ /// <code>
+ /// public class Program
+ /// {
+ /// static void Main(string[] args)
+ /// {
+ /// PushClient.PushServiceConnect("xxxxx");
+ /// Task<ServerResponse> tr = PushClient.PushServerRegister();
+ /// tr.GetAwaiter().OnCompleted(() => {
+ /// ServerResponse res = tr.Result;
+ /// PushClient.GetUnreadNotifications();
+ /// Task<ServerResponse> tu = PushClient.PushServerUnregister();
+ /// tu.GetAwaiter().OnCompleted(() => {
+ /// PushClient.PushServiceDisconnect();
+ /// });
+ /// });
+ /// PushClient.NotificationReceived += EventHandlerNotificationReceived;
+ /// PushClient.StateChanged += EventHandlerStateChanged;
+ /// }
+ /// }
+ /// static void EventHandlerNotificationReceived(object sender, PushMessageEventArgs e)
+ /// {
+ /// // any user code
+ /// }
+ /// static void EventHandlerStateChanged(object sender, PushConnectionStateEventArgs e)
+ /// {
+ /// // any user code
+ /// }
+ /// </code>
+ /// </example>
+ public static class PushClient
+ {
+ /// <summary>
+ /// Event Handler for receiving the notifications.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static event EventHandler<PushMessageEventArgs> NotificationReceived
+ {
+ add
+ {
+ lock (_lock)
+ {
+ _notificationReceived += value;
+ }
+ }
+ remove
+ {
+ lock (_lock)
+ {
+ _notificationReceived -= value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Event Handler for receiving changes in States of the connection.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static event EventHandler<PushConnectionStateEventArgs> StateChanged
+ {
+ add
+ {
+ lock (_lock)
+ {
+ _stateChanged += value;
+ }
+ }
+ remove
+ {
+ lock (_lock)
+ {
+ _stateChanged -= value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// API to connect with the push service.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="pushAppId"> The Push Application Id Registered with the server.</param>
+ public static void PushServiceConnect(string pushAppId)
+ {
+ PushImpl.Instance.PushServiceConnect(pushAppId);
+ }
+
+ /// <summary>
+ /// API to disconnect from the push service.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static void PushServiceDisconnect()
+ {
+ PushImpl.Instance.PushServiceDisconnect();
+ //PushImpl.Reset();
+ }
+
+
+ /// <summary>
+ /// API to Register the application with the push server.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// The method returns a task which on completion with give a ServerResponse Object.
+ /// </returns>
+ public static Task<ServerResponse> PushServerRegister()
+ {
+ return PushImpl.Instance.PushServerRegister();
+ }
+
+ /// <summary>
+ /// API to Deregister the application from the push server.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// The method returns a task which on completion with give a ServerResponse Object.
+ /// </returns>
+ public static Task<ServerResponse> PushServerUnregister()
+ {
+ return PushImpl.Instance.PushServerUnregister();
+ }
+
+ /// <summary>
+ /// Gets the unread notifications for the application.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static void GetUnreadNotifications()
+ {
+ PushImpl.Instance.GetUnreadNotifications();
+ }
+
+ /// <summary>
+ /// registration Id received from server. </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// It is the string which is the Id received from the server.
+ /// </returns>
+ public static string GetRegistrationId()
+ {
+ return PushImpl.Instance.GetRegistrationId();
+ }
+
+ internal static void StateChange(PushConnectionStateEventArgs args)
+ {
+ if (_stateChanged != null)
+ _stateChanged(null, args);
+ }
+
+ internal static void Notify(PushMessageEventArgs args)
+ {
+ if (_notificationReceived != null)
+ _notificationReceived(null, args);
+ }
+
+ private static object _lock = new object();
+ private static event EventHandler<PushMessageEventArgs> _notificationReceived;
+ private static event EventHandler<PushConnectionStateEventArgs> _stateChanged;
+ }
+}
diff --git a/src/Tizen.Messaging.Push/Tizen.Messaging.Push/PushConnectionStateEventArgs.cs b/src/Tizen.Messaging.Push/Tizen.Messaging.Push/PushConnectionStateEventArgs.cs
new file mode 100644
index 0000000..dcf4965
--- /dev/null
+++ b/src/Tizen.Messaging.Push/Tizen.Messaging.Push/PushConnectionStateEventArgs.cs
@@ -0,0 +1,85 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Messaging.Push
+{
+ /// <summary>
+ /// An extended EventArgs class which contains the State Information.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class PushConnectionStateEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Enumeration for the different states.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum PushState
+ {
+ /// <summary>
+ /// Registered with the Server.
+ /// </summary>
+ Registered = 0,
+ /// <summary>
+ /// Unregistered.
+ /// </summary>
+ Unregistered = 1,
+ /// <summary>
+ /// To change the provisioning server IP.
+ /// </summary>
+ ProvisioningIPChanged = 2,
+ /// <summary>
+ /// Ping interval is changing.
+ /// </summary>
+ PingChanged = 3,
+ /// <summary>
+ /// Error Occured in Changing State.
+ /// </summary>
+ StateError = 4
+ }
+
+ /// <summary>
+ /// Gives the current state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// It is the current state.</value>
+ public PushState State
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// Gives information about the error if set.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// It is the string which contains the error string if set.</value>
+ public string Error
+ {
+ get;
+ internal set;
+ }
+
+ internal PushConnectionStateEventArgs(PushState state, string error)
+ {
+ State = state;
+ Error = error;
+ }
+ }
+}
diff --git a/src/Tizen.Messaging.Push/Tizen.Messaging.Push/PushExceptionFactory.cs b/src/Tizen.Messaging.Push/Tizen.Messaging.Push/PushExceptionFactory.cs
new file mode 100644
index 0000000..465e661
--- /dev/null
+++ b/src/Tizen.Messaging.Push/Tizen.Messaging.Push/PushExceptionFactory.cs
@@ -0,0 +1,83 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Tizen.Messaging.Push
+{
+ class PushExceptionFactory
+ {
+ internal static Exception CreateResponseException(Interop.PushClient.ServiceError result)
+ {
+ Exception exp;
+ switch (result)
+ {
+ case Interop.PushClient.ServiceError.OutOfMemory:
+ {
+ Tizen.Log.Error(Interop.PushClient.LogTag, "Interop.PushClient.ServiceError.OutOfMemory");
+ exp = new InvalidOperationException("Memory Not Sufficient for the current operation");
+ break;
+ }
+ case Interop.PushClient.ServiceError.InvalidParameter:
+ {
+ Tizen.Log.Error(Interop.PushClient.LogTag, "Interop.PushClient.ServiceError.InvalidParameter");
+ exp = new InvalidOperationException("The Parameter Passed was Invalid or Invalid Operation Intented");
+ break;
+ }
+ case Interop.PushClient.ServiceError.NotConnected:
+ {
+ Tizen.Log.Error(Interop.PushClient.LogTag, "Interop.PushClient.ServiceError.NotConnected");
+ exp = new InvalidOperationException("Not Connected to Server");
+ break;
+ }
+ case Interop.PushClient.ServiceError.NoData:
+ {
+ Tizen.Log.Error(Interop.PushClient.LogTag, "Interop.PushClient.ServiceError.NoData");
+ exp = new InvalidOperationException("No Data");
+ break;
+ }
+ case Interop.PushClient.ServiceError.OpearationFailed:
+ {
+ Tizen.Log.Error(Interop.PushClient.LogTag, "Interop.PushClient.ServiceError.OpearationFailed");
+ exp = new InvalidOperationException("Operation Failed");
+ break;
+ }
+ case Interop.PushClient.ServiceError.PermissionDenied:
+ {
+ Tizen.Log.Error(Interop.PushClient.LogTag, "Interop.PushClient.ServiceError.PermissionDenied");
+ exp = new InvalidOperationException("Permission Denied");
+ break;
+ }
+ case Interop.PushClient.ServiceError.NotSupported:
+ {
+ Tizen.Log.Error(Interop.PushClient.LogTag, "Interop.PushClient.ServiceError.NotSupported");
+ exp = new InvalidOperationException("Not Supported");
+ break;
+ }
+ default:
+ {
+ Tizen.Log.Error(Interop.PushClient.LogTag, "Creating Exception for Default case for error code " + result);
+ exp = new Exception();
+ break;
+ }
+ }
+ return exp;
+ }
+ }
+}
diff --git a/src/Tizen.Messaging.Push/Tizen.Messaging.Push/PushImpl.cs b/src/Tizen.Messaging.Push/Tizen.Messaging.Push/PushImpl.cs
new file mode 100644
index 0000000..2c49734
--- /dev/null
+++ b/src/Tizen.Messaging.Push/Tizen.Messaging.Push/PushImpl.cs
@@ -0,0 +1,243 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using System.Runtime.InteropServices;
+using Tizen;
+
+namespace Tizen.Messaging.Push
+{
+ internal class PushImpl
+ {
+ private static readonly object _lock = new object();
+ private static PushImpl _instance;
+
+ internal static PushImpl Instance
+ {
+ get
+ {
+ lock (_lock)
+ {
+ if (_instance == null)
+ {
+ Log.Info(Interop.PushClient.LogTag, "Creating New Instance");
+ _instance = new PushImpl();
+ }
+ }
+ return _instance;
+ }
+ }
+
+ internal PushImpl()
+ {
+ //Empty
+ }
+
+ private IntPtr _connection;
+
+ internal void PushServiceConnect(string pushAppId)
+ {
+ Interop.PushClient.VoidStateChangedCallback stateDelegate = (int state, string err, IntPtr userData) =>
+ {
+ if (err == null)
+ {
+ err = "";
+ }
+ PushConnectionStateEventArgs args = new PushConnectionStateEventArgs((PushConnectionStateEventArgs.PushState)state, err);
+ PushClient.StateChange(args);
+ };
+ Interop.PushClient.VoidNotifyCallback notifyDelegate = (IntPtr notification, IntPtr userData) =>
+ {
+ Interop.PushClient.ServiceError result;
+ PushMessageEventArgs ob = new PushMessageEventArgs();
+ string data;
+ result = Interop.PushClient.GetNotificationData(notification, out data);
+ if ((result == Interop.PushClient.ServiceError.None) && !(String.IsNullOrEmpty(data)))
+ {
+ ob.AppData = data;
+ }
+ else
+ {
+ ob.AppData = "";
+ }
+ string message;
+ result = Interop.PushClient.GetNotificationMessage(notification, out message);
+ if ((result == Interop.PushClient.ServiceError.None) && !(String.IsNullOrEmpty(message)))
+ {
+ ob.Message = message;
+ }
+ else
+ {
+ ob.Message = "";
+ }
+ string sender;
+ result = Interop.PushClient.GetNotificationSender(notification, out sender);
+ if ((result == Interop.PushClient.ServiceError.None) && !(String.IsNullOrEmpty(sender)))
+ {
+ ob.Sender = sender;
+ }
+ else
+ {
+ ob.Sender = "";
+ }
+ string sessioninfo;
+ result = Interop.PushClient.GetNotificationSessionInfo(notification, out sessioninfo);
+ if ((result == Interop.PushClient.ServiceError.None) && !(String.IsNullOrEmpty(sessioninfo)))
+ {
+ ob.SessionInfo = sessioninfo;
+ }
+ else
+ {
+ ob.SessionInfo = "";
+ }
+ string requestid;
+ result = Interop.PushClient.GetNotificationRequestId(notification, out requestid);
+ if ((result == Interop.PushClient.ServiceError.None) && !(String.IsNullOrEmpty(requestid)))
+ {
+ ob.RequestId = requestid;
+ }
+ else
+ {
+ ob.RequestId = "";
+ }
+ int time;
+ result = Interop.PushClient.GetNotificationTime(notification, out time);
+ DateTime utc;
+ if ((result == Interop.PushClient.ServiceError.None) && (time != 0))
+ {
+ Log.Info(Interop.PushClient.LogTag, "Ticks received: " + time);
+ utc = DateTime.SpecifyKind(new DateTime(1970, 1, 1).AddSeconds(time), DateTimeKind.Utc);
+ ob.ReceivedAt = utc.ToLocalTime();
+ }
+ else
+ {
+ Log.Info(Interop.PushClient.LogTag, "No Date received");
+ ob.ReceivedAt = DateTime.Now;
+ }
+ int type = -1;
+ result = Interop.PushClient.GetNotificationType(notification, out type);
+ if (result == Interop.PushClient.ServiceError.None)
+ {
+ ob.Type = type;
+ }
+ PushClient.Notify(ob);
+ //Interop.PushClient.FreeNotification(notification);
+ Log.Info(Interop.PushClient.LogTag, "Free Notification Done");
+ };
+ Interop.PushClient.ServiceError connectResult = Interop.PushClient.ServiceConnect(pushAppId, stateDelegate, notifyDelegate, IntPtr.Zero, out _connection);
+ if (connectResult != Interop.PushClient.ServiceError.None)
+ {
+ Log.Error(Interop.PushClient.LogTag, "Connect failed with " + connectResult);
+ throw PushExceptionFactory.CreateResponseException(connectResult);
+ }
+ }
+
+ internal void PushServiceDisconnect()
+ {
+ Interop.PushClient.ServiceDisconnect(_connection);
+ Log.Info(Interop.PushClient.LogTag, "PushServiceDisconnect Completed");
+ }
+
+ internal async Task<ServerResponse> PushServerRegister()
+ {
+ Log.Info(Interop.PushClient.LogTag, "Register Called");
+ var task = new TaskCompletionSource<ServerResponse>();
+ Interop.PushClient.VoidResultCallback registerResult = (Interop.PushClient.Result regResult, IntPtr msgPtr, IntPtr userData) =>
+ {
+ Log.Info(Interop.PushClient.LogTag, "Register Callback Called");
+ string msg = "";
+ if (msgPtr != IntPtr.Zero)
+ {
+ msg = Marshal.PtrToStringAnsi(msgPtr);
+ }
+ ServerResponse response = new ServerResponse();
+ response.ServerResult = (ServerResponse.Result)regResult;
+ response.ServerMessage = msg;
+ if (task.TrySetResult(response) == false)
+ {
+ Log.Error(Interop.PushClient.LogTag, "Unable to set the Result for register");
+ }
+ };
+ Interop.PushClient.ServiceError result = Interop.PushClient.ServiceRegister(_connection, registerResult, IntPtr.Zero);
+ Log.Info(Interop.PushClient.LogTag, "Interop.PushClient.ServiceRegister Completed");
+ if (result != Interop.PushClient.ServiceError.None)
+ {
+ Log.Error(Interop.PushClient.LogTag, "Register failed with " + result);
+ task.SetException(PushExceptionFactory.CreateResponseException(result));
+ }
+ return await task.Task;
+ }
+
+ internal async Task<ServerResponse> PushServerUnregister()
+ {
+ var task = new TaskCompletionSource<ServerResponse>();
+ Interop.PushClient.VoidResultCallback registerResult = (Interop.PushClient.Result regResult, IntPtr msgPtr, IntPtr userData) =>
+ {
+ Log.Info(Interop.PushClient.LogTag, "Unregister Callback Called");
+ string msg = "";
+ if (msgPtr != IntPtr.Zero)
+ {
+ msg = Marshal.PtrToStringAnsi(msgPtr);
+ }
+ ServerResponse response = new ServerResponse();
+ response.ServerResult = (ServerResponse.Result)regResult;
+ response.ServerMessage = msg;
+ if (task.TrySetResult(response) == false)
+ {
+ Log.Error(Interop.PushClient.LogTag, "Unable to set the Result for Unregister");
+ }
+ };
+ Interop.PushClient.ServiceError result = Interop.PushClient.ServiceDeregister(_connection, registerResult, IntPtr.Zero);
+ if (result != Interop.PushClient.ServiceError.None)
+ {
+ task.SetException(PushExceptionFactory.CreateResponseException(result));
+ }
+ return await task.Task;
+ }
+
+ internal string GetRegistrationId()
+ {
+ string regID = "";
+ Interop.PushClient.ServiceError result = Interop.PushClient.GetRegistrationId(_connection, out regID);
+ if (result != Interop.PushClient.ServiceError.None)
+ {
+ throw PushExceptionFactory.CreateResponseException(result);
+ }
+ Log.Info(Interop.PushClient.LogTag, "Returning Reg Id: " + regID);
+ return regID;
+ }
+
+ internal void GetUnreadNotifications()
+ {
+ Interop.PushClient.ServiceError result = Interop.PushClient.RequestUnreadNotification(_connection);
+ if (result != Interop.PushClient.ServiceError.None)
+ {
+ throw PushExceptionFactory.CreateResponseException(result);
+ }
+ }
+
+ internal static void Reset()
+ {
+ lock (_lock)
+ {
+ Log.Info(Interop.PushClient.LogTag, "Making _instance as null");
+ _instance = null;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Messaging.Push/Tizen.Messaging.Push/PushMessageEventArgs.cs b/src/Tizen.Messaging.Push/Tizen.Messaging.Push/PushMessageEventArgs.cs
new file mode 100644
index 0000000..1cb283e
--- /dev/null
+++ b/src/Tizen.Messaging.Push/Tizen.Messaging.Push/PushMessageEventArgs.cs
@@ -0,0 +1,121 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Messaging.Push
+{
+ /// <summary>
+ /// An extended EventArgs class which contains the message received.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class PushMessageEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Gives the Application Data recieved. </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// It is the string which stores the application data.</value>
+ public string AppData
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// Gives the Message Received Field.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// It is the string which stores the message field.</value>
+ public string Message
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// Gives the time at which the Notification was received.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// It is the DateTime field representing the time at which the Notification was received.</value>
+ public DateTime ReceivedAt
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// Gives the Sender of the notification.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// It is a string value representing the Sender of the Notification.</value>
+ public string Sender
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// Gives the session ID of the notification.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// It is a string value representing the session ID of the Notification.</value>
+ public string SessionInfo
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// Gives the request Id of the notification.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// It is a string value representing the request Id of the Notification.</value>
+ public string RequestId
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// Gives the value in the type field of the notification.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// It is an integer value representing the type field of the notification.</value>
+ public int Type
+ {
+ get;
+ internal set;
+ }
+
+ internal PushMessageEventArgs()
+ {
+ // Giving Default Values
+ AppData = "";
+ Message = "";
+ ReceivedAt = new DateTime();
+ Sender = "";
+ SessionInfo= "";
+ RequestId = "";
+ }
+ }
+}
diff --git a/src/Tizen.Messaging.Push/Tizen.Messaging.Push/ServerResponse.cs b/src/Tizen.Messaging.Push/Tizen.Messaging.Push/ServerResponse.cs
new file mode 100644
index 0000000..e0d895b
--- /dev/null
+++ b/src/Tizen.Messaging.Push/Tizen.Messaging.Push/ServerResponse.cs
@@ -0,0 +1,73 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Messaging.Push
+{
+ /// <summary>
+ /// The ServerResponse structure provides the result and the server response if any.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public struct ServerResponse
+ {
+ /// <summary>
+ /// Enumeration for the Result from the server.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum Result
+ {
+ /// <summary>
+ /// Successful.
+ /// </summary>
+ Success = 0,
+ /// <summary>
+ /// Time Out Occured.
+ /// </summary>
+ Timeout = 1,
+ /// <summary>
+ /// Server Error Occured.
+ /// </summary>
+ ServerError = 2,
+ /// <summary>
+ /// System Error Occured.
+ /// </summary>
+ SystemError = 3
+ }
+
+ /// <summary>
+ /// Gives the Result of the opeartion.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// It is the Result state of the operation performed.</value>
+ public Result ServerResult
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// Gives the Message from the server.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// It is the Message sent by the server.</value>
+ public string ServerMessage
+ {
+ get;
+ internal set;
+ }
+ }
+}
diff --git a/src/Tizen.Messaging/Interop/Interop.Email.cs b/src/Tizen.Messaging/Interop/Interop.Email.cs
new file mode 100755
index 0000000..28601a9
--- /dev/null
+++ b/src/Tizen.Messaging/Interop/Interop.Email.cs
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal enum EmailRecipientType
+ {
+ To = 1,
+ Cc = 2,
+ Bcc = 3
+ }
+
+ internal static partial class Email
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void EmailSentCallback(IntPtr handle, int result, IntPtr userData);
+
+ [DllImport(Libraries.Email, EntryPoint = "email_create_message")]
+ internal static extern int CreateEmail(out IntPtr EmailHandle);
+
+ [DllImport(Libraries.Email, EntryPoint = "email_destroy_message")]
+ internal static extern int DestroyEmail(IntPtr EmailHandle);
+
+ [DllImport(Libraries.Email, EntryPoint = "email_set_subject")]
+ internal static extern int SetSubject(IntPtr EmailHandle, string text);
+
+ [DllImport(Libraries.Email, EntryPoint = "email_set_body")]
+ internal static extern int SetBody(IntPtr EmailHandle, string text);
+
+ [DllImport(Libraries.Email, EntryPoint = "email_add_recipient")]
+ internal static extern int AddRecipient(IntPtr EmailHandle, int type, string text);
+
+ [DllImport(Libraries.Email, EntryPoint = "email_remove_all_recipients")]
+ internal static extern int RemoveRecipient(IntPtr EmailHandle);
+
+ [DllImport(Libraries.Email, EntryPoint = "email_add_attach")]
+ internal static extern int AddAttachment(IntPtr EmailHandle, string text);
+
+ [DllImport(Libraries.Email, EntryPoint = "email_remove_all_attachments")]
+ internal static extern int RemoveAttachments(IntPtr EmailHandle);
+
+ [DllImport(Libraries.Email, EntryPoint = "email_save_message")]
+ internal static extern int SaveEmail(IntPtr EmailHandle);
+
+ [DllImport(Libraries.Email, EntryPoint = "email_send_message")]
+ internal static extern int SendEmail(IntPtr EmailHandle, bool SaveToSentBox);
+
+ [DllImport(Libraries.Email, EntryPoint = "email_set_message_sent_cb")]
+ internal static extern int SetCb(IntPtr EmailHandle, EmailSentCallback Cb, IntPtr UserData);
+
+ [DllImport(Libraries.Email, EntryPoint = "email_unset_message_sent_cb")]
+ internal static extern int UnsetCb(IntPtr EmailHandle);
+ }
+}
diff --git a/src/Tizen.Messaging/Interop/Interop.Libraries.cs b/src/Tizen.Messaging/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..64170be
--- /dev/null
+++ b/src/Tizen.Messaging/Interop/Interop.Libraries.cs
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string Messages = "libcapi-messaging-messages.so.0";
+ public const string Email = "libcapi-messaging-email.so.0";
+ }
+}
diff --git a/src/Tizen.Messaging/Interop/Interop.Messages.cs b/src/Tizen.Messaging/Interop/Interop.Messages.cs
new file mode 100755
index 0000000..7697262
--- /dev/null
+++ b/src/Tizen.Messaging/Interop/Interop.Messages.cs
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Messages
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MessageIncomingCallback(IntPtr messageHandle, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MessageSentCallback(int result, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool MessageSearchCallback(IntPtr messageHandle, int index, int resultCount, int totalCount, IntPtr userData);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_open_service")]
+ internal static extern int OpenService(out IntPtr serviceHandle);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_close_service")]
+ internal static extern int CloseService(IntPtr serviceHandle);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_create_message")]
+ internal static extern int CreateMessage(int type, out IntPtr messageHandle);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_destroy_message")]
+ internal static extern int DestroyMessage(IntPtr messageHandle);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_get_message_id")]
+ internal static extern int GetMessageId(IntPtr messageHandle, out int messageId);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_set_sim_id")]
+ internal static extern int SetSimId(IntPtr messageHandle, int simId);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_get_sim_id")]
+ internal static extern int GetSimId(IntPtr messageHandle, out int simId);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_set_mbox_type")]
+ internal static extern int SetMboxType(IntPtr messageHandle, int mboxType);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_get_mbox_type")]
+ internal static extern int GetMboxType(IntPtr messageHandle, out int mboxType);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_get_message_port")]
+ internal static extern int GetMessagePort(IntPtr messageHandle, out int messagePort);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_get_message_type")]
+ internal static extern int GetMessageType(IntPtr messageHandle, out int messageType);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_set_text")]
+ internal static extern int SetText(IntPtr messageHandle, string text);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_get_text")]
+ internal static extern int GetText(IntPtr messageHandle, out string text);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_set_time")]
+ internal static extern int SetTime(IntPtr messageHandle, int time);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_get_time")]
+ internal static extern int GetTime(IntPtr messageHandle, out int time);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_mms_set_subject")]
+ internal static extern int SetSubject(IntPtr messageHandle, string subject);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_mms_get_subject")]
+ internal static extern int GetSubject(IntPtr messageHandle, out string subject);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_add_address")]
+ internal static extern int AddAddress(IntPtr messageHandle, string address, int type);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_get_address_count")]
+ internal static extern int GetAddressCount(IntPtr messageHandle, out int count);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_get_address")]
+ internal static extern int GetAddress(IntPtr messageHandle, int index, out string address, out int type);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_remove_all_addresses")]
+ internal static extern int RemoveAllAddress(IntPtr messageHandle);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_mms_add_attachment")]
+ internal static extern int AddAttachment(IntPtr messageHandle, int type, string path);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_mms_get_attachment_count")]
+ internal static extern int GetAttachmentCount(IntPtr messageHandle, out int count);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_mms_get_attachment")]
+ internal static extern int GetAttachment(IntPtr messageHandle, int index, out int type, out string path);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_mms_remove_all_attachments")]
+ internal static extern int RemoveAllAttachment(IntPtr messageHandle);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_set_message_incoming_cb")]
+ internal static extern int SetMessageIncomingCb(IntPtr serviceHandle, MessageIncomingCallback cb, IntPtr userData);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_unset_message_incoming_cb")]
+ internal static extern int UnsetMessageIncomingCb(IntPtr serviceHandle);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_send_message")]
+ internal static extern int SendMessage(IntPtr serviceHandle, IntPtr messageHandle, bool saveToSentbox, MessageSentCallback cb, IntPtr userData);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_search_message_by_id")]
+ internal static extern int GetMessageById(IntPtr serviceHandle, int msgId, out IntPtr messageHandle);
+
+ [DllImport(Libraries.Messages, EntryPoint = "messages_foreach_message")]
+ internal static extern int SearchMessage(IntPtr serviceHandle, int mbox, int messageType, string textKeyword, string addressKeyword, int offset, int limit, MessageSearchCallback cb, IntPtr userData);
+
+ }
+}
diff --git a/src/Tizen.Messaging/Tizen.Messaging.Email/EmailAttachment.cs b/src/Tizen.Messaging/Tizen.Messaging.Email/EmailAttachment.cs
new file mode 100644
index 0000000..5f8028a
--- /dev/null
+++ b/src/Tizen.Messaging/Tizen.Messaging.Email/EmailAttachment.cs
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Messaging.Email
+{
+ /// <summary>
+ /// Represents an email attachment
+ /// </summary>
+ public class EmailAttachment
+ {
+ /// <summary>
+ /// The absolute full path of the file to be attached
+ /// </summary>
+ public string FilePath { get; set; }
+ /// <summary>
+ /// The constructor
+ /// </summary>
+ public EmailAttachment()
+ {
+
+ }
+ }
+}
diff --git a/src/Tizen.Messaging/Tizen.Messaging.Email/EmailEnumerations.cs b/src/Tizen.Messaging/Tizen.Messaging.Email/EmailEnumerations.cs
new file mode 100755
index 0000000..fdeaa37
--- /dev/null
+++ b/src/Tizen.Messaging/Tizen.Messaging.Email/EmailEnumerations.cs
@@ -0,0 +1,34 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+namespace Tizen.Messaging.Email
+{
+ /// <summary>
+ /// Result of sending the email
+ /// </summary>
+ public enum EmailSendResult
+ {
+ /// <summary>
+ /// Failed to send the message
+ /// </summary>
+ Failure = -1,
+
+ /// <summary>
+ /// email sent successfully
+ /// </summary>
+ Success = 0
+ }
+}
diff --git a/src/Tizen.Messaging/Tizen.Messaging.Email/EmailErrorFactory.cs b/src/Tizen.Messaging/Tizen.Messaging.Email/EmailErrorFactory.cs
new file mode 100755
index 0000000..90dbe54
--- /dev/null
+++ b/src/Tizen.Messaging/Tizen.Messaging.Email/EmailErrorFactory.cs
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.IO;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Messaging.Email
+{
+ internal enum EmailError
+ {
+ None = ErrorCode.None,
+ OutOfMemory = ErrorCode.OutOfMemory,
+ InvalidParameter = ErrorCode.InvalidParameter,
+ ServerNotReady = -0x01710000 | 0x501,
+ CommunicationWithServerFailed = -0x01710000 | 0x502,
+ OutOfRange = -0x01710000 | 0x503,
+ SendingFailed = -0x01710000 | 0x504,
+ OperationFailed = -0x01710000 | 0x505,
+ NoSimCard = -0x01710000 | 0x506,
+ NoData = -0x01710000 | 0x507,
+ PermissionDenied = ErrorCode.PermissionDenied,
+ NotSupported = ErrorCode.NotSupported
+ }
+
+ internal static class EmailErrorFactory
+ {
+ internal const string LogTag = "Tizen.Messaging.Email";
+
+ internal static Exception GetException(int err)
+ {
+ EmailError error = (EmailError)err;
+ if (error == EmailError.OutOfMemory)
+ {
+ return new OutOfMemoryException("Out of memory");
+ }
+ else if (error == EmailError.InvalidParameter)
+ {
+ return new ArgumentException("Invalid parameter");
+ }
+ else if (error == EmailError.ServerNotReady)
+ {
+ return new IOException("Server not ready yet"); ;
+ }
+ else if (error == EmailError.NoData)
+ {
+ return new InvalidDataException("No data found");
+ }
+ else if (error == EmailError.CommunicationWithServerFailed)
+ {
+ return new TimeoutException("timed out");
+ }
+ else if (error == EmailError.PermissionDenied)
+ {
+ return new UnauthorizedAccessException("Permission denied");
+ }
+ else if (error == EmailError.NotSupported)
+ {
+ return new NotSupportedException("Not supported");
+ }
+ else if (error == EmailError.OutOfRange)
+ {
+ return new IndexOutOfRangeException("Out of range");
+ }
+ else if (error == EmailError.SendingFailed)
+ {
+ return new Exception("Sending failed");
+ }
+ else if (error == EmailError.OperationFailed)
+ {
+ return new InvalidOperationException("operation failed");
+ }
+ else if (error == EmailError.NoSimCard)
+ {
+ return new Exception("No sim card found");
+ }
+ else
+ {
+ return new Exception("System operation");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Messaging/Tizen.Messaging.Email/EmailMessage.cs b/src/Tizen.Messaging/Tizen.Messaging.Email/EmailMessage.cs
new file mode 100644
index 0000000..f7756c9
--- /dev/null
+++ b/src/Tizen.Messaging/Tizen.Messaging.Email/EmailMessage.cs
@@ -0,0 +1,229 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+
+namespace Tizen.Messaging.Email
+{
+ /// <summary>
+ /// The class contains Messaging API to support sending email messages.
+ /// </summary>
+ public class EmailMessage : IDisposable
+ {
+ internal IntPtr _emailHandle = IntPtr.Zero;
+ private bool _disposed = false;
+ private String _subject;
+ private String _body;
+ private IList<EmailAttachment> _attachments = new List<EmailAttachment>();
+ private ICollection<EmailRecipient> _to = new Collection<EmailRecipient>();
+ private ICollection<EmailRecipient> _cc = new Collection<EmailRecipient>();
+ private ICollection<EmailRecipient> _bcc = new Collection<EmailRecipient>();
+
+ /// <summary>
+ /// The constructor
+ /// </summary>
+ public EmailMessage()
+ {
+ int ret = Interop.Email.CreateEmail(out _emailHandle);
+ if (ret != (int)EmailError.None)
+ {
+ Log.Error(EmailErrorFactory.LogTag, "Failed to create message handle, Error code: " + (EmailError)ret);
+ throw EmailErrorFactory.GetException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Subject of the email message
+ /// </summary>
+ public string Subject
+ {
+ set
+ {
+ _subject = value;
+ int ret = Interop.Email.SetSubject(_emailHandle, _subject);
+ if (ret != (int)EmailError.None)
+ {
+ Log.Error(EmailErrorFactory.LogTag, "Failed to set subject, Error code: " + (EmailError)ret);
+ throw EmailErrorFactory.GetException(ret);
+ }
+ }
+ get
+ {
+ return _subject;
+ }
+
+ }
+
+ /// <summary>
+ /// Body of the email message
+ /// </summary>
+ public string Body
+ {
+ set
+ {
+ _body = value;
+ int ret = Interop.Email.SetBody(_emailHandle, _body);
+ if (ret != (int)EmailError.None)
+ {
+ Log.Error(EmailErrorFactory.LogTag, "Failed to set body, Error code: " + (EmailError)ret);
+ throw EmailErrorFactory.GetException(ret);
+ }
+ }
+ get
+ {
+ return _body;
+ }
+ }
+
+ /// <summary>
+ /// List of file attachments
+ /// </summary>
+ public IList<EmailAttachment> Attachments
+ {
+ get
+ {
+ return _attachments;
+ }
+ }
+
+ /// <summary>
+ /// Collection of normal email recipients
+ /// </summary>
+ /// <remarks>
+ /// Email address should be in standard format (as described in Internet standards RFC 5321 and RFC 5322).
+ /// </remarks>
+ public ICollection<EmailRecipient> To
+ {
+ get
+ {
+ return _to;
+ }
+ }
+
+ /// <summary>
+ /// Collection of CC(carbon copy) email recipients
+ /// </summary>
+ /// <remarks>
+ /// Email address should be in standard format (as described in Internet standards RFC 5321 and RFC 5322).
+ /// </remarks>
+ public ICollection<EmailRecipient> Cc
+ {
+ get
+ {
+ return _cc;
+ }
+ }
+
+ /// <summary>
+ /// Collection of BCC(blind carbon copy) email recipients
+ /// </summary>
+ /// <remarks>
+ /// Email address should be in standard format (as described in Internet standards RFC 5321 and RFC 5322).
+ /// </remarks>
+ public ICollection<EmailRecipient> Bcc
+ {
+ get
+ {
+ return _bcc;
+ }
+ }
+
+
+ internal void Save()
+ {
+ int ret;
+ FillHandle();
+
+ ret = Interop.Email.SaveEmail(_emailHandle);
+ if (ret != (int)EmailError.None)
+ {
+ Log.Error(EmailErrorFactory.LogTag, "Failed to save email, Error code: " + (EmailError)ret);
+ throw EmailErrorFactory.GetException(ret);
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_disposed)
+ return;
+
+ if (disposing)
+ {
+
+ }
+
+ if (_emailHandle != IntPtr.Zero)
+ {
+ Interop.Email.DestroyEmail(_emailHandle);
+ _emailHandle = IntPtr.Zero;
+ }
+ _disposed = true;
+ }
+
+ internal void FillHandle()
+ {
+ int ret = (int)EmailError.None;
+ foreach (EmailAttachment it in Attachments)
+ {
+ Console.WriteLine(it.FilePath);
+ ret = Interop.Email.AddAttachment(_emailHandle, it.FilePath);
+ if (ret != (int)EmailError.None)
+ {
+ Log.Error(EmailErrorFactory.LogTag, "Failed to add attachment, Error code: " + (EmailError)ret);
+ throw EmailErrorFactory.GetException(ret);
+ }
+ }
+
+ foreach (EmailRecipient it in To)
+ {
+ ret = Interop.Email.AddRecipient(_emailHandle, (int)Interop.EmailRecipientType.To, it.Address);
+ if (ret != (int)EmailError.None)
+ {
+ Log.Error(EmailErrorFactory.LogTag, "Failed to add recipients, Error code: " + (EmailError)ret);
+ throw EmailErrorFactory.GetException(ret);
+ }
+ }
+
+ foreach (EmailRecipient it in Cc)
+ {
+ ret = Interop.Email.AddRecipient(_emailHandle, (int)Interop.EmailRecipientType.Cc, it.Address);
+ if (ret != (int)EmailError.None)
+ {
+ Log.Error(EmailErrorFactory.LogTag, "Failed to add recipients, Error code: " + (EmailError)ret);
+ throw EmailErrorFactory.GetException(ret);
+ }
+ }
+
+ foreach (EmailRecipient it in Bcc)
+ {
+ ret = Interop.Email.AddRecipient(_emailHandle, (int)Interop.EmailRecipientType.Bcc, it.Address);
+ if (ret != (int)EmailError.None)
+ {
+ Log.Error(EmailErrorFactory.LogTag, "Failed to add recipients, Error code: " + (EmailError)ret);
+ throw EmailErrorFactory.GetException(ret);
+ }
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Messaging/Tizen.Messaging.Email/EmailRecipient.cs b/src/Tizen.Messaging/Tizen.Messaging.Email/EmailRecipient.cs
new file mode 100644
index 0000000..3c1fc24
--- /dev/null
+++ b/src/Tizen.Messaging/Tizen.Messaging.Email/EmailRecipient.cs
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Messaging.Email
+{
+ /// <summary>
+ /// The class represents recipients of an email
+ /// </summary>
+ public class EmailRecipient
+ {
+ /// <summary>
+ /// The email address of the recipient
+ /// </summary>
+ public string Address { get; set; }
+ /// <summary>
+ /// The constructor
+ /// </summary>
+ public EmailRecipient()
+ {
+
+ }
+ }
+}
diff --git a/src/Tizen.Messaging/Tizen.Messaging.Email/EmailSender.cs b/src/Tizen.Messaging/Tizen.Messaging.Email/EmailSender.cs
new file mode 100644
index 0000000..57220ed
--- /dev/null
+++ b/src/Tizen.Messaging/Tizen.Messaging.Email/EmailSender.cs
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Threading.Tasks;
+
+namespace Tizen.Messaging.Email
+{
+ /// <summary>
+ /// The class to send email messages.
+ /// </summary>
+ public static class EmailSender
+ {
+ /// <summary>
+ /// Sends the email message.
+ /// </summary>
+ /// <param name="email">The email message</param>
+ /// <returns> Failure if email sending failed otherwise Success</returns>
+ public static async Task<EmailSendResult> SendAsync(EmailMessage email)
+ {
+ var task = new TaskCompletionSource<EmailSendResult>();
+ int ret = (int)EmailError.None;
+ bool saveToSentBox = false;
+
+ email.FillHandle();
+ email.Save();
+
+ Interop.Email.EmailSentCallback _emailSendingCallback = (IntPtr handle, int result, IntPtr userData) =>
+ {
+ task.SetResult((EmailSendResult)result);
+ };
+
+ ret = Interop.Email.SetCb(email._emailHandle, _emailSendingCallback, IntPtr.Zero);
+ if (ret != (int)EmailError.None)
+ {
+ Log.Error(EmailErrorFactory.LogTag, "Failed to set email incoming callback, Error code: " + (EmailError)ret);
+ throw EmailErrorFactory.GetException(ret);
+ }
+
+ ret = Interop.Email.SendEmail(email._emailHandle, saveToSentBox);
+ if (ret != (int)EmailError.None)
+ {
+ Log.Error(EmailErrorFactory.LogTag, "Failed to send email, Error code: " + (EmailError)ret);
+ throw EmailErrorFactory.GetException(ret);
+ }
+
+ var sendResult = await task.Task;
+
+ ret = Interop.Email.UnsetCb(email._emailHandle);
+ if (ret != (int)EmailError.None)
+ {
+ Log.Error(EmailErrorFactory.LogTag, "Failed to set email incoming callback, Error code: " + (EmailError)ret);
+ throw EmailErrorFactory.GetException(ret);
+ }
+
+ return sendResult;
+ }
+ }
+}
diff --git a/src/Tizen.Messaging/Tizen.Messaging.Email/NamespaceDoc.cs b/src/Tizen.Messaging/Tizen.Messaging.Email/NamespaceDoc.cs
new file mode 100755
index 0000000..1c51cb5
--- /dev/null
+++ b/src/Tizen.Messaging/Tizen.Messaging.Email/NamespaceDoc.cs
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/// <summary>
+/// The <b>Tizen.Messaging.Email</b> namespace contains classes providing functionality to send emails.
+/// </summary>
+/// <remarks>
+/// The <b>Tizen.Messaging.Email</b> namespace contains classes providing functionality to send emails.
+/// </remarks>
+namespace Tizen.Messaging.Email
+{
+}
diff --git a/src/Tizen.Messaging/Tizen.Messaging.Messages/CBMessage.cs b/src/Tizen.Messaging/Tizen.Messaging.Messages/CBMessage.cs
new file mode 100755
index 0000000..949a1c8
--- /dev/null
+++ b/src/Tizen.Messaging/Tizen.Messaging.Messages/CBMessage.cs
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Messaging.Messages
+{
+ /// <summary>
+ /// A class to represent cell broadcast messages.
+ /// </summary>
+ public class CBMessage : Message
+ {
+ internal CBMessage(IntPtr messageHandle) : base(messageHandle)
+ {
+ }
+ }
+}
diff --git a/src/Tizen.Messaging/Tizen.Messaging.Messages/Message.cs b/src/Tizen.Messaging/Tizen.Messaging.Messages/Message.cs
new file mode 100755
index 0000000..e0e27f2
--- /dev/null
+++ b/src/Tizen.Messaging/Tizen.Messaging.Messages/Message.cs
@@ -0,0 +1,335 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+
+namespace Tizen.Messaging.Messages
+{
+ /// <summary>
+ /// A class to represent all messages.
+ /// </summary>
+ public abstract class Message : IDisposable
+ {
+ internal IntPtr _messageHandle = IntPtr.Zero;
+ private bool disposed = false;
+ private int _memoryPressureSize = IntPtr.Size * 11 + sizeof(int) * 5 + sizeof(bool) * 5 + sizeof(short) * 2 + sizeof(byte) * 1176;
+
+ private ICollection<MessagesAddress> _from = new Collection<MessagesAddress>();
+ internal ICollection<MessagesAddress> _to = new Collection<MessagesAddress>();
+ internal ICollection<MessagesAddress> _cc = new Collection<MessagesAddress>();
+ internal ICollection<MessagesAddress> _bcc = new Collection<MessagesAddress>();
+
+ internal Message(MessageType type)
+ {
+ int ret = Interop.Messages.CreateMessage((int)type, out _messageHandle);
+ if (ret != (int)MessagesError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to create message handle, Error - " + (MessagesError)ret);
+ MessagesErrorFactory.ThrowMessagesException(ret);
+ }
+
+ GC.AddMemoryPressure(_memoryPressureSize);
+ }
+
+ internal Message(IntPtr messageHandle)
+ {
+ _messageHandle = messageHandle;
+ GetAllAddresses();
+ GC.AddMemoryPressure(_memoryPressureSize);
+ }
+
+ internal void FillHandle()
+ {
+ SetAddresses();
+ (this as MmsMessage)?.SetAttachments();
+ }
+
+ ~Message()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ GC.RemoveMemoryPressure(_memoryPressureSize);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects
+ }
+
+ // Free unmanaged objects
+ if (_messageHandle != IntPtr.Zero)
+ {
+ Interop.Messages.DestroyMessage(_messageHandle);
+ _messageHandle = IntPtr.Zero;
+ }
+ disposed = true;
+ }
+
+ internal IntPtr GetHandle()
+ {
+ return _messageHandle;
+ }
+
+ private void SetAddresses()
+ {
+ foreach (var it in _to)
+ {
+ AddAddress(it);
+ }
+
+ foreach (var it in _cc)
+ {
+ AddAddress(it);
+ }
+
+ foreach (var it in _bcc)
+ {
+ AddAddress(it);
+ }
+ }
+
+ private void AddAddress(MessagesAddress address)
+ {
+ int ret = Interop.Messages.AddAddress(_messageHandle, address.Number, (int)address.Type);
+ if (ret != (int)MessagesError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to add address, Error - " + (MessagesError)ret);
+ MessagesErrorFactory.ThrowMessagesException(ret, _messageHandle);
+ }
+ }
+
+ private void GetAllAddresses()
+ {
+ int count;
+
+ int ret = Interop.Messages.GetAddressCount(_messageHandle, out count);
+ if (ret != (int)MessagesError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get address count, Error - " + (MessagesError)ret);
+ MessagesErrorFactory.ThrowMessagesException(ret, _messageHandle);
+ }
+
+ string number;
+ int type;
+ var To = new Collection<MessagesAddress>();
+ var Cc = new Collection<MessagesAddress>();
+ var Bcc = new Collection<MessagesAddress>();
+ var From = new Collection<MessagesAddress>();
+
+ for (int i = 0; i < count; i++)
+ {
+ ret = Interop.Messages.GetAddress(_messageHandle, i, out number, out type);
+ if (ret != (int)MessagesError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get address, Error - " + (MessagesError)ret);
+ MessagesErrorFactory.ThrowMessagesException(ret, _messageHandle);
+ }
+
+ var addressItem = new MessagesAddress((RecipientType)type, number);
+ switch ((RecipientType)type)
+ {
+ case RecipientType.To:
+ To.Add(addressItem);
+ break;
+ case RecipientType.Cc:
+ Cc.Add(addressItem);
+ break;
+ case RecipientType.Bcc:
+ Bcc.Add(addressItem);
+ break;
+ default:
+ From.Add(addressItem);
+ break;
+ }
+ }
+
+ _to = To;
+ _cc = Cc;
+ _bcc = Bcc;
+ _from = From;
+ }
+
+ /// <summary>
+ /// The message ID
+ /// </summary>
+ /// <remarks>
+ /// After creating Message object, default value of this property is 0. After sending, this value is changed.
+ /// </remarks>
+ public int Id
+ {
+ get
+ {
+ int id = 0;
+ int ret = Interop.Messages.GetMessageId(_messageHandle, out id);
+ if (ret != (int)MessagesError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get message id, Error - " + (MessagesError)ret);
+ }
+
+ return id;
+ }
+ }
+
+ /// <summary>
+ /// The destination port of the message
+ /// </summary>
+ public int Port
+ {
+ get
+ {
+ int port = 0;
+ int ret = Interop.Messages.GetMessagePort(_messageHandle, out port);
+ if (ret != (int)MessagesError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get message port, Error - " + (MessagesError)ret);
+ }
+
+ return port;
+ }
+ }
+
+ /// <summary>
+ /// The message box type
+ /// </summary>
+ public MessageBoxType BoxType
+ {
+ get
+ {
+ int boxType = (int)MessageBoxType.All;
+ int ret = Interop.Messages.GetMboxType(_messageHandle, out boxType);
+ if (ret != (int)MessagesError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get message box type, Error - " + (MessagesError)ret);
+ }
+
+ return (MessageBoxType)boxType;
+ }
+ set
+ {
+ int ret = Interop.Messages.SetMboxType(_messageHandle, (int)value);
+ if (ret != (int)MessagesError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set message box type, Error - " + (MessagesError)ret);
+ MessagesErrorFactory.ThrowMessagesException(ret, _messageHandle);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The text of the message
+ /// </summary>
+ public string Text
+ {
+ get
+ {
+ string text = null;
+ int ret = Interop.Messages.GetText(_messageHandle, out text);
+ if (ret != (int)MessagesError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get text, Error - " + (MessagesError)ret);
+ }
+
+ return text;
+ }
+ set
+ {
+ int ret = Interop.Messages.SetText(_messageHandle, value);
+ if (ret != (int)MessagesError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set text, Error - " + (MessagesError)ret);
+ MessagesErrorFactory.ThrowMessagesException(ret, _messageHandle);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The time of the message
+ /// </summary>
+ public DateTime Time
+ {
+ get
+ {
+ int time = 0;
+ int ret = Interop.Messages.GetTime(_messageHandle, out time);
+ if (ret != (int)MessagesError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get time, Error - " + (MessagesError)ret);
+ }
+
+ return (new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).AddSeconds(time).ToLocalTime();
+ }
+ set
+ {
+ int ret = Interop.Messages.SetTime(_messageHandle, (int)(value.ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds));
+ if (ret != (int)MessagesError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set time, Error - " + (MessagesError)ret);
+ MessagesErrorFactory.ThrowMessagesException(ret, _messageHandle);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The SIM slot index of the message
+ /// </summary>
+ public SimSlotId SimId
+ {
+ get
+ {
+ int simId = (int)SimSlotId.Unknown;
+ int ret = Interop.Messages.GetSimId(_messageHandle, out simId);
+ if (ret != (int)MessagesError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get simId, Error - " + (MessagesError)ret);
+ }
+
+ return (SimSlotId)simId;
+ }
+ set
+ {
+ int ret = Interop.Messages.SetSimId(_messageHandle, (int)value);
+ if (ret != (int)MessagesError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set simId, Error - " + (MessagesError)ret);
+ MessagesErrorFactory.ThrowMessagesException(ret, _messageHandle);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Indicates sender of the message
+ /// </summary>
+ public IReadOnlyCollection<MessagesAddress> From
+ {
+ get
+ {
+ return _from as IReadOnlyCollection<MessagesAddress>;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Messaging/Tizen.Messaging.Messages/MessageReceivedEventArgs.cs b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessageReceivedEventArgs.cs
new file mode 100755
index 0000000..cd9f7ee
--- /dev/null
+++ b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessageReceivedEventArgs.cs
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Messaging.Messages
+{
+ /// <summary>
+ /// An extended EventArgs class which contains a received message.
+ /// </summary>
+ public class MessageReceivedEventArgs : EventArgs
+ {
+ private Message _message;
+
+ internal MessageReceivedEventArgs(Message message)
+ {
+ _message = message;
+ }
+
+ /// <summary>
+ /// The received message
+ /// </summary>
+ public Message ReceivedMessage
+ {
+ get
+ {
+ return _message;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesAddress.cs b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesAddress.cs
new file mode 100755
index 0000000..19143fb
--- /dev/null
+++ b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesAddress.cs
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Messaging.Messages
+{
+ /// <summary>
+ /// A class to manage informations of message address.
+ /// </summary>
+ public class MessagesAddress
+ {
+ internal RecipientType Type;
+ /// <summary>
+ /// The address of the sender/recipient
+ /// </summary>
+ public string Number { get; }
+
+ /// <summary>
+ /// Creates a message address.
+ /// </summary>
+ /// <param name="number">The recipient's address to receive a message</param>
+ public MessagesAddress(string number)
+ {
+ Number = number;
+ }
+
+ internal MessagesAddress(RecipientType type, string number)
+ {
+ Type = type;
+ Number = number;
+ }
+ }
+}
diff --git a/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesAttachment.cs b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesAttachment.cs
new file mode 100755
index 0000000..6096278
--- /dev/null
+++ b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesAttachment.cs
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Messaging.Messages
+{
+ /// <summary>
+ /// A class to manage informations of message attachment.
+ /// </summary>
+ public class MessagesAttachment
+ {
+ /// <summary>
+ /// The media type of attachment
+ /// </summary>
+ public MediaType Type { get; }
+
+ /// <summary>
+ /// The file path of attachment
+ /// </summary>
+ public string FilePath { get; }
+
+ /// <summary>
+ /// Creates an attachment.
+ /// </summary>
+ /// <param name="type">The attachment's type</param>
+ /// <param name="filePath">The file path to attach</param>
+ public MessagesAttachment(MediaType type, string filePath)
+ {
+ Type = type;
+ FilePath = filePath;
+ }
+ }
+}
diff --git a/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesEnumerations.cs b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesEnumerations.cs
new file mode 100755
index 0000000..dd43eb0
--- /dev/null
+++ b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesEnumerations.cs
@@ -0,0 +1,152 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+namespace Tizen.Messaging.Messages
+{
+ /// <summary>
+ /// Enumeration for the result of sending a message.
+ /// </summary>
+ public enum SentResult
+ {
+ /// <summary>
+ /// Message sending failed
+ /// </summary>
+ Failed = -1,
+ /// <summary>
+ /// Message sending succeeded
+ /// </summary>
+ Success = 0
+ }
+
+ /// <summary>
+ /// Enumeration for the message type.
+ /// </summary>
+ public enum MessageType
+ {
+ /// <summary>
+ /// Unknown type
+ /// </summary>
+ Unknown = 0,
+ /// <summary>
+ /// SMS type
+ /// </summary>
+ Sms = 1,
+ /// <summary>
+ /// MMS type
+ /// </summary>
+ Mms = 2,
+ /// <summary>
+ /// CB(Cell Broadcast) type
+ /// </summary>
+ CellBroadcast = Sms | 1 << 4,
+ /// <summary>
+ /// WAP Push type
+ /// </summary>
+ Push = Sms | 10 << 4
+ }
+
+ /// <summary>
+ /// Enumeration for the message box type.
+ /// </summary>
+ public enum MessageBoxType
+ {
+ /// <summary>
+ /// All message box type
+ /// </summary>
+ All = 0,
+ /// <summary>
+ /// Inbox type
+ /// </summary>
+ Inbox = 1,
+ /// <summary>
+ /// Outbox type
+ /// </summary>
+ Outbox = 2,
+ /// <summary>
+ /// Sentbox type
+ /// </summary>
+ Sentbox = 3,
+ /// <summary>
+ /// Draft type
+ /// </summary>
+ Draft = 4
+ }
+
+ /// <summary>
+ /// Enumeration for the SIM slot index of a message
+ /// </summary>
+ public enum SimSlotId
+ {
+ /// <summary>
+ /// Unknown SIM Slot
+ /// </summary>
+ Unknown = 0,
+ /// <summary>
+ /// SIM Slot 1
+ /// </summary>
+ Sim1 = 1,
+ /// <summary>
+ /// SIM Slot 2
+ /// </summary>
+ Sim2 = 2
+ }
+
+ /// <summary>
+ /// Enumeration for the recipient type of a message
+ /// </summary>
+ internal enum RecipientType
+ {
+ /// <summary>
+ /// Unknown
+ /// </summary>
+ Unknown = 0,
+ /// <summary>
+ /// 'To' recipient
+ /// </summary>
+ To = 1,
+ /// <summary>
+ /// 'Cc' (carbon copy) recipient
+ /// </summary>
+ Cc = 2,
+ /// <summary>
+ /// 'Bcc' (blind carbon copy) recipient
+ /// </summary>
+ Bcc = 3
+ }
+
+ /// <summary>
+ /// Enumeration for the attachment tyoe for MMS messaging.
+ /// </summary>
+ public enum MediaType
+ {
+ /// <summary>
+ /// Unknown
+ /// </summary>
+ Unknown = 0,
+ /// <summary>
+ /// The image
+ /// </summary>
+ Image = 1,
+ /// <summary>
+ /// The audio
+ /// </summary>
+ Audio = 2,
+ /// <summary>
+ /// The video
+ /// </summary>
+ Video = 3
+ }
+}
diff --git a/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesErrorFactory.cs b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesErrorFactory.cs
new file mode 100755
index 0000000..c331aab
--- /dev/null
+++ b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesErrorFactory.cs
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Messaging.Messages
+{
+ internal enum MessagesError
+ {
+ None = ErrorCode.None,
+ OutOfMemory = ErrorCode.OutOfMemory,
+ InvalidParameter = ErrorCode.InvalidParameter,
+ ServerNotReady = -0x01710000 | 0x501,
+ CommunicationWithServerFailed = -0x01710000 | 0x502,
+ OutOfRange = -0x01710000 | 0x503,
+ SendingFailed = -0x01710000 | 0x504,
+ OperationFailed = -0x01710000 | 0x505,
+ NoSimCard = -0x01710000 | 0x506,
+ NoData = -0x01710000 | 0x507,
+ PermissionDenied = ErrorCode.PermissionDenied,
+ NotSupported = ErrorCode.NotSupported
+ }
+
+ internal static class MessagesErrorFactory
+ {
+ static internal void ThrowMessagesException(int e)
+ {
+ ThrowException(e, false);
+ }
+
+ static internal void ThrowMessagesException(int e, IntPtr handle)
+ {
+ ThrowException(e, (handle == IntPtr.Zero));
+ }
+
+ static private void ThrowException(int e, bool isHandleNull)
+ {
+ MessagesError err = (MessagesError)e;
+
+ if (isHandleNull)
+ {
+ throw new InvalidOperationException("Invalid instance (object may have been disposed or release)");
+ }
+
+ switch (err)
+ {
+ case MessagesError.OutOfMemory:
+ throw new OutOfMemoryException(err.ToString());
+ case MessagesError.InvalidParameter:
+ throw new ArgumentException(err.ToString());
+ case MessagesError.PermissionDenied:
+ throw new UnauthorizedAccessException(err.ToString());
+ case MessagesError.NotSupported:
+ throw new NotSupportedException(err.ToString());
+ default:
+ throw new InvalidOperationException(err.ToString());
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesEvent.cs b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesEvent.cs
new file mode 100755
index 0000000..dd0d616
--- /dev/null
+++ b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesEvent.cs
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Messaging.Messages
+{
+ internal partial class MessagesManagerImpl
+ {
+ private event EventHandler<MessageReceivedEventArgs> _messageReceived;
+
+ private Interop.Messages.MessageIncomingCallback _messageReceivedCallback;
+
+ internal event EventHandler<MessageReceivedEventArgs> _MessageReceived
+ {
+ add
+ {
+ if (_messageReceived == null)
+ {
+ RegisterMessageReceivedEvent();
+ }
+ _messageReceived += value;
+ }
+ remove
+ {
+ _messageReceived -= value;
+ if (_messageReceived == null)
+ {
+ UnregisterMessageReceivedEvent();
+ }
+ }
+ }
+
+ private void RegisterMessageReceivedEvent()
+ {
+ _messageReceivedCallback = (IntPtr messageHandle, IntPtr userData) =>
+ {
+ try
+ {
+ IntPtr duplicatedMessageHandle = IntPtr.Zero;
+
+ DuplicateMessageHandle(messageHandle, out duplicatedMessageHandle);
+ if (duplicatedMessageHandle != IntPtr.Zero)
+ {
+ int type = (int)MessageType.Unknown;
+ int result = Interop.Messages.GetMessageType(duplicatedMessageHandle, out type);
+ if (result != (int)MessagesError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get message type, Error - " + (MessagesError)result);
+ }
+
+ switch ((MessageType)type)
+ {
+ case MessageType.Sms:
+ {
+ var receivedMessage = new SmsMessage(duplicatedMessageHandle);
+ MessageReceivedEventArgs args = new MessageReceivedEventArgs(receivedMessage);
+ _messageReceived?.Invoke(null, args);
+ break;
+ }
+ case MessageType.Mms:
+ {
+ var receivedMessage = new MmsMessage(duplicatedMessageHandle);
+ MessageReceivedEventArgs args = new MessageReceivedEventArgs(receivedMessage);
+ _messageReceived?.Invoke(null, args);
+ break;
+ }
+ case MessageType.CellBroadcast:
+ {
+ var receivedMessage = new CBMessage(duplicatedMessageHandle);
+ MessageReceivedEventArgs args = new MessageReceivedEventArgs(receivedMessage);
+ _messageReceived?.Invoke(null, args);
+ break;
+ }
+ case MessageType.Push:
+ {
+ var receivedMessage = new PushMessage(duplicatedMessageHandle);
+ MessageReceivedEventArgs args = new MessageReceivedEventArgs(receivedMessage);
+ _messageReceived?.Invoke(null, args);
+ break;
+ }
+ default:
+ {
+ Log.Error(Globals.LogTag, "Invaild message type - " + type);
+ break;
+ }
+ }
+ }
+ }
+ catch
+ {
+ Log.Error(Globals.LogTag, "Exception in Callback");
+ }
+ };
+
+ int ret = Interop.Messages.SetMessageIncomingCb(_MessageServiceHandle, _messageReceivedCallback, IntPtr.Zero);
+ if (ret != (int)MessagesError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set message incoming callback, Error - " + (MessagesError)ret);
+ }
+ }
+
+ private void UnregisterMessageReceivedEvent()
+ {
+ int ret = Interop.Messages.UnsetMessageIncomingCb(_MessageServiceHandle);
+ if (ret != (int)MessagesError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset message incoming callback, Error - " + (MessagesError)ret);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesManager.cs b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesManager.cs
new file mode 100755
index 0000000..6b23ffa
--- /dev/null
+++ b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesManager.cs
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Tizen.Messaging.Messages
+{
+ /// <summary>
+ /// A class for message management. It allows applications to use message service.
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/message.read</privilege>
+ public static class MessagesManager
+ {
+ /// <summary>
+ /// Sends a message.
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/message.write</privilege>
+ /// <param name="message">The message to be sent</param>
+ /// <param name="saveToSentbox">The boolean variable to indicate sent message should be saved in sentbox or not</param>
+ /// <returns>A task contains the result of message sending</returns>
+ /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
+ /// <exception cref="NotSupportedException">Thrown when message service is not supported</exception>
+ /// <exception cref="ArgumentException">Thrown when input coordinates are invalid</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
+ public static Task<SentResult> SendMessageAsync(Message message, bool saveToSentbox)
+ {
+ return MessagesManagerImpl.Instance.SendMessageAsync(message, saveToSentbox);
+ }
+
+ /// <summary>
+ /// Searches for messages.
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/message.read</privilege>
+ /// <param name="filter">The search filter for searching messages</param>
+ /// <returns>A task contains the messages which fit with search filter</returns>
+ /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
+ /// <exception cref="NotSupportedException">Thrown when message service is not supported</exception>
+ /// <exception cref="ArgumentException">Thrown when input coordinates are invalid</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
+ public static Task<IEnumerable<Message>> SearchMessageAsync(MessagesSearchFilter filter)
+ {
+ return MessagesManagerImpl.Instance.SearchMessageAsync(filter);
+ }
+
+ /// <summary>
+ /// (event) MessageReceived is raised when receiving a message.
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/message.read</privilege>
+ static public event EventHandler<MessageReceivedEventArgs> MessageReceived
+ {
+ add
+ {
+ MessagesManagerImpl.Instance._MessageReceived += value;
+ }
+ remove
+ {
+ MessagesManagerImpl.Instance._MessageReceived -= value;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesManagerImpl.cs b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesManagerImpl.cs
new file mode 100755
index 0000000..63cd9fc
--- /dev/null
+++ b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesManagerImpl.cs
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Tizen.Messaging.Messages
+{
+ static internal class Globals
+ {
+ internal const string LogTag = "Tizen.Messaging.Messages";
+ }
+
+ internal partial class MessagesManagerImpl : IDisposable
+ {
+ private static readonly MessagesManagerImpl _instance = new MessagesManagerImpl();
+ private bool disposed = false;
+
+ private static IntPtr _MessageServiceHandle;
+
+ private Interop.Messages.MessageSentCallback _messageSentCallback;
+
+ internal static MessagesManagerImpl Instance
+ {
+ get
+ {
+ return _instance;
+ }
+ }
+
+ private MessagesManagerImpl()
+ {
+ initialize();
+ }
+
+ ~MessagesManagerImpl()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects
+ }
+
+ // Free unmanaged objects
+ deinitialize();
+ disposed = true;
+ }
+
+ private void initialize()
+ {
+ int ret;
+
+ ret = Interop.Messages.OpenService(out _MessageServiceHandle);
+ if (ret != (int)MessagesError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to open service, Error - " + (MessagesError)ret);
+ MessagesErrorFactory.ThrowMessagesException(ret);
+ }
+ }
+
+ private void deinitialize()
+ {
+ if (_MessageServiceHandle != IntPtr.Zero)
+ {
+ int ret;
+
+ ret = Interop.Messages.CloseService(_MessageServiceHandle);
+ if (ret != (int)MessagesError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to close service, Error - " + (MessagesError)ret);
+ }
+
+ _MessageServiceHandle = IntPtr.Zero;
+ }
+ }
+
+ internal Task<SentResult> SendMessageAsync(Message message, bool saveToSentbox)
+ {
+ var task = new TaskCompletionSource<SentResult>();
+
+ _messageSentCallback = (int result, IntPtr data) =>
+ {
+ task.SetResult((SentResult)result);
+ };
+
+ message.FillHandle();
+
+ int ret;
+ IntPtr messageHandle = message.GetHandle();
+
+ ret = Interop.Messages.SendMessage(_MessageServiceHandle, messageHandle, saveToSentbox, _messageSentCallback, IntPtr.Zero);
+ if (ret != (int)MessagesError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to send message, Error - " + (MessagesError)ret);
+ MessagesErrorFactory.ThrowMessagesException(ret, _MessageServiceHandle);
+ }
+
+ return task.Task;
+ }
+
+ internal Task<IEnumerable<Message>> SearchMessageAsync(MessagesSearchFilter filter)
+ {
+ return Task.Run<IEnumerable<Message>>(() =>
+ {
+ List<Message> messageList = new List<Message>();
+ int ret;
+
+ Interop.Messages.MessageSearchCallback callback = (IntPtr messageHandle, int index, int resultCount, int totalCount, IntPtr userData) =>
+ {
+ try
+ {
+ if (messageHandle != IntPtr.Zero)
+ {
+ IntPtr duplicatedMessageHandle = IntPtr.Zero;
+
+ DuplicateMessageHandle(messageHandle, out duplicatedMessageHandle);
+ if (duplicatedMessageHandle != IntPtr.Zero)
+ {
+ int type = (int)MessageType.Unknown;
+ int result = Interop.Messages.GetMessageType(duplicatedMessageHandle, out type);
+ if (result != (int)MessagesError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get message type, Error - " + (MessagesError)result);
+ }
+
+ switch ((MessageType)type)
+ {
+ case MessageType.Sms:
+ {
+ var messageItem = new SmsMessage(duplicatedMessageHandle);
+ messageList.Add(messageItem);
+ break;
+ }
+ case MessageType.Mms:
+ {
+ var messageItem = new MmsMessage(duplicatedMessageHandle);
+ messageList.Add(messageItem);
+ break;
+ }
+ case MessageType.CellBroadcast:
+ {
+ var messageItem = new CBMessage(duplicatedMessageHandle);
+ messageList.Add(messageItem);
+ break;
+ }
+ case MessageType.Push:
+ {
+ var messageItem = new PushMessage(duplicatedMessageHandle);
+ messageList.Add(messageItem);
+ break;
+ }
+ default:
+ {
+ Log.Error(Globals.LogTag, "Invaild message type - " + type);
+ break;
+ }
+ }
+
+ return true;
+ }
+ }
+ }
+ catch
+ {
+ Log.Error(Globals.LogTag, "Exception in Callback");
+ }
+
+ return false;
+ };
+
+ ret = Interop.Messages.SearchMessage(_MessageServiceHandle, (int)filter.MessageBoxType, (int)filter.MessageType, filter.TextKeyword, filter.AddressKeyword, 0, 0, callback, IntPtr.Zero);
+ if (ret != (int)MessagesError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to search message, Error - " + (MessagesError)ret);
+ MessagesErrorFactory.ThrowMessagesException(ret, _MessageServiceHandle);
+ }
+
+ return messageList;
+ });
+ }
+
+ private void DuplicateMessageHandle(IntPtr sourceHandle, out IntPtr clonedHandle)
+ {
+ int msgId;
+ IntPtr returnedHandle = IntPtr.Zero;
+
+ int ret = Interop.Messages.GetMessageId(sourceHandle, out msgId);
+ if (ret == (int)MessagesError.None)
+ {
+ ret = Interop.Messages.GetMessageById(_MessageServiceHandle, msgId, out returnedHandle);
+ if (ret != (int)MessagesError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get message by id, Error - " + (MessagesError)ret);
+ MessagesErrorFactory.ThrowMessagesException(ret, _MessageServiceHandle);
+ }
+ }
+ else
+ {
+ Log.Error(Globals.LogTag, "Failed to get message id, Error - " + (MessagesError)ret);
+ MessagesErrorFactory.ThrowMessagesException(ret, _MessageServiceHandle);
+ }
+
+ clonedHandle = returnedHandle;
+ }
+ }
+}
diff --git a/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesSearchFilter.cs b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesSearchFilter.cs
new file mode 100755
index 0000000..6561463
--- /dev/null
+++ b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesSearchFilter.cs
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Messaging.Messages
+{
+ /// <summary>
+ /// A class to represent message search filters.
+ /// </summary>
+ public class MessagesSearchFilter
+ {
+ /// <summary>
+ /// Create a search filter for searching messages.
+ /// </summary>
+ public MessagesSearchFilter()
+ {
+ }
+
+ /// <summary>
+ /// The message box type
+ /// </summary>
+ public MessageBoxType MessageBoxType { get; set; }
+ /// <summary>
+ /// The message type
+ /// </summary>
+ public MessageType MessageType { get; set; }
+ /// <summary>
+ /// The keyword to search in the text and subject
+ /// </summary>
+ public string TextKeyword { get; set; }
+ /// <summary>
+ /// The recipient address
+ /// </summary>
+ public string AddressKeyword { get; set; }
+ }
+}
diff --git a/src/Tizen.Messaging/Tizen.Messaging.Messages/MmsMessage.cs b/src/Tizen.Messaging/Tizen.Messaging.Messages/MmsMessage.cs
new file mode 100755
index 0000000..f73310a
--- /dev/null
+++ b/src/Tizen.Messaging/Tizen.Messaging.Messages/MmsMessage.cs
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Messaging.Messages
+{
+ /// <summary>
+ /// A class to represent multimedia messages.
+ /// </summary>
+ public class MmsMessage : Message
+ {
+ private IList<MessagesAttachment> _attachment = new List<MessagesAttachment>();
+
+ /// <summary>
+ /// Creates a multimedia message.
+ /// </summary>
+ public MmsMessage() : base(MessageType.Mms)
+ {
+ }
+
+ internal MmsMessage(IntPtr messageHandle) : base(messageHandle)
+ {
+ GetAllAttachments();
+ }
+
+ /// <summary>
+ /// The subject of the multimedia message
+ /// </summary>
+ public string Subject
+ {
+ get
+ {
+ string subject = null;
+ int ret = Interop.Messages.GetSubject(_messageHandle, out subject);
+ if (ret != (int)MessagesError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get subject, Error - " + (MessagesError)ret);
+ }
+
+ return subject;
+ }
+ set
+ {
+ int ret = Interop.Messages.SetSubject(_messageHandle, value);
+ if (ret != (int)MessagesError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set subject, Error - " + (MessagesError)ret);
+ MessagesErrorFactory.ThrowMessagesException(ret, _messageHandle);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Collection of normal message recipients
+ /// </summary>
+ public ICollection<MessagesAddress> To
+ {
+ get
+ {
+ return _to;
+ }
+ }
+
+ /// <summary>
+ /// Collection of CC(carbon copy) message recipients
+ /// </summary>
+ public ICollection<MessagesAddress> Cc
+ {
+ get
+ {
+ return _cc;
+ }
+ }
+
+ /// <summary>
+ /// Collection of BCC(blind carbon copy) message recipients
+ /// </summary>
+ public ICollection<MessagesAddress> Bcc
+ {
+ get
+ {
+ return _bcc;
+ }
+ }
+
+ /// <summary>
+ /// The list of attachment files
+ /// </summary>
+ public IList<MessagesAttachment> Attachments
+ {
+ get
+ {
+ return _attachment;
+ }
+ }
+
+ internal void SetAttachments()
+ {
+ foreach (var it in _attachment)
+ {
+ AddAttachment(it);
+ }
+ }
+
+ private void AddAttachment(MessagesAttachment attach)
+ {
+ int ret = Interop.Messages.AddAttachment(_messageHandle, (int)attach.Type, attach.FilePath);
+ if (ret != (int)MessagesError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to add attachment, Error - " + (MessagesError)ret);
+ MessagesErrorFactory.ThrowMessagesException(ret, _messageHandle);
+ }
+ }
+
+ private void GetAllAttachments()
+ {
+ int count;
+
+ int ret = Interop.Messages.GetAttachmentCount(_messageHandle, out count);
+ if (ret != (int)MessagesError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get attachment count, Error - " + (MessagesError)ret);
+ MessagesErrorFactory.ThrowMessagesException(ret, _messageHandle);
+ }
+
+ string path;
+ int type;
+ var attachmentList = new List<MessagesAttachment>();
+
+ for (int i = 0; i < count; i++)
+ {
+ ret = Interop.Messages.GetAttachment(_messageHandle, i, out type, out path);
+ if (ret != (int)MessagesError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get attachment, Error - " + (MessagesError)ret);
+ MessagesErrorFactory.ThrowMessagesException(ret, _messageHandle);
+ }
+
+ var attachmentItem = new MessagesAttachment((MediaType)type, path);
+ attachmentList.Add(attachmentItem);
+ }
+
+ _attachment = attachmentList;
+ }
+
+ }
+}
diff --git a/src/Tizen.Messaging/Tizen.Messaging.Messages/NamespaceDoc.cs b/src/Tizen.Messaging/Tizen.Messaging.Messages/NamespaceDoc.cs
new file mode 100755
index 0000000..45d5a8e
--- /dev/null
+++ b/src/Tizen.Messaging/Tizen.Messaging.Messages/NamespaceDoc.cs
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/// <summary>
+/// The <b>Tizen.Messaging.Messages</b> namespace contains classes providing functionality to send, receive and search for messages.
+/// </summary>
+/// <remarks>
+/// The <b>Tizen.Messaging.Messages</b> namespace contains classes providing functionality to send, receive and search for messages.
+/// </remarks>
+namespace Tizen.Messaging.Messages
+{
+}
diff --git a/src/Tizen.Messaging/Tizen.Messaging.Messages/PushMessage.cs b/src/Tizen.Messaging/Tizen.Messaging.Messages/PushMessage.cs
new file mode 100755
index 0000000..667e7ff
--- /dev/null
+++ b/src/Tizen.Messaging/Tizen.Messaging.Messages/PushMessage.cs
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Messaging.Messages
+{
+ /// <summary>
+ /// A class to represent WAP push messages.
+ /// </summary>
+ public class PushMessage : Message
+ {
+ internal PushMessage(IntPtr messageHandle) : base(messageHandle)
+ {
+ }
+ }
+}
diff --git a/src/Tizen.Messaging/Tizen.Messaging.Messages/SmsMessage.cs b/src/Tizen.Messaging/Tizen.Messaging.Messages/SmsMessage.cs
new file mode 100755
index 0000000..62ffd1e
--- /dev/null
+++ b/src/Tizen.Messaging/Tizen.Messaging.Messages/SmsMessage.cs
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Messaging.Messages
+{
+ /// <summary>
+ /// A class to represent short text messages.
+ /// </summary>
+ public class SmsMessage : Message
+ {
+ /// <summary>
+ /// Creates a short text message.
+ /// </summary>
+ public SmsMessage() : base(MessageType.Sms)
+ {
+ }
+
+ internal SmsMessage(IntPtr messageHandle) : base(messageHandle)
+ {
+ }
+
+ /// <summary>
+ /// Collection of normal message recipients
+ /// </summary>
+ public ICollection<MessagesAddress> To
+ {
+ get
+ {
+ return _to;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Messaging/Tizen.Messaging.csproj b/src/Tizen.Messaging/Tizen.Messaging.csproj
new file mode 100644
index 0000000..d5717a4
--- /dev/null
+++ b/src/Tizen.Messaging/Tizen.Messaging.csproj
@@ -0,0 +1,15 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
+
diff --git a/src/Tizen.Multimedia.AudioIO/AudioIO/AudioCapture.cs b/src/Tizen.Multimedia.AudioIO/AudioIO/AudioCapture.cs
new file mode 100644
index 0000000..1284919
--- /dev/null
+++ b/src/Tizen.Multimedia.AudioIO/AudioIO/AudioCapture.cs
@@ -0,0 +1,397 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides the ability to directly manage the system audio input devices.
+ /// </summary>
+ /// <remarks>The recorder privilege(http://tizen.org/privilege/recorder) is required.</remarks>
+ public abstract class AudioCaptureBase : IDisposable
+ {
+ /// <summary>
+ /// Specifies the minimum value allowed for the audio capture.
+ /// </summary>
+ public static readonly int MinSampleRate = 8000;
+
+ /// <summary>
+ /// Specifies the maximum value allowed for the audio capture.
+ /// </summary>
+ public static readonly int MaxSampleRate = 48000;
+
+ internal IntPtr _handle = IntPtr.Zero;
+
+ private AudioIOState _state = AudioIOState.Idle;
+
+ internal AudioCaptureBase(int sampleRate, AudioChannel channel, AudioSampleType sampleType)
+ {
+ if (sampleRate < MinSampleRate || MaxSampleRate < sampleRate)
+ {
+ throw new ArgumentOutOfRangeException(nameof(sampleRate), sampleRate,
+ $"Valid sampleRate range is { MinSampleRate } <= x <= { MaxSampleRate }.");
+ }
+
+ ValidationUtil.ValidateEnum(typeof(AudioChannel), channel, nameof(channel));
+ ValidationUtil.ValidateEnum(typeof(AudioSampleType), sampleType, nameof(sampleType));
+
+ SampleRate = sampleRate;
+ Channel = channel;
+ SampleType = sampleType;
+
+ AudioIOUtil.ThrowIfError(
+ Interop.AudioIO.AudioInput.Create(SampleRate, (int)Channel, (int)SampleType, out _handle));
+
+ RegisterStateChangedCallback();
+ }
+
+ ~AudioCaptureBase()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Occurs when the state of the AudioCapture is changed.
+ /// </summary>
+ public event EventHandler<AudioIOStateChangedEventArgs> StateChanged;
+
+ private Interop.AudioIO.AudioStateChangedCallback _stateChangedCallback;
+
+ private void RegisterStateChangedCallback()
+ {
+ _stateChangedCallback = (IntPtr handle, int previous, int current, bool byPolicy, IntPtr _) =>
+ {
+ _state = (AudioIOState)current;
+
+ StateChanged?.Invoke(this,
+ new AudioIOStateChangedEventArgs((AudioIOState)previous, _state, byPolicy));
+ };
+
+ AudioIOUtil.ThrowIfError(
+ Interop.AudioIO.AudioInput.SetStateChangedCallback(_handle, _stateChangedCallback, IntPtr.Zero));
+ }
+
+ #region Dispose support
+ private bool _isDisposed = false;
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_isDisposed)
+ {
+ return;
+ }
+
+ if (_handle != IntPtr.Zero)
+ {
+ if (_state != AudioIOState.Idle)
+ {
+ try
+ {
+ Unprepare();
+ }
+ catch (Exception)
+ {
+ }
+ }
+
+ Interop.AudioIO.AudioInput.Destroy(_handle);
+ _handle = IntPtr.Zero;
+ _isDisposed = true;
+ }
+ }
+
+ internal void ValidateNotDisposed()
+ {
+ if (_isDisposed)
+ {
+ throw new ObjectDisposedException(GetType().Name);
+ }
+ }
+ #endregion
+
+ internal void ValidateState(params AudioIOState[] desiredStates)
+ {
+ ValidateNotDisposed();
+
+ AudioIOUtil.ValidateState(_state, desiredStates);
+ }
+
+ /// <summary>
+ /// Gets the sample rate of the audio input data stream.
+ /// </summary>
+ public int SampleRate { get; }
+
+ /// <summary>
+ /// Gets the channel type of the audio input data stream.
+ /// </summary>
+ public AudioChannel Channel { get; }
+
+ /// <summary>
+ /// Gets the sample type of the audio input data stream.
+ /// </summary>
+ public AudioSampleType SampleType { get; }
+
+ /// <summary>
+ /// Gets the size allocated for the audio input buffer.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">The AudioPlayback has already been disposed.</exception>
+ public int GetBufferSize()
+ {
+ AudioIOUtil.ThrowIfError(Interop.AudioIO.AudioInput.GetBufferSize(_handle, out var size));
+ return size;
+ }
+
+ /// <summary>
+ /// Prepares the AudioCapture for reading audio data by starting buffering of audio data from the device.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">
+ /// Operation failed due to internal error.\n
+ /// -or-\n
+ /// The current state is not <see cref="AudioIOState.Idle"/>.
+ /// </exception>
+ /// <seealso cref="Unprepare"/>
+ public void Prepare()
+ {
+ ValidateState(AudioIOState.Idle);
+
+ AudioIOUtil.ThrowIfError(Interop.AudioIO.AudioInput.Prepare(_handle),
+ "Failed to prepare the AudioCapture");
+ }
+
+ /// <summary>
+ /// Unprepares the AudioCapture.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">
+ /// Operation failed due to internal error.\n
+ /// \n
+ /// The current state is <see cref="AudioIOState.Idle"/>.
+ /// </exception>
+ /// <seealso cref="Prepare"/>
+ public void Unprepare()
+ {
+ ValidateState(AudioIOState.Running, AudioIOState.Paused);
+
+ AudioIOUtil.ThrowIfError(Interop.AudioIO.AudioInput.Unprepare(_handle),
+ "Failed to unprepare the AudioCapture");
+ }
+
+ /// <summary>
+ /// Pauses buffering of audio data from the device.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">
+ /// The current state is <see cref="AudioState.Idle"/>.\n
+ /// -or-\n
+ /// The method is called in the <see cref="AsyncAudioCapture.DataAvailable"/> event handler.
+ /// </exception>
+ /// <seealso cref="Resume"/>
+ public void Pause()
+ {
+ if (_state == AudioIOState.Paused)
+ {
+ return;
+ }
+ ValidateState(AudioIOState.Running);
+
+ AudioIOUtil.ThrowIfError(Interop.AudioIO.AudioInput.Pause(_handle));
+ }
+ /// <summary>
+ /// Resumes buffering audio data from the device.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">
+ /// The current state is <see cref="AudioState.Idle"/>.\n
+ /// -or-\n
+ /// The method is called in the <see cref="AsyncAudioCapture.DataAvailable"/> event handler.
+ /// </exception>
+ /// <seealso cref="Pause"/>
+ public void Resume()
+ {
+ if (_state == AudioIOState.Running)
+ {
+ return;
+ }
+ ValidateState(AudioIOState.Paused);
+
+ AudioIOUtil.ThrowIfError(Interop.AudioIO.AudioInput.Resume(_handle));
+ }
+ /// <summary>
+ /// Flushes and discards buffered audio data from the input stream.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">The current state is <see cref="AudioState.Idle"/>.</exception>
+ public void Flush()
+ {
+ ValidateState(AudioIOState.Running, AudioIOState.Paused);
+
+ int ret = Interop.AudioIO.AudioInput.Flush(_handle);
+
+ MultimediaDebug.AssertNoError(ret);
+ }
+
+ /// <summary>
+ /// Sets the sound stream information to the audio input.
+ /// </summary>
+ /// <param name="streamPolicy">The <see cref="AudioStreamPolicy"/> to apply for the AudioCapture.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="streamPolicy"/> is null.</exception>
+ /// <exception cref="ObjectDisposedException"><paramref name="streamPolicy"/> has already been disposed.</exception>
+ /// <exception cref="NotSupportedException"><paramref name="streamPolicy"/> is not supported.</exception>
+ /// <exception cref="ArgumentException">Not able to retrieve information from <paramref name="streamPolicy"/>.</exception>
+ public void ApplyStreamPolicy(AudioStreamPolicy streamPolicy)
+ {
+ if (streamPolicy == null)
+ {
+ throw new ArgumentNullException(nameof(streamPolicy));
+ }
+
+ if (streamPolicy.Handle == IntPtr.Zero)
+ {
+ throw new ObjectDisposedException(nameof(streamPolicy));
+ }
+
+ ValidateNotDisposed();
+
+ AudioIOUtil.ThrowIfError(Interop.AudioIO.AudioInput.SetStreamInfo(_handle, streamPolicy.Handle));
+ }
+ }
+
+ /// <summary>
+ /// Provides the ability to record audio from system audio input devices in synchronous way.
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/recorder</privilege>
+ public class AudioCapture : AudioCaptureBase
+ {
+ /// <summary>
+ /// Initializes a new instance of the AudioCapture class with the specified sample rate, channel and sampleType.
+ /// </summary>
+ /// <param name="sampleRate">The audio sample rate.(8000 ~ 48000Hz)</param>
+ /// <param name="channel">The audio channel type.</param>
+ /// <param name="sampleType">The audio sample type.</param>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="sampleRate"/> is less than <see cref="MinSampleRate"/>.\n
+ /// -or-\n
+ /// <paramref name="sampleRate"/> is greater than <see cref="MaxSampleRate"/>.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="channel"/> is invalid.\n
+ /// -or-\n
+ /// <paramref name="sampleType"/> is invalid.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">The required privilege is not specified.</exception>
+ /// <exception cref="NotSupportedException">The system does not support microphone.</exception>
+ public AudioCapture(int sampleRate, AudioChannel channel, AudioSampleType sampleType)
+ : base(sampleRate, channel, sampleType)
+ {
+ }
+
+ /// <summary>
+ /// Reads audio data from the audio input buffer.
+ /// </summary>
+ /// <param name="count">The number of bytes to be read.</param>
+ /// <returns>The buffer of audio data captured.</returns>
+ /// <exception cref="InvalidOperationException">The current state is not <see cref="AudioIOState.Running"/>.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="count"/> is equal to or less than zero.</exception>
+ public byte[] Read(int count)
+ {
+ if (count <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(count), count,
+ $"{ nameof(count) } can't be equal to or less than zero.");
+ }
+ ValidateState(AudioIOState.Running);
+
+ byte[] buffer = new byte[count];
+
+ AudioIOUtil.ThrowIfError(Interop.AudioIO.AudioInput.Read(_handle, buffer, count),
+ "Failed to read");
+
+ return buffer;
+ }
+ }
+
+ /// <summary>
+ /// Provides the ability to record audio from system audio input devices in asynchronous way.
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/recorder</privilege>
+ public class AsyncAudioCapture : AudioCaptureBase
+ {
+
+ /// <summary>
+ /// Occurs when audio data is available.
+ /// </summary>
+ public event EventHandler<AudioDataAvailableEventArgs> DataAvailable;
+
+ /// <summary>
+ /// Initializes a new instance of the AsyncAudioCapture class with the specified sample rate, channel and sampleType.
+ /// </summary>
+ /// <param name="sampleRate">The audio sample rate.(8000 ~ 48000Hz)</param>
+ /// <param name="channel">The audio channel type.</param>
+ /// <param name="sampleType">The audio sample type.</param>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="sampleRate"/> is less than <see cref="MinSampleRate"/>.\n
+ /// -or-\n
+ /// <paramref name="sampleRate"/> is greater than <see cref="MaxSampleRate"/>.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="channel"/> is invalid.\n
+ /// -or-\n
+ /// <paramref name="sampleType"/> is invalid.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">The required privilege is not specified.</exception>
+ /// <exception cref="NotSupportedException">The system does not support microphone.</exception>
+ public AsyncAudioCapture(int sampleRate, AudioChannel channel, AudioSampleType sampleType)
+ : base(sampleRate, channel, sampleType)
+ {
+ _streamCallback = (IntPtr handle, uint length, IntPtr _) => { OnInputDataAvailable(handle, length); };
+
+ AudioIOUtil.ThrowIfError(
+ Interop.AudioIO.AudioInput.SetStreamCallback(_handle, _streamCallback, IntPtr.Zero),
+ $"Failed to initialize a { nameof(AsyncAudioCapture) }");
+ }
+
+ private Interop.AudioIO.AudioStreamCallback _streamCallback;
+
+ private void OnInputDataAvailable(IntPtr handle, uint length)
+ {
+ if (length == 0U)
+ {
+ return;
+ }
+
+ IntPtr ptr = IntPtr.Zero;
+ try
+ {
+ AudioIOUtil.ThrowIfError(Interop.AudioIO.AudioInput.Peek(_handle, out ptr, ref length));
+
+ byte[] buffer = new byte[length];
+ Marshal.Copy(ptr, buffer, 0, (int)length);
+
+ Interop.AudioIO.AudioInput.Drop(_handle);
+
+ DataAvailable?.Invoke(this, new AudioDataAvailableEventArgs(buffer));
+ }
+ catch (Exception e)
+ {
+ Log.Error(nameof(AsyncAudioCapture), e.Message);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.AudioIO/AudioIO/AudioDataAvailableEventArgs.cs b/src/Tizen.Multimedia.AudioIO/AudioIO/AudioDataAvailableEventArgs.cs
new file mode 100644
index 0000000..8fc7940
--- /dev/null
+++ b/src/Tizen.Multimedia.AudioIO/AudioIO/AudioDataAvailableEventArgs.cs
@@ -0,0 +1,36 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides data for the <see cref="AsyncAudioCapture.DataAvailable"/> event.
+ /// </summary>
+ public class AudioDataAvailableEventArgs : EventArgs
+ {
+ internal AudioDataAvailableEventArgs(byte[] data)
+ {
+ Data = data;
+ }
+
+ /// <summary>
+ /// Gets the audio data captured.
+ /// </summary>
+ public byte[] Data { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia.AudioIO/AudioIO/AudioIOEnums.cs b/src/Tizen.Multimedia.AudioIO/AudioIO/AudioIOEnums.cs
new file mode 100644
index 0000000..bec87b0
--- /dev/null
+++ b/src/Tizen.Multimedia.AudioIO/AudioIO/AudioIOEnums.cs
@@ -0,0 +1,80 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using Tizen.Internals.Errors;
+
+namespace Tizen.Multimedia
+{
+ public enum AudioChannel
+ {
+ Mono = 0x80,
+ Stereo
+ };
+
+ internal enum AudioIOError
+ {
+ None = ErrorCode.None,
+ OutOfMemory = ErrorCode.OutOfMemory,
+ InvalidParameter = ErrorCode.InvalidParameter,
+ InvalidOperation = ErrorCode.InvalidOperation,
+ PermissionDenied = ErrorCode.PermissionDenied, //Device open error by security
+ NotSupported = ErrorCode.NotSupported, //Not supported
+ DevicePolicyRestriction = (-2147483648 / 2) + 4,
+ DeviceNotOpened = -0x01900000 | 0x01,
+ DeviceNotClosed = -0x01900000 | 0x02,
+ InvalidBuffer = -0x01900000 | 0x03,
+ SoundPolicy = -0x01900000 | 0x04,
+ InvalidState = -0x01900000 | 0x05,
+ NotSupportedType = -0x01900000 | 0x06,
+ }
+
+ /// <summary>
+ /// Specifies the states for the <see cref="AudioPlayback"/>, <see cref="AudioCapture"/> and <see cref="AsyncAudioCapture"/>.
+ /// </summary>
+ public enum AudioIOState
+ {
+ /// <summary>
+ /// Not prepared.
+ /// </summary>
+ Idle = 0,
+
+ /// <summary>
+ /// The stream is running.
+ /// </summary>
+ Running = 1,
+
+ /// <summary>
+ /// The stream is paused.
+ /// </summary>
+ Paused = 2
+ }
+
+ /// <summary>
+ /// Enumeration for audio sample type.
+ /// </summary>
+ public enum AudioSampleType
+ {
+ /// <summary>
+ /// Unsigned 8-bit audio samples.
+ /// </summary>
+ U8 = 0x70,
+ /// <summary>
+ /// Signed 16-bit audio samples.
+ /// </summary>
+ S16Le
+ }
+
+}
diff --git a/src/Tizen.Multimedia.AudioIO/AudioIO/AudioIOStateChangedEventArgs.cs b/src/Tizen.Multimedia.AudioIO/AudioIO/AudioIOStateChangedEventArgs.cs
new file mode 100644
index 0000000..5d1677d
--- /dev/null
+++ b/src/Tizen.Multimedia.AudioIO/AudioIO/AudioIOStateChangedEventArgs.cs
@@ -0,0 +1,48 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides data for the <see cref="AudioCaptureBase.StateChanged"/> event and <see cref="AudioPlayback.StateChanged"/>.
+ /// </summary>
+ public class AudioIOStateChangedEventArgs : EventArgs
+ {
+ internal AudioIOStateChangedEventArgs(AudioIOState previous, AudioIOState current, bool byPolicy)
+ {
+ Previous = previous;
+ Current = current;
+ ByPolicy = byPolicy;
+ }
+
+ /// <summary>
+ /// Gets the previous state.
+ /// </summary>
+ public AudioIOState Previous { get; }
+
+ /// <summary>
+ /// Gets the current state.
+ /// </summary>
+ public AudioIOState Current { get; }
+
+ /// <summary>
+ /// Gets the value indicating whether the state is changed by policy or not.
+ /// </summary>
+ public bool ByPolicy { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia.AudioIO/AudioIO/AudioIOUtil.cs b/src/Tizen.Multimedia.AudioIO/AudioIO/AudioIOUtil.cs
new file mode 100644
index 0000000..d6a0c76
--- /dev/null
+++ b/src/Tizen.Multimedia.AudioIO/AudioIO/AudioIOUtil.cs
@@ -0,0 +1,95 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Diagnostics;
+using System.Linq;
+
+namespace Tizen.Multimedia
+{
+ internal static class AudioIOUtil
+ {
+ internal static void ThrowIfError(int errorCode, string msg = null)
+ {
+ AudioIOError code = (AudioIOError)errorCode;
+ // 현재는 에러코드 최상위 exception으로 전달, 추후 상황에 맞게 케이스 처리해야 함.
+
+ msg = (msg == null ? "" : msg + " ") + $": { code }";
+
+ if (code > 0)
+ {
+ Log.Info("Audio", "Code > 0, no error!!!!");
+ return;
+ }
+
+ switch (code)
+ {
+ case AudioIOError.None:
+ break;
+ case AudioIOError.OutOfMemory:
+ Log.Info("Audio", "OutOfMemoryException");
+ throw new OutOfMemoryException();
+ case AudioIOError.InvalidParameter:
+ Log.Info("Audio", "ArgumentException");
+ throw new ArgumentException(msg);
+ case AudioIOError.InvalidOperation:
+ throw new InvalidOperationException(msg);
+ case AudioIOError.PermissionDenied:
+ Log.Info("Audio", "Permission Denied Error");
+ throw new InvalidOperationException(msg);
+ case AudioIOError.NotSupported:
+ throw new NotSupportedException(msg);
+ case AudioIOError.DevicePolicyRestriction:
+ Log.Info("Audio", "Device_policy_restriction");
+ throw new Exception("Device_policy_restriction");
+ case AudioIOError.DeviceNotOpened:
+ Log.Info("Audio", "Device Not Opened Error");
+ throw new Exception("Device Not Opened Error");
+ case AudioIOError.DeviceNotClosed:
+ Log.Info("Audio", "Device Not Closed Error");
+ throw new Exception("Device Not Closed Error");
+ case AudioIOError.InvalidBuffer:
+ Log.Info("Audio", "Invalid Buffer Error");
+ throw new InvalidOperationException(msg);
+ case AudioIOError.SoundPolicy:
+ Log.Info("Audio", "Sound Policy Error");
+ throw new Exception(msg);
+ case AudioIOError.InvalidState:
+ Log.Info("Audio", "Invalid State Error");
+ throw new InvalidOperationException(msg);
+ case AudioIOError.NotSupportedType:
+ Log.Info("Audio", "Not supported stream type Error");
+ throw new NotSupportedException(msg);
+ default:
+ Log.Info("Audio", "Unknown Exception" + code);
+ throw new Exception(msg);
+ }
+ }
+
+ internal static void ValidateState(AudioIOState curState, params AudioIOState[] desiredStates)
+ {
+ Debug.Assert(desiredStates.Length > 0);
+
+ if (desiredStates.Contains(curState))
+ {
+ return;
+ }
+
+ throw new InvalidOperationException($"The audio is not in a valid state. " +
+ $"Current State : { curState }, Valid State : { string.Join(", ", desiredStates) }.");
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.AudioIO/AudioIO/AudioPlayback.cs b/src/Tizen.Multimedia.AudioIO/AudioIO/AudioPlayback.cs
new file mode 100644
index 0000000..1a6b8a9
--- /dev/null
+++ b/src/Tizen.Multimedia.AudioIO/AudioIO/AudioPlayback.cs
@@ -0,0 +1,386 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides the ability to directly manage the system audio output devices and play PCM (pulse-code modulation) data.
+ /// </summary>
+ public class AudioPlayback : IDisposable
+ {
+ public static readonly int MinSampleRate = 8000;
+ public static readonly int MaxSampleRate = 48000;
+
+ private IntPtr _handle = IntPtr.Zero;
+
+ private AudioIOState _state = AudioIOState.Idle;
+
+ #region Event
+ /// <summary>
+ /// Occurs when audio playback data can be written.
+ /// </summary>
+ /// <seealso cref="Write(byte[])"/>
+ public event EventHandler<AudioPlaybackBufferAvailableEventArgs> BufferAvailable;
+
+ private Interop.AudioIO.AudioStreamCallback _streamCallback;
+
+ private void RegisterStreamCallback()
+ {
+ _streamCallback = (IntPtr handle, uint bytes, IntPtr _) =>
+ {
+ BufferAvailable?.Invoke(this, new AudioPlaybackBufferAvailableEventArgs((int)bytes));
+ };
+
+ AudioIOUtil.ThrowIfError(
+ Interop.AudioIO.AudioOutput.SetStreamChangedCallback(_handle, _streamCallback, IntPtr.Zero),
+ $"Failed to create {nameof(AudioPlayback)}");
+ }
+
+ /// <summary>
+ /// Occurs when the state of the AudioPlayback is changed.
+ /// </summary>
+ public event EventHandler<AudioIOStateChangedEventArgs> StateChanged;
+
+ private Interop.AudioIO.AudioStateChangedCallback _stateChangedCallback;
+
+ private void RegisterStateChangedCallback()
+ {
+ _stateChangedCallback = (IntPtr handle, int previous, int current, bool byPolicy, IntPtr _) =>
+ {
+ _state = (AudioIOState)current;
+
+ StateChanged?.Invoke(this,
+ new AudioIOStateChangedEventArgs((AudioIOState)previous, _state, byPolicy));
+ };
+
+ AudioIOUtil.ThrowIfError(
+ Interop.AudioIO.AudioOutput.SetStateChangedCallback(_handle, _stateChangedCallback, IntPtr.Zero),
+ $"Failed to create {nameof(AudioPlayback)}");
+ }
+ #endregion
+
+ /// <summary>
+ /// Initializes a new instance of the AudioPlayback class with the specified sample rate, channel and sample type.
+ /// </summary>
+ /// <param name="sampleRate">The audio sample rate.(8000 ~ 48000Hz)</param>
+ /// <param name="channel">The audio channel type.</param>
+ /// <param name="sampleType">The audio sample type.</param>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="sampleRate"/> is less than <see cref="MinSampleRate"/>.\n
+ /// -or-\n
+ /// <paramref name="sampleRate"/> is greater than <see cref="MaxSampleRate"/>.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="channel"/> is invalid.\n
+ /// -or-\n
+ /// <paramref name="sampleType"/> is invalid.
+ /// </exception>
+ public AudioPlayback(int sampleRate, AudioChannel channel, AudioSampleType sampleType)
+ {
+ if (sampleRate < MinSampleRate || MaxSampleRate < sampleRate)
+ {
+ throw new ArgumentOutOfRangeException(nameof(sampleRate), sampleRate,
+ $"Valid sampleRate range is { MinSampleRate } <= x <= { MaxSampleRate }.");
+ }
+
+ ValidationUtil.ValidateEnum(typeof(AudioChannel), channel, nameof(channel));
+ ValidationUtil.ValidateEnum(typeof(AudioSampleType), sampleType, nameof(sampleType));
+
+ SampleRate = sampleRate;
+ Channel = channel;
+ SampleType = sampleType;
+
+ AudioIOUtil.ThrowIfError(
+ Interop.AudioIO.AudioOutput.Create(SampleRate, (int)Channel, (int)SampleType, out _handle),
+ $"Failed to create {nameof(AudioPlayback)}");
+
+ RegisterStreamCallback();
+ RegisterStateChangedCallback();
+ }
+
+ ~AudioPlayback()
+ {
+ Dispose(false);
+ }
+
+ #region Dispose support
+ private bool _isDisposed = false;
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_isDisposed)
+ {
+ return;
+ }
+
+ if (_handle != IntPtr.Zero)
+ {
+ if (_state != AudioIOState.Idle)
+ {
+ try
+ {
+ Unprepare();
+ }
+ catch (Exception)
+ {
+ }
+ }
+
+ Interop.AudioIO.AudioOutput.Destroy(_handle);
+ _handle = IntPtr.Zero;
+ _isDisposed = true;
+ }
+ }
+
+ private void ValidateNotDisposed()
+ {
+ if (_isDisposed)
+ {
+ throw new ObjectDisposedException(GetType().Name);
+ }
+ }
+ #endregion
+
+ private void ValidateState(params AudioIOState[] desiredStates)
+ {
+ ValidateNotDisposed();
+
+ AudioIOUtil.ValidateState(_state, desiredStates);
+ }
+
+ /// <summary>
+ /// Gets the sample rate of the audio output data stream.
+ /// </summary>
+ public int SampleRate { get; }
+
+ /// <summary>
+ /// Gets the channel type of the audio output data stream.
+ /// </summary>
+ public AudioChannel Channel { get; }
+
+ /// <summary>
+ /// Gets the sample type of the audio output data stream.
+ /// </summary>
+ public AudioSampleType SampleType { get; }
+
+ /// <summary>
+ /// Gets the sound type supported by the audio output device.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">The AudioPlayback has already been disposed.</exception>
+ public AudioStreamType StreamType
+ {
+ get
+ {
+ ValidateNotDisposed();
+
+ int audioType = 0;
+ int ret = Interop.AudioIO.AudioOutput.GetSoundType(_handle, out audioType);
+ MultimediaDebug.AssertNoError(ret);
+
+ return (AudioStreamType)audioType;
+ }
+ }
+
+ /// <summary>
+ /// Gets the size allocated for the audio output buffer.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">The AudioPlayback has already been disposed.</exception>
+ public int GetBufferSize()
+ {
+ AudioIOUtil.ThrowIfError(Interop.AudioIO.AudioOutput.GetBufferSize(_handle, out var size));
+ return size;
+ }
+
+ /// <summary>
+ /// Drains buffered audio data from the output stream.
+ /// It blocks the calling thread until draining the stream buffer completely. (e.g end of playback)
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">The AudioPlayback has already been disposed.</exception>
+ /// <exception cref="InvalidOperationException">The current state is <see cref="AudioIOState.Idle"/>.</exception>
+ public void Drain()
+ {
+ ValidateState(AudioIOState.Running, AudioIOState.Paused);
+
+ int ret = Interop.AudioIO.AudioOutput.Drain(_handle);
+
+ MultimediaDebug.AssertNoError(ret);
+ }
+
+ /// <summary>
+ /// Starts writing the audio data to the device.
+ /// </summary>
+ /// <param name="buffer">The buffer to write.</param>
+ /// <returns>The written size.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception>
+ /// <exception cref="ArgumentException">The length of <paramref name="buffer"/> is zero.</exception>
+ /// <exception cref="InvalidOperationException">The current state is not <see cref="AudioIOState.Running"/>.</exception>
+ /// <exception cref="ObjectDisposedException">The AudioPlayback has already been disposed.</exception>
+ public int Write(byte[] buffer)
+ {
+ ValidateState(AudioIOState.Running);
+
+ if (buffer == null)
+ {
+ throw new ArgumentNullException(nameof(buffer));
+ }
+
+ if (buffer.Length == 0)
+ {
+ throw new ArgumentException("buffer has no data.(the Length is zero.)", nameof(buffer));
+ }
+
+ int ret = Interop.AudioIO.AudioOutput.Write(_handle, buffer, (uint)buffer.Length);
+
+ AudioIOUtil.ThrowIfError(ret, "Failed to write buffer");
+
+ return ret;
+ }
+
+ /// <summary>
+ /// Prepares the AudioPlayback.
+ /// </summary>
+ /// <remarks>
+ /// This must be called before <see cref="Write(byte[])"/>.
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">
+ /// Operation failed due to internal error.\n
+ /// -or-\n
+ /// The current state is not <see cref="AudioIOState.Idle"/>.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">The AudioPlayback has already been disposed.</exception>
+ /// <seealso cref="Unprepare"/>
+ public void Prepare()
+ {
+ ValidateState(AudioIOState.Idle);
+
+ AudioIOUtil.ThrowIfError(Interop.AudioIO.AudioOutput.Prepare(_handle),
+ $"Failed to prepare the {nameof(AudioPlayback)}");
+ }
+
+ /// <summary>
+ /// Unprepares the AudioPlayback.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">
+ /// Operation failed due to internal error.\n
+ /// -or-\n
+ /// The current state is <see cref="AudioIOState.Idle"/>.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">The AudioPlayback has already been disposed.</exception>
+ /// <seealso cref="Prepare"/>
+ public void Unprepare()
+ {
+ ValidateState(AudioIOState.Running, AudioIOState.Paused);
+
+ AudioIOUtil.ThrowIfError(Interop.AudioIO.AudioOutput.Unprepare(_handle),
+ $"Failed to unprepare the {nameof(AudioPlayback)}");
+ }
+
+ /// <summary>
+ /// Pauses feeding of audio data to the device.
+ /// </summary>
+ /// <remarks>It has no effect if the current is the <see cref="AudioIOState.Paused"/>.</remarks>
+ /// <exception cref="InvalidOperationException">
+ /// The current state is <see cref="AudioIOState.Idle"/>.\n
+ /// -or-\n
+ /// The method is called in the <see cref="BufferAvailable"/> event handler.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">The AudioPlayback has already been disposed.</exception>
+ /// <seealso cref="Resume"/>
+ public void Pause()
+ {
+ if (_state == AudioIOState.Paused)
+ {
+ return;
+ }
+ ValidateState(AudioIOState.Running);
+
+ AudioIOUtil.ThrowIfError(Interop.AudioIO.AudioOutput.Pause(_handle));
+ }
+
+ /// <summary>
+ /// Resumes feeding of audio data to the device.
+ /// </summary>
+ /// <remarks>It has no effect if the current is the <see cref="AudioIOState.Running"/>.</remarks>
+ /// <exception cref="InvalidOperationException">
+ /// The current state is <see cref="AudioIOState.Idle"/>.\n
+ /// -or-\n
+ /// The method is called in an event handler.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">The AudioPlayback has already been disposed.</exception>
+ /// <seealso cref="Pause"/>
+ public void Resume()
+ {
+ if (_state == AudioIOState.Running)
+ {
+ return;
+ }
+ ValidateState(AudioIOState.Paused);
+
+ AudioIOUtil.ThrowIfError(Interop.AudioIO.AudioOutput.Resume(_handle));
+ }
+
+ /// <summary>
+ /// Flushes and discards buffered audio data from the output stream.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">The current state is <see cref="AudioIOState.Idle"/>.</exception>
+ /// <exception cref="ObjectDisposedException">The AudioPlayback has already been disposed.</exception>
+ public void Flush()
+ {
+ ValidateState(AudioIOState.Running, AudioIOState.Paused);
+
+ int ret = Interop.AudioIO.AudioOutput.Flush(_handle);
+
+ MultimediaDebug.AssertNoError(ret);
+ }
+
+ /// <summary>
+ /// Applies the sound stream information to the AudioPlayback.
+ /// </summary>
+ /// <param name="streamPolicy">The <see cref="AudioStreamPolicy"/> to apply for the AudioPlayback.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="streamPolicy"/> is null.</exception>
+ /// <exception cref="ObjectDisposedException">
+ /// <paramref name="streamPolicy"/> has already been disposed.\n
+ /// -or-\n
+ /// The AudioPlayback has already been disposed.
+ /// </exception>
+ /// <exception cref="NotSupportedException"><paramref name="streamPolicy"/> is not supported.</exception>
+ /// <exception cref="ArgumentException">Not able to retrieve information from <paramref name="streamPolicy"/>.</exception>
+ public void ApplyStreamPolicy(AudioStreamPolicy streamPolicy)
+ {
+ if (streamPolicy == null)
+ {
+ throw new ArgumentNullException(nameof(streamPolicy));
+ }
+
+ if (streamPolicy.Handle == IntPtr.Zero)
+ {
+ throw new ObjectDisposedException(nameof(streamPolicy));
+ }
+
+ ValidateNotDisposed();
+
+ AudioIOUtil.ThrowIfError(Interop.AudioIO.AudioOutput.SetStreamInfo(_handle, streamPolicy.Handle));
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.AudioIO/AudioIO/AudioPlaybackBufferAvailableEventArgs.cs b/src/Tizen.Multimedia.AudioIO/AudioIO/AudioPlaybackBufferAvailableEventArgs.cs
new file mode 100644
index 0000000..ac9a495
--- /dev/null
+++ b/src/Tizen.Multimedia.AudioIO/AudioIO/AudioPlaybackBufferAvailableEventArgs.cs
@@ -0,0 +1,30 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ public class AudioPlaybackBufferAvailableEventArgs : EventArgs
+ {
+ internal AudioPlaybackBufferAvailableEventArgs(int length)
+ {
+ Length = length;
+ }
+
+ public int Length { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia.AudioIO/Interop/Interop.AudioIO.cs b/src/Tizen.Multimedia.AudioIO/Interop/Interop.AudioIO.cs
new file mode 100644
index 0000000..1685489
--- /dev/null
+++ b/src/Tizen.Multimedia.AudioIO/Interop/Interop.AudioIO.cs
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class AudioIO
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate void AudioStreamCallback(IntPtr handle, uint nbytes, IntPtr userdata);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate void AudioStateChangedCallback(IntPtr handle, int previous, int current, bool byPolicy, IntPtr userData);
+
+ internal static partial class AudioInput
+ {
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_in_set_state_changed_cb")]
+ internal static extern int SetStateChangedCallback(IntPtr handle, AudioStateChangedCallback callback, IntPtr user_data);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_in_set_stream_cb")]
+ internal static extern int SetStreamCallback(IntPtr handle, AudioStreamCallback callback, IntPtr user_data);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_in_create")]
+ internal static extern int Create(int sampleRate, int channel, int type, out IntPtr handle);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_in_destroy")]
+ internal static extern int Destroy(IntPtr handle);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_in_set_sound_stream_info")]
+ internal static extern int SetStreamInfo(IntPtr handle, IntPtr streamInfoHandle);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_in_prepare")]
+ internal static extern int Prepare(IntPtr handle);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_in_unprepare")]
+ internal static extern int Unprepare(IntPtr handle);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_in_pause")]
+ internal static extern int Pause(IntPtr handle);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_in_resume")]
+ internal static extern int Resume(IntPtr handle);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_in_flush")]
+ internal static extern int Flush(IntPtr handle);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_in_read")]
+ internal static extern int Read(IntPtr handle, byte[] buffer, int length);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_in_get_buffer_size")]
+ internal static extern int GetBufferSize(IntPtr handle, out int size);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_in_get_sample_rate")]
+ internal static extern int GetSampleRate(IntPtr handle, out int sampleRate);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_in_get_channel")]
+ internal static extern int GetChannel(IntPtr handle, out int channel);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_in_get_sample_type")]
+ internal static extern int GetSampleType(IntPtr handle, out int sampleType);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_in_peek")]
+ internal static extern int Peek(IntPtr handle, out IntPtr buffer, ref uint length);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_in_drop")]
+ internal static extern int Drop(IntPtr handle);
+ }
+ internal static partial class AudioOutput
+ {
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_out_set_state_changed_cb")]
+ internal static extern int SetStateChangedCallback(IntPtr handle, AudioStateChangedCallback callback, IntPtr user_data);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_out_set_stream_cb")]
+ internal static extern int SetStreamChangedCallback(IntPtr handle, AudioStreamCallback callback, IntPtr user_data);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_out_create_new")]
+ internal static extern int Create(int sampleRate, int channel, int type, out IntPtr handle);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_out_destroy")]
+ internal static extern int Destroy(IntPtr handle);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_out_drain")]
+ internal static extern int Drain(IntPtr handle);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_out_flush")]
+ internal static extern int Flush(IntPtr handle);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_out_get_buffer_size")]
+ internal static extern int GetBufferSize(IntPtr handle, out int size);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_out_get_channel")]
+ internal static extern int GetChannel(IntPtr handle, out int channel);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_out_get_sample_rate")]
+ internal static extern int GetSampleRate(IntPtr handle, out int sampleRate);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_out_get_sample_type")]
+ internal static extern int GetSampleType(IntPtr handle, out int sampleType);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_out_get_sound_type")]
+ internal static extern int GetSoundType(IntPtr handle, out int soundType);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_out_pause")]
+ internal static extern int Pause(IntPtr handle);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_out_prepare")]
+ internal static extern int Prepare(IntPtr handle);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_out_resume")]
+ internal static extern int Resume(IntPtr handle);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_out_set_sound_stream_info")]
+ internal static extern int SetStreamInfo(IntPtr handle, IntPtr streamInfoHandle);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_out_unprepare")]
+ internal static extern int Unprepare(IntPtr handle);
+
+ [DllImport(Libraries.AudioIO, EntryPoint = "audio_out_write")]
+ internal static extern int Write(IntPtr handle, byte[] buffer, uint length);
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.AudioIO/Interop/Interop.Libraries.cs b/src/Tizen.Multimedia.AudioIO/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..3469f9f
--- /dev/null
+++ b/src/Tizen.Multimedia.AudioIO/Interop/Interop.Libraries.cs
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string AudioIO = "libcapi-media-audio-io.so.0";
+ public const string WavPlayer = "libcapi-media-wav-player.so.0";
+ public const string TonePlayer = "libcapi-media-tone-player.so.0";
+ }
+}
diff --git a/src/Tizen.Multimedia.AudioIO/Interop/Interop.TonePlayer.cs b/src/Tizen.Multimedia.AudioIO/Interop/Interop.TonePlayer.cs
new file mode 100644
index 0000000..17f8f0a
--- /dev/null
+++ b/src/Tizen.Multimedia.AudioIO/Interop/Interop.TonePlayer.cs
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Multimedia;
+
+internal static partial class Interop
+{
+ internal static partial class TonePlayer
+ {
+ [DllImport(Libraries.TonePlayer, EntryPoint = "tone_player_start_new")]
+ internal static extern int Start(ToneType tone, IntPtr streamInfoHandle, int durationMs, out int playerId);
+
+ [DllImport(Libraries.TonePlayer, EntryPoint = "tone_player_stop")]
+ internal static extern int Stop(int PlayerId);
+ }
+}
+
diff --git a/src/Tizen.Multimedia.AudioIO/Interop/Interop.WavPlayer.cs b/src/Tizen.Multimedia.AudioIO/Interop/Interop.WavPlayer.cs
new file mode 100644
index 0000000..933b1de
--- /dev/null
+++ b/src/Tizen.Multimedia.AudioIO/Interop/Interop.WavPlayer.cs
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class WavPlayer
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void WavPlayerCompletedCallback(int playerId, IntPtr userData);
+
+ [DllImport(Libraries.WavPlayer, EntryPoint = "wav_player_start_new")]
+ internal static extern int WavPlayerStart(string filePath, IntPtr streamInfoHandle, WavPlayerCompletedCallback completedCallback,
+ IntPtr userData, out int playerId);
+
+ [DllImport(Libraries.WavPlayer, EntryPoint = "wav_player_stop")]
+ internal static extern int WavPlayerStop(int PlayerId);
+ }
+}
diff --git a/src/Tizen.Multimedia.AudioIO/MultimediaDebug.cs b/src/Tizen.Multimedia.AudioIO/MultimediaDebug.cs
new file mode 100644
index 0000000..3e00569
--- /dev/null
+++ b/src/Tizen.Multimedia.AudioIO/MultimediaDebug.cs
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System.Diagnostics;
+
+namespace Tizen.Multimedia
+{
+ internal class MultimediaDebug
+ {
+ [Conditional("DEBUG")]
+ internal static void AssertNoError(int errorCode)
+ {
+ Debug.Assert(errorCode == (int)Internals.Errors.ErrorCode.None,
+ $"The API is supposed not to return an error! But it returns error({ errorCode }).",
+ "Implementation of core may have been changed, modify the call to throw if the return code is not ok.");
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.AudioIO/Tizen.Multimedia.AudioIO.csproj b/src/Tizen.Multimedia.AudioIO/Tizen.Multimedia.AudioIO.csproj
new file mode 100644
index 0000000..0e5378c
--- /dev/null
+++ b/src/Tizen.Multimedia.AudioIO/Tizen.Multimedia.AudioIO.csproj
@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen.Multimedia\Tizen.Multimedia.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Multimedia.AudioIO/TonePlayer/TonePlayer.cs b/src/Tizen.Multimedia.AudioIO/TonePlayer/TonePlayer.cs
new file mode 100644
index 0000000..091ba9c
--- /dev/null
+++ b/src/Tizen.Multimedia.AudioIO/TonePlayer/TonePlayer.cs
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Tizen.Multimedia
+{
+ static internal class TonePlayerLog
+ {
+ internal const string LogTag = "Tizen.Multimedia.TonePlayer";
+ }
+
+ /// <summary>
+ /// The TonePlayer class allows you to play and stop playing the tone. To play a particular
+ /// type of tone <see cref="Tizen.Multimedia.ToneType"/>,
+ /// use <see cref="Tizen.Multimedia.TonePlayer.StartAsync"/>.
+ /// </summary>
+ public static class TonePlayer
+ {
+ /// <summary>
+ /// Plays a tone, asynchronously.
+ /// </summary>
+ /// <param name="tone">The tone type to play.</param>
+ /// <param name="streamPolicy">The Audiostream policy object.</param>
+ /// <param name="durationMs">The tone duration in milliseconds. -1 indicates an infinite duration.</param>
+ /// <param name="cancellationToken">The cancellation token which can be used to stop playing the tone.</param>
+ /// <exception cref="ArgumentException">In case of invalid parameters</exception>
+ /// <exception cref="ArgumentNullException">In case of null parameters</exception>
+ /// <exception cref="ArgumentOutOfRangeException">In case of play duration less than -1.</exception>
+ /// <exception cref="InvalidOperationException">In case of any invalid operations</exception>
+ /// <exception cref="NotSupportedException">In case of tone type not supported.</exception>
+ public static async Task StartAsync(ToneType tone, AudioStreamPolicy streamPolicy, int durationMs, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ if (durationMs < -1)
+ {
+ throw new ArgumentOutOfRangeException(nameof(durationMs));
+ }
+
+ if (streamPolicy == null)
+ {
+ throw new ArgumentNullException(nameof(streamPolicy));
+
+ }
+
+ if (Enum.IsDefined(typeof(ToneType), tone) == false)
+ {
+ throw new ArgumentException("Invalid ToneType provided : " + tone);
+ }
+
+ int id;
+ var task = new TaskCompletionSource<int>();
+ int ret = Interop.TonePlayer.Start(tone, streamPolicy.Handle, durationMs, out id);
+ if (ret != (int)TonePlayerError.None)
+ {
+ Log.Error(TonePlayerLog.LogTag, "Error Occured with error code: " + (TonePlayerError)ret);
+ throw TonePlayerErrorFactory.CreateException(ret, "Failed to play tone.");
+ }
+
+ if (cancellationToken != CancellationToken.None)
+ {
+ cancellationToken.Register((playerId) =>
+ {
+ int resultCancel = Interop.TonePlayer.Stop((int)playerId);
+ if ((TonePlayerError)resultCancel != TonePlayerError.None)
+ {
+ Log.Error(TonePlayerLog.LogTag, "Failed to stop tone Player with error code: " + (TonePlayerError)resultCancel);
+ }
+ task.TrySetCanceled();
+ }, id);
+ }
+
+ if (durationMs != -1)
+ {
+ Task delayTask = Task.Delay(durationMs, cancellationToken);
+ await delayTask;
+ if (delayTask.IsCompleted)
+ {
+ task.TrySetResult(id);
+ }
+ }
+ await task.Task;
+ }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.AudioIO/TonePlayer/TonePlayerEnums.cs b/src/Tizen.Multimedia.AudioIO/TonePlayer/TonePlayerEnums.cs
new file mode 100644
index 0000000..cc256bf
--- /dev/null
+++ b/src/Tizen.Multimedia.AudioIO/TonePlayer/TonePlayerEnums.cs
@@ -0,0 +1,472 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Enumeration for Audio Codec.
+ /// </summary>
+ public enum ToneType
+ {
+ /// <summary>
+ /// The default tone.
+ /// </summary>
+ Default = 0,
+ /// <summary>
+ /// Predefined DTMF 0.
+ /// </summary>
+ Dtmf0 = 0,
+ /// <summary>
+ /// Predefined DTMF 1.
+ /// </summary>
+ Dtmf1,
+ /// <summary>
+ /// Predefined DTMF 2.
+ /// </summary>
+ Dtmf2,
+ /// <summary>
+ /// redefined DTMF 3.
+ /// </summary>
+ Dtmf3,
+ /// <summary>
+ /// Predefined DTMF 4.
+ /// </summary>
+ Dtmf4,
+ /// <summary>
+ /// Predefined DTMF 5.
+ /// </summary>
+ Dtmf5,
+ /// <summary>
+ /// Predefined DTMF 6.
+ /// </summary>
+ Dtmf6,
+ /// <summary>
+ /// Predefined DTMF 7.
+ /// </summary>
+ Dtmf7,
+ /// <summary>
+ /// Predefined DTMF 8.
+ /// </summary>
+ Dtmf8,
+ /// <summary>
+ /// Predefined DTMF 9.
+ /// </summary>
+ Dtmf9,
+ /// <summary>
+ /// Predefined DTMF Star - Asterisk.
+ /// </summary>
+ DtmfS,
+ /// <summary>
+ /// Predefined DTMF sharP (#).
+ /// </summary>
+ DtmfP,
+ /// <summary>
+ /// Predefined DTMF A (A).
+ /// </summary>
+ DtmfA,
+ /// <summary>
+ /// Predefined DTMF B (B).
+ /// </summary>
+ DtmfB,
+ /// <summary>
+ /// Predefined DTMF C (C).
+ /// </summary>
+ DtmfC,
+ /// <summary>
+ /// Predefined DTMF D (D).
+ /// </summary>
+ DtmfD,
+ /// <summary>
+ /// Call supervisory tone, Dial tone: CEPT: 425Hz, continuous.
+ /// </summary>
+ SupDial,
+ /// <summary>
+ /// Call supervisory tone, Dial tone: ANSI (IS-95): 350Hz+440Hz, continuous.
+ /// </summary>
+ AnsiDial,
+ /// <summary>
+ /// Call supervisory tone, Dial tone: JAPAN: 400Hz, continuous.
+ /// </summary>
+ JapanDial,
+ /// <summary>
+ /// Call supervisory tone, Busy: CEPT: 425Hz, 500ms ON, 500ms OFF.
+ /// </summary>
+ SupBusy,
+ /// <summary>
+ /// Call supervisory tone, Busy: ANSI (IS-95): 480Hz+620Hz, 500ms ON, 500ms OFF.
+ /// </summary>
+ AnsiBusy,
+ /// <summary>
+ /// Call supervisory tone, Busy: JAPAN: 400Hz, 500ms ON, 500ms OFF.
+ /// </summary>
+ JapanBusy,
+ /// <summary>
+ /// Call supervisory tone, Congestion: CEPT, JAPAN: 425Hz, 200ms ON, 200ms OFF.
+ /// </summary>
+ TsupCongestion,
+ /// <summary>
+ /// Call supervisory tone, Congestion: ANSI (IS-95): 480Hz+620Hz, 250ms ON, 250ms OFF.
+ /// </summary>
+ AnsiCongestion,
+ /// <summary>
+ /// Call supervisory tone, Radio path acknowledgment : CEPT, ANSI: 425Hz, 200ms ON.
+ /// </summary>
+ SupRadioAck,
+ /// <summary>
+ /// Call supervisory tone, Radio path acknowledgment : JAPAN: 400Hz, 1s ON, 2s OFF.
+ /// </summary>
+ JapanRadioAck,
+ /// <summary>
+ /// Call supervisory tone, Radio path not available: 425Hz, 200ms ON, 200 OFF 3 bursts.
+ /// </summary>
+ SupRadioNotavail,
+ /// <summary>
+ /// Call supervisory tone, Error/Special info: 950Hz+1400Hz+1800Hz, 330ms ON, 1s OFF.
+ /// </summary>
+ SupError,
+ /// <summary>
+ /// Call supervisory tone, Call Waiting: CEPT, JAPAN: 425Hz, 200ms ON, 600ms OFF, 200ms ON, 3s OFF.
+ /// </summary>
+ SupCallWaiting,
+ /// <summary>
+ /// Call supervisory tone, Call Waiting: ANSI (IS-95): 440 Hz, 300 ms ON, 9.7 s OFF, (100 ms ON, 100 ms OFF, 100 ms ON, 9.7s OFF.
+ /// </summary>
+ AnsiCallWaiting,
+ /// <summary>
+ /// Call supervisory tone, Ring Tone: CEPT, JAPAN: 425Hz, 1s ON, 4s OFF.
+ /// </summary>
+ SupRingtone,
+ /// <summary>
+ /// Call supervisory tone, Ring Tone: ANSI (IS-95): 440Hz + 480Hz, 2s ON, 4s OFF.
+ /// </summary>
+ AnsiRingtone,
+ /// <summary>
+ /// General beep: 400Hz+1200Hz, 35ms ON.
+ /// </summary>
+ PropBeep,
+ /// <summary>
+ /// Proprietary tone, positive acknowledgment: 1200Hz, 100ms ON, 100ms OFF 2 bursts.
+ /// </summary>
+ PropAck,
+ /// <summary>
+ /// Proprietary tone, negative acknowledgment: 300Hz+400Hz+500Hz, 400ms ON.
+ /// </summary>
+ PropNack,
+ /// <summary>
+ /// Proprietary tone, prompt tone: 400Hz+1200Hz, 200ms ON.
+ /// </summary>
+ PropPrompt,
+ /// <summary>
+ /// Proprietary tone, general double beep: twice 400Hz+1200Hz, 35ms ON, 200ms OFF, 35ms ON.
+ /// </summary>
+ PropBeep2,
+ /// <summary>
+ /// Call supervisory tone (IS-95), intercept tone: alternating 440 Hz and 620 Hz tones, each on for 250 ms.
+ /// </summary>
+ SupIntercept,
+ /// <summary>
+ /// Call supervisory tone (IS-95), abbreviated intercept: intercept tone limited to 4 seconds.
+ /// </summary>
+ SupInterceptAbbrev,
+ /// <summary>
+ /// Call supervisory tone (IS-95), abbreviated congestion: congestion tone limited to 4 seconds.
+ /// </summary>
+ SupCongestionAbbrev,
+ /// <summary>
+ /// Call supervisory tone (IS-95), confirm tone: a 350 Hz tone added to a 440 Hz tone repeated 3 times in a 100 ms on, 100 ms off cycle.
+ /// </summary>
+ SupConfirm,
+ /// <summary>
+ /// Call supervisory tone (IS-95), pip tone: four bursts of 480 Hz tone (0.1 s on, 0.1 s off).
+ /// </summary>
+ SupPip,
+ /// <summary>
+ /// 425Hz continuous.
+ /// </summary>
+ CdmaDialToneLite,
+ /// <summary>
+ /// CDMA USA Ringback: 440Hz+480Hz 2s ON, 4000 OFF.
+ /// </summary>
+ CdmaNetworkUsaRingback,
+ /// <summary>
+ /// CDMA Intercept tone: 440Hz 250ms ON, 620Hz 250ms ON.
+ /// </summary>
+ CdmaIntercept,
+ /// <summary>
+ /// CDMA Abbr Intercept tone: 440Hz 250ms ON, 620Hz 250ms ON.
+ /// </summary>
+ CdmaAbbrIntercept,
+ /// <summary>
+ /// CDMA Reorder tone: 480Hz+620Hz 250ms ON, 250ms OFF.
+ /// </summary>
+ CdmaReorder,
+ /// <summary>
+ /// CDMA Abbr Reorder tone: 480Hz+620Hz 250ms ON, 250ms OFF repeated for 8 times.
+ /// </summary>
+ CdmaAbbrReorder,
+ /// <summary>
+ /// CDMA Network Busy tone: 480Hz+620Hz 500ms ON, 500ms OFF continuous.
+ /// </summary>
+ CdmaNetworkBusy,
+ /// <summary>
+ /// CDMA Confirm tone: 350Hz+440Hz 100ms ON, 100ms OFF repeated for 3 times.
+ /// </summary>
+ CdmaConfirm,
+ /// <summary>
+ /// CDMA answer tone: silent tone - definition Frequency 0, 0ms ON, 0ms OFF.
+ /// </summary>
+ CdmaAnswer,
+ /// <summary>
+ /// CDMA Network Callwaiting tone: 440Hz 300ms ON.
+ /// </summary>
+ /// CdmaNetworkCallwaiting,
+ /// <summary>
+ /// CDMA PIP tone: 480Hz 100ms ON, 100ms OFF repeated for 4 times.
+ /// </summary>
+ CdmaPip,
+ /// <summary>
+ /// ISDN Call Signal Normal tone: {2091Hz 32ms ON, 2556 64ms ON} 20 times, 2091 32ms ON, 2556 48ms ON, 4s OFF.
+ /// </summary>
+ CdmaCallSignalIsdnNormal,
+ /// <summary>
+ /// ISDN Call Signal Intergroup tone: {2091Hz 32ms ON, 2556 64ms ON} 8 times, 2091Hz 32ms ON, 400ms OFF, {2091Hz 32ms ON, 2556Hz 64ms ON} 8times, 2091Hz 32ms ON, 4s OFF.
+ /// </summary>
+ CdmaCallSignalIsdnIntergroup,
+ /// <summary>
+ /// ISDN Call Signal SP PRI tone:{2091Hz 32ms ON, 2556 64ms ON} 4 times 2091Hz 16ms ON, 200ms OFF, {2091Hz 32ms ON, 2556Hz 64ms ON} 4 times, 2091Hz 16ms ON, 200ms OFF.
+ /// </summary>
+ CdmaCallSignalIsdnSpPri,
+ /// <summary>
+ /// ISDN Call sign PAT3 tone: silent tone.
+ /// </summary>
+ CdmaCallSignalIsdnPat3,
+ /// <summary>
+ /// ISDN Ping Ring tone: {2091Hz 32ms ON, 2556Hz 64ms ON} 5 times 2091Hz 20ms ON.
+ /// </summary>
+ CdmaCallSignalIsdnPingRing,
+ /// <summary>
+ /// ISDN Pat5 tone: silent tone.
+ /// </summary>
+ CdmaCallSignalIsdnPat5,
+ /// <summary>
+ /// ISDN Pat6 tone: silent tone.
+ /// </summary>
+ CdmaCallSignalIsdnPat6,
+ /// <summary>
+ /// ISDN Pat7 tone: silent tone.
+ /// </summary>
+ CdmaCallSignalIsdnPat7,
+ /// <summary>
+ /// TONE_CDMA_HIGH_L tone: {3700Hz 25ms, 4000Hz 25ms} 40 times 4000ms OFF, Repeat.
+ /// </summary>
+ CdmaHighL,
+ /// <summary>
+ /// TONE_CDMA_MED_L tone: {2600Hz 25ms, 2900Hz 25ms} 40 times 4000ms OFF, Repeat.
+ /// </summary>
+ CdmaMedL,
+ /// <summary>
+ /// TONE_CDMA_LOW_L tone: {1300Hz 25ms, 1450Hz 25ms} 40 times, 4000ms OFF, Repeat.
+ /// </summary>
+ CdmaLowL,
+ /// <summary>
+ /// CDMA HIGH SS tone: {3700Hz 25ms, 4000Hz 25ms} repeat 16 times, 400ms OFF, repeat.
+ /// </summary>
+ CdmaHighSs,
+ /// <summary>
+ /// CDMA MED SS tone: {2600Hz 25ms, 2900Hz 25ms} repeat 16 times, 400ms OFF, repeat.
+ /// </summary>
+ CdmaMedSs,
+ /// <summary>
+ /// CDMA LOW SS tone: {1300z 25ms, 1450Hz 25ms} repeat 16 times, 400ms OFF, repeat.
+ /// </summary>
+ CdmaLowSs,
+ /// <summary>
+ /// CDMA HIGH SSL tone: {3700Hz 25ms, 4000Hz 25ms} 8 times, 200ms OFF, {3700Hz 25ms, 4000Hz 25ms} repeat 8 times, 200ms OFF, {3700Hz 25ms, 4000Hz 25ms} repeat 16 times, 4000ms OFF, repeat.
+ /// </summary>
+ CdmaHighSsl,
+ /// <summary>
+ /// CDMA MED SSL tone: {2600Hz 25ms, 2900Hz 25ms} 8 times, 200ms OFF, {2600Hz 25ms, 2900Hz 25ms} repeat 8 times, 200ms OFF, {2600Hz 25ms, 2900Hz 25ms} repeat 16 times, 4000ms OFF, repeat.
+ /// </summary>
+ CdmaMedSsl,
+ /// <summary>
+ /// CDMA LOW SSL tone: {1300Hz 25ms, 1450Hz 25ms} 8 times, 200ms OFF, {1300Hz 25ms, 1450Hz 25ms} repeat 8 times, 200ms OFF, {1300Hz 25ms, 1450Hz 25ms} repeat 16 times, 4000ms OFF, repeat.
+ /// </summary>
+ CdmaLowSsl,
+ /// <summary>
+ /// CDMA HIGH SS2 tone: {3700Hz 25ms, 4000Hz 25ms} 20 times, 1000ms OFF, {3700Hz 25ms, 4000Hz 25ms} 20 times, 3000ms OFF, repeat.
+ /// </summary>
+ CdmaHighSs2,
+ /// <summary>
+ /// CDMA MED SS2 tone: {2600Hz 25ms, 2900Hz 25ms} 20 times, 1000ms OFF, {2600Hz 25ms, 2900Hz 25ms} 20 times, 3000ms OFF, repeat.
+ /// </summary>
+ CdmaMedSs2,
+ /// <summary>
+ /// CDMA LOW SS2 tone: {1300Hz 25ms, 1450Hz 25ms} 20 times, 1000ms OFF, {1300Hz 25ms, 1450Hz 25ms} 20 times, 3000ms OFF, repeat.
+ /// </summary>
+ CdmaLowSs2,
+ /// <summary>
+ /// CDMA HIGH SLS tone: {3700Hz 25ms, 4000Hz 25ms} 10 times, 500ms OFF, {3700Hz 25ms, 4000Hz 25ms} 20 times, 500ms OFF, {3700Hz 25ms, 4000Hz 25ms} 10 times, 3000ms OFF, REPEAT.
+ /// </summary>
+ CdmaHighSls,
+ /// <summary>
+ /// CDMA MED SLS tone: {2600Hz 25ms, 2900Hz 25ms} 10 times, 500ms OFF, {2600Hz 25ms, 2900Hz 25ms} 20 times, 500ms OFF, {2600Hz 25ms, 2900Hz 25ms} 10 times, 3000ms OFF, REPEAT.
+ /// </summary>
+ CdmaMedSls,
+ /// <summary>
+ /// CDMA LOW SLS tone: {1300Hz 25ms, 1450Hz 25ms} 10 times, 500ms OFF, {1300Hz 25ms, 1450Hz 25ms} 20 times, 500ms OFF, {1300Hz 25ms, 1450Hz 25ms} 10 times, 3000ms OFF, REPEAT.
+ /// </summary>
+ CdmaLowSls,
+ /// <summary>
+ /// CDMA HIGH S X4 tone: {3700Hz 25ms, 4000Hz 25ms} 10 times, 500ms OFF, {3700Hz 25ms, 4000Hz 25ms} 10 times, 500ms OFF, {3700Hz 25ms, 4000Hz 25ms} 10 times, 500ms OFF, {3700Hz 25ms, 4000Hz 25ms} 10 times, 2500ms OFF, REPEAT.
+ /// </summary>
+ CdmaHighSx4,
+ /// <summary>
+ /// CDMA MED S X4 tone: {2600Hz 25ms, 2900Hz 25ms} 10 times, 500ms OFF, {2600Hz 25ms, 2900Hz 25ms} 10 times, 500ms OFF, {2600Hz 25ms, 2900Hz 25ms} 10 times, 500ms OFF, {2600Hz 25ms, 2900Hz 25ms} 10 times, 2500ms OFF, REPEAT.
+ /// </summary>
+ CdmaMedSX4,
+ /// <summary>
+ /// CDMA LOW S X4 tone: {2600Hz 25ms, 2900Hz 25ms} 10 times, 500ms OFF, {2600Hz 25ms, 2900Hz 25ms} 10 times, 500ms OFF, {2600Hz 25ms, 2900Hz 25ms} 10 times, 500ms OFF, {2600Hz 25ms, 2900Hz 25ms} 10 times, 2500ms OFF, REPEAT.
+ /// </summary>
+ CdmaLowSX4,
+ /// <summary>
+ /// CDMA HIGH PBX L: {3700Hz 25ms, 4000Hz 25ms}20 times, 2000ms OFF, REPEAT.
+ /// </summary>
+ CdmaHighPbxL,
+ /// <summary>
+ /// CDMA MED PBX L: {2600Hz 25ms, 2900Hz 25ms}20 times, 2000ms OFF, REPEAT.
+ /// </summary>
+ CdmaMedPbxL,
+ /// <summary>
+ /// CDMA LOW PBX L: {1300Hz 25ms,1450Hz 25ms}20 times, 2000ms OFF, REPEAT.
+ /// </summary>
+ CdmaLowPbxL,
+ /// <summary>
+ /// CDMA HIGH PBX SS tone: {3700Hz 25ms, 4000Hz 25ms} 8 times 200 ms OFF, {3700Hz 25ms 4000Hz 25ms}8 times, 2000ms OFF, REPEAT.
+ /// </summary>
+ CdmaHighPbxSs,
+ /// <summary>
+ /// CDMA MED PBX SS tone: {2600Hz 25ms, 2900Hz 25ms} 8 times 200 ms OFF, {2600Hz 25ms 2900Hz 25ms}8 times, 2000ms OFF, REPEAT.
+ /// </summary>
+ CdmaMedPbxSs,
+ /// <summary>
+ /// CDMA LOW PBX SS tone: {1300Hz 25ms, 1450Hz 25ms} 8 times 200 ms OFF, {1300Hz 25ms 1450Hz 25ms}8 times, 2000ms OFF, REPEAT.
+ /// </summary>
+ CdmaLowPbxSs,
+ /// <summary>
+ /// CDMA HIGH PBX SSL tone:{3700Hz 25ms, 4000Hz 25ms} 8 times 200ms OFF, {3700Hz 25ms, 4000Hz 25ms} 8 times, 200ms OFF, {3700Hz 25ms, 4000Hz 25ms} 16 times, 1000ms OFF, REPEAT.
+ /// </summary>
+ CdmaHighPbxSsl,
+ /// <summary>
+ /// CDMA MED PBX SSL tone:{2600Hz 25ms, 2900Hz 25ms} 8 times 200ms OFF, {2600Hz 25ms, 2900Hz 25ms} 8 times, 200ms OFF, {2600Hz 25ms, 2900Hz 25ms} 16 times, 1000ms OFF, REPEAT.
+ /// </summary>
+ CdmaMedPbxSsl,
+ /// <summary>
+ /// CDMA LOW PBX SSL tone:{1300Hz 25ms, 1450Hz 25ms} 8 times 200ms OFF, {1300Hz 25ms, 1450Hz 25ms} 8 times, 200ms OFF, {1300Hz 25ms, 1450Hz 25ms} 16 times, 1000ms OFF, REPEAT.
+ /// </summary>
+ CdmaLowPbxSsl,
+ /// <summary>
+ /// CDMA HIGH PBX SLS tone:{3700Hz 25ms, 4000Hz 25ms} 8 times 200ms OFF, {3700Hz 25ms, 4000Hz 25ms} 16 times, 200ms OFF, {3700Hz 25ms, 4000Hz 25ms} 8 times, 1000ms OFF, REPEAT.
+ /// </summary>
+ CdmaHighPbxSls,
+ /// <summary>
+ /// CDMA MED PBX SLS tone:{2600Hz 25ms, 2900Hz 25ms} 8 times 200ms OFF, {2600Hz 25ms, 2900Hz 25ms} 16 times, 200ms OFF, {2600Hz 25ms, 2900Hz 25ms} 8 times, 1000ms OFF, REPEAT.
+ /// </summary>
+ CdmaMedPbxSls,
+ /// <summary>
+ /// CDMA LOW PBX SLS tone:{1300Hz 25ms, 1450Hz 25ms} 8 times 200ms OFF, {1300Hz 25ms, 1450Hz 25ms} 16 times, 200ms OFF, {1300Hz 25ms, 1450Hz 25ms} 8 times, 1000ms OFF, REPEAT.
+ /// </summary>
+ CdmaLowPbxSls,
+ /// <summary>
+ /// CDMA HIGH PBX X S4 tone: {3700Hz 25ms 4000Hz 25ms} 8 times, 200ms OFF, {3700Hz 25ms 4000Hz 25ms} 8 times, 200ms OFF, {3700Hz 25ms 4000Hz 25ms} 8 times, 200ms OFF, {3700Hz 25ms 4000Hz 25ms} 8 times, 800ms OFF, REPEAT.
+ /// </summary>
+ CdmaHighPbxSX4,
+ /// <summary>
+ /// CDMA MED PBX X S4 tone: {2600Hz 25ms 2900Hz 25ms} 8 times, 200ms OFF, {2600Hz 25ms 2900Hz 25ms} 8 times, 200ms OFF, {2600Hz 25ms 2900Hz 25ms} 8 times, 200ms OFF, {2600Hz 25ms 2900Hz 25ms} 8 times, 800ms OFF, REPEAT.
+ /// </summary>
+ CdmaMedPbxSX4,
+ /// <summary>
+ /// CDMA LOW PBX X S4 tone: {1300Hz 25ms 1450Hz 25ms} 8 times, 200ms OFF, {1300Hz 25ms 1450Hz 25ms} 8 times, 200ms OFF, {1300Hz 25ms 1450Hz 25ms} 8 times, 200ms OFF, {1300Hz 25ms 1450Hz 25ms} 8 times, 800ms OFF, REPEAT.
+ /// </summary>
+ CdmaLowPbxSX4,
+ /// <summary>
+ /// CDMA Alert Network Lite tone: 1109Hz 62ms ON, 784Hz 62ms ON, 740Hz 62ms ON 622Hz 62ms ON, 1109Hz 62ms ON.
+ /// </summary>
+ CdmaAlertNetworkLite,
+ /// <summary>
+ ///CDMA Alert Auto Redial tone: {1245Hz 62ms ON, 659Hz 62ms ON} 3 times, 1245 62ms ON.
+ /// </summary>
+ CdmaAlertAutoredialLite,
+ /// <summary>
+ /// CDMA One Min Beep tone: 1150Hz+770Hz 400ms ON.
+ /// </summary>
+ CdmaOneMinBeep,
+ /// <summary>
+ /// CDMA KEYPAD Volume key lite tone: 941Hz+1477Hz 120ms ON.
+ /// </summary>
+ CdmaKeypadVolumeKeyLite,
+ /// <summary>
+ /// CDMA PRESSHOLDKEY LITE tone: 587Hz 375ms ON, 1175Hz 125ms ON.
+ /// </summary>
+ CdmaPressHoldKeyLite,
+ /// <summary>
+ /// CDMA ALERT INCALL LITE tone: 587Hz 62ms, 784 62ms, 831Hz 62ms, 784Hz 62ms, 1109 62ms, 784Hz 62ms, 831Hz 62ms, 784Hz 62ms.
+ /// </summary>
+ CdmaAlertIncallLite,
+ /// <summary>
+ /// CDMA EMERGENCY RINGBACK tone: {941Hz 125ms ON, 10ms OFF} 3times 4990ms OFF, REPEAT.
+ /// </summary>
+ CdmaEmergencyRingback,
+ /// <summary>
+ /// CDMA ALERT CALL GUARD tone: {1319Hz 125ms ON, 125ms OFF} 3 times.
+ /// </summary>
+ CdmaAlertCallGuard,
+ /// <summary>
+ /// CDMA SOFT ERROR LITE tone: 1047Hz 125ms ON, 370Hz 125ms.
+ /// </summary>
+ CdmaSoftErrorLite,
+ /// <summary>
+ /// CDMA CALLDROP LITE tone: 1480Hz 125ms, 1397Hz 125ms, 784Hz 125ms.
+ /// </summary>
+ CdmaCalldropLite,
+ /// <summary>
+ /// CDMA_NETWORK_BUSY_ONE_SHOT tone: 425Hz 500ms ON, 500ms OFF.
+ /// </summary>
+ CdmaNetworkBusyOneShot,
+ /// <summary>
+ /// CDMA_ABBR_ALERT tone: 1150Hz+770Hz 400ms ON.
+ /// </summary>
+ CdmaAbbrAlert,
+ /// <summary>
+ /// CDMA_SIGNAL_OFF - silent tone.
+ /// </summary>
+ CdmaSignalOff,
+ /// <summary>
+ /// User Defined Tone: 100Hz continuous.
+ /// </summary>
+ UserDefinedLowFre,
+ /// <summary>
+ /// User Defined Tone: 200Hz continuous.
+ /// </summary>
+ UserDefinedMedFre,
+ /// <summary>
+ /// User Defined Tone: 300Hz continuous.
+ /// </summary>
+ UserDefinedHighFre
+ }
+}
+
diff --git a/src/Tizen.Multimedia.AudioIO/TonePlayer/TonePlayerErrorFactory.cs b/src/Tizen.Multimedia.AudioIO/TonePlayer/TonePlayerErrorFactory.cs
new file mode 100644
index 0000000..8386558
--- /dev/null
+++ b/src/Tizen.Multimedia.AudioIO/TonePlayer/TonePlayerErrorFactory.cs
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Multimedia
+{
+ internal enum TonePlayerError
+ {
+ None = ErrorCode.None,
+ InvalidParameter = ErrorCode.InvalidParameter,
+ InvalidOperation = ErrorCode.InvalidOperation,
+ TizenErrorTonePlayer = -0x01970000,
+ TypeNotSupported = TizenErrorTonePlayer | 0x01
+ }
+
+ internal static class TonePlayerErrorFactory
+ {
+ internal static Exception CreateException(int errorCode, string errorMessage)
+ {
+ TonePlayerError err = (TonePlayerError)errorCode;
+ Exception exp;
+ if (string.IsNullOrEmpty(errorMessage))
+ {
+ errorMessage = err.ToString();
+ }
+
+ switch ((TonePlayerError)errorCode)
+ {
+ case TonePlayerError.InvalidParameter:
+ {
+ exp = new ArgumentException(errorMessage + "Invalid parameters provided");
+ break;
+ }
+
+ case TonePlayerError.TypeNotSupported:
+ {
+ exp = new NotSupportedException(errorMessage + "Not Supported");
+ break;
+ }
+
+ case TonePlayerError.InvalidOperation:
+ {
+ exp = new InvalidOperationException(errorMessage + "Invalid Operation");
+ break;
+ }
+ default:
+ {
+ exp = new InvalidOperationException(errorMessage);
+ break;
+ }
+ }
+ return exp;
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.AudioIO/ValdiationUtil.cs b/src/Tizen.Multimedia.AudioIO/ValdiationUtil.cs
new file mode 100644
index 0000000..d896ced
--- /dev/null
+++ b/src/Tizen.Multimedia.AudioIO/ValdiationUtil.cs
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ internal static class ValidationUtil
+ {
+ internal static void ValidateEnum(Type enumType, object value, string paramName)
+ {
+ if (!Enum.IsDefined(enumType, value))
+ {
+ throw new ArgumentException($"Invalid { enumType.Name } value : { value }", paramName);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.AudioIO/WavPlayer/WavPlayer.cs b/src/Tizen.Multimedia.AudioIO/WavPlayer/WavPlayer.cs
new file mode 100644
index 0000000..ad27fce
--- /dev/null
+++ b/src/Tizen.Multimedia.AudioIO/WavPlayer/WavPlayer.cs
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Tizen.Multimedia
+{
+ static internal class WavPlayerLog
+ {
+ internal const string LogTag = "Tizen.Multimedia.WavPlayer";
+ }
+
+ /// <summary>
+ /// The WavPlayer class allows you to simply play and stop a wav file. To play a certain
+ /// wav file, call <see cref="Tizen.Multimedia.WavPlayer.StartAsync"/> with
+ /// a path to the .wav file.
+ /// </summary>
+ public static class WavPlayer
+ {
+ /// <summary>
+ /// Plays a WAV file with the stream information of AudioManager, asynchronously.
+ /// </summary>
+ /// <param name="inputFilePath">The file path to play.</param>
+ /// <param name="streamPolicy">The Audiostream policy object.</param>
+ /// <param name="cancellationToken">The cancellation token which can be used to stop the Wav Player.</param>
+ /// <returns>The WAV player ID.</returns>
+ /// <exception cref="ArgumentException">In case of invalid parameters</exception>
+ /// <exception cref="ArgumentNullException">In case of null parameters</exception>
+ /// <exception cref="InvalidOperationException">In case of any invalid operations</exception>
+ /// <exception cref="NotSupportedException">In case of format not supported.</exception>
+ public static async Task StartAsync(string inputFilePath, AudioStreamPolicy streamPolicy, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ int id;
+ var task = new TaskCompletionSource<int>();
+
+ if (String.IsNullOrEmpty(inputFilePath))
+ {
+ throw new ArgumentNullException(nameof(inputFilePath));
+ }
+
+ if (streamPolicy == null)
+ {
+ throw new ArgumentNullException(nameof(streamPolicy));
+ }
+
+ Interop.WavPlayer.WavPlayerCompletedCallback _playerCompletedCallback = (int playerId, IntPtr userData) =>
+ {
+ task.TrySetResult(playerId);
+ };
+ GCHandle callbackHandle = GCHandle.Alloc(_playerCompletedCallback);
+
+ int ret = Interop.WavPlayer.WavPlayerStart(inputFilePath, streamPolicy.Handle, _playerCompletedCallback, IntPtr.Zero, out id);
+ if (ret != (int)WavPlayerError.None)
+ {
+ Log.Error(WavPlayerLog.LogTag, "Error Occured with error code: " + (WavPlayerError)ret);
+ task.TrySetException(WavPlayerErrorFactory.CreateException(ret, "Failed to play Wav file."));
+ }
+
+ if (cancellationToken != CancellationToken.None)
+ {
+ cancellationToken.Register((playerId) =>
+ {
+ int resultCancel = Interop.WavPlayer.WavPlayerStop((int)playerId);
+ if ((WavPlayerError)resultCancel != WavPlayerError.None)
+ {
+ Log.Error(WavPlayerLog.LogTag, "Failed to stop Wav Player with error code: " + (WavPlayerError)resultCancel);
+ }
+ task.TrySetCanceled();
+ }, id);
+ }
+
+ await task.Task;
+ callbackHandle.Free();
+ }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.AudioIO/WavPlayer/WavPlayerErrorFactory.cs b/src/Tizen.Multimedia.AudioIO/WavPlayer/WavPlayerErrorFactory.cs
new file mode 100644
index 0000000..435a127
--- /dev/null
+++ b/src/Tizen.Multimedia.AudioIO/WavPlayer/WavPlayerErrorFactory.cs
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Multimedia
+{
+ internal enum WavPlayerError
+ {
+ None = ErrorCode.None,
+ InvalidParameter = ErrorCode.InvalidParameter,
+ InvalidOperation = ErrorCode.InvalidOperation,
+ TizenErrorWavPlayer = -0x01990000,
+ FormatNotSupported = TizenErrorWavPlayer | 0x01,
+ NotSupportedType = TizenErrorWavPlayer | 0x02
+ }
+
+ internal static class WavPlayerErrorFactory
+ {
+ internal static void ThrowException(int errorCode, string errorMessage = null, string paramName = null)
+ {
+ WavPlayerError err = (WavPlayerError)errorCode;
+ if (string.IsNullOrEmpty(errorMessage))
+ {
+ errorMessage = err.ToString();
+ }
+
+ switch ((WavPlayerError)errorCode)
+ {
+ case WavPlayerError.InvalidParameter:
+ throw new ArgumentException(errorMessage, paramName);
+
+ case WavPlayerError.FormatNotSupported:
+ case WavPlayerError.NotSupportedType:
+ throw new NotSupportedException(errorMessage);
+
+ case WavPlayerError.InvalidOperation:
+ throw new InvalidOperationException(errorMessage);
+ }
+ }
+
+ internal static Exception CreateException(int errorCode, string errorMessage)
+ {
+ WavPlayerError err = (WavPlayerError)errorCode;
+ Exception exp;
+ if (string.IsNullOrEmpty(errorMessage))
+ {
+ errorMessage = err.ToString();
+ }
+
+ switch ((WavPlayerError)errorCode)
+ {
+ case WavPlayerError.InvalidParameter:
+ {
+ exp = new ArgumentException(errorMessage + "Invalid parameters provided");
+ break;
+ }
+
+ case WavPlayerError.FormatNotSupported:
+ case WavPlayerError.NotSupportedType:
+ {
+ exp = new NotSupportedException(errorMessage + "Not Supported");
+ break;
+ }
+
+ case WavPlayerError.InvalidOperation:
+ {
+ exp = new InvalidOperationException(errorMessage + "Invalid Operation");
+ break;
+ }
+ default:
+ {
+ exp = new InvalidOperationException(errorMessage);
+ break;
+ }
+ }
+ return exp;
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Camera/Camera/Camera.cs b/src/Tizen.Multimedia.Camera/Camera/Camera.cs
new file mode 100755
index 0000000..691f450
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Camera/Camera.cs
@@ -0,0 +1,954 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Threading;
+using static Interop;
+using Native = Interop.Camera;
+
+namespace Tizen.Multimedia
+{
+ static internal class CameraLog
+ {
+ internal const string Tag = "Tizen.Multimedia.Camera";
+ internal const string Enter = "[Enter]";
+ internal const string Leave = "[Leave]";
+ }
+
+ /// <summary>
+ /// The camera class provides methods to capture photos and support setting up notifications
+ /// for state changes of capturing, previewing, focusing, information about resolution and binary format
+ /// and functions for picture manipulations like sepia negative and many more.
+ /// It also notifies you when a significant picture parameter changes e.g. focus.
+ /// </summary>
+ public class Camera : IDisposable, IDisplayable<CameraError>
+ {
+ private IntPtr _handle = IntPtr.Zero;
+ private bool _disposed = false;
+ private CameraState _state = CameraState.None;
+ private static Dictionary<object, int> _callbackIdInfo = new Dictionary<object, int>();
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Camera"/> Class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="device">The camera device to access</param>
+ public Camera(CameraDevice device)
+ {
+ CameraErrorFactory.ThrowIfError(Native.Create(device, out _handle),
+ "Failed to create camera instance");
+
+ Feature = new CameraFeatures(this);
+ Setting = new CameraSettings(this);
+ DisplaySettings = new CameraDisplaySettings(this);
+
+ RegisterCallbacks();
+
+ SetState(CameraState.Created);
+ }
+
+ /// <summary>
+ /// Destructor of the camera class.
+ /// </summary>
+ ~Camera()
+ {
+ Dispose(false);
+ }
+
+ public IntPtr Handle => GetHandle();
+
+ internal IntPtr GetHandle()
+ {
+ ValidateNotDisposed();
+ return _handle;
+ }
+
+ #region Dispose support
+ /// <summary>
+ /// Releases the unmanaged resources used by the Camera.
+ /// </summary>
+ /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (disposing)
+ {
+ // to be used if there are any other disposable objects
+ }
+
+ if (_handle != IntPtr.Zero)
+ {
+ Native.Destroy(_handle);
+ _handle = IntPtr.Zero;
+ }
+
+ _disposed = true;
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by the Camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public void Dispose()
+ {
+ ReplaceDisplay(null);
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ internal void ValidateNotDisposed()
+ {
+ if (_disposed)
+ {
+ Log.Error(CameraLog.Tag, "Camera handle is disposed.");
+ throw new ObjectDisposedException(nameof(Camera));
+ }
+ }
+ #endregion Dispose support
+
+ #region Check camera state
+ internal void ValidateState(params CameraState[] required)
+ {
+ ValidateNotDisposed();
+
+ Debug.Assert(required.Length > 0);
+
+ var curState = _state;
+ if (!required.Contains(curState))
+ {
+ throw new InvalidOperationException($"The camera is not in a valid state. " +
+ $"Current State : { curState }, Valid State : { string.Join(", ", required) }.");
+ }
+ }
+
+ internal void SetState(CameraState state)
+ {
+ _state = state;
+ }
+ #endregion Check camera state
+
+ #region EventHandlers
+ /// <summary>
+ /// Event that occurs when an camera is interrupted by policy.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<CameraInterruptedEventArgs> Interrupted;
+ private Native.InterruptedCallback _interruptedCallback;
+
+ /// <summary>
+ /// Event that occurs when there is an asynchronous error.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<CameraErrorOccurredEventArgs> ErrorOccurred;
+ private Native.ErrorCallback _errorCallback;
+
+ /// <summary>
+ /// Event that occurs when the auto focus state is changed.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<CameraFocusStateChangedEventArgs> FocusStateChanged;
+ private Native.FocusStateChangedCallback _focusStateChangedCallback;
+
+ /// <summary>
+ /// Event that occurs when a face is detected in preview frame.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<FaceDetectedEventArgs> FaceDetected;
+ private Native.FaceDetectedCallback _faceDetectedCallback;
+
+ /// <summary>
+ /// Event that occurs during capture of image.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<CameraCapturingEventArgs> Capturing;
+ private Native.CapturingCallback _capturingCallback;
+
+ /// <summary>
+ /// Event that occurs after the capture of the image.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<EventArgs> CaptureCompleted;
+ private Native.CaptureCompletedCallback _captureCompletedCallback;
+
+ /// <summary>
+ /// Event that occurs when there is change in HDR capture progress.
+ /// Check whether HdrCapture feature is supported or not before add this EventHandler.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<HdrCaptureProgressEventArgs> HdrCaptureProgress;
+ private Native.HdrCaptureProgressCallback _hdrCaptureProgressCallback;
+
+ /// <summary>
+ /// Event that occurs when camera state is changed.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<CameraStateChangedEventArgs> StateChanged;
+ private Native.StateChangedCallback _stateChangedCallback;
+
+ #region DeviceStateChanged callback
+ internal static Native.DeviceStateChangedCallback _deviceStateChangedCallback;
+ private static event EventHandler<CameraDeviceStateChangedEventArgs> _deviceStateChanged;
+ private static object _deviceStateChangedEventLock = new object();
+
+ /// <summary>
+ /// Set the DeviceStateChanged Callback.
+ /// User doesn't need to create camera instance.
+ /// This static EventHandler calls platform function every time because each callback function have to remain its own callbackId.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="callback">Callback of type <see cref="Native.DeviceStateChangedCallback"/>.</param>
+ /// <param name="callbackId">The Id of registered callback.</param>
+ /// <exception cref="InvalidOperationException">In case of any invalid operations</exception>
+ /// <exception cref="NotSupportedException">In case of this feature is not supported</exception>
+ /// <exception cref="ArgumentException">In case of invalid parameters</exception>
+ public static event EventHandler<CameraDeviceStateChangedEventArgs> DeviceStateChanged
+ {
+ add
+ {
+ lock (_deviceStateChangedEventLock)
+ {
+ _deviceStateChangedCallback = (CameraDevice device, CameraDeviceState state, IntPtr userData) =>
+ {
+ _deviceStateChanged?.Invoke(null, new CameraDeviceStateChangedEventArgs(device, state));
+ };
+ CameraErrorFactory.ThrowIfError(Native.SetDeviceStateChangedCallback(_deviceStateChangedCallback, IntPtr.Zero, out int callbackId),
+ "Failed to set interrupt callback");
+
+ // Keep current callbackId and EventHandler pair to remove EventHandler later.
+ _callbackIdInfo.Add(value, callbackId);
+ Log.Info(CameraLog.Tag, "add callbackId " + callbackId.ToString());
+
+ _deviceStateChanged += value;
+ }
+ }
+
+ remove
+ {
+ lock (_deviceStateChangedEventLock)
+ {
+ _deviceStateChanged -= value;
+
+ _callbackIdInfo.TryGetValue(value, out int callbackId);
+ Log.Info(CameraLog.Tag, "remove callbackId " + callbackId.ToString());
+
+ CameraErrorFactory.ThrowIfError(Native.UnsetDeviceStateChangedCallback(callbackId),
+ "Unsetting media packet preview callback failed");
+
+ _callbackIdInfo.Remove(value);
+
+ if (_deviceStateChanged == null)
+ {
+ _deviceStateChangedCallback = null;
+ }
+ }
+ }
+ }
+ #endregion DeviceStateChanged callback
+
+ #region Preview EventHandler
+ private Native.PreviewCallback _previewCallback;
+ private event EventHandler<PreviewEventArgs> _preview;
+ private object _previewEventLock = new object();
+ /// <summary>
+ /// Event that occurs once per frame when previewing.
+ /// Preview callback is registered when user add callback explicitly to avoid useless P/Invoke.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<PreviewEventArgs> Preview
+ {
+ add
+ {
+ lock (_previewEventLock)
+ {
+ if (_preview == null)
+ {
+ RegisterPreviewCallback();
+ }
+
+ _preview += value;
+ }
+ }
+
+ remove
+ {
+ lock (_previewEventLock)
+ {
+ _preview -= value;
+
+ if (_preview == null)
+ {
+ CameraErrorFactory.ThrowIfError(Native.UnsetPreviewCallback(_handle),
+ "Unsetting preview callback failed");
+ _previewCallback = null;
+ }
+ }
+ }
+ }
+ #endregion Preview EventHandler
+
+ #region MediaPacketPreview EventHandler
+ private Native.MediaPacketPreviewCallback _mediaPacketPreviewCallback;
+ private EventHandler<MediaPacketPreviewEventArgs> _mediaPacketPreview;
+ private object _mediaPacketPreviewEventLock = new object();
+
+ /// <summary>
+ /// Event that occurs once per frame when previewing.
+ /// Preview callback is registered when user add callback explicitly to avoid useless P/Invoke.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<MediaPacketPreviewEventArgs> MediaPacketPreview
+ {
+ add
+ {
+ lock (_mediaPacketPreviewEventLock)
+ {
+ if (_mediaPacketPreview == null)
+ {
+ RegisterMediaPacketPreviewCallback();
+ }
+
+ _mediaPacketPreview += value;
+ }
+ }
+
+ remove
+ {
+ lock (_mediaPacketPreviewEventLock)
+ {
+ _mediaPacketPreview -= value;
+
+ if (_mediaPacketPreview == null)
+ {
+ CameraErrorFactory.ThrowIfError(Native.UnsetMediaPacketPreviewCallback(_handle),
+ "Unsetting media packet preview callback failed");
+ _mediaPacketPreviewCallback = null;
+ }
+ }
+ }
+ }
+ #endregion MediaPacketPreview EventHandler
+ #endregion EventHandlers
+
+ #region Properties
+ /// <summary>
+ /// Get/Set the various camera settings.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public CameraSettings Setting { get; }
+
+ /// <summary>
+ /// Gets the various camera features.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public CameraFeatures Feature { get; }
+
+ /// <summary>
+ /// Get/set various camera display properties.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public CameraDisplaySettings DisplaySettings{ get; }
+
+ private Display _display;
+
+ private CameraError SetDisplay(Display display)
+ {
+ if (display == null)
+ {
+ return CameraDisplay.SetTarget(GetHandle(), DisplayType.None, IntPtr.Zero);
+ }
+
+ return display.ApplyTo(this);
+ }
+
+ private void ReplaceDisplay(Display newDisplay)
+ {
+ if (_display != null)
+ {
+ _display.Owner = null;
+ }
+ _display = newDisplay;
+ if (_display != null)
+ {
+ _display.Owner = this;
+ }
+ }
+
+ /// <summary>
+ /// Sets or gets the display type and handle to show preview images.
+ /// The camera must be in the <see cref="CameraState.Created"/> state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// This must be set before StartPreview() method.
+ /// In Custom ROI display mode, DisplayRoiArea property must be set before calling this method.
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">In case of any invalid operations.</exception>
+ /// <exception cref="NotSupportedException">In case of this feature is not supported.</exception>
+ /// <exception cref="ObjectDisposedException" > The camera already has been disposed.</exception>
+ /// <exception cref="UnauthorizedAccessException">In case of access to the resources cannot be granted.</exception>
+ public Display Display
+ {
+ get
+ {
+ return _display;
+ }
+
+ set
+ {
+ ValidateState(CameraState.Created);
+
+ if (value != null && value.Owner != null)
+ {
+ if (ReferenceEquals(this, value.Owner))
+ {
+ return;
+ }
+ else
+ {
+ throw new ArgumentException("The display has already been assigned to another.");
+ }
+ }
+ CameraErrorFactory.ThrowIfError(SetDisplay(value), "Failed to set the camera display");
+
+ ReplaceDisplay(value);
+ }
+ }
+
+ CameraError IDisplayable<CameraError>.ApplyEvasDisplay(DisplayType type, ElmSharp.EvasObject evasObject)
+ {
+ Debug.Assert(_disposed == false);
+ ValidationUtil.ValidateEnum(typeof(DisplayType), type, nameof(type));
+
+ return CameraDisplay.SetTarget(GetHandle(), type, evasObject);
+ }
+
+ /// <summary>
+ /// Gets the state of the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> None, Created, Preview, Capturing, Captured </value>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public CameraState State
+ {
+ get
+ {
+ ValidateNotDisposed();
+
+ CameraState val = CameraState.None;
+ CameraErrorFactory.ThrowIfError(Native.GetState(_handle, out val),
+ "Failed to get camera state");
+
+ return val;
+ }
+ }
+
+ /// <summary>
+ /// The hint for display reuse.
+ /// If the hint is set to true, the display will be reused when the camera device is changed with
+ /// ChangeDevice method.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ArgumentException">In case of invalid parameters.</exception>
+ /// <exception cref="InvalidOperationException">Invalid state.</exception>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public bool DisplayReuseHint
+ {
+ get
+ {
+ ValidateNotDisposed();
+
+ CameraErrorFactory.ThrowIfError(Native.GetDisplayReuseHint(_handle, out bool val),
+ "Failed to get camera display reuse hint");
+
+ return val;
+ }
+
+ set
+ {
+ ValidateState(CameraState.Preview);
+
+ CameraErrorFactory.ThrowIfError(Native.SetDisplayReuseHint(_handle, value),
+ "Failed to set display reuse hint.");
+ }
+ }
+
+ /// <summary>
+ /// Gets the facing direction of camera module.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A <see cref="CameraFacingDirection"/> that specifies the facing direction of camera device.</value>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public CameraFacingDirection Direction
+ {
+ get
+ {
+ ValidateNotDisposed();
+
+ CameraErrorFactory.ThrowIfError(Native.GetFacingDirection(_handle, out var val),
+ "Failed to get camera direction");
+
+ return val;
+ }
+ }
+
+ /// <summary>
+ /// Gets the camera device count.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>This returns 2, if the device supports primary and secondary cameras.
+ /// Otherwise 1, if the device only supports primary camera.</value>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public int CameraCount
+ {
+ get
+ {
+ ValidateNotDisposed();
+
+ CameraErrorFactory.ThrowIfError(Native.GetDeviceCount(_handle, out int val),
+ "Failed to get camera device count");
+
+ return val;
+ }
+ }
+ #endregion Properties
+
+ #region Methods
+ /// <summary>
+ /// Changes the camera device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="device">The hardware camera to access.</param>
+ /// <remarks>
+ /// If display reuse is set using <see cref="DisplayReuseHint"/>
+ /// before stopping the preview, the display will be reused and last frame on the display
+ /// can be kept even though camera device is changed.
+ /// The camera must be in the <see cref="CameraState.Created"/>.
+ /// </remarks>
+ /// <exception cref="ArgumentException">In case of invalid parameters.</exception>
+ /// <exception cref="InvalidOperationException">In case of any invalid operations.</exception>
+ /// <exception cref="NotSupportedException">In case of ChangeDevice feature is not supported.</exception>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public void ChangeDevice(CameraDevice device)
+ {
+ ValidateState(CameraState.Created);
+ ValidationUtil.ValidateEnum(typeof(CameraDevice), device, nameof(device));
+
+ CameraErrorFactory.ThrowIfError(Native.ChangeDevice(_handle, device),
+ "Failed to change the camera device");
+ }
+
+ /// <summary>
+ /// Gets the device state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="device">The device to get state.</param>
+ /// <returns>Returns the state of camera device</returns>
+ /// <exception cref="ArgumentException">In case of invalid parameters.</exception>
+ /// <exception cref="InvalidOperationException">In case of any invalid operations.</exception>
+ /// <exception cref="NotSupportedException">In case of this feature is not supported.</exception>
+ public CameraDeviceState GetDeviceState(CameraDevice device)
+ {
+ ValidationUtil.ValidateEnum(typeof(CameraDevice), device, nameof(device));
+
+ CameraErrorFactory.ThrowIfError(Native.GetDeviceState(device, out var val),
+ "Failed to get the camera device state.");
+
+ return val;
+ }
+
+ /// <summary>
+ /// Gets the flash state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="device">The device to get state.</param>
+ /// <returns>Returns the flash state of camera device</returns>
+ /// <exception cref="ArgumentException">In case of invalid parameters.</exception>
+ /// <exception cref="InvalidOperationException">In case of any invalid operations.</exception>
+ /// <exception cref="NotSupportedException">In case of this feature is not supported.</exception>
+ public static CameraFlashState GetFlashState(CameraDevice device)
+ {
+ ValidationUtil.ValidateEnum(typeof(CameraDevice), device, nameof(device));
+
+ CameraErrorFactory.ThrowIfError(Native.GetFlashState(device, out var val),
+ "Failed to get camera flash state");
+
+ return val;
+ }
+
+ /// <summary>
+ /// Starts capturing and drawing preview frames on the screen.
+ /// The display handle must be set using <see cref="CameraDisplaySettings.SetInfo"/>
+ /// before using this method.
+ /// If needed set fps <see cref="CameraSettings.PreviewFps"/>, preview resolution
+ /// <see cref="CameraSettings.PreviewResolution"/>, or preview format <see cref="CameraSettings.PreviewPixelFormat"/>
+ /// before using this method.
+ /// The camera must be in the <see cref="CameraState.Created"/> or <see cref="CameraState.Captured"/> state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/camera
+ /// </privilege>
+ /// <exception cref="InvalidOperationException">In case of any invalid operations.</exception>
+ /// <exception cref="NotSupportedException">In case of this feature is not supported.</exception>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ /// <exception cref="UnauthorizedAccessException">In case of access to the resources cannot be granted.</exception>
+ public void StartPreview()
+ {
+ ValidateState(CameraState.Created, CameraState.Captured);
+
+ CameraErrorFactory.ThrowIfError(Native.StartPreview(_handle),
+ "Failed to start the camera preview.");
+
+ // Update by StateChangedCallback can be delayed for dozens of milliseconds.
+ SetState(CameraState.Preview);
+ }
+
+ /// <summary>
+ /// Stops capturing and drawing preview frames on the screen.
+ /// The camera must be in the <see cref="CameraState.Preview"/> state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/camera
+ /// </privilege>
+ /// <exception cref="InvalidOperationException">In case of any invalid operations.</exception>
+ /// <exception cref="NotSupportedException">In case of this feature is not supported.</exception>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ /// <exception cref="UnauthorizedAccessException">In case of access to the resources cannot be granted.</exception>
+ public void StopPreview()
+ {
+ ValidateState(CameraState.Preview);
+
+ CameraErrorFactory.ThrowIfError(Native.StopPreview(_handle),
+ "Failed to stop the camera preview.");
+
+ SetState(CameraState.Created);
+ }
+
+ /// <summary>
+ /// Starts capturing of still images.
+ /// EventHandler must be set for capturing using <see cref="Capturing"/>
+ /// and for completed using <see cref="CaptureCompleted"/> before calling this method.
+ /// The camera must be in the <see cref="CameraState.Preview"/> state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/camera
+ /// </privilege>
+ /// <remarks>
+ /// This function causes the transition of the camera state from Capturing to Captured
+ /// automatically and the corresponding EventHandlers will be invoked.
+ /// The preview should be restarted by calling <see cref="StartPreview"/> method after capture is completed.
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">In case of any invalid operations.</exception>
+ /// <exception cref="NotSupportedException">In case of this feature is not supported.</exception>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ /// <exception cref="UnauthorizedAccessException">In case of access to the resources cannot be granted.</exception>
+ public void StartCapture()
+ {
+ ValidateState(CameraState.Preview);
+
+ CameraErrorFactory.ThrowIfError(Native.StartCapture(_handle, _capturingCallback, _captureCompletedCallback, IntPtr.Zero),
+ "Failed to start the camera capture.");
+
+ SetState(CameraState.Capturing);
+ }
+
+ /// <summary>
+ /// Starts continuously capturing still images.
+ /// EventHandler must be set for capturing using <see cref="Capturing"/>
+ /// and for completed using <see cref="CaptureCompleted"/> before calling this method.
+ /// The camera must be in the <see cref="CameraState.Preview"/> state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/camera
+ /// </privilege>
+ /// <param name="count">The number of still images.</param>
+ /// <param name="interval">The interval of the capture(milliseconds).</param>
+ /// <param name="cancellationToken">The cancellation token to cancel capturing.</param>
+ /// <seealso cref="System.Threading.CancellationToken"/>
+ /// <remarks>
+ /// If this is not supported zero shutter lag occurs. The capture resolution could be
+ /// changed to the preview resolution. This function causes the transition of the camera state
+ /// from Capturing to Captured automatically and the corresponding Eventhandlers will be invoked.
+ /// Each captured image will be delivered through Eventhandler set using <see cref="Capturing"/> event.
+ /// The preview should be restarted by calling <see cref="StartPreview"/> method after capture is completed.
+ /// </remarks>
+ /// <exception cref="ArgumentOutOfRangeException">In case of invalid parameters.</exception>
+ /// <exception cref="InvalidOperationException">In case of any invalid operations.</exception>
+ /// <exception cref="NotSupportedException">In case of this feature is not supported.</exception>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ /// <exception cref="UnauthorizedAccessException">In case of access to the resources cannot be granted.</exception>
+ public void StartCapture(int count, int interval, CancellationToken cancellationToken)
+ {
+ ValidateState(CameraState.Preview);
+
+ if (count < 2)
+ {
+ throw new ArgumentOutOfRangeException(nameof(count), count, $"{nameof(count)} should be greater than one.");
+ }
+
+ if (interval < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(interval), interval, $"{nameof(interval)} should be greater than or equal to zero.");
+ }
+
+ //Handle CancellationToken
+ if (cancellationToken != CancellationToken.None)
+ {
+ cancellationToken.Register(() =>
+ {
+ CameraErrorFactory.ThrowIfError(Native.StopContinuousCapture(_handle),
+ "Failed to cancel the continuous capture");
+ SetState(CameraState.Captured);
+ });
+ }
+
+ CameraErrorFactory.ThrowIfError(Native.StartContinuousCapture(_handle, count, interval,
+ _capturingCallback, _captureCompletedCallback, IntPtr.Zero), "Failed to start the continuous capture.");
+
+ SetState(CameraState.Capturing);
+ }
+
+ /// <summary>
+ /// Starts camera auto-focusing, asynchronously.
+ /// The camera must be in the <see cref="CameraState.Preview"/> or <see cref="CameraState.Captured"/> state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="continuous">Continuous auto focus</param>
+ /// <privilege>
+ /// http://tizen.org/privilege/camera
+ /// </privilege>
+ /// <remarks>
+ /// If continuous status is true, the camera continuously tries to focus.
+ /// </remarks>
+ /// <exception cref="ArgumentException">In case of invalid parameters.</exception>
+ /// <exception cref="InvalidOperationException">In case of any invalid operations.</exception>
+ /// <exception cref="NotSupportedException">In case of this feature is not supported.</exception>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ /// <exception cref="UnauthorizedAccessException">In case of access to the resources cannot be granted.</exception>
+ public void StartFocusing(bool continuous)
+ {
+ ValidateState(CameraState.Preview, CameraState.Captured);
+
+ CameraErrorFactory.ThrowIfError(Native.StartFocusing(_handle, continuous),
+ "Failed to cancel the camera focus.");
+ }
+
+ /// <summary>
+ /// Stops camera auto focusing.
+ /// The camera must be in the <see cref="CameraState.Preview"/> or <see cref="CameraState.Captured"/> state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/camera
+ /// </privilege>
+ /// <exception cref="InvalidOperationException">In case of any invalid operations.</exception>
+ /// <exception cref="NotSupportedException">In case of this feature is not supported.</exception>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ /// <exception cref="UnauthorizedAccessException">In case of access to the resources cannot be granted.</exception>
+ public void StopFocusing()
+ {
+ ValidateState(CameraState.Preview, CameraState.Captured);
+
+ CameraErrorFactory.ThrowIfError(Native.CancelFocusing(_handle),
+ "Failed to cancel the camera focus.");
+ }
+
+ /// <summary>
+ /// Starts face detection.
+ /// The camera must be in the <see cref="CameraState.Preview"/> state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/camera
+ /// </privilege>
+ /// <remarks>
+ /// This should be called after <see cref="StartPreview"/> is started.
+ /// The Eventhandler set using <see cref="FaceDetected"/> invoked when the face is detected in preview frame.
+ /// Internally it starts continuous focus and focusing on the detected face.
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">In case of any invalid operations.</exception>
+ /// <exception cref="NotSupportedException">In case of this feature is not supported.</exception>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ /// <exception cref="UnauthorizedAccessException">In case of access to the resources cannot be granted.</exception>
+ public void StartFaceDetection()
+ {
+ ValidateState(CameraState.Preview);
+
+ _faceDetectedCallback = (IntPtr faces, int count, IntPtr userData) =>
+ {
+ var result = new List<FaceDetectionData>();
+ IntPtr current = faces;
+
+ for (int i = 0; i < count; i++)
+ {
+ result.Add(new FaceDetectionData(current));
+ current = IntPtr.Add(current, Marshal.SizeOf<Native.DetectedFaceStruct>());
+ }
+
+ FaceDetected?.Invoke(this, new FaceDetectedEventArgs(result));
+ };
+ CameraErrorFactory.ThrowIfError(Native.StartFaceDetection(_handle, _faceDetectedCallback, IntPtr.Zero),
+ "Failed to start face detection");
+ }
+
+ /// <summary>
+ /// Stops face detection.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/camera
+ /// </privilege>
+ /// <exception cref="InvalidOperationException">In case of any invalid operations</exception>
+ /// <exception cref="NotSupportedException">In case of this feature is not supported</exception>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ /// <exception cref="UnauthorizedAccessException">In case of access to the resources cannot be granted</exception>
+ public void StopFaceDetection()
+ {
+ if (_faceDetectedCallback == null)
+ {
+ throw new InvalidOperationException("The face detection is not started.");
+ }
+
+ CameraErrorFactory.ThrowIfError(Native.StopFaceDetection(_handle),
+ "Failed to stop the face detection.");
+
+ _faceDetectedCallback = null;
+ }
+ #endregion Methods
+
+ #region Callback registrations
+ private void RegisterCallbacks()
+ {
+ RegisterErrorCallback();
+ RegisterFocusStateChanged();
+ RegisterHdrCaptureProgress();
+ RegisterInterruptedCallback();
+ RegisterStateChangedCallback();
+
+ //Define capturing callback
+ _capturingCallback = (IntPtr image, IntPtr postview, IntPtr thumbnail, IntPtr userData) =>
+ {
+ Capturing?.Invoke(this, new CameraCapturingEventArgs(new ImageData(image),
+ postview == IntPtr.Zero ? null : new ImageData(postview),
+ thumbnail == IntPtr.Zero ? null : new ImageData(thumbnail)));
+ };
+
+ //Define captureCompleted callback
+ _captureCompletedCallback = _ =>
+ {
+ SetState(CameraState.Captured);
+ CaptureCompleted?.Invoke(this, EventArgs.Empty);
+ };
+ }
+
+ private void RegisterInterruptedCallback()
+ {
+ _interruptedCallback = (CameraPolicy policy, CameraState previous, CameraState current, IntPtr userData) =>
+ {
+ Interrupted?.Invoke(this, new CameraInterruptedEventArgs(policy, previous, current));
+ };
+ CameraErrorFactory.ThrowIfError(Native.SetInterruptedCallback(_handle, _interruptedCallback, IntPtr.Zero),
+ "Failed to set interrupt callback");
+ }
+
+ private void RegisterErrorCallback()
+ {
+ _errorCallback = (CameraErrorCode error, CameraState current, IntPtr userData) =>
+ {
+ ErrorOccurred?.Invoke(this, new CameraErrorOccurredEventArgs(error, current));
+ };
+ CameraErrorFactory.ThrowIfError(Native.SetErrorCallback(_handle, _errorCallback, IntPtr.Zero),
+ "Setting error callback failed");
+ }
+
+ private void RegisterStateChangedCallback()
+ {
+ _stateChangedCallback = (CameraState previous, CameraState current, bool byPolicy, IntPtr _) =>
+ {
+ SetState(current);
+ Log.Info(CameraLog.Tag, "Camera state changed " + previous.ToString() + " -> " + current.ToString());
+ StateChanged?.Invoke(this, new CameraStateChangedEventArgs(previous, current, byPolicy));
+ };
+ CameraErrorFactory.ThrowIfError(Native.SetStateChangedCallback(_handle, _stateChangedCallback, IntPtr.Zero),
+ "Setting state changed callback failed");
+ }
+
+ private void RegisterFocusStateChanged()
+ {
+ _focusStateChangedCallback = (CameraFocusState state, IntPtr userData) =>
+ {
+ FocusStateChanged?.Invoke(this, new CameraFocusStateChangedEventArgs(state));
+ };
+ CameraErrorFactory.ThrowIfError(Native.SetFocusStateChangedCallback(_handle, _focusStateChangedCallback, IntPtr.Zero),
+ "Setting focus changed callback failed");
+ }
+
+ private void RegisterHdrCaptureProgress()
+ {
+ //Hdr Capture can not be supported.
+ if (Feature.IsHdrCaptureSupported)
+ {
+ _hdrCaptureProgressCallback = (int percent, IntPtr userData) =>
+ {
+ HdrCaptureProgress?.Invoke(this, new HdrCaptureProgressEventArgs(percent));
+ };
+ CameraErrorFactory.ThrowIfError(Native.SetHdrCaptureProgressCallback(_handle, _hdrCaptureProgressCallback, IntPtr.Zero),
+ "Setting Hdr capture progress callback failed");
+ }
+ }
+
+ private void RegisterPreviewCallback()
+ {
+ _previewCallback = (IntPtr frame, IntPtr userData) =>
+ {
+ _preview?.Invoke(this, new PreviewEventArgs(new PreviewData(frame)));
+ };
+ CameraErrorFactory.ThrowIfError(Native.SetPreviewCallback(_handle, _previewCallback, IntPtr.Zero),
+ "Setting preview callback failed");
+ }
+
+ private void RegisterMediaPacketPreviewCallback()
+ {
+ _mediaPacketPreviewCallback = (IntPtr mediaPacket, IntPtr userData) =>
+ {
+ MediaPacket packet = MediaPacket.From(mediaPacket);
+ var eventHandler = _mediaPacketPreview;
+
+ if (eventHandler != null)
+ {
+ eventHandler.Invoke(this, new MediaPacketPreviewEventArgs(packet));
+ }
+ else
+ {
+ packet.Dispose();
+ }
+ };
+ CameraErrorFactory.ThrowIfError(Native.SetMediaPacketPreviewCallback(_handle, _mediaPacketPreviewCallback, IntPtr.Zero),
+ "Setting media packet preview callback failed");
+ }
+ #endregion Callback registrations
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Camera/Camera/CameraCapturingEventArgs.cs b/src/Tizen.Multimedia.Camera/Camera/CameraCapturingEventArgs.cs
new file mode 100755
index 0000000..119b802
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Camera/CameraCapturingEventArgs.cs
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// An extended EventArgs class which contains details about the captured image.
+ /// </summary>
+ public class CameraCapturingEventArgs : EventArgs
+ {
+ internal CameraCapturingEventArgs(ImageData img, ImageData post, ImageData thumbnail)
+ {
+ Image = img;
+ PostView = post;
+ Thumbnail = thumbnail;
+ }
+
+ /// <summary>
+ /// The image data of the captured picture.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ImageData Image { get; }
+
+ /// <summary>
+ /// The image data of the postview.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ImageData PostView { get; }
+
+ /// <summary>
+ /// The image data of the thumbnail.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ImageData Thumbnail { get; }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Camera/Camera/CameraDeviceStateChangedEventArgs.cs b/src/Tizen.Multimedia.Camera/Camera/CameraDeviceStateChangedEventArgs.cs
new file mode 100755
index 0000000..32353f1
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Camera/CameraDeviceStateChangedEventArgs.cs
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// An extended EventArgs class which contains details about previous and current state
+ /// of the camera when its state is changed.
+ /// </summary>
+ public class CameraDeviceStateChangedEventArgs : EventArgs
+ {
+ internal CameraDeviceStateChangedEventArgs(CameraDevice device, CameraDeviceState state)
+ {
+ Device = device;
+ State = state;
+ }
+
+ /// <summary>
+ /// Camera device type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public CameraDevice Device { get; }
+
+ /// <summary>
+ /// Current state of the camera device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public CameraDeviceState State { get; }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Camera/Camera/CameraDisplaySettings.cs b/src/Tizen.Multimedia.Camera/Camera/CameraDisplaySettings.cs
new file mode 100755
index 0000000..0ded01e
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Camera/CameraDisplaySettings.cs
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using Native = Interop.CameraDisplay;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// The CameraDisplay class allows you to manage display for the camera.
+ /// It allows to set and get various display properties such as
+ /// rotation, display visibility and display mode.
+ /// </summary>
+ public class CameraDisplaySettings
+ {
+ internal readonly Camera _camera;
+
+ internal CameraDisplaySettings(Camera camera)
+ {
+ _camera = camera;
+ }
+
+ /// <summary>
+ /// The display mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A <see cref="CameraDisplayMode"/> that specifies the display mode.</value>
+ /// <exception cref="ObjectDisposedException" > The camera already has been disposed.</exception>
+ public CameraDisplayMode Mode
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(Native.GetMode(_camera.GetHandle(), out var val),
+ "Failed to get camera display mode");
+
+ return val;
+ }
+
+ set
+ {
+ ValidationUtil.ValidateEnum(typeof(CameraDisplayMode), value);
+ CameraErrorFactory.ThrowIfError(Native.SetMode(_camera.GetHandle(), value),
+ "Failed to set camera display mode.");
+ }
+ }
+
+ /// <summary>
+ /// The display visibility.
+ /// True if camera display visible, otherwise false.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ObjectDisposedException" > The camera already has been disposed.</exception>
+ public bool Visible
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(Native.GetVisible(_camera.GetHandle(), out bool val),
+ "Failed to get visible value");
+
+ return val;
+ }
+
+ set
+ {
+ CameraErrorFactory.ThrowIfError(Native.SetVisible(_camera.GetHandle(), value),
+ "Failed to set display visible.");
+ }
+ }
+
+ /// <summary>
+ /// The display rotation.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A <see cref="CameraRotation"/> that specifies the rotation of camera device.</value>
+ /// <exception cref="ObjectDisposedException" > The camera already has been disposed.</exception>
+ public CameraRotation Rotation
+ {
+ get
+ {
+ CameraRotation val = CameraRotation.None;
+
+ CameraErrorFactory.ThrowIfError(Native.GetRotation(_camera.GetHandle(), out val),
+ "Failed to get display rotation");
+
+ return val;
+ }
+
+ set
+ {
+ ValidationUtil.ValidateEnum(typeof(CameraRotation), value);
+ CameraErrorFactory.ThrowIfError(Native.SetRotation(_camera.GetHandle(), value),
+ "Failed to set display rotation.");
+ }
+ }
+
+ /// <summary>
+ /// The display flip.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A <see cref="CameraFlip"/> that specifies camera flip type.</value>
+ /// <exception cref="ObjectDisposedException" > The camera already has been disposed.</exception>
+ public CameraFlip Flip
+ {
+ get
+ {
+ CameraFlip val = CameraFlip.None;
+
+ CameraErrorFactory.ThrowIfError(Native.GetFlip(_camera.GetHandle(), out val),
+ "Failed to get display flip");
+
+ return val;
+ }
+
+ set
+ {
+ ValidationUtil.ValidateEnum(typeof(CameraFlip), value);
+ CameraErrorFactory.ThrowIfError(Native.SetFlip(_camera.GetHandle(), value),
+ "Failed to set display flip.");
+ }
+ }
+
+ /// <summary>
+ /// the ROI(Region Of Interest) area of display.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ObjectDisposedException" > The camera already has been disposed.</exception>
+ public Rectangle RoiArea
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(Native.GetRoiArea(_camera.GetHandle(),
+ out int x, out int y, out int width, out int height), "Failed to get display roi area");
+
+ return new Rectangle(x, y, width, height);
+ }
+
+ set
+ {
+ CameraErrorFactory.ThrowIfError(Native.SetRoiArea(_camera.GetHandle(),
+ value.X, value.Y, value.Width, value.Height), "Failed to set display roi area.");
+ }
+ }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Camera/Camera/CameraEnums.cs b/src/Tizen.Multimedia.Camera/Camera/CameraEnums.cs
new file mode 100755
index 0000000..2e25a6e
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Camera/CameraEnums.cs
@@ -0,0 +1,908 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Enumeration for Camera device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CameraDevice
+ {
+ /// <summary>
+ /// Rear Camera device.
+ /// </summary>
+ Rear,
+ /// <summary>
+ /// Front Camera device.
+ /// </summary>
+ Front
+ }
+
+ /// <summary>
+ /// Enumeration for Camera device state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CameraDeviceState
+ {
+ /// <summary>
+ /// Not opened.
+ /// </summary>
+ NotOpened,
+ /// <summary>
+ /// Opened.
+ /// </summary>
+ Opened,
+ /// <summary>
+ /// Now previewing or capturing or is being used for video recording.
+ /// </summary>
+ Working
+ }
+
+ /// <summary>
+ /// Enumeration for the facing direction of camera module .
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CameraFacingDirection
+ {
+ /// <summary>
+ /// Rear direction.
+ /// </summary>
+ Rear,
+ /// <summary>
+ /// Front direction
+ /// </summary>
+ Front
+ }
+
+ /// <summary>
+ /// Enumeration for the current flash state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CameraFlashState
+ {
+ /// <summary>
+ /// Flash is not used now through camera API.
+ /// </summary>
+ NotUsed,
+ /// <summary>
+ /// Flash is used now through camera API.
+ /// </summary>
+ Used
+ }
+
+ /// <summary>
+ /// Enumeration for the camera flip type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CameraFlip
+ {
+ /// <summary>
+ /// No Flip.
+ /// </summary>
+ None,
+ /// <summary>
+ /// Horizontal flip.
+ /// </summary>
+ Horizontal,
+ /// <summary>
+ /// Vertical flip.
+ /// </summary>
+ Vertical,
+ /// <summary>
+ /// Horizontal and vertical flip.
+ /// </summary>
+ Both
+ }
+
+ /// <summary>
+ /// Enumeration for the camera focus state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CameraFocusState
+ {
+ /// <summary>
+ /// Focus released.
+ /// </summary>
+ Released,
+ /// <summary>
+ /// Focus in progress
+ /// </summary>
+ Ongoing,
+ /// <summary>
+ /// Focus succeeded
+ /// </summary>
+ Focused,
+ /// <summary>
+ /// Focus failed.
+ /// </summary>
+ Failed
+ }
+
+ /// <summary>
+ /// Enumeration for the camera pixel format.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CameraPixelFormat
+ {
+ /// <summary>
+ /// Invalid pixel format.
+ /// </summary>
+ Invalid = -1,
+ /// <summary>
+ /// NV12 pixel format.
+ /// </summary>
+ Nv12,
+ /// <summary>
+ /// NV12 Tiled pixel format.
+ /// </summary>
+ Nv12t,
+ /// <summary>
+ /// NV16 pixel format.
+ /// </summary>
+ Nv16,
+ /// <summary>
+ /// NV21 pixel format.
+ /// </summary>
+ Nv21,
+ /// <summary>
+ /// YUYV(YUY2) pixel format.
+ /// </summary>
+ Yuyv,
+ /// <summary>
+ /// UYVY pixel format.
+ /// </summary>
+ Uyvy,
+ /// <summary>
+ /// YUV422(Y:U:V) planar pixel format.
+ /// </summary>
+ Yuv422Planar,
+ /// <summary>
+ /// I420 pixel format.
+ /// </summary>
+ I420,
+ /// <summary>
+ /// YV12 pixel format.
+ /// </summary>
+ Yv12,
+ /// <summary>
+ /// RGB565 pixel format.
+ /// </summary>
+ Rgb565,
+ /// <summary>
+ /// RGB565 pixel format.
+ /// </summary>
+ Rgb888,
+ /// <summary>
+ /// RGBA pixel format.
+ /// </summary>
+ Rgba,
+ /// <summary>
+ /// ARGB pixel format.
+ /// </summary>
+ Argb,
+ /// <summary>
+ /// Encoded pixel format.
+ /// </summary>
+ Jpeg,
+ /// <summary>
+ /// Encoded pixel format : H264.
+ /// </summary>
+ H264 = 15
+ }
+
+ /// <summary>
+ /// Enumeration for the camera policy.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CameraPolicy
+ {
+ /// <summary>
+ /// None.
+ /// </summary>
+ None,
+ /// <summary>
+ /// Security policy
+ /// </summary>
+ Security = 4,
+ /// <summary>
+ /// Resource conflict
+ /// </summary>
+ ResourceConflict
+ }
+
+ /// <summary>
+ /// Enumeration for the camera rotation type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CameraRotation
+ {
+ /// <summary>
+ /// No rotation.
+ /// </summary>
+ None,
+ /// <summary>
+ /// 90 degree rotation.
+ /// </summary>
+ Rotation90,
+ /// <summary>
+ /// 180 degree rotation.
+ /// </summary>
+ Rotation180,
+ /// <summary>
+ /// 270 degree rotation.
+ /// </summary>
+ Rotation270
+ }
+
+ /// <summary>
+ /// Enumeration for the camera state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CameraState
+ {
+ /// <summary>
+ /// Before creating.
+ /// </summary>
+ None,
+ /// <summary>
+ /// Created, but not initialized yet.
+ /// </summary>
+ Created,
+ /// <summary>
+ /// Preview.
+ /// </summary>
+ Preview,
+ /// <summary>
+ /// While capturing.
+ /// </summary>
+ Capturing,
+ /// <summary>
+ /// After capturing.
+ /// </summary>
+ Captured
+ }
+
+ /// <summary>
+ /// Enumeration for the auto focus mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CameraAutoFocusMode
+ {
+ /// <summary>
+ /// auto-focus is not set.
+ /// </summary>
+ None,
+ /// <summary>
+ /// auto-focus in the normal mode.
+ /// </summary>
+ Normal,
+ /// <summary>
+ /// auto-focus in the macro mode(close distance).
+ /// </summary>
+ Macro,
+ /// <summary>
+ /// auto-focus in the full mode(all range scan, limited by device spec).
+ /// </summary>
+ Full
+ }
+
+ /// <summary>
+ /// Enumeration for the color tone, which provides the impression of looking through a tinted glass.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CameraEffectMode
+ {
+ /// <summary>
+ /// None.
+ /// </summary>
+ None,
+ /// <summary>
+ /// Mono.
+ /// </summary>
+ Mono,
+ /// <summary>
+ /// Sepia.
+ /// </summary>
+ Sepia,
+ /// <summary>
+ /// Negative.
+ /// </summary>
+ Negative,
+ /// <summary>
+ /// Blue.
+ /// </summary>
+ Blue,
+ /// <summary>
+ /// Green.
+ /// </summary>
+ Green,
+ /// <summary>
+ /// Aqua.
+ /// </summary>
+ Aqua,
+ /// <summary>
+ /// Violet.
+ /// </summary>
+ Violet,
+ /// <summary>
+ /// Orange.
+ /// </summary>
+ Orange,
+ /// <summary>
+ /// Gray.
+ /// </summary>
+ Gray,
+ /// <summary>
+ /// Red.
+ /// </summary>
+ Red,
+ /// <summary>
+ /// Antique.
+ /// </summary>
+ Antique,
+ /// <summary>
+ /// Warm.
+ /// </summary>
+ Warm,
+ /// <summary>
+ /// Pink.
+ /// </summary>
+ Pink,
+ /// <summary>
+ /// Yellow.
+ /// </summary>
+ Yellow,
+ /// <summary>
+ /// Purple.
+ /// </summary>
+ Purple,
+ /// <summary>
+ /// Emboss.
+ /// </summary>
+ Emboss,
+ /// <summary>
+ /// Outline.
+ /// </summary>
+ Outline,
+ /// <summary>
+ /// Solarization.
+ /// </summary>
+ Solarization,
+ /// <summary>
+ /// Sketch.
+ /// </summary>
+ Sketch,
+ /// <summary>
+ /// Washed.
+ /// </summary>
+ Washed,
+ /// <summary>
+ /// Vintage warm.
+ /// </summary>
+ VintageWarm,
+ /// <summary>
+ /// Vintage cold .
+ /// </summary>
+ VintageCold,
+ /// <summary>
+ /// Posterization.
+ /// </summary>
+ Posterization,
+ /// <summary>
+ /// Cartoon.
+ /// </summary>
+ Cartoon,
+ /// <summary>
+ /// Selective color - Red.
+ /// </summary>
+ SelectiveRed,
+ /// <summary>
+ /// Selective color - Green.
+ /// </summary>
+ SelectiveGreen,
+ /// <summary>
+ /// Selective color - Blue.
+ /// </summary>
+ SelectiveBlue,
+ /// <summary>
+ /// Selective color - Yellow.
+ /// </summary>
+ SelectiveYellow,
+ /// <summary>
+ /// Selective color - Red and Yellow.
+ /// </summary>
+ SelectiveRedYellow,
+ /// <summary>
+ /// Other Graphic effects.
+ /// </summary>
+ OtherGraphics
+ }
+
+ /// <summary>
+ /// Enumeration for the camera exposure modes.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CameraExposureMode
+ {
+ /// <summary>
+ /// Off.
+ /// </summary>
+ Off,
+ /// <summary>
+ /// All mode.
+ /// </summary>
+ All,
+ /// <summary>
+ /// Center mode.
+ /// </summary>
+ Center,
+ /// <summary>
+ /// Spot mode.
+ /// </summary>
+ Spot,
+ /// <summary>
+ /// Custom mode.
+ /// </summary>
+ Custom
+ }
+
+ /// <summary>
+ /// Enumeration for the flash mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CameraFlashMode
+ {
+ /// <summary>
+ /// Always off.
+ /// </summary>
+ Off,
+ /// <summary>
+ /// Always splashes.
+ /// </summary>
+ On,
+ /// <summary>
+ /// Depending on intensity of light, strobe starts to flash.
+ /// </summary>
+ Auto,
+ /// <summary>
+ /// Red eye reduction. Multiple flash before capturing.
+ /// </summary>
+ RedEyeReduction,
+ /// <summary>
+ /// Slow sync curtain synchronization.
+ /// </summary>
+ SlowSync,
+ /// <summary>
+ /// Front curtain synchronization.
+ /// </summary>
+ FrontCurtain,
+ /// <summary>
+ /// Rear curtain synchronization.
+ /// </summary>
+ RearCurtain,
+ /// <summary>
+ /// Keep turned on until turning off.
+ /// </summary>
+ Permanent
+ }
+
+ /// <summary>
+ /// Enumeration for preview FPS.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CameraFps
+ {
+ /// <summary>
+ /// Auto FPS.
+ /// </summary>
+ Auto = 0,
+ /// <summary>
+ /// 7 FPS.
+ /// </summary>
+ Fps7 = 7,
+ /// <summary>
+ /// 8 FPS.
+ /// </summary>
+ Fps8 = 8,
+ /// <summary>
+ /// 15 FPS.
+ /// </summary>
+ Fps15 = 15,
+ /// <summary>
+ /// 20 FPS.
+ /// </summary>
+ Fps20 = 20,
+ /// <summary>
+ /// 24 FPS.
+ /// </summary>
+ Fps24 = 24,
+ /// <summary>
+ /// 25 FPS.
+ /// </summary>
+ Fps25 = 25,
+ /// <summary>
+ /// 30 FPS.
+ /// </summary>
+ Fps30 = 30,
+ /// <summary>
+ /// 60 FPS.
+ /// </summary>
+ Fps60 = 60,
+ /// <summary>
+ /// 90 FPS.
+ /// </summary>
+ Fps90 = 90,
+ /// <summary>
+ /// 120 FPS.
+ /// </summary>
+ Fps120 = 120
+ }
+
+ /// <summary>
+ /// Enumeration for HDR capture mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CameraHdrMode
+ {
+ /// <summary>
+ /// Disable HDR capture.
+ /// </summary>
+ Disable,
+ /// <summary>
+ /// Enable HDR capture.
+ /// </summary>
+ Enable,
+ /// <summary>
+ /// Enable HDR capture and keep original image data.
+ /// </summary>
+ KeepOriginal
+ }
+
+ /// <summary>
+ /// Enumeration for the ISO levels of the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CameraIsoLevel
+ {
+ /// <summary>
+ /// ISO auto mode.
+ /// </summary>
+ Auto,
+ /// <summary>
+ /// ISO 50.
+ /// </summary>
+ Iso50,
+ /// <summary>
+ /// ISO 100.
+ /// </summary>
+ Iso100,
+ /// <summary>
+ /// ISO 200.
+ /// </summary>
+ Iso200,
+ /// <summary>
+ /// ISO 400.
+ /// </summary>
+ Iso400,
+ /// <summary>
+ /// ISO 800.
+ /// </summary>
+ Iso800,
+ /// <summary>
+ /// ISO 1600.
+ /// </summary>
+ Iso1600,
+ /// <summary>
+ /// ISO 3200.
+ /// </summary>
+ Iso3200
+ }
+
+ /// <summary>
+ /// Enumeration for PTZ(Pan Tilt Zoom) movement type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CameraPtzMoveType
+ {
+ /// <summary>
+ /// Move to a specific coordinate position.
+ /// </summary>
+ Absoulute,
+ /// <summary>
+ /// Move a specific distance from the current position.
+ /// </summary>
+ Relative
+ }
+
+ /// <summary>
+ /// Enumeration for PTZ(Pan Tilt Zoom) type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CameraPtzType
+ {
+ /// <summary>
+ /// Move the camera device physically.
+ /// </summary>
+ Mechanical,
+ /// <summary>
+ /// Zoom digitally and move into portion of the image.
+ /// </summary>
+ Electronic
+ }
+
+ /// <summary>
+ /// Enumeration for the camera scene mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CameraSceneMode
+ {
+ /// <summary>
+ /// Normal.
+ /// </summary>
+ Normal,
+ /// <summary>
+ /// Portrait.
+ /// </summary>
+ Portrait,
+ /// <summary>
+ /// Landscape.
+ /// </summary>
+ Landscape,
+ /// <summary>
+ /// Sports.
+ /// </summary>
+ Sports,
+ /// <summary>
+ /// Party &amp; Indoor.
+ /// </summary>
+ PartyAndIndoor,
+ /// <summary>
+ /// Beach &amp; Indoor.
+ /// </summary>
+ BeachAndIndoor,
+ /// <summary>
+ /// Sunset.
+ /// </summary>
+ Sunset,
+ /// <summary>
+ /// Dusk &amp; Dawn.
+ /// </summary>
+ DuskAndDawn,
+ /// <summary>
+ /// Fall.
+ /// </summary>
+ FallColor,
+ /// <summary>
+ /// Night scene.
+ /// </summary>
+ NightScene,
+ /// <summary>
+ /// Firework.
+ /// </summary>
+ FireWork,
+ /// <summary>
+ /// Text.
+ /// </summary>
+ Text,
+ /// <summary>
+ /// Show window.
+ /// </summary>
+ ShowWindow,
+ /// <summary>
+ /// Candle light.
+ /// </summary>
+ CandleLight,
+ /// <summary>
+ /// Backlight.
+ /// </summary>
+ BackLight,
+ /// <summary>
+ /// Aqua.
+ /// </summary>
+ Aqua
+ }
+
+ /// <summary>
+ /// Enumeration for the orientation values of tag.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CameraTagOrientation
+ {
+ /// <summary>
+ /// Row #0 is at the top, Column #0 is to the left.
+ /// </summary>
+ TopLeft = 1,
+ /// <summary>
+ /// Row #0 is at the top, Column #0 is to the right.
+ /// </summary>
+ TopRight = 2,
+ /// <summary>
+ /// Row #0 is at the bottom, Column #0 is to the right.
+ /// </summary>
+ BottomRight = 3,
+ /// <summary>
+ /// Row #0 is at the bottom, Column #0 is to the left.
+ /// </summary>
+ BottomLeft = 4,
+ /// <summary>
+ /// Row #0 is at the left, Column #0 is to the top.
+ /// </summary>
+ LeftTop = 5,
+ /// <summary>
+ /// Row #0 is at the right, Column #0 is to the top.
+ /// </summary>
+ RightTop = 6,
+ /// <summary>
+ /// Row #0 is at the right, Column #0 is to the bottom.
+ /// </summary>
+ RightBottom = 7,
+ /// <summary>
+ /// Row #0 is at the left, Column #0 is to the bottom.
+ /// </summary>
+ LeftBottom = 8
+ }
+
+ /// <summary>
+ /// Enumeration for the theater mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CameraTheaterMode
+ {
+ /// <summary>
+ /// Disable theater mode - External display shows same image as device display.
+ /// </summary>
+ Disable,
+ /// <summary>
+ /// Clone mode - Preview image is displayed on external display with full screen mode. Also preview image is shown by the UI on device display.
+ /// </summary>
+ Clone,
+ /// <summary>
+ /// Enable theater mode - Preview image is displayed on external display with full screen mode, but preview image is not shown on device display.
+ /// </summary>
+ Enable
+ }
+
+ /// <summary>
+ ///Enumeration for the white balance levels of the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CameraWhiteBalance
+ {
+ /// <summary>
+ /// None.
+ /// </summary>
+ None,
+ /// <summary>
+ /// Automatic.
+ /// </summary>
+ Automatic,
+ /// <summary>
+ /// Daylight.
+ /// </summary>
+ Daylight,
+ /// <summary>
+ /// Cloudy.
+ /// </summary>
+ Cloudy,
+ /// <summary>
+ /// Fluorescent.
+ /// </summary>
+ Fluorescent,
+ /// <summary>
+ /// Incandescent.
+ /// </summary>
+ Incandescent,
+ /// <summary>
+ /// Shade.
+ /// </summary>
+ Shade,
+ /// <summary>
+ /// Horizon.
+ /// </summary>
+ Horizon,
+ /// <summary>
+ /// Flash.
+ /// </summary>
+ Flash,
+ /// <summary>
+ /// Custom.
+ /// </summary>
+ Custom
+ }
+
+ /// <summary>
+ /// Enumeration for the camera display mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CameraDisplayMode
+ {
+ /// <summary>
+ /// Letter box.
+ /// </summary>
+ LetterBox,
+ /// <summary>
+ /// Origin size.
+ /// </summary>
+ OriginSize,
+ /// <summary>
+ /// Full screen.
+ /// </summary>
+ Full,
+ /// <summary>
+ /// Cropped full screen.
+ /// </summary>
+ CroppedFull,
+ /// <summary>
+ /// Original size or letter box.
+ /// </summary>
+ OriginOrLetterBox,
+ /// <summary>
+ /// Custom ROI.
+ /// </summary>
+ CustomROI
+ }
+
+ /// <summary>
+ /// Enumeration for camera failure error.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CameraErrorCode
+ {
+ /// <summary>
+ /// Device Error.
+ /// </summary>
+ DeviceError = CameraError.DeviceError,
+ /// <summary>
+ /// Internal error.
+ /// </summary>
+ InvalidOperation = CameraError.InvalidOperation,
+ /// <summary>
+ /// Out of memory.
+ /// </summary>
+ OutOfMemory = CameraError.OutOfMemory,
+ /// <summary>
+ /// Service is disconnected.
+ /// </summary>
+ ServiceDisconnected = CameraError.ServiceDisconnected
+ }
+
+ /// <summary>
+ /// Enumeration for Image datatype.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum PlaneType
+ {
+ /// <summary>
+ /// Single plane data.
+ /// </summary>
+ SinglePlane,
+ /// <summary>
+ /// Double plane data.
+ /// </summary>
+ DoublePlane,
+ /// <summary>
+ /// Triple plane data.
+ /// </summary>
+ TriplePlane,
+ /// <summary>
+ /// Encoded plane data.
+ /// </summary>
+ EncodedPlane
+ }
+}
diff --git a/src/Tizen.Multimedia.Camera/Camera/CameraErrorFactory.cs b/src/Tizen.Multimedia.Camera/Camera/CameraErrorFactory.cs
new file mode 100644
index 0000000..15862f3
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Camera/CameraErrorFactory.cs
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.CompilerServices;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Multimedia
+{
+ internal enum CameraError
+ {
+ TizenErrorCamera = -0x01910000,
+ CameraErrorClass = TizenErrorCamera,
+ None = ErrorCode.None,
+ InvalidParameter = ErrorCode.InvalidParameter,
+ InvalidState = CameraErrorClass | 0x02,
+ OutOfMemory = ErrorCode.OutOfMemory,
+ DeviceError = CameraErrorClass | 0x04,
+ InvalidOperation = ErrorCode.InvalidOperation,
+ SecurityRestricted = CameraErrorClass | 0x07,
+ DeviceBusy = CameraErrorClass | 0x08,
+ DeviceNotFound = CameraErrorClass | 0x09,
+ Esd = CameraErrorClass | 0x0c,
+ PermissionDenied = ErrorCode.PermissionDenied,
+ NotSupported = ErrorCode.NotSupported,
+ ResourceConflict = CameraErrorClass | 0x0d,
+ ServiceDisconnected = CameraErrorClass | 0x0e
+ }
+
+ internal static class CameraErrorFactory
+ {
+ internal static void ThrowIfError(CameraError errorCode, string errorMessage = null,
+ [CallerMemberName] string caller = null, [CallerLineNumber] int line = 0)
+ {
+ if (errorCode == CameraError.None)
+ {
+ return;
+ }
+
+ Log.Info(CameraLog.Tag, "errorCode : " + errorCode.ToString() + ", Caller : " + caller + ", line " + line.ToString());
+
+ switch (errorCode)
+ {
+ case CameraError.InvalidParameter:
+ throw new ArgumentException(errorMessage);
+
+ case CameraError.OutOfMemory:
+ throw new OutOfMemoryException(errorMessage);
+
+ case CameraError.DeviceError:
+ case CameraError.DeviceBusy:
+ case CameraError.Esd:
+ throw new CameraDeviceException(errorMessage);
+
+ case CameraError.DeviceNotFound:
+ throw new CameraDeviceNotFoundException(errorMessage);
+
+ case CameraError.SecurityRestricted:
+ case CameraError.PermissionDenied:
+ throw new UnauthorizedAccessException(errorMessage);
+
+ case CameraError.NotSupported:
+ throw new NotSupportedException(errorMessage);
+
+ case CameraError.InvalidState:
+ case CameraError.InvalidOperation:
+ case CameraError.ResourceConflict:
+ case CameraError.ServiceDisconnected:
+ throw new InvalidOperationException(errorMessage);
+
+ default:
+ throw new Exception("Unknown error : " + errorCode);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Camera/Camera/CameraErrorOccurredEventArgs.cs b/src/Tizen.Multimedia.Camera/Camera/CameraErrorOccurredEventArgs.cs
new file mode 100755
index 0000000..883596b
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Camera/CameraErrorOccurredEventArgs.cs
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// An extended EventArgs class which contains details about error status and
+ /// state of the camera when it failed.
+ /// </summary>
+ public class CameraErrorOccurredEventArgs : EventArgs
+ {
+ internal CameraErrorOccurredEventArgs(CameraErrorCode error, CameraState state)
+ {
+ Error = error;
+ State = state;
+ }
+
+ /// <summary>
+ /// The camera error code.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public CameraErrorCode Error { get; }
+
+ /// <summary>
+ /// The state of the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public CameraState State { get; }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Camera/Camera/CameraException.cs b/src/Tizen.Multimedia.Camera/Camera/CameraException.cs
new file mode 100644
index 0000000..36f46d7
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Camera/CameraException.cs
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ public class CameraException : Exception
+ {
+ public CameraException() : base()
+ {
+ }
+
+ public CameraException(string message) : base(message)
+ {
+ }
+ }
+
+ public class CameraDeviceException : CameraException
+ {
+ public CameraDeviceException() : base()
+ {
+ }
+
+ public CameraDeviceException(string message) : base(message)
+ {
+ }
+ }
+
+ public class CameraDeviceNotFoundException : CameraException
+ {
+ public CameraDeviceNotFoundException() : base()
+ {
+ }
+
+ public CameraDeviceNotFoundException(string message) : base(message)
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Multimedia.Camera/Camera/CameraFeatures.cs b/src/Tizen.Multimedia.Camera/Camera/CameraFeatures.cs
new file mode 100755
index 0000000..2361a9f
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Camera/CameraFeatures.cs
@@ -0,0 +1,816 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using NativeFeatures = Interop.CameraFeatures;
+using NativeSettings = Interop.CameraSettings;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// The CameraFeatures class provides properties
+ /// to get various capability information of the camera device.
+ /// </summary>
+ public class CameraFeatures
+ {
+ internal readonly Camera _camera;
+
+ private List<Size> _previewResolutions;
+ private List<Size> _cameraResolutions;
+ private List<CameraPixelFormat> _captureFormats;
+ private List<CameraPixelFormat> _previewFormats;
+ private List<CameraFps> _fps;
+ private List<CameraFps> _fpsByResolution;
+ private List<CameraAutoFocusMode> _autoFocusModes;
+ private List<CameraExposureMode> _exposureModes;
+ private List<CameraIsoLevel> _isoLevels;
+ private List<CameraTheaterMode> _theaterModes;
+ private List<CameraWhiteBalance> _whitebalances;
+ private List<CameraFlashMode> _flashModes;
+ private List<CameraSceneMode> _sceneModes;
+ private List<CameraEffectMode> _effectModes;
+ private List<CameraRotation> _streamRotations;
+ private List<CameraFlip> _streamFlips;
+ private List<CameraPtzType> _ptzTypes;
+
+ private delegate CameraError GetRangeDelegate(IntPtr handle, out int min, out int max);
+ private delegate bool IsSupportedDelegate(IntPtr handle);
+
+ internal CameraFeatures(Camera camera)
+ {
+ _camera = camera;
+
+ IsFaceDetectionSupported = IsFeatureSupported(NativeFeatures.IsFaceDetectionSupported);
+ IsMediaPacketPreviewCallbackSupported = IsFeatureSupported(NativeFeatures.IsMediaPacketPreviewCallbackSupported);
+ IsZeroShutterLagSupported = IsFeatureSupported(NativeFeatures.IsZeroShutterLagSupported);
+ IsContinuousCaptureSupported = IsFeatureSupported(NativeFeatures.IsContinuousCaptureSupported);
+ IsHdrCaptureSupported = IsFeatureSupported(NativeFeatures.IsHdrCaptureSupported);
+ IsAntiShakeSupported = IsFeatureSupported(NativeFeatures.IsAntiShakeSupported);
+ IsVideoStabilizationSupported = IsFeatureSupported(NativeFeatures.IsVideoStabilizationSupported);
+ IsAutoContrastSupported = IsFeatureSupported(NativeFeatures.IsAutoContrastSupported);
+ IsBrigtnessSupported = CheckRangeValid(NativeSettings.GetBrightnessRange);
+ IsExposureSupported = CheckRangeValid(NativeSettings.GetExposureRange);
+ IsZoomSupported = CheckRangeValid(NativeSettings.GetZoomRange);
+ IsPanSupported = CheckRangeValid(NativeSettings.GetPanRange);
+ IsTiltSupported = CheckRangeValid(NativeSettings.GetTiltRange);
+ }
+
+ private bool IsFeatureSupported(IsSupportedDelegate func)
+ {
+ return func(_camera.GetHandle());
+ }
+
+ private bool CheckRangeValid(GetRangeDelegate func)
+ {
+ CameraErrorFactory.ThrowIfError(func(_camera.GetHandle(), out int min, out int max),
+ "Failed to check feature is suported or not.");
+
+ return min < max;
+ }
+
+ /// <summary>
+ /// Gets the face detection feature's supported state.
+ /// true if supported, otherwise false.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool IsFaceDetectionSupported { get; }
+
+ /// <summary>
+ /// Gets the media packet preview callback feature's supported state.
+ /// true if supported, otherwise false.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool IsMediaPacketPreviewCallbackSupported { get; }
+
+ /// <summary>
+ /// Gets the zero shutter lag feature's supported state.
+ /// true if supported, otherwise false.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool IsZeroShutterLagSupported { get; }
+
+ /// <summary>
+ /// Gets continuous capture feature's supported state.
+ /// true if supported, otherwise false.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool IsContinuousCaptureSupported { get; }
+
+ /// <summary>
+ /// Gets the support state of HDR capture.
+ /// true if supported, otherwise false.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool IsHdrCaptureSupported { get; }
+
+ /// <summary>
+ /// Gets the support state of the anti-shake feature.
+ /// true if supported, otherwise false.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool IsAntiShakeSupported { get; }
+
+ /// <summary>
+ /// Gets the support state of the video stabilization feature.
+ /// true if supported, otherwise false.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool IsVideoStabilizationSupported { get; }
+
+ /// <summary>
+ /// Gets the support state of auto contrast feature.
+ /// true if supported, otherwise false.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool IsAutoContrastSupported { get; }
+
+ /// <summary>
+ /// Gets the support state of brightness feature.
+ /// true if supported, otherwise false.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool IsBrigtnessSupported { get; }
+
+ /// <summary>
+ /// Gets the support state of exposure feature.
+ /// true if supported, otherwise false.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool IsExposureSupported { get; }
+
+ /// <summary>
+ /// Gets the support state of zoom feature.
+ /// true if supported, otherwise false.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool IsZoomSupported { get; }
+
+ /// <summary>
+ /// Gets the support state of pan feature.
+ /// true if supported, otherwise false.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool IsPanSupported { get; }
+
+ /// <summary>
+ /// Gets the support state of tilt feature.
+ /// true if supported, otherwise false.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool IsTiltSupported { get; }
+
+ /// <summary>
+ /// Retrieves all the preview resolutions supported by the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// It returns a list containing all the supported preview resolutions.
+ /// by recorder.
+ /// </returns>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public IEnumerable<Size> SupportedPreviewResolutions
+ {
+ get
+ {
+ if (_previewResolutions == null)
+ {
+ try
+ {
+ _previewResolutions = new List<Size>();
+
+ NativeFeatures.PreviewResolutionCallback callback = (int width, int height, IntPtr userData) =>
+ {
+ _previewResolutions.Add(new Size(width, height));
+ return true;
+ };
+ CameraErrorFactory.ThrowIfError(NativeFeatures.SupportedPreviewResolutions(_camera.GetHandle(), callback, IntPtr.Zero),
+ "Failed to get the supported preview resolutions");
+ }
+ catch
+ {
+ _previewResolutions = null;
+ throw;
+ }
+ }
+
+ return _previewResolutions;
+ }
+ }
+
+ /// <summary>
+ /// Retrieves all the capture resolutions supported by the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// It returns a list containing all the supported capture resolutions.
+ /// </returns>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public IEnumerable<Size> SupportedCaptureResolutions
+ {
+ get
+ {
+ if (_cameraResolutions == null)
+ {
+ try
+ {
+ _cameraResolutions = new List<Size>();
+
+ NativeFeatures.CaptureResolutionCallback callback = (int width, int height, IntPtr userData) =>
+ {
+ _cameraResolutions.Add(new Size(width, height));
+ return true;
+ };
+ CameraErrorFactory.ThrowIfError(NativeFeatures.SupportedCaptureResolutions(_camera.GetHandle(), callback, IntPtr.Zero),
+ "Failed to get the supported capture resolutions");
+ }
+ catch
+ {
+ _cameraResolutions = null;
+ throw;
+ }
+ }
+
+ return _cameraResolutions;
+ }
+ }
+
+ /// <summary>
+ /// Retrieves all the capture formats supported by the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// It returns a list containing all the supported <see cref="CameraPixelFormat"/>.
+ /// </returns>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public IEnumerable<CameraPixelFormat> SupportedCapturePixelFormats
+ {
+ get
+ {
+ if (_captureFormats == null)
+ {
+ try
+ {
+ _captureFormats = new List<CameraPixelFormat>();
+
+ NativeFeatures.CaptureFormatCallback callback = (CameraPixelFormat format, IntPtr userData) =>
+ {
+ _captureFormats.Add(format);
+ return true;
+ };
+ CameraErrorFactory.ThrowIfError(NativeFeatures.SupportedCapturePixelFormats(_camera.GetHandle(), callback, IntPtr.Zero),
+ "Failed to get the supported capture formats.");
+ }
+ catch
+ {
+ _captureFormats = null;
+ throw;
+ }
+ }
+
+ return _captureFormats;
+ }
+ }
+
+ /// <summary>
+ /// Retrieves all the preview formats supported by the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// It returns a list containing all the supported <see cref="CameraPixelFormat"/>.
+ /// </returns>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public IEnumerable<CameraPixelFormat> SupportedPreviewPixelFormats
+ {
+ get
+ {
+ if (_previewFormats == null)
+ {
+ try
+ {
+ _previewFormats = new List<CameraPixelFormat>();
+
+ NativeFeatures.PreviewFormatCallback callback = (CameraPixelFormat format, IntPtr userData) =>
+ {
+ _previewFormats.Add(format);
+ return true;
+ };
+ CameraErrorFactory.ThrowIfError(NativeFeatures.SupportedPreviewPixelFormats(_camera.GetHandle(), callback, IntPtr.Zero),
+ "Failed to get the supported preview formats.");
+ }
+ catch
+ {
+ _previewFormats = null;
+ throw;
+ }
+ }
+
+ return _previewFormats;
+ }
+ }
+
+ /// <summary>
+ /// Retrieves all the fps supported by the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// It returns a list containing all the supported <see cref="CameraFps"/>.
+ /// </returns>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public IEnumerable<CameraFps> SupportedPreviewFps
+ {
+ get
+ {
+ if (_fps == null)
+ {
+ try
+ {
+ _fps = new List<CameraFps>();
+
+ NativeFeatures.FpsCallback callback = (CameraFps fps, IntPtr userData) =>
+ {
+ _fps.Add(fps);
+ return true;
+ };
+ CameraErrorFactory.ThrowIfError(NativeFeatures.SupportedPreviewFps(_camera.GetHandle(), callback, IntPtr.Zero),
+ "Failed to get the supported camera fps");
+ }
+ catch
+ {
+ _fps = null;
+ throw;
+ }
+ }
+
+ return _fps;
+ }
+ }
+
+ /// <summary>
+ /// Retrieves all the fps by resolution supported by the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// It returns a list containing all the supported <see cref="CameraFps"/> by resolution.
+ /// </returns>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public IEnumerable<CameraFps> GetSupportedPreviewFpsByResolution(int width, int height)
+ {
+ if (_fpsByResolution == null)
+ {
+ try
+ {
+ _fpsByResolution = new List<CameraFps>();
+
+ NativeFeatures.FpsByResolutionCallback callback = (CameraFps fps, IntPtr userData) =>
+ {
+ _fpsByResolution.Add(fps);
+ return true;
+ };
+ CameraErrorFactory.ThrowIfError(NativeFeatures.SupportedPreviewFpsByResolution(_camera.GetHandle(),
+ width, height, callback, IntPtr.Zero), "Failed to get the supported fps by resolutions.");
+ }
+ catch
+ {
+ _fpsByResolution = null;
+ throw;
+ }
+ }
+
+ return _fpsByResolution;
+ }
+
+ /// <summary>
+ /// Retrieves all the fps by resolution supported by the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// It returns a list containing all the supported <see cref="CameraFps"/> by resolution.
+ /// </returns>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public IEnumerable<CameraFps> GetSupportedPreviewFpsByResolution(Size size)
+ {
+ return GetSupportedPreviewFpsByResolution(size.Width, size.Height);
+ }
+
+ /// <summary>
+ /// Retrieves all the auto focus modes supported by the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// It returns a list containing all the supported <see cref="CameraAutoFocusMode"/>.
+ /// </returns>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public IEnumerable<CameraAutoFocusMode> SupportedAutoFocusModes
+ {
+ get
+ {
+ if (_autoFocusModes == null)
+ {
+ try
+ {
+ _autoFocusModes = new List<CameraAutoFocusMode>();
+
+ NativeFeatures.AfModeCallback callback = (CameraAutoFocusMode mode, IntPtr userData) =>
+ {
+ _autoFocusModes.Add(mode);
+ return true;
+ };
+ CameraErrorFactory.ThrowIfError(NativeFeatures.SupportedAfModes(_camera.GetHandle(), callback, IntPtr.Zero),
+ "Failed to get the supported Auto focus modes.");
+ }
+ catch
+ {
+ _autoFocusModes = null;
+ throw;
+ }
+ }
+
+ return _autoFocusModes;
+ }
+ }
+
+ /// <summary>
+ /// Retrieves all the exposure modes supported by the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// It returns a list containing all the supported <see cref="CameraExposureMode"/>.
+ /// </returns>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public IEnumerable<CameraExposureMode> SupportedExposureModes
+ {
+ get
+ {
+ if (_exposureModes == null)
+ {
+ try
+ {
+ _exposureModes = new List<CameraExposureMode>();
+
+ NativeFeatures.ExposureModeCallback callback = (CameraExposureMode mode, IntPtr userData) =>
+ {
+ _exposureModes.Add(mode);
+ return true;
+ };
+ CameraErrorFactory.ThrowIfError(NativeFeatures.SupportedExposureModes(_camera.GetHandle(), callback, IntPtr.Zero),
+ "Failed to get the supported Exposure modes.");
+ }
+ catch
+ {
+ _exposureModes = null;
+ throw;
+ }
+ }
+
+ return _exposureModes;
+ }
+ }
+
+ /// <summary>
+ /// Retrieves all the Iso level supported by the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// It returns a list containing all the supported <see cref="CameraIsoLevel"/>.
+ /// </returns>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public IEnumerable<CameraIsoLevel> SupportedIsoLevels
+ {
+ get
+ {
+ if (_isoLevels == null)
+ {
+ try
+ {
+ _isoLevels = new List<CameraIsoLevel>();
+
+ NativeFeatures.IsoCallback callback = (CameraIsoLevel iso, IntPtr userData) =>
+ {
+ _isoLevels.Add(iso);
+ return true;
+ };
+ CameraErrorFactory.ThrowIfError(NativeFeatures.SupportedIso(_camera.GetHandle(), callback, IntPtr.Zero),
+ "Failed to get the supported Iso levels.");
+ }
+ catch
+ {
+ _isoLevels = null;
+ throw;
+ }
+ }
+
+ return _isoLevels;
+ }
+ }
+
+ /// <summary>
+ /// Retrieves all the theater modes supported by the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// It returns a list containing all the supported <see cref="CameraTheaterMode"/>.
+ /// </returns>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public IEnumerable<CameraTheaterMode> SupportedTheaterModes
+ {
+ get
+ {
+ if (_theaterModes == null)
+ {
+ try
+ {
+ _theaterModes = new List<CameraTheaterMode>();
+
+ NativeFeatures.TheaterModeCallback callback = (CameraTheaterMode theaterMode, IntPtr userData) =>
+ {
+ _theaterModes.Add(theaterMode);
+ return true;
+ };
+ CameraErrorFactory.ThrowIfError(NativeFeatures.SupportedTheaterModes(_camera.GetHandle(), callback, IntPtr.Zero),
+ "Failed to get the supported theater modes.");
+ }
+ catch
+ {
+ _theaterModes = null;
+ throw;
+ }
+ }
+
+ return _theaterModes;
+ }
+ }
+
+ /// <summary>
+ /// Retrieves all the whitebalance modes supported by the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// It returns a list containing all the supported <see cref="CameraWhiteBalance"/>.
+ /// </returns>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public IEnumerable<CameraWhiteBalance> SupportedWhiteBalances
+ {
+ get
+ {
+ if (_whitebalances == null)
+ {
+ try
+ {
+ _whitebalances = new List<CameraWhiteBalance>();
+
+ NativeFeatures.WhitebalanceCallback callback = (CameraWhiteBalance whiteBalance, IntPtr userData) =>
+ {
+ _whitebalances.Add(whiteBalance);
+ return true;
+ };
+ CameraErrorFactory.ThrowIfError(NativeFeatures.SupportedWhitebalance(_camera.GetHandle(), callback, IntPtr.Zero),
+ "Failed to get the supported white balance.");
+ }
+ catch
+ {
+ _whitebalances = null;
+ throw;
+ }
+ }
+
+ return _whitebalances;
+ }
+ }
+
+ /// <summary>
+ /// Retrieves all the flash modes supported by the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// It returns a list containing all the supported <see cref="CameraFlashMode"/>.
+ /// </returns>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public IEnumerable<CameraFlashMode> SupportedFlashModes
+ {
+ get
+ {
+ if (_flashModes == null)
+ {
+ try
+ {
+ _flashModes = new List<CameraFlashMode>();
+
+ NativeFeatures.FlashModeCallback callback = (CameraFlashMode flashMode, IntPtr userData) =>
+ {
+ _flashModes.Add(flashMode);
+ return true;
+ };
+ CameraErrorFactory.ThrowIfError(NativeFeatures.SupportedFlashModes(_camera.GetHandle(), callback, IntPtr.Zero),
+ "Failed to get the supported flash modes.");
+ }
+ catch
+ {
+ _flashModes = null;
+ throw;
+ }
+ }
+
+ return _flashModes;
+ }
+ }
+
+ /// <summary>
+ /// Retrieves all the scene modes supported by the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// It returns a list containing all the supported <see cref="CameraSceneMode"/>.
+ /// </returns>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public IEnumerable<CameraSceneMode> SupportedSceneModes
+ {
+ get
+ {
+ if (_sceneModes == null)
+ {
+ try
+ {
+ _sceneModes = new List<CameraSceneMode>();
+
+ NativeFeatures.SceneModeCallback callback = (CameraSceneMode sceneMode, IntPtr userData) =>
+ {
+ _sceneModes.Add(sceneMode);
+ return true;
+ };
+ CameraErrorFactory.ThrowIfError(NativeFeatures.SupportedSceneModes(_camera.GetHandle(), callback, IntPtr.Zero),
+ "Failed to get the supported scene modes.");
+ }
+ catch
+ {
+ _sceneModes = null;
+ throw;
+ }
+ }
+
+ return _sceneModes;
+ }
+ }
+
+ /// <summary>
+ /// Retrieves all the effect modes supported by the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// It returns a list containing all the supported <see cref="CameraEffectMode"/>.
+ /// </returns>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public IEnumerable<CameraEffectMode> SupportedEffects
+ {
+ get
+ {
+ if (_effectModes == null)
+ {
+ try
+ {
+ _effectModes = new List<CameraEffectMode>();
+
+ NativeFeatures.EffectCallback callback = (CameraEffectMode effect, IntPtr userData) =>
+ {
+ _effectModes.Add(effect);
+ return true;
+ };
+ CameraErrorFactory.ThrowIfError(NativeFeatures.SupportedEffects(_camera.GetHandle(), callback, IntPtr.Zero),
+ "Failed to get the supported camera effects.");
+ }
+ catch
+ {
+ _effectModes = null;
+ throw;
+ }
+ }
+
+ return _effectModes;
+ }
+ }
+
+ /// <summary>
+ /// Retrieves all the stream rotation supported by the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// It returns a list containing all the supported <see cref="CameraRotation"/>.
+ /// </returns>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public IEnumerable<CameraRotation> SupportedStreamRotations
+ {
+ get
+ {
+ if (_streamRotations == null)
+ {
+ try
+ {
+ _streamRotations = new List<CameraRotation>();
+
+ NativeFeatures.StreamRotationCallback callback = (CameraRotation streamRotation, IntPtr userData) =>
+ {
+ _streamRotations.Add(streamRotation);
+ return true;
+ };
+ CameraErrorFactory.ThrowIfError(NativeFeatures.SupportedStreamRotations(_camera.GetHandle(), callback, IntPtr.Zero),
+ "Failed to get the supported camera rotations.");
+ }
+ catch
+ {
+ _streamRotations = null;
+ throw;
+ }
+ }
+
+ return _streamRotations;
+ }
+ }
+
+ /// <summary>
+ /// Retrieves all the flips supported by the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// It returns a list containing all the supported <see cref="CameraFlip"/>.
+ /// </returns>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public IEnumerable<CameraFlip> SupportedStreamFlips
+ {
+ get
+ {
+ if (_streamFlips == null)
+ {
+ try
+ {
+ _streamFlips = new List<CameraFlip>();
+
+ NativeFeatures.StreamFlipCallback callback = (CameraFlip streamFlip, IntPtr userData) =>
+ {
+ _streamFlips.Add(streamFlip);
+ return true;
+ };
+ CameraErrorFactory.ThrowIfError(NativeFeatures.SupportedStreamFlips(_camera.GetHandle(), callback, IntPtr.Zero),
+ "Failed to get the supported camera flips.");
+ }
+ catch
+ {
+ _streamFlips = null;
+ throw;
+ }
+ }
+
+ return _streamFlips;
+ }
+ }
+
+ /// <summary>
+ /// Retrieves all the ptz types by the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// It returns a list containing all the supported <see cref="CameraPtzType"/>.
+ /// </returns>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public IEnumerable<CameraPtzType> SupportedPtzTypes
+ {
+ get
+ {
+ if (_ptzTypes.Count == 0)
+ {
+ try
+ {
+ _ptzTypes = new List<CameraPtzType>();
+
+ NativeFeatures.PtzTypeCallback callback = (CameraPtzType ptzType, IntPtr userData) =>
+ {
+ _ptzTypes.Add(ptzType);
+ return true;
+ };
+ CameraErrorFactory.ThrowIfError(NativeFeatures.SupportedPtzTypes(_camera.GetHandle(), callback, IntPtr.Zero),
+ "Failed to get the supported Ptz types.");
+ }
+ catch
+ {
+ _ptzTypes = null;
+ throw;
+ }
+ }
+
+ return _ptzTypes;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Camera/Camera/CameraFocusStateChangedEventArgs.cs b/src/Tizen.Multimedia.Camera/Camera/CameraFocusStateChangedEventArgs.cs
new file mode 100755
index 0000000..c288d73
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Camera/CameraFocusStateChangedEventArgs.cs
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// An extended EventArgs class which contains details about focus state of the
+ /// camera.
+ /// </summary>
+ public class CameraFocusStateChangedEventArgs : EventArgs
+ {
+ internal CameraFocusStateChangedEventArgs(CameraFocusState state)
+ {
+ State = state;
+ }
+
+ /// <summary>
+ /// Focus state of the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public CameraFocusState State { get; }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Camera/Camera/CameraInterruptedEventArgs.cs b/src/Tizen.Multimedia.Camera/Camera/CameraInterruptedEventArgs.cs
new file mode 100755
index 0000000..4ce158a
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Camera/CameraInterruptedEventArgs.cs
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// An extended EventArgs class which contains details about previous and current state
+ /// of the camera when its interrupted.
+ /// </summary>
+ public class CameraInterruptedEventArgs : EventArgs
+ {
+ internal CameraInterruptedEventArgs(CameraPolicy policy, CameraState previous, CameraState current)
+ {
+ Policy = policy;
+ Current = current;
+ Previous = previous;
+ }
+
+ /// <summary>
+ /// Previous state of the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public CameraState Previous { get; }
+
+ /// <summary>
+ /// Current state of the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public CameraState Current { get; }
+
+ /// <summary>
+ /// The policy that interrupted the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public CameraPolicy Policy { get; }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Camera/Camera/CameraSettings.cs b/src/Tizen.Multimedia.Camera/Camera/CameraSettings.cs
new file mode 100755
index 0000000..d188ef5
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Camera/CameraSettings.cs
@@ -0,0 +1,1159 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Native = Interop.CameraSettings;
+using static Interop.Camera;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// The camera setting class provides methods/properties to get and
+ /// set basic camera attributes.
+ /// </summary>
+ public class CameraSettings
+ {
+ internal readonly Camera _camera;
+
+ private readonly Range? _brightnessRange;
+ private readonly Range? _contrastRange;
+ private readonly Range? _panRange;
+ private readonly Range? _tiltRange;
+ private readonly Range? _exposureRange;
+ private readonly Range? _zoomRange;
+
+ internal CameraSettings(Camera camera)
+ {
+ _camera = camera;
+
+ _contrastRange = GetRange(Native.GetContrastRange);
+ _brightnessRange = GetRange(Native.GetBrightnessRange);
+ _exposureRange = GetRange(Native.GetExposureRange);
+ _zoomRange = GetRange(Native.GetZoomRange);
+ _panRange = GetRange(Native.GetPanRange);
+ _tiltRange = GetRange(Native.GetTiltRange);
+ }
+
+ private delegate CameraError GetRangeDelegate(IntPtr handle, out int min, out int max);
+ private Range? GetRange(GetRangeDelegate func)
+ {
+ CameraErrorFactory.ThrowIfError(func(_camera.GetHandle(), out int min, out int max),
+ "Failed to initialize the camera settings");
+
+ if (min > max)
+ {
+ return null;
+ }
+
+ return new Range(min, max);
+ }
+
+ #region Auto Focus
+ /// <summary>
+ /// Sets auto focus area.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// <see cref="CameraAutoFocusMode"/> should not be the <see cref="CameraAutoFocusMode.None"/>.
+ /// </remarks>
+ /// <param name="x">X position</param>
+ /// <param name="y">Y position</param>
+ /// <exception cref="ArgumentException">In case of invalid parameters.</exception>
+ /// <exception cref="InvalidOperationException">In case of any invalid operations.</exception>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public void SetAutoFocusArea(int x, int y)
+ {
+ CameraErrorFactory.ThrowIfError(Native.SetAutoFocusArea(_camera.GetHandle(), x, y),
+ "Failed to set the autofocus area.");
+ }
+
+ /// <summary>
+ /// Sets auto focus area.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// <see cref="CameraAutoFocusMode"/> should not be the <see cref="CameraAutoFocusMode.None"/>.
+ /// </remarks>
+ /// <param name="pos"><see cref="Point"/> structure including X, Y position</param>
+ /// <exception cref="ArgumentException">In case of invalid parameters.</exception>
+ /// <exception cref="InvalidOperationException">In case of any invalid operations.</exception>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public void SetAutoFocusArea(Point pos)
+ {
+ CameraErrorFactory.ThrowIfError(Native.SetAutoFocusArea(_camera.GetHandle(), pos.X, pos.Y),
+ "Failed to set the autofocus area.");
+ }
+
+ /// <summary>
+ /// Clears the auto focus area.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public void ClearFocusArea()
+ {
+ CameraErrorFactory.ThrowIfError(Native.ClearAutoFocusArea(_camera.GetHandle()),
+ "Failed to clear the autofocus area.");
+ }
+
+ /// <summary>
+ /// The auto focus mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A <see cref="CameraAutoFocusMode"/> that specifies the auto focus mode.</value>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public CameraAutoFocusMode AutoFocusMode
+ {
+ get
+ {
+ CameraAutoFocusMode val = CameraAutoFocusMode.None;
+
+ CameraErrorFactory.ThrowIfError(Native.GetAutoFocusMode(_camera.GetHandle(), out val),
+ "Failed to get camera autofocus mode");
+
+ return val;
+ }
+
+ set
+ {
+ ValidationUtil.ValidateEnum(typeof(CameraAutoFocusMode), value);
+ CameraErrorFactory.ThrowIfError(Native.SetAutoFocusMode(_camera.GetHandle(), value),
+ "Failed to set camera autofocus mode.");
+ }
+ }
+ #endregion Auto Focus
+
+ #region Contrast
+ /// <summary>
+ /// The contrast level of the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public int Contrast
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(Native.GetContrast(_camera.GetHandle(), out int val),
+ "Failed to get camera contrast value");
+
+ return val;
+ }
+
+ set
+ {
+ CameraErrorFactory.ThrowIfError(Native.SetContrast(_camera.GetHandle(), value),
+ "Failed to set camera contrast value.");
+ }
+ }
+
+ /// <summary>
+ /// The auto contrast.
+ /// If true auto contrast is enabled, otherwise false.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public bool AutoContrast
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(Native.IsEnabledAutoContrast(_camera.GetHandle(), out bool val),
+ "Failed to get camera auto contrast");
+
+ return val;
+ }
+
+ set
+ {
+ CameraErrorFactory.ThrowIfError(Native.EnableAutoContrast(_camera.GetHandle(), value),
+ "Failed to set camera enable auto contrast.");
+ }
+ }
+ /// <summary>
+ /// Gets the available contrast level.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// If min value is greater than the max value, it means this feature is not supported.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">In case of this feature is not supported.</exception>
+ public Range ContrastRange
+ {
+ get
+ {
+ if (!_contrastRange.HasValue)
+ {
+ throw new NotSupportedException("Contrast is not supported.");
+ }
+
+ return _contrastRange.Value;
+ }
+ }
+ #endregion Contrast
+
+ #region Brightness
+ /// <summary>
+ /// The brightness level of the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public int Brightness
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(Native.GetBrightness(_camera.GetHandle(), out int val),
+ "Failed to get camera brightness value");
+
+ return val;
+ }
+
+ set
+ {
+ CameraErrorFactory.ThrowIfError(Native.SetBrightness(_camera.GetHandle(), value),
+ "Failed to set camera brightness value.");
+ }
+ }
+
+ /// <summary>
+ /// Gets the available brightness level.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// If min value is greater than the max value, it means this feature is not supported.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">In case of this feature is not supported.</exception>
+ public Range BrightnessRange
+ {
+ get
+ {
+ if (!_brightnessRange.HasValue)
+ {
+ throw new NotSupportedException("Brightness is not supported.");
+ }
+
+ return _brightnessRange.Value;
+ }
+ }
+ #endregion Brightness
+
+ #region Exposure
+ /// <summary>
+ /// The exposure value.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public int Exposure
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(Native.GetExposure(_camera.GetHandle(), out int val),
+ "Failed to get camera exposure value");
+
+ return val;
+ }
+
+ set
+ {
+ CameraErrorFactory.ThrowIfError(Native.SetExposure(_camera.GetHandle(), value),
+ "Failed to set camera exposure value.");
+ }
+ }
+
+ /// <summary>
+ /// The exposure mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A <see cref="CameraExposureMode"/> that specifies the exposure mode.</value>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public CameraExposureMode ExposureMode
+ {
+ get
+ {
+ CameraExposureMode val = CameraExposureMode.Off;
+
+ CameraErrorFactory.ThrowIfError(Native.GetExposureMode(_camera.GetHandle(), out val),
+ "Failed to get camera exposure mode");
+
+ return val;
+ }
+
+ set
+ {
+ ValidationUtil.ValidateEnum(typeof(CameraExposureMode), value);
+ CameraErrorFactory.ThrowIfError(Native.SetExposureMode(_camera.GetHandle(), value),
+ "Failed to set camera exposure mode.");
+ }
+ }
+
+ /// <summary>
+ /// Gets the available exposure value.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// If min value is greater than the max value, it means this feature is not supported.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">In case of this feature is not supported.</exception>
+ public Range ExposureRange
+ {
+ get
+ {
+ if (!_exposureRange.HasValue)
+ {
+ throw new NotSupportedException("Exposure is not supported.");
+ }
+
+ return _exposureRange.Value;
+ }
+ }
+ #endregion Exposure
+
+ #region Zoom
+ /// <summary>
+ /// The zoom level.
+ /// The range for zoom level is received from ZoomRange property.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public int ZoomLevel
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(Native.GetZoom(_camera.GetHandle(), out int val),
+ "Failed to get zoom level");
+
+ return val;
+ }
+
+ set
+ {
+ CameraErrorFactory.ThrowIfError(Native.SetZoom(_camera.GetHandle(), value),
+ "Failed to set zoom level.");
+ }
+ }
+
+ /// <summary>
+ /// Gets the available zoom level.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// If min value is greater than the max value, it means this feature is not supported.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">In case of this feature is not supported.</exception>
+ public Range ZoomRange
+ {
+ get
+ {
+ if (!_zoomRange.HasValue)
+ {
+ throw new NotSupportedException("Zoom is not supported.");
+ }
+
+ return _zoomRange.Value;
+ }
+ }
+ #endregion Zoom
+
+ /// <summary>
+ /// The whitebalance mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A <see cref="CameraWhiteBalance"/> that specifies the white balance mode.</value>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public CameraWhiteBalance WhiteBalance
+ {
+ get
+ {
+ CameraWhiteBalance val = CameraWhiteBalance.None;
+
+ CameraErrorFactory.ThrowIfError(Native.GetWhiteBalance(_camera.GetHandle(), out val),
+ "Failed to get camera whitebalance");
+
+ return val;
+ }
+
+ set
+ {
+ ValidationUtil.ValidateEnum(typeof(CameraWhiteBalance), value);
+ CameraErrorFactory.ThrowIfError(Native.SetWhitebalance(_camera.GetHandle(), value),
+ "Failed to set camera whitebalance.");
+ }
+ }
+
+ /// <summary>
+ /// The ISO level.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A <see cref="CameraIsoLevel"/> that specifies ISO level.</value>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public CameraIsoLevel IsoLevel
+ {
+ get
+ {
+ CameraIsoLevel val = CameraIsoLevel.Auto;
+
+ CameraErrorFactory.ThrowIfError(Native.GetIso(_camera.GetHandle(), out val),
+ "Failed to get camera Iso level");
+
+ return val;
+ }
+
+ set
+ {
+ ValidationUtil.ValidateEnum(typeof(CameraIsoLevel), value);
+ CameraErrorFactory.ThrowIfError(Native.SetIso(_camera.GetHandle(), value),
+ "Failed to set camera Iso level.");
+ }
+ }
+
+ /// <summary>
+ /// The quality of the image.
+ /// The range for image quality is 1 to 100.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public int ImageQuality
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(Native.GetImageQuality(_camera.GetHandle(), out int val),
+ "Failed to get image quality");
+
+ return val;
+ }
+
+ set
+ {
+ if (value < 1 || value > 100)
+ {
+ throw new ArgumentException("Valid value is from 1(lowest quality) to 100(highest quality)");
+ }
+
+ CameraErrorFactory.ThrowIfError(Native.SetImageQuality(_camera.GetHandle(), value),
+ "Failed to set image quality.");
+ }
+ }
+
+ #region Resolution, Format, Fps of preview, capture
+ /// <summary>
+ /// The preview frame rate.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A <see cref="CameraFps"/> that specifies preview frame rate.</value>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public CameraFps PreviewFps
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(Native.GetPreviewFps(_camera.GetHandle(), out var val),
+ "Failed to get camera preview fps");
+
+ return val;
+ }
+
+ set
+ {
+ ValidationUtil.ValidateEnum(typeof(CameraFps), value);
+ CameraErrorFactory.ThrowIfError(Native.SetPreviewFps(_camera.GetHandle(), value),
+ "Failed to set preview fps.");
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the resolution of preview
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ArgumentException">In case of invalid parameters.</exception>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public Size PreviewResolution
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(GetPreviewResolution(_camera.GetHandle(), out int width, out int height),
+ "Failed to get camera preview resolution");
+
+ return new Size(width, height);
+ }
+
+ set
+ {
+ CameraErrorFactory.ThrowIfError(SetPreviewResolution(_camera.GetHandle(), value.Width, value.Height),
+ "Failed to set preview resolution.");
+ }
+ }
+
+ /// <summary>
+ /// Gets the recommended preview resolution.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// Depending on the capture resolution aspect ratio and display resolution,
+ /// the recommended preview resolution is determined.
+ /// </remarks>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public Size RecommendedPreviewResolution
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(GetRecommendedPreviewResolution(_camera.GetHandle(), out int width, out int height),
+ "Failed to get recommended preview resolution");
+
+ return new Size(width, height);
+ }
+ }
+
+ /// <summary>
+ /// The preview data format.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A <see cref="CameraPixelFormat"/> that specifies the pixel format of preview data.</value>
+ /// <exception cref="ArgumentException">In case of invalid parameters.</exception>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public CameraPixelFormat PreviewPixelFormat
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(GetPreviewPixelFormat(_camera.GetHandle(), out var val),
+ "Failed to get preview format");
+
+ return val;
+ }
+
+ set
+ {
+ ValidationUtil.ValidateEnum(typeof(CameraPixelFormat), value);
+ CameraErrorFactory.ThrowIfError(SetPreviewPixelFormat(_camera.GetHandle(), value),
+ "Failed to set preview format.");
+ }
+ }
+
+ /// <summary>
+ /// Resolution of the captured image.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ArgumentException">In case of invalid parameters</exception>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public Size CaptureResolution
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(GetCaptureResolution(_camera.GetHandle(), out int width, out int height),
+ "Failed to get camera capture resolution");
+
+ return new Size(width, height);
+ }
+
+ set
+ {
+ Size res = value;
+
+ CameraErrorFactory.ThrowIfError(SetCaptureResolution(_camera.GetHandle(), res.Width, res.Height),
+ "Failed to set capture resolution.");
+ }
+ }
+
+ /// <summary>
+ /// Format of an image to be captured.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A <see cref="CameraPixelFormat"/> that specifies the pixel format of captured image.</value>
+ /// <exception cref="ArgumentException">In case of invalid parameters</exception>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public CameraPixelFormat CapturePixelFormat
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(GetCaptureFormat(_camera.GetHandle(), out var val),
+ "Failed to get camera capture formats");
+
+ return val;
+ }
+
+ set
+ {
+ ValidationUtil.ValidateEnum(typeof(CameraPixelFormat), value);
+ CameraErrorFactory.ThrowIfError(SetCaptureFormat(_camera.GetHandle(), value),
+ "Failed to set capture format.");
+ }
+ }
+ #endregion Resolution, Format, Fps of preview, capture
+
+ #region Encoded preview
+ /// <summary>
+ /// The bit rate of encoded preview.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public int EncodedPreviewBitrate
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(Native.GetBitrate(_camera.GetHandle(), out int val),
+ "Failed to get preview bitrate");
+
+ return val;
+ }
+
+ set
+ {
+ CameraErrorFactory.ThrowIfError(Native.SetBitrate(_camera.GetHandle(), value),
+ "Failed to set encoded preview bitrate.");
+ }
+ }
+
+ /// <summary>
+ /// GOP(Group Of Pictures) interval of encoded preview.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public int EncodedPreviewGopInterval
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(Native.GetGopInterval(_camera.GetHandle(), out int val),
+ "Failed to get preview gop interval");
+
+ return val;
+ }
+
+ set
+ {
+ CameraErrorFactory.ThrowIfError(Native.SetGopInterval(_camera.GetHandle(), value),
+ "Failed to set encoded preview gop intervals.");
+ }
+ }
+ #endregion Encoded preview
+
+ /// <summary>
+ /// The theater mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A <see cref="CameraTheaterMode"/> that specifies theater mode.</value>
+ /// <remarks>
+ /// If you want to display the preview image on the external display with the full screen mode,
+ /// use this property.
+ /// </remarks>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public CameraTheaterMode TheaterMode
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(Native.GetTheaterMode(_camera.GetHandle(), out var val),
+ "Failed to get camera theater mode");
+
+ return val;
+ }
+
+ set
+ {
+ ValidationUtil.ValidateEnum(typeof(CameraTheaterMode), value);
+ CameraErrorFactory.ThrowIfError(Native.SetTheaterMode(_camera.GetHandle(), value),
+ "Failed to set camera theater mode.");
+ }
+ }
+
+ /// <summary>
+ /// The camera effect mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A <see cref="CameraEffectMode"/> that specifies effect mode.</value>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public CameraEffectMode Effect
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(Native.GetEffect(_camera.GetHandle(), out var val),
+ "Failed to get camera effect");
+
+ return val;
+ }
+
+ set
+ {
+ ValidationUtil.ValidateEnum(typeof(CameraEffectMode), value);
+ CameraErrorFactory.ThrowIfError(Native.SetEffect(_camera.GetHandle(), value),
+ "Failed to set camera effect.");
+ }
+ }
+
+ /// <summary>
+ /// The scene mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A <see cref="CameraSceneMode"/> that specifies scene mode.</value>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public CameraSceneMode SceneMode
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(Native.GetSceneMode(_camera.GetHandle(), out var val),
+ "Failed to get camera scene mode");
+
+ return val;
+ }
+
+ set
+ {
+ ValidationUtil.ValidateEnum(typeof(CameraSceneMode), value);
+ CameraErrorFactory.ThrowIfError(Native.SetSceneMode(_camera.GetHandle(), value),
+ "Failed to set camera scene mode.");
+ }
+ }
+
+ /// <summary>
+ /// The camera's flash mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A <see cref="CameraFlashMode"/> that specifies flash mode.</value>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public CameraFlashMode FlashMode
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(Native.GetFlashMode(_camera.GetHandle(), out var val),
+ "Failed to get camera flash mode");
+
+ return val;
+ }
+
+ set
+ {
+ ValidationUtil.ValidateEnum(typeof(CameraFlashMode), value);
+ CameraErrorFactory.ThrowIfError(Native.SetFlashMode(_camera.GetHandle(), value),
+ "Failed to set camera flash mode.");
+ }
+ }
+
+ /// <summary>
+ /// Gets the camera lens orientation angle.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public int LensOrientation
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(Native.GetLensOrientation(_camera.GetHandle(), out var val),
+ "Failed to get camera lens orientation");
+
+ return val;
+ }
+ }
+
+ /// <summary>
+ /// The stream rotation.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A <see cref="CameraRotation"/> that specifies the rotation of camera device.</value>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public CameraRotation StreamRotation
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(Native.GetStreamRotation(_camera.GetHandle(), out var val),
+ "Failed to get camera stream rotation");
+
+ return val;
+ }
+
+ set
+ {
+ ValidationUtil.ValidateEnum(typeof(CameraRotation), value);
+ CameraErrorFactory.ThrowIfError(Native.SetStreamRotation(_camera.GetHandle(), value),
+ "Failed to set camera stream rotation.");
+ }
+ }
+
+ /// <summary>
+ /// The stream flip.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A <see cref="CameraFlip"/> that specifies camera flip type.</value>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public CameraFlip StreamFlip
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(Native.GetFlip(_camera.GetHandle(), out var val),
+ "Failed to get camera stream flip");
+
+ return val;
+ }
+
+ set
+ {
+ ValidationUtil.ValidateEnum(typeof(CameraFlip), value);
+ CameraErrorFactory.ThrowIfError(Native.SetFlip(_camera.GetHandle(), value),
+ "Failed to set camera flip.");
+ }
+ }
+
+ /// <summary>
+ /// The mode of HDR(High dynamic range) capture.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A <see cref="CameraHdrMode"/> that specifies the HDR mode.</value>
+ /// <remarks>
+ /// Taking multiple pictures at different exposure levels and intelligently stitching them together
+ /// so that we eventually arrive at a picture that is representative in both dark and bright areas.
+ /// If this attribute is set, then eventhandler set for HdrCaptureProgress event is invoked.
+ /// </remarks>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public CameraHdrMode HdrMode
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(Native.GetHdrMode(_camera.GetHandle(), out var val),
+ "Failed to get camera hdr mode");
+
+ return val;
+ }
+
+ set
+ {
+ ValidationUtil.ValidateEnum(typeof(CameraHdrMode), value);
+ CameraErrorFactory.ThrowIfError(Native.SetHdrMode(_camera.GetHandle(), value),
+ "Failed to set camera hdr mode.");
+ }
+ }
+
+ /// <summary>
+ /// The anti shake feature.
+ /// If true the antishake feature is enabled, otherwise false.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public bool AntiShake
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(Native.IsEnabledAntiShake(_camera.GetHandle(), out bool val),
+ "Failed to get camera anti shake value");
+
+ return val;
+ }
+
+ set
+ {
+ CameraErrorFactory.ThrowIfError(Native.EnableAntiShake(_camera.GetHandle(), value),
+ "Failed to set camera anti shake value.");
+ }
+ }
+
+ /// <summary>
+ /// Enables/Disables the video stabilization feature.
+ /// If true video stabilization is enabled, otherwise false.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// If video stabilization is enabled, zero shutter lag is disabled.
+ /// This feature is used to record a video.
+ /// </remarks>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public bool VideoStabilization
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(Native.IsEnabledVideoStabilization(_camera.GetHandle(), out bool val),
+ "Failed to get camera video stabilization");
+
+ return val;
+ }
+
+ set
+ {
+ CameraErrorFactory.ThrowIfError(Native.EnableVideoStabilization(_camera.GetHandle(), value),
+ "Failed to set camera video stabilization.");
+ }
+ }
+
+ /// <summary>
+ /// Disables shutter sound.
+ /// If true shutter sound is disabled, otherwise false.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// In some countries, this operation is not permitted.
+ /// </remarks>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public bool DisableShutterSound
+ {
+ set
+ {
+ CameraErrorFactory.ThrowIfError(Native.DisableShutterSound(_camera.GetHandle(), value),
+ "Failed to set disable shutter sound.");
+ }
+ }
+
+ #region PTZ(Pan Tilt Zoom), Pan, Tilt
+ /// <summary>
+ /// Sets the type of PTZ(Pan Tilt Zoom). Mechanical or Electronic.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A <see cref="CameraPtzType"/> that specifies the type of PTZ.</value>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public CameraPtzType PtzType
+ {
+ set
+ {
+ ValidationUtil.ValidateEnum(typeof(CameraPtzType), value);
+
+ CameraErrorFactory.ThrowIfError(Native.SetPtzType(_camera.GetHandle(), value),
+ "Failed to set camera ptz type.");
+ }
+ }
+
+ /// <summary>
+ /// Sets the position to move horizontally.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="type">ptz move type. <seealso cref="CameraPtzMoveType"/></param>
+ /// <param name="panStep">pan step</param>
+ /// <exception cref="ArgumentException">In case of invalid parameters</exception>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public void SetPan(CameraPtzMoveType type, int panStep)
+ {
+ ValidationUtil.ValidateEnum(typeof(CameraPtzMoveType), type, nameof(type));
+ CameraErrorFactory.ThrowIfError(Native.SetPan(_camera.GetHandle(), type, panStep),
+ "Failed to set the camera pan type.");
+ }
+
+ /// <summary>
+ /// Gets the current position of the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>Returns the camera's horizontal position</returns>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public int GetPan()
+ {
+ CameraErrorFactory.ThrowIfError(Native.GetPan(_camera.GetHandle(), out int val),
+ "Failed to get the camera pan step.");
+
+ return val;
+ }
+
+ /// <summary>
+ /// Sets the position to move vertically.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="type">ptz move type</param>
+ /// <param name="tiltStep">tilt step</param>
+ /// <exception cref="ArgumentException">In case of invalid parameters</exception>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public void SetTilt(CameraPtzMoveType type, int tiltStep)
+ {
+ ValidationUtil.ValidateEnum(typeof(CameraPtzMoveType), type, nameof(type));
+ CameraErrorFactory.ThrowIfError(Native.SetTilt(_camera.GetHandle(), type, tiltStep),
+ "Failed to set the camera tilt type\t.");
+ }
+
+ /// <summary>
+ /// Gets the current position of the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>Returns the current vertical position</returns>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public int GetTilt()
+ {
+ CameraErrorFactory.ThrowIfError(Native.GetTilt(_camera.GetHandle(), out int val),
+ "Failed to set the camera current position.");
+
+ return val;
+ }
+
+ /// <summary>
+ /// Gets lower limit and upper limit for pan position.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// If min value is greater than the max value, it means this feature is not supported.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">In case of this feature is not supported.</exception>
+ public Range PanRange
+ {
+ get
+ {
+ if (!_panRange.HasValue)
+ {
+ throw new NotSupportedException("Pan is not supported.");
+ }
+ return _panRange.Value;
+ }
+ }
+
+ /// <summary>
+ /// Gets lower limit and upper limit for tilt position.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// If min value is greater than the max value, it means this feature is not supported.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">In case of this feature is not supported.</exception>
+ public Range TiltRange
+ {
+ get
+ {
+ if (!_tiltRange.HasValue)
+ {
+ throw new NotSupportedException("Tilt is not supported.");
+ }
+ return _tiltRange.Value;
+ }
+ }
+ #endregion PTZ(Pan Tilt Zoom), Pan, Tilt
+
+ #region EXIF tag
+ /// <summary>
+ /// The scene mode.
+ /// true if EXIF tags are enabled in JPEG file, otherwise false.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public bool EnableTag
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(Native.IsEnabledTag(_camera.GetHandle(), out bool val),
+ "Failed to get camera enable tag");
+
+ return val;
+ }
+
+ set
+ {
+ CameraErrorFactory.ThrowIfError(Native.EnableTag(_camera.GetHandle(), value),
+ "Failed to set camera enable tag.");
+ }
+ }
+
+ /// <summary>
+ /// The camera image description in the EXIF tag.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public string ImageDescriptionTag
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+ try
+ {
+ CameraErrorFactory.ThrowIfError(Native.GetImageDescription(_camera.GetHandle(), out val),
+ "Failed to get image description");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ LibcSupport.Free(val);
+ }
+ }
+
+ set
+ {
+ CameraErrorFactory.ThrowIfError(Native.SetImageDescription(_camera.GetHandle(), value),
+ "Failed to set image description.");
+ }
+ }
+
+ /// <summary>
+ /// The software information in the EXIF tag.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public string SoftwareTag
+ {
+ get
+ {
+ IntPtr val = IntPtr.Zero;
+
+ try
+ {
+ CameraErrorFactory.ThrowIfError(Native.GetTagSoftware(_camera.GetHandle(), out val),
+ "Failed to get tag software");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ LibcSupport.Free(val);
+ }
+ }
+
+ set
+ {
+ CameraErrorFactory.ThrowIfError(Native.SetTagSoftware(_camera.GetHandle(), value),
+ "Failed to set tag software.");
+ }
+ }
+
+ /// <summary>
+ /// The geotag(GPS data) in the EXIF tag.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public Location GeoTag
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(Native.GetGeotag(_camera.GetHandle(),
+ out double latitude, out double longitude, out double altitude), "Failed to get tag");
+
+ return new Location(latitude, longitude, altitude);
+ }
+
+ set
+ {
+ CameraErrorFactory.ThrowIfError(Native.SetGeotag(_camera.GetHandle(),
+ value.Latitude, value.Longitude, value.Altitude), "Failed to set geo tag.");
+ }
+ }
+
+ /// <summary>
+ /// Removes the geotag(GPS data) in the EXIF(Exchangeable image file format) tag.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public void RemoveGeoTag()
+ {
+ CameraErrorFactory.ThrowIfError(Native.RemoveGeotag(_camera.GetHandle()),
+ "Failed to remove the geotag\t.");
+ }
+
+ /// <summary>
+ /// The camera orientation in the tag.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public CameraTagOrientation OrientationTag
+ {
+ get
+ {
+ CameraErrorFactory.ThrowIfError(Native.GetTagOrientation(_camera.GetHandle(), out var val),
+ "Failed to get camera tag orientation");
+
+ return val;
+ }
+
+ set
+ {
+ ValidationUtil.ValidateEnum(typeof(CameraTagOrientation), value);
+ CameraErrorFactory.ThrowIfError(Native.SetTagOrientation(_camera.GetHandle(), value),
+ "Failed to set camera tag orientation.");
+ }
+ }
+ #endregion EXIF tag
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Camera/Camera/CameraStateChangedEventArgs.cs b/src/Tizen.Multimedia.Camera/Camera/CameraStateChangedEventArgs.cs
new file mode 100755
index 0000000..96e2e0c
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Camera/CameraStateChangedEventArgs.cs
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// An extended EventArgs class which contains details about previous and current state
+ /// of the camera when its state is changed.
+ /// </summary>
+ public class CameraStateChangedEventArgs : EventArgs
+ {
+ internal CameraStateChangedEventArgs(CameraState previous, CameraState current, bool policy)
+ {
+ Previous = previous;
+ Current = current;
+ ByPolicy = policy;
+ }
+
+ /// <summary>
+ /// Previous state of the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public CameraState Previous { get; }
+
+ /// <summary>
+ /// Current state of the camera.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public CameraState Current { get; }
+
+ /// <summary>
+ /// true if the state changed by policy such as Resource Conflict or Security, otherwise false
+ /// in normal state change.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool ByPolicy { get; }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Camera/Camera/DoublePlane.cs b/src/Tizen.Multimedia.Camera/Camera/DoublePlane.cs
new file mode 100755
index 0000000..e6960f1
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Camera/DoublePlane.cs
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System.Runtime.InteropServices;
+using static Interop.Camera;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// The class containing image data which has two planes.
+ /// </summary>
+ public class DoublePlane : IPreviewPlane
+ {
+ internal DoublePlane(DoublePlaneStruct unmanaged)
+ {
+ Y = new byte[unmanaged.YLength];
+ UV = new byte[unmanaged.UVLength];
+ Marshal.Copy(unmanaged.Y, Y, 0, (int)unmanaged.YLength);
+ Marshal.Copy(unmanaged.UV, UV, 0, (int)unmanaged.UVLength);
+ }
+
+ /// <summary>
+ /// The Y plane data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public byte[] Y { get; }
+
+ /// <summary>
+ /// The UV plane data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public byte[] UV { get; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Multimedia.Camera/Camera/EncodedPlane.cs b/src/Tizen.Multimedia.Camera/Camera/EncodedPlane.cs
new file mode 100755
index 0000000..d88e596
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Camera/EncodedPlane.cs
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System.Runtime.InteropServices;
+using static Interop.Camera;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// The class containing Encoded image data.
+ /// </summary>
+ public class EncodedPlane : IPreviewPlane
+ {
+ internal EncodedPlane(EncodedPlaneStruct unmanagedData)
+ {
+ Data = new byte[unmanagedData.DataLength];
+ Marshal.Copy(unmanagedData.Data, Data, 0, (int)unmanagedData.DataLength);
+ }
+
+ /// <summary>
+ /// The buffer containing encoded image data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public byte[] Data { get; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Multimedia.Camera/Camera/FaceDetectedEventArgs.cs b/src/Tizen.Multimedia.Camera/Camera/FaceDetectedEventArgs.cs
new file mode 100755
index 0000000..6c5feaa
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Camera/FaceDetectedEventArgs.cs
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// An extended EventArgs class which contains details about all the faces detected.
+ /// If user need to remain faces data, user have to copy the data.
+ /// </summary>
+ public class FaceDetectedEventArgs : EventArgs
+ {
+ internal FaceDetectedEventArgs(List<FaceDetectionData> faces)
+ {
+ Faces = faces;
+ }
+
+ /// <summary>
+ /// List containing faces of type <see cref="Tizen.Multimedia.FaceDetectionData"/>.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public IEnumerable<FaceDetectionData> Faces { get; }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Camera/Camera/FaceDetectionData.cs b/src/Tizen.Multimedia.Camera/Camera/FaceDetectionData.cs
new file mode 100755
index 0000000..53905c7
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Camera/FaceDetectionData.cs
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using static Interop.Camera;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// The class contains the details of the detected face.
+ /// </summary>
+ public class FaceDetectionData
+ {
+ internal FaceDetectionData(IntPtr ptr)
+ {
+ var unmanagedStruct = Marshal.PtrToStructure<DetectedFaceStruct>(ptr);
+
+ Id = unmanagedStruct.Id;
+ Score = unmanagedStruct.Score;
+ X = unmanagedStruct.X;
+ Y = unmanagedStruct.Y;
+ Width = unmanagedStruct.Width;
+ Height = unmanagedStruct.Height;
+ }
+
+ /// <summary>
+ /// The Id of each face.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Id { get; }
+
+ /// <summary>
+ /// The confidence level for the detection of the face.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Score { get; }
+
+ /// <summary>
+ /// The X co-ordinate of the face.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int X { get; }
+
+ /// <summary>
+ /// The Y co-ordinate of the face.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Y { get; }
+
+ /// <summary>
+ /// The width of the face.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Width { get; }
+
+ /// <summary>
+ /// The height of the face.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Height { get; }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Camera/Camera/HdrCaptureProgressEventArgs.cs b/src/Tizen.Multimedia.Camera/Camera/HdrCaptureProgressEventArgs.cs
new file mode 100755
index 0000000..ce5db62
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Camera/HdrCaptureProgressEventArgs.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// An extended EventArgs class which contains details about the hdr capture progress.
+ /// </summary>
+ public class HdrCaptureProgressEventArgs : EventArgs
+ {
+ internal HdrCaptureProgressEventArgs(int percent)
+ {
+ Percent = percent;
+ }
+
+ /// <summary>
+ /// Hdr Capture progress in percent.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Percent { get; }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Camera/Camera/IPreviewPlane.cs b/src/Tizen.Multimedia.Camera/Camera/IPreviewPlane.cs
new file mode 100755
index 0000000..e3b506b
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Camera/IPreviewPlane.cs
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ public interface IPreviewPlane
+ {
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Multimedia.Camera/Camera/ImageData.cs b/src/Tizen.Multimedia.Camera/Camera/ImageData.cs
new file mode 100755
index 0000000..0066447
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Camera/ImageData.cs
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using static Interop.Camera;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// The class containing the captured image data.
+ /// </summary>
+ public class ImageData
+ {
+ internal ImageData(IntPtr ptr)
+ {
+ var unmanagedStruct = Marshal.PtrToStructure<ImageDataStruct>(ptr);
+
+ Format = unmanagedStruct.Format;
+ Width = unmanagedStruct.Width;
+ Height = unmanagedStruct.Height;
+
+ if (unmanagedStruct.Data != IntPtr.Zero && unmanagedStruct.DataLength > 0)
+ {
+ Data = new byte[unmanagedStruct.DataLength];
+ Marshal.Copy(unmanagedStruct.Data, Data, 0, (int)unmanagedStruct.DataLength);
+ }
+ else
+ {
+ Debug.Fail("ImageData is null!");
+ }
+
+ //Exif can be null
+ if (unmanagedStruct.ExifLength > 0)
+ {
+ Exif = new byte[unmanagedStruct.ExifLength];
+ Marshal.Copy(unmanagedStruct.Exif, Exif, 0, (int)unmanagedStruct.ExifLength);
+ }
+ }
+
+ /// <summary>
+ /// The pixel format of the captured image.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public CameraPixelFormat Format { get; }
+
+ /// <summary>
+ /// The width of the image.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Width { get; }
+
+ /// <summary>
+ /// The height of the image.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Height { get; }
+
+ /// <summary>
+ /// The buffer containing image data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public byte[] Data { get; }
+
+ /// <summary>
+ /// String containing Exif data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public byte[] Exif { get; }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Camera/Camera/Location.cs b/src/Tizen.Multimedia.Camera/Camera/Location.cs
new file mode 100755
index 0000000..1733352
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Camera/Location.cs
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Location class containing GPS data details.
+ /// </summary>
+ public class Location
+ {
+ /// <summary>
+ /// Public constructor.
+ /// </summary>
+ /// <param name="latitude">Latitude data</param>
+ /// <param name="longitude">Longitude data</param>
+ /// <param name="altitude">Altitude data</param>
+ public Location(double latitude, double longitude, double altitude)
+ {
+ Latitude = latitude;
+ Longitude = longitude;
+ Altitude = altitude;
+ }
+
+ /// <summary>
+ /// The Latitude data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public double Latitude { get; }
+
+ /// <summary>
+ /// The Longitude data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public double Longitude { get; }
+
+ /// <summary>
+ /// The Altitude data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public double Altitude { get; }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Camera/Camera/MediaPacketPreviewEventArgs.cs b/src/Tizen.Multimedia.Camera/Camera/MediaPacketPreviewEventArgs.cs
new file mode 100755
index 0000000..40736c1
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Camera/MediaPacketPreviewEventArgs.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// An extended EventArgs class which contains details about the Media packet preview frame.
+ /// </summary>
+ public class MediaPacketPreviewEventArgs : EventArgs
+ {
+ internal MediaPacketPreviewEventArgs(MediaPacket packet)
+ {
+ Packet = packet;
+ }
+
+ /// <summary>
+ /// Media Packet data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public MediaPacket Packet { get; }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Camera/Camera/PreviewData.cs b/src/Tizen.Multimedia.Camera/Camera/PreviewData.cs
new file mode 100755
index 0000000..cfe628b
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Camera/PreviewData.cs
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using static Interop.Camera;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// The class containing preview image data.
+ /// </summary>
+ public class PreviewData
+ {
+ internal PreviewData(IntPtr ptr)
+ {
+ var unmanagedStruct = Marshal.PtrToStructure<CameraPreviewDataStruct>(ptr);
+
+ Format = unmanagedStruct.Format;
+ Width = unmanagedStruct.Width;
+ Height = unmanagedStruct.Height;
+ TimeStamp = unmanagedStruct.TimeStamp;
+ PlaneType = GetPlaneType(unmanagedStruct);
+ Plane = ConvertPlane(unmanagedStruct);
+ }
+
+ private static IPreviewPlane ConvertPlane(CameraPreviewDataStruct unmanagedStruct)
+ {
+ if (unmanagedStruct.NumOfPlanes == 1)
+ {
+ if (unmanagedStruct.Format == CameraPixelFormat.H264 || unmanagedStruct.Format == CameraPixelFormat.Jpeg)
+ {
+ return new EncodedPlane(unmanagedStruct.Plane.EncodedPlane);
+ }
+ else
+ {
+ return new SinglePlane(unmanagedStruct.Plane.SinglePlane);
+ }
+ }
+ else if (unmanagedStruct.NumOfPlanes == 2)
+ {
+ return new DoublePlane(unmanagedStruct.Plane.DoublePlane);
+ }
+ else if (unmanagedStruct.NumOfPlanes == 3)
+ {
+ return new TriplePlane(unmanagedStruct.Plane.TriplePlane);
+ }
+
+ Debug.Fail("Unknown preview data!");
+ return null;
+ }
+
+ private static PlaneType GetPlaneType(CameraPreviewDataStruct unmanagedStruct)
+ {
+ if (unmanagedStruct.NumOfPlanes == 1)
+ {
+ if (unmanagedStruct.Format == CameraPixelFormat.H264 || unmanagedStruct.Format == CameraPixelFormat.Jpeg)
+ {
+ return PlaneType.EncodedPlane;
+ }
+ else
+ {
+ return PlaneType.SinglePlane;
+ }
+ }
+ else if (unmanagedStruct.NumOfPlanes == 2)
+ {
+ return PlaneType.DoublePlane;
+ }
+
+ return PlaneType.TriplePlane;
+ }
+
+ /// <summary>
+ /// The pixel format of the image.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public CameraPixelFormat Format { get; }
+
+ /// <summary>
+ /// The width of the image.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Width { get; }
+
+ /// <summary>
+ /// The height of the image.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Height { get; }
+
+ /// <summary>
+ /// The timestamp of preview frame.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public uint TimeStamp { get; }
+
+ /// <summary>
+ /// The buffer including preview frame.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public IPreviewPlane Plane { get; }
+
+ /// <summary>
+ /// The type of preview plane. <see cref="Tizen.Multimedia.PlaneType"/>
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public PlaneType PlaneType { get; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Multimedia.Camera/Camera/PreviewEventArgs.cs b/src/Tizen.Multimedia.Camera/Camera/PreviewEventArgs.cs
new file mode 100755
index 0000000..2db3b85
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Camera/PreviewEventArgs.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// An extended EventArgs class which contains details about the preview frame.
+ /// </summary>
+ public class PreviewEventArgs : EventArgs
+ {
+ internal PreviewEventArgs(PreviewData preview)
+ {
+ Preview = preview;
+ }
+
+ /// <summary>
+ /// PreviewData frame.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public PreviewData Preview { get; }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Camera/Camera/SinglePlane.cs b/src/Tizen.Multimedia.Camera/Camera/SinglePlane.cs
new file mode 100755
index 0000000..33e64f2
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Camera/SinglePlane.cs
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System.Runtime.InteropServices;
+using static Interop.Camera;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// The class containing image data which has single plane.
+ /// </summary>
+ public class SinglePlane : IPreviewPlane
+ {
+ internal SinglePlane(SinglePlaneStruct unmanaged)
+ {
+ Data = new byte[unmanaged.DataLength];
+ Marshal.Copy(unmanaged.Data, Data, 0, (int)unmanaged.DataLength);
+ }
+
+ /// <summary>
+ /// The YUV plane data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public byte[] Data { get; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Multimedia.Camera/Camera/TriplePlane.cs b/src/Tizen.Multimedia.Camera/Camera/TriplePlane.cs
new file mode 100755
index 0000000..132911b
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Camera/TriplePlane.cs
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System.Runtime.InteropServices;
+using static Interop.Camera;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// The class containing image data which has three planes.
+ /// </summary>
+ public class TriplePlane : IPreviewPlane
+ {
+ internal TriplePlane(TriplePlaneStruct unmanaged)
+ {
+ Y = new byte[unmanaged.YLength];
+ U = new byte[unmanaged.ULength];
+ V = new byte[unmanaged.VLength];
+ Marshal.Copy(unmanaged.Y, Y, 0, (int)unmanaged.YLength);
+ Marshal.Copy(unmanaged.U, U, 0, (int)unmanaged.ULength);
+ Marshal.Copy(unmanaged.V, V, 0, (int)unmanaged.VLength);
+ }
+
+ /// <summary>
+ /// The Y plane data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public byte[] Y { get; }
+
+ /// <summary>
+ /// The U plane data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public byte[] U { get; }
+
+ /// <summary>
+ /// The V plane data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public byte[] V { get; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Multimedia.Camera/Interop/Interop.Camera.cs b/src/Tizen.Multimedia.Camera/Interop/Interop.Camera.cs
new file mode 100755
index 0000000..0f4f289
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Interop/Interop.Camera.cs
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Multimedia;
+
+internal static partial class Interop
+{
+ internal static partial class Camera
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void FaceDetectedCallback(IntPtr faces, int count, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void StateChangedCallback(CameraState previous, CameraState current, bool byPolicy, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void InterruptedCallback(CameraPolicy policy, CameraState previous, CameraState current, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void FocusStateChangedCallback(CameraFocusState state, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ErrorCallback(CameraErrorCode error, CameraState current, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void CapturingCallback(IntPtr image, IntPtr postview, IntPtr thumbnail, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void CaptureCompletedCallback(IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void PreviewCallback(IntPtr frame, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MediaPacketPreviewCallback(IntPtr mediaPacketHandle, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void HdrCaptureProgressCallback(int percent, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void DeviceStateChangedCallback(CameraDevice device, CameraDeviceState state, IntPtr userData);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_create")]
+ internal static extern CameraError Create(CameraDevice device, out IntPtr handle);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_change_device")]
+ internal static extern CameraError ChangeDevice(IntPtr handle, CameraDevice device);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_destroy")]
+ internal static extern CameraError Destroy(IntPtr handle);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_get_device_count")]
+ internal static extern CameraError GetDeviceCount(IntPtr handle, out int count);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_start_preview")]
+ internal static extern CameraError StartPreview(IntPtr handle);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_stop_preview")]
+ internal static extern CameraError StopPreview(IntPtr handle);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_get_device_state")]
+ internal static extern CameraError GetDeviceState(CameraDevice device, out CameraDeviceState state);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_start_capture")]
+ internal static extern CameraError StartCapture(IntPtr handle, CapturingCallback captureCallback,
+ CaptureCompletedCallback completedCallback, IntPtr userData);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_start_continuous_capture")]
+ internal static extern CameraError StartContinuousCapture(IntPtr handle, int count, int interval,
+ CapturingCallback captureCallback, CaptureCompletedCallback completedCallback, IntPtr userData);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_stop_continuous_capture")]
+ internal static extern CameraError StopContinuousCapture(IntPtr handle);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_get_state")]
+ internal static extern CameraError GetState(IntPtr handle, out CameraState state);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_start_focusing")]
+ internal static extern CameraError StartFocusing(IntPtr handle, bool continuous);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_cancel_focusing")]
+ internal static extern CameraError CancelFocusing(IntPtr handle);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_set_preview_resolution")]
+ internal static extern CameraError SetPreviewResolution(IntPtr handle, int width, int height);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_get_preview_resolution")]
+ internal static extern CameraError GetPreviewResolution(IntPtr handle, out int width, out int height);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_get_recommended_preview_resolution")]
+ internal static extern CameraError GetRecommendedPreviewResolution(IntPtr handle, out int width, out int height);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_start_face_detection")]
+ internal static extern CameraError StartFaceDetection(IntPtr handle, FaceDetectedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_stop_face_detection")]
+ internal static extern CameraError StopFaceDetection(IntPtr handle);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_set_display_reuse_hint")]
+ internal static extern CameraError SetDisplayReuseHint(IntPtr handle, bool hint);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_get_display_reuse_hint")]
+ internal static extern CameraError GetDisplayReuseHint(IntPtr handle, out bool hint);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_set_capture_resolution")]
+ internal static extern CameraError SetCaptureResolution(IntPtr handle, int width, int height);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_get_capture_resolution")]
+ internal static extern CameraError GetCaptureResolution(IntPtr handle, out int width, out int height);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_set_capture_format")]
+ internal static extern CameraError SetCaptureFormat(IntPtr handle, CameraPixelFormat format);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_get_capture_format")]
+ internal static extern CameraError GetCaptureFormat(IntPtr handle, out CameraPixelFormat format);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_set_preview_format")]
+ internal static extern CameraError SetPreviewPixelFormat(IntPtr handle, CameraPixelFormat format);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_get_preview_format")]
+ internal static extern CameraError GetPreviewPixelFormat(IntPtr handle, out CameraPixelFormat format);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_get_facing_direction")]
+ internal static extern CameraError GetFacingDirection(IntPtr handle, out CameraFacingDirection direction);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_get_flash_state")]
+ internal static extern CameraError GetFlashState(CameraDevice device, out CameraFlashState state);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_set_preview_cb")]
+ internal static extern CameraError SetPreviewCallback(IntPtr handle, PreviewCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_unset_preview_cb")]
+ internal static extern CameraError UnsetPreviewCallback(IntPtr handle);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_set_media_packet_preview_cb")]
+ internal static extern CameraError SetMediaPacketPreviewCallback(IntPtr handle, MediaPacketPreviewCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_unset_media_packet_preview_cb")]
+ internal static extern CameraError UnsetMediaPacketPreviewCallback(IntPtr handle);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_set_state_changed_cb")]
+ internal static extern CameraError SetStateChangedCallback(IntPtr handle, StateChangedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_add_device_state_changed_cb")]
+ internal static extern CameraError SetDeviceStateChangedCallback(DeviceStateChangedCallback callback, IntPtr userData, out int callbackId);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_unset_state_changed_cb")]
+ internal static extern CameraError UnsetStateChangedCallback(IntPtr handle);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_remove_device_state_changed_cb")]
+ internal static extern CameraError UnsetDeviceStateChangedCallback(int cbId);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_set_interrupted_cb")]
+ internal static extern CameraError SetInterruptedCallback(IntPtr handle, InterruptedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_unset_interrupted_cb")]
+ internal static extern CameraError UnsetInterruptedCallback(IntPtr handle);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_set_focus_changed_cb")]
+ internal static extern CameraError SetFocusStateChangedCallback(IntPtr handle, FocusStateChangedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_unset_focus_changed_cb")]
+ internal static extern CameraError UnsetFocusChangedCallback(IntPtr handle);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_set_error_cb")]
+ internal static extern CameraError SetErrorCallback(IntPtr handle, ErrorCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_unset_error_cb")]
+ internal static extern CameraError UnsetErrorCallback(IntPtr handle);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_set_hdr_capture_progress_cb")]
+ internal static extern CameraError SetHdrCaptureProgressCallback(IntPtr handle, HdrCaptureProgressCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_unset_hdr_capture_progress_cb")]
+ internal static extern CameraError UnsetHdrCaptureProgressCallback(IntPtr handle);
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct ImageDataStruct
+ {
+ internal IntPtr Data;
+ internal uint DataLength;
+ internal int Width;
+ internal int Height;
+ internal CameraPixelFormat Format;
+ internal IntPtr Exif;
+ internal uint ExifLength;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct DetectedFaceStruct
+ {
+ internal int Id;
+ internal int Score;
+ internal int X;
+ internal int Y;
+ internal int Width;
+ internal int Height;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct SinglePlaneStruct
+ {
+ internal IntPtr Data;
+ internal uint DataLength;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct DoublePlaneStruct
+ {
+ internal IntPtr Y;
+ internal IntPtr UV;
+ internal uint YLength;
+ internal uint UVLength;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct TriplePlaneStruct
+ {
+ internal IntPtr Y;
+ internal IntPtr U;
+ internal IntPtr V;
+ internal uint YLength;
+ internal uint ULength;
+ internal uint VLength;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct EncodedPlaneStruct
+ {
+ internal IntPtr Data;
+ internal uint DataLength;
+ }
+
+ [StructLayout(LayoutKind.Explicit)]
+ internal struct PreviewPlaneStruct
+ {
+ [FieldOffsetAttribute(0)]
+ internal SinglePlaneStruct SinglePlane;
+ [FieldOffsetAttribute(0)]
+ internal DoublePlaneStruct DoublePlane;
+ [FieldOffsetAttribute(0)]
+ internal TriplePlaneStruct TriplePlane;
+ [FieldOffsetAttribute(0)]
+ internal EncodedPlaneStruct EncodedPlane;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct CameraPreviewDataStruct
+ {
+ internal CameraPixelFormat Format;
+ internal int Width;
+ internal int Height;
+ internal int NumOfPlanes;
+ internal uint TimeStamp;
+ internal PreviewPlaneStruct Plane;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Multimedia.Camera/Interop/Interop.CameraDisplay.cs b/src/Tizen.Multimedia.Camera/Interop/Interop.CameraDisplay.cs
new file mode 100644
index 0000000..6f88d4a
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Interop/Interop.CameraDisplay.cs
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Multimedia;
+
+internal static partial class Interop
+{
+ internal static partial class CameraDisplay
+ {
+ [DllImport(Libraries.Camera, EntryPoint = "camera_get_display_mode")]
+ internal static extern CameraError GetMode(IntPtr handle, out CameraDisplayMode mode);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_set_display_mode")]
+ internal static extern CameraError SetMode(IntPtr handle, CameraDisplayMode mode);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_is_display_visible")]
+ internal static extern CameraError GetVisible(IntPtr handle, out bool visible);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_set_display_visible")]
+ internal static extern CameraError SetVisible(IntPtr handle, bool visible);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_get_display_rotation")]
+ internal static extern CameraError GetRotation(IntPtr handle, out CameraRotation rotation);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_set_display_rotation")]
+ internal static extern CameraError SetRotation(IntPtr handle, CameraRotation rotation);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_get_display_flip")]
+ internal static extern CameraError GetFlip(IntPtr handle, out CameraFlip flip);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_set_display_flip")]
+ internal static extern CameraError SetFlip(IntPtr handle, CameraFlip flip);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_display_roi_area")]
+ internal static extern CameraError GetRoiArea(IntPtr handle, out int x, out int y, out int width, out int height);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_set_display_roi_area")]
+ internal static extern CameraError SetRoiArea(IntPtr handle, int x, int y, int width, int height);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_set_display")]
+ internal static extern CameraError SetTarget(IntPtr handle, DisplayType displayType, IntPtr displayHandle);
+ }
+}
diff --git a/src/Tizen.Multimedia.Camera/Interop/Interop.CameraFeatures.cs b/src/Tizen.Multimedia.Camera/Interop/Interop.CameraFeatures.cs
new file mode 100644
index 0000000..f2e34de
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Interop/Interop.CameraFeatures.cs
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Multimedia;
+
+internal static partial class Interop
+{
+ internal static partial class CameraFeatures
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool PreviewResolutionCallback(int Width, int Height, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool CaptureResolutionCallback(int Width, int Height, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool CaptureFormatCallback(CameraPixelFormat format, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool PreviewFormatCallback(CameraPixelFormat format, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool FpsCallback(CameraFps fps, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool FpsByResolutionCallback(CameraFps fps, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool AfModeCallback(CameraAutoFocusMode mode, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool ExposureModeCallback(CameraExposureMode mode, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool IsoCallback(CameraIsoLevel iso, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool TheaterModeCallback(CameraTheaterMode mode, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool WhitebalanceCallback(CameraWhiteBalance whitebalance, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool EffectCallback(CameraEffectMode effect, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool SceneModeCallback(CameraSceneMode mode, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool FlashModeCallback(CameraFlashMode mode, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool StreamRotationCallback(CameraRotation rotation, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool StreamFlipCallback(CameraFlip flip, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool PtzTypeCallback(CameraPtzType type, IntPtr userData);
+
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_is_supported_continuous_capture")]
+ [return: MarshalAs(UnmanagedType.I1)]
+ internal static extern bool IsContinuousCaptureSupported(IntPtr handle);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_is_supported_face_detection")]
+ [return: MarshalAs(UnmanagedType.I1)]
+ internal static extern bool IsFaceDetectionSupported(IntPtr handle);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_is_supported_zero_shutter_lag")]
+ [return: MarshalAs(UnmanagedType.I1)]
+ internal static extern bool IsZeroShutterLagSupported(IntPtr handle);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_is_supported_media_packet_preview_cb")]
+ [return: MarshalAs(UnmanagedType.I1)]
+ internal static extern bool IsMediaPacketPreviewCallbackSupported(IntPtr handle);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_is_supported_hdr_capture")]
+ [return: MarshalAs(UnmanagedType.I1)]
+ internal static extern bool IsHdrCaptureSupported(IntPtr handle);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_is_supported_anti_shake")]
+ [return: MarshalAs(UnmanagedType.I1)]
+ internal static extern bool IsAntiShakeSupported(IntPtr handle);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_is_supported_video_stabilization")]
+ [return: MarshalAs(UnmanagedType.I1)]
+ internal static extern bool IsVideoStabilizationSupported(IntPtr handle);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_is_supported_auto_contrast")]
+ [return: MarshalAs(UnmanagedType.I1)]
+ internal static extern bool IsAutoContrastSupported(IntPtr handle);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_foreach_supported_preview_resolution")]
+ internal static extern CameraError SupportedPreviewResolutions(IntPtr handle, PreviewResolutionCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_foreach_supported_capture_resolution")]
+ internal static extern CameraError SupportedCaptureResolutions(IntPtr handle, CaptureResolutionCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_foreach_supported_capture_format")]
+ internal static extern CameraError SupportedCapturePixelFormats(IntPtr handle, CaptureFormatCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_foreach_supported_preview_format")]
+ internal static extern CameraError SupportedPreviewPixelFormats(IntPtr handle, PreviewFormatCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_foreach_supported_fps")]
+ internal static extern CameraError SupportedPreviewFps(IntPtr handle, FpsCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_foreach_supported_fps_by_resolution")]
+ internal static extern CameraError SupportedPreviewFpsByResolution(IntPtr handle, int width, int height, FpsByResolutionCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_foreach_supported_af_mode")]
+ internal static extern CameraError SupportedAfModes(IntPtr handle, AfModeCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_foreach_supported_exposure_mode")]
+ internal static extern CameraError SupportedExposureModes(IntPtr handle, ExposureModeCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_foreach_supported_iso")]
+ internal static extern CameraError SupportedIso(IntPtr handle, IsoCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_foreach_supported_theater_mode")]
+ internal static extern CameraError SupportedTheaterModes(IntPtr handle, TheaterModeCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_foreach_supported_whitebalance")]
+ internal static extern CameraError SupportedWhitebalance(IntPtr handle, WhitebalanceCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_foreach_supported_effect")]
+ internal static extern CameraError SupportedEffects(IntPtr handle, EffectCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_foreach_supported_scene_mode")]
+ internal static extern CameraError SupportedSceneModes(IntPtr handle, SceneModeCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_foreach_supported_flash_mode")]
+ internal static extern CameraError SupportedFlashModes(IntPtr handle, FlashModeCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_foreach_supported_stream_rotation")]
+ internal static extern CameraError SupportedStreamRotations(IntPtr handle, StreamRotationCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_foreach_supported_stream_flip")]
+ internal static extern CameraError SupportedStreamFlips(IntPtr handle, StreamFlipCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_foreach_supported_ptz_type")]
+ internal static extern CameraError SupportedPtzTypes(IntPtr handle, PtzTypeCallback callback, IntPtr userData);
+ }
+}
diff --git a/src/Tizen.Multimedia.Camera/Interop/Interop.CameraSettings.cs b/src/Tizen.Multimedia.Camera/Interop/Interop.CameraSettings.cs
new file mode 100755
index 0000000..1ff1a83
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Interop/Interop.CameraSettings.cs
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Multimedia;
+
+internal static partial class Interop
+{
+ internal static partial class CameraSettings
+ {
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_set_preview_fps")]
+ internal static extern CameraError SetPreviewFps(IntPtr handle, CameraFps fps);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_preview_fps")]
+ internal static extern CameraError GetPreviewFps(IntPtr handle, out CameraFps fps);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_set_image_quality")]
+ internal static extern CameraError SetImageQuality(IntPtr handle, int quality);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_image_quality")]
+ internal static extern CameraError GetImageQuality(IntPtr handle, out int quality);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_set_encoded_preview_bitrate")]
+ internal static extern CameraError SetBitrate(IntPtr handle, int bitrate);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_encoded_preview_bitrate")]
+ internal static extern CameraError GetBitrate(IntPtr handle, out int bitrate);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_set_encoded_preview_gop_interval")]
+ internal static extern CameraError SetGopInterval(IntPtr handle, int interval);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_encoded_preview_gop_interval")]
+ internal static extern CameraError GetGopInterval(IntPtr handle, out int interval);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_set_zoom")]
+ internal static extern CameraError SetZoom(IntPtr handle, int zoom);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_zoom")]
+ internal static extern CameraError GetZoom(IntPtr handle, out int zoom);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_zoom_range")]
+ internal static extern CameraError GetZoomRange(IntPtr handle, out int min, out int max);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_set_af_mode")]
+ internal static extern CameraError SetAutoFocusMode(IntPtr handle, CameraAutoFocusMode mode);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_af_mode")]
+ internal static extern CameraError GetAutoFocusMode(IntPtr handle, out CameraAutoFocusMode mode);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_set_af_area")]
+ internal static extern CameraError SetAutoFocusArea(IntPtr handle, int x, int y);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_clear_af_area")]
+ internal static extern CameraError ClearAutoFocusArea(IntPtr handle);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_set_exposure_mode")]
+ internal static extern CameraError SetExposureMode(IntPtr handle, CameraExposureMode mode);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_exposure_mode")]
+ internal static extern CameraError GetExposureMode(IntPtr handle, out CameraExposureMode mode);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_set_exposure")]
+ internal static extern CameraError SetExposure(IntPtr handle, int value);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_exposure")]
+ internal static extern CameraError GetExposure(IntPtr handle, out int value);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_exposure_range")]
+ internal static extern CameraError GetExposureRange(IntPtr handle, out int min, out int max);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_set_iso")]
+ internal static extern CameraError SetIso(IntPtr handle, CameraIsoLevel iso);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_iso")]
+ internal static extern CameraError GetIso(IntPtr handle, out CameraIsoLevel iso);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_set_theater_mode")]
+ internal static extern CameraError SetTheaterMode(IntPtr handle, CameraTheaterMode mode);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_theater_mode")]
+ internal static extern CameraError GetTheaterMode(IntPtr handle, out CameraTheaterMode mode);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_set_brightness")]
+ internal static extern CameraError SetBrightness(IntPtr handle, int level);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_brightness")]
+ internal static extern CameraError GetBrightness(IntPtr handle, out int level);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_brightness_range")]
+ internal static extern CameraError GetBrightnessRange(IntPtr handle, out int min, out int max);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_set_contrast")]
+ internal static extern CameraError SetContrast(IntPtr handle, int level);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_contrast")]
+ internal static extern CameraError GetContrast(IntPtr handle, out int level);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_contrast_range")]
+ internal static extern CameraError GetContrastRange(IntPtr handle, out int min, out int max);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_set_whitebalance")]
+ internal static extern CameraError SetWhitebalance(IntPtr handle, CameraWhiteBalance level);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_whitebalance")]
+ internal static extern CameraError GetWhiteBalance(IntPtr handle, out CameraWhiteBalance level);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_set_effect")]
+ internal static extern CameraError SetEffect(IntPtr handle, CameraEffectMode mode);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_effect")]
+ internal static extern CameraError GetEffect(IntPtr handle, out CameraEffectMode mode);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_set_scene_mode")]
+ internal static extern CameraError SetSceneMode(IntPtr handle, CameraSceneMode mode);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_scene_mode")]
+ internal static extern CameraError GetSceneMode(IntPtr handle, out CameraSceneMode mode);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_enable_tag")]
+ internal static extern CameraError EnableTag(IntPtr handle, bool enable);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_is_enabled_tag")]
+ internal static extern CameraError IsEnabledTag(IntPtr handle, out bool enabled);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_set_tag_image_description")]
+ internal static extern CameraError SetImageDescription(IntPtr handle, string description);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_tag_image_description")]
+ internal static extern CameraError GetImageDescription(IntPtr handle, out IntPtr description);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_set_tag_software")]
+ internal static extern CameraError SetTagSoftware(IntPtr handle, string software);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_tag_software")]
+ internal static extern CameraError GetTagSoftware(IntPtr handle, out IntPtr software);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_set_tag_orientation")]
+ internal static extern CameraError SetTagOrientation(IntPtr handle, CameraTagOrientation orientation);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_tag_orientation")]
+ internal static extern CameraError GetTagOrientation(IntPtr handle, out CameraTagOrientation orientation);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_set_geotag")]
+ internal static extern CameraError SetGeotag(IntPtr handle, double latitude, double longtitude, double altitude);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_geotag")]
+ internal static extern CameraError GetGeotag(IntPtr handle, out double latitude, out double longtitude, out double altitude);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_remove_geotag")]
+ internal static extern CameraError RemoveGeotag(IntPtr handle);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_set_flash_mode")]
+ internal static extern CameraError SetFlashMode(IntPtr handle, CameraFlashMode mode);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_flash_mode")]
+ internal static extern CameraError GetFlashMode(IntPtr handle, out CameraFlashMode mode);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_lens_orientation")]
+ internal static extern CameraError GetLensOrientation(IntPtr handle, out int angle);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_set_stream_rotation")]
+ internal static extern CameraError SetStreamRotation(IntPtr handle, CameraRotation mode);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_stream_rotation")]
+ internal static extern CameraError GetStreamRotation(IntPtr handle, out CameraRotation mode);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_set_stream_flip")]
+ internal static extern CameraError SetFlip(IntPtr handle, CameraFlip flip);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_stream_flip")]
+ internal static extern CameraError GetFlip(IntPtr handle, out CameraFlip flip);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_set_hdr_mode")]
+ internal static extern CameraError SetHdrMode(IntPtr handle, CameraHdrMode hdr);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_hdr_mode")]
+ internal static extern CameraError GetHdrMode(IntPtr handle, out CameraHdrMode hdr);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_enable_anti_shake")]
+ internal static extern CameraError EnableAntiShake(IntPtr handle, bool enable);
+
+ [DllImport(Libraries.Camera, EntryPoint = " camera_attr_is_enabled_anti_shake")]
+ internal static extern CameraError IsEnabledAntiShake(IntPtr handle, out bool enabled);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_enable_video_stabilization")]
+ internal static extern CameraError EnableVideoStabilization(IntPtr handle, bool enable);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_is_enabled_video_stabilization")]
+ internal static extern CameraError IsEnabledVideoStabilization(IntPtr handle, out bool enabled);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_enable_auto_contrast")]
+ internal static extern CameraError EnableAutoContrast(IntPtr handle, bool enable);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_is_enabled_auto_contrast")]
+ internal static extern CameraError IsEnabledAutoContrast(IntPtr handle, out bool enabled);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_disable_shutter_sound")]
+ internal static extern CameraError DisableShutterSound(IntPtr handle, bool disable);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_set_pan")]
+ internal static extern CameraError SetPan(IntPtr handle, CameraPtzMoveType type, int step);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_pan")]
+ internal static extern CameraError GetPan(IntPtr handle, out int step);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_pan_range")]
+ internal static extern CameraError GetPanRange(IntPtr handle, out int min, out int max);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_set_tilt")]
+ internal static extern CameraError SetTilt(IntPtr handle, CameraPtzMoveType type, int step);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_tilt")]
+ internal static extern CameraError GetTilt(IntPtr handle, out int step);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_get_tilt_range")]
+ internal static extern CameraError GetTiltRange(IntPtr handle, out int min, out int max);
+
+ [DllImport(Libraries.Camera, EntryPoint = "camera_attr_set_ptz_type")]
+ internal static extern CameraError SetPtzType(IntPtr handle, CameraPtzType type);
+ }
+}
diff --git a/src/Tizen.Multimedia.Camera/Interop/Interop.Libraries.cs b/src/Tizen.Multimedia.Camera/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..624807e
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Interop/Interop.Libraries.cs
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string Camera = "libcapi-media-camera.so.0";
+ }
+}
diff --git a/src/Tizen.Multimedia.Camera/Tizen.Multimedia.Camera.csproj b/src/Tizen.Multimedia.Camera/Tizen.Multimedia.Camera.csproj
new file mode 100644
index 0000000..0e5378c
--- /dev/null
+++ b/src/Tizen.Multimedia.Camera/Tizen.Multimedia.Camera.csproj
@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen.Multimedia\Tizen.Multimedia.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Multimedia.MediaCodec/Interop/Interop.Libraries.cs b/src/Tizen.Multimedia.MediaCodec/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..ba8ac5b
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaCodec/Interop/Interop.Libraries.cs
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia.MediaCodec
+{
+ internal static partial class Interop
+ {
+ internal static partial class Libraries
+ {
+ public const string MediaCodec = "libcapi-media-codec.so.0";
+ public const string MediaTool = "libcapi-media-tool.so.0";
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaCodec/Interop/Interop.MediaCodec.cs b/src/Tizen.Multimedia.MediaCodec/Interop/Interop.MediaCodec.cs
new file mode 100644
index 0000000..5d484cc
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaCodec/Interop/Interop.MediaCodec.cs
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Multimedia.MediaCodec
+{
+ internal static partial class Interop
+ {
+ internal static class MediaCodec
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void InputBufferUsedCallback(IntPtr mediaPacket, IntPtr arg);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void OutputBufferAvailableCallback(IntPtr mediaPacket, IntPtr arg);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ErrorCallback(int errorCode, IntPtr arg);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void EosCallback(IntPtr arg);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void BufferStatusCallback(int statusCode, IntPtr arg);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool SupportedCodecCallback(int codecType, IntPtr arg);
+
+ [DllImport(Libraries.MediaCodec, EntryPoint = "mediacodec_create")]
+ internal static extern int Create(out IntPtr handle);
+
+ [DllImport(Libraries.MediaCodec, EntryPoint = "mediacodec_destroy")]
+ internal static extern int Destroy(IntPtr handle);
+
+ [DllImport(Libraries.MediaCodec, EntryPoint = "mediacodec_set_codec")]
+ internal static extern int Configure(IntPtr handle, int codecType, int flags);
+
+ [DllImport(Libraries.MediaCodec, EntryPoint = "mediacodec_set_vdec_info")]
+ internal static extern int SetVideoDecoderInfo(IntPtr handle, int width, int height);
+
+ [DllImport(Libraries.MediaCodec, EntryPoint = "mediacodec_set_venc_info")]
+ internal static extern int SetVideoEncoderInfo(IntPtr handle, int width, int height,
+ int fps, int targetBits);
+
+ [DllImport(Libraries.MediaCodec, EntryPoint = "mediacodec_set_adec_info")]
+ internal static extern int SetAudioDecoderInfo(IntPtr handle, int sampleRate, int channel,
+ int bit);
+
+ [DllImport(Libraries.MediaCodec, EntryPoint = "mediacodec_set_aenc_info")]
+ internal static extern int SetAudioEncoderInfo(IntPtr handle, int sampleRate, int channel,
+ int bit, int bitRate);
+
+ [DllImport(Libraries.MediaCodec, EntryPoint = "mediacodec_prepare")]
+ internal static extern int Prepare(IntPtr handle);
+
+ [DllImport(Libraries.MediaCodec, EntryPoint = "mediacodec_unprepare")]
+ internal static extern int Unprepare(IntPtr handle);
+
+ [DllImport(Libraries.MediaCodec, EntryPoint = "mediacodec_process_input")]
+ internal static extern int Process(IntPtr handle, IntPtr mediaPacket, ulong timeoutInUs);
+
+ [DllImport(Libraries.MediaCodec, EntryPoint = "mediacodec_get_output")]
+ internal static extern int GetOutput(IntPtr handle, out IntPtr packet, ulong timeoutInUs);
+
+ [DllImport(Libraries.MediaCodec, EntryPoint = "mediacodec_flush_buffers")]
+ internal static extern int FlushBuffers(IntPtr handle);
+
+ [DllImport(Libraries.MediaCodec, EntryPoint = "mediacodec_set_input_buffer_used_cb")]
+ internal static extern int SetInputBufferUsedCb(IntPtr handle,
+ InputBufferUsedCallback cb, IntPtr arg);
+
+ [DllImport(Libraries.MediaCodec, EntryPoint = "mediacodec_unset_input_buffer_used_cb")]
+ internal static extern int UnsetInputBufferUsedCb(IntPtr handle);
+
+ [DllImport(Libraries.MediaCodec, EntryPoint = "mediacodec_set_output_buffer_available_cb")]
+ internal static extern int SetOutputBufferAvailableCb(IntPtr handle,
+ OutputBufferAvailableCallback cb, IntPtr arg);
+
+ [DllImport(Libraries.MediaCodec, EntryPoint = "mediacodec_unset_output_buffer_available_cb")]
+ internal static extern int UnsetOutputBufferAvailableCb(IntPtr handle);
+
+ [DllImport(Libraries.MediaCodec, EntryPoint = "mediacodec_set_error_cb")]
+ internal static extern int SetErrorCb(IntPtr handle, ErrorCallback cb, IntPtr arg);
+
+ [DllImport(Libraries.MediaCodec, EntryPoint = "mediacodec_unset_error_cb")]
+ internal static extern int UnsetErrorCb(IntPtr handle);
+
+ [DllImport(Libraries.MediaCodec, EntryPoint = "mediacodec_set_eos_cb")]
+ internal static extern int SetEosCb(IntPtr handle, EosCallback cb, IntPtr arg);
+
+ [DllImport(Libraries.MediaCodec, EntryPoint = "mediacodec_unset_eos_cb")]
+ internal static extern int UnsetEosCb(IntPtr handle);
+
+ [DllImport(Libraries.MediaCodec, EntryPoint = "mediacodec_set_buffer_status_cb")]
+ internal static extern int SetBufferStatusCb(IntPtr handle, BufferStatusCallback cb,
+ IntPtr arg);
+
+ [DllImport(Libraries.MediaCodec, EntryPoint = "mediacodec_unset_buffer_status_cb")]
+ internal static extern int UnsetBufferStatusCb(IntPtr handle);
+
+ [DllImport(Libraries.MediaCodec, EntryPoint = "mediacodec_get_supported_type")]
+ internal static extern int GetSupportedType(IntPtr handle, int codecType, bool isEncoder,
+ out int value);
+
+ [DllImport(Libraries.MediaCodec, EntryPoint = "mediacodec_foreach_supported_codec_static")]
+ internal static extern int ForeachSupportedCodec(SupportedCodecCallback cb, IntPtr arg);
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaCodec/Interop/Interop.MediaTool.cs b/src/Tizen.Multimedia.MediaCodec/Interop/Interop.MediaTool.cs
new file mode 100644
index 0000000..318153c
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaCodec/Interop/Interop.MediaTool.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Multimedia.MediaCodec
+{
+ internal static partial class Interop
+ {
+ internal static class MediaPacket
+ {
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_packet_destroy")]
+ internal static extern int Destroy(IntPtr handle);
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaCodec/MediaCodec/BufferStatusChangedEventArgs.cs b/src/Tizen.Multimedia.MediaCodec/MediaCodec/BufferStatusChangedEventArgs.cs
new file mode 100644
index 0000000..6beac7c
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaCodec/MediaCodec/BufferStatusChangedEventArgs.cs
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia.MediaCodec
+{
+ /// <summary>
+ /// Provides data for the <see cref="MediaCodec.BufferStatusChanged"/> event.
+ /// </summary>
+ public class BufferStatusChangedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Initializes a new instance of the BufferStatusChangedEventArgs class.
+ /// </summary>
+ /// <param name="status">The value representing new status of the codec.</param>
+ public BufferStatusChangedEventArgs(MediaCodecStatus status)
+ {
+ Status = status;
+ }
+
+ /// <summary>
+ /// Gets the value indicating new status of the codec.
+ /// </summary>
+ public MediaCodecStatus Status { get; }
+
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaCodec/MediaCodec/InputProcessedEventArgs.cs b/src/Tizen.Multimedia.MediaCodec/MediaCodec/InputProcessedEventArgs.cs
new file mode 100644
index 0000000..1883d95
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaCodec/MediaCodec/InputProcessedEventArgs.cs
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Diagnostics;
+
+namespace Tizen.Multimedia.MediaCodec
+{
+ /// <summary>
+ /// Provides data for the <see cref="MediaCodec.InputProcessed"/> event.
+ /// </summary>
+ public class InputProcessedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Initializes a new instance of the InputProcessedEventArgs class.
+ /// </summary>
+ /// <param name="packet">The packet that the codec has processed.</param>
+ internal InputProcessedEventArgs(MediaPacket packet)
+ {
+ Debug.Assert(packet != null);
+
+ Packet = packet;
+ }
+
+ /// <summary>
+ /// Gets the packet that the codec has processed.
+ /// </summary>
+ public MediaPacket Packet { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaCodec/MediaCodec/MediaCodec.cs b/src/Tizen.Multimedia.MediaCodec/MediaCodec/MediaCodec.cs
new file mode 100644
index 0000000..0d37d31
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaCodec/MediaCodec/MediaCodec.cs
@@ -0,0 +1,691 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace Tizen.Multimedia.MediaCodec
+{
+ /// <summary>
+ /// Provides the means to encode and decode video and audio data.
+ /// </summary>
+ public class MediaCodec : IDisposable
+ {
+ private const int CodecTypeMask = 0xFFFF;
+ private const int CodecKindMask = 0x3000;
+// private const int CodecKindAudio = 0x1000; // Not used
+ private const int CodecKindVideo = 0x2000;
+
+ private IntPtr _handle;
+
+ /// <summary>
+ /// Initialize a new instance of the MediaCodec class.
+ /// </summary>
+ public MediaCodec()
+ {
+ int ret = Interop.MediaCodec.Create(out _handle);
+
+ if (ret == (int)MediaCodecErrorCode.InvalidOperation)
+ {
+ throw new InvalidOperationException("Not able to initialize a new media codec.");
+ }
+
+ MultimediaDebug.AssertNoError(ret);
+
+ RegisterInputProcessed();
+ RegisterErrorOccurred();
+ }
+
+ #region IDisposable-support
+ private bool _isDisposed = false;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_isDisposed)
+ {
+ if (_handle != IntPtr.Zero)
+ {
+ Interop.MediaCodec.Destroy(_handle);
+ _handle = IntPtr.Zero;
+ }
+
+ _isDisposed = true;
+ }
+ }
+
+ ~MediaCodec()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+
+ /// <summary>
+ /// Validates if the object already has been disposed of.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">The current object has been disposed of.</exception>
+ private void ValidateNotDisposed()
+ {
+ if (_isDisposed)
+ {
+ throw new ObjectDisposedException(nameof(MediaCodec));
+ }
+ }
+
+ private static IEnumerable<MediaFormatVideoMimeType> _supportedVideoCodecs;
+
+ /// <summary>
+ /// Gets the audio codec list that the current device supports.
+ /// </summary>
+ public static IEnumerable<MediaFormatVideoMimeType> SupportedVideoCodecs
+ {
+ get
+ {
+ if (_supportedVideoCodecs == null)
+ {
+ LoadSupportedCodec();
+ }
+
+ return _supportedVideoCodecs;
+ }
+ }
+
+ private static IEnumerable<MediaFormatAudioMimeType> _supportedAudioCodecs;
+
+
+ /// <summary>
+ /// Gets the audio codec list that the current device supports.
+ /// </summary>
+ public static IEnumerable<MediaFormatAudioMimeType> SupportedAudioCodecs
+ {
+ get
+ {
+ if (_supportedAudioCodecs == null)
+ {
+ LoadSupportedCodec();
+ }
+
+ return _supportedAudioCodecs;
+ }
+ }
+
+ private static bool TryGetMimeTypeFromCodecType<T>(int codecType, ref T result)
+ {
+ if (codecType == -1)
+ {
+ return false;
+ }
+
+ foreach (T value in Enum.GetValues(typeof(T)))
+ {
+ if ((Convert.ToInt32(value) & CodecTypeMask) == codecType)
+ {
+ result = value;
+ return true;
+ }
+ }
+
+ Debug.Fail($"Unknown codec : { codecType }.");
+ return false;
+ }
+
+ private static void LoadSupportedCodec()
+ {
+ var videoCodecList = new List<MediaFormatVideoMimeType>();
+ var audioCodecList = new List<MediaFormatAudioMimeType>();
+
+ Interop.MediaCodec.SupportedCodecCallback cb = (codecType, _) =>
+ {
+ if ((codecType & CodecKindMask) == CodecKindVideo)
+ {
+ MediaFormatVideoMimeType mimeType = 0;
+ if (TryGetMimeTypeFromCodecType(codecType, ref mimeType))
+ {
+ videoCodecList.Add(mimeType);
+ }
+ }
+ else
+ {
+ MediaFormatAudioMimeType mimeType = 0;
+ if (TryGetMimeTypeFromCodecType(codecType, ref mimeType))
+ {
+ audioCodecList.Add(mimeType);
+ }
+ }
+
+ return true;
+ };
+
+ int ret = Interop.MediaCodec.ForeachSupportedCodec(cb, IntPtr.Zero);
+
+ MultimediaDebug.AssertNoError(ret);
+
+ _supportedVideoCodecs = videoCodecList.AsReadOnly();
+ _supportedAudioCodecs = audioCodecList.AsReadOnly();
+ }
+
+ /// <summary>
+ /// Prepares the MediaCodec for encoding or decoding.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">
+ /// The codec is not configured, yet.\n
+ /// -or-\n
+ /// Internal error.
+ /// </exception>
+ public void Prepare()
+ {
+ ValidateNotDisposed();
+
+ int ret = Interop.MediaCodec.Prepare(_handle);
+
+ if (ret == (int)MediaCodecErrorCode.NotInitialized)
+ {
+ throw new InvalidOperationException("The codec is not configured.");
+ }
+ if (ret != (int)MediaCodecErrorCode.None)
+ {
+ throw new InvalidOperationException("Operation failed.");
+ }
+
+ MultimediaDebug.AssertNoError(ret);
+ }
+
+ /// <summary>
+ /// Unprepares the MediaCodec.
+ /// </summary>
+ public void Unprepare()
+ {
+ ValidateNotDisposed();
+
+ int ret = Interop.MediaCodec.Unprepare(_handle);
+
+ MultimediaDebug.AssertNoError(ret);
+ }
+
+ /// <summary>
+ /// Configures the MediaCodec.
+ /// </summary>
+ /// <param name="format">The <see cref="MediaFormat"/> for properties of media data to decode or encode.</param>
+ /// <param name="encoder">The value indicating whether the codec works as a encoder or a decoder.</param>
+ /// <param name="codecType">The value indicating whether the codec uses hardware acceleration.</param>
+ /// <exception cref="ArgumentNullException">format is null</exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="codecType"/> is invalid.\n
+ /// -or-\n
+ /// <paramref name="format"/> is neither audio type nor video type.
+ /// </exception>
+ /// <exception cref="NotSupportedException">the mime type of the format is not supported.</exception>
+ /// <see cref="SupportedAudioCodecs"/>
+ /// <see cref="SupportedVideoCodecs"/>
+ public void Configure(MediaFormat format, bool encoder, MediaCodecTypes codecType)
+ {
+ ValidateNotDisposed();
+
+ if (format == null)
+ {
+ throw new ArgumentNullException(nameof(format));
+ }
+
+ if (codecType != MediaCodecTypes.Hardware && codecType != MediaCodecTypes.Software)
+ {
+ throw new ArgumentException("codecType is invalid.");
+ }
+
+ if (format.Type == MediaFormatType.Audio)
+ {
+ ConfigureAudio((AudioMediaFormat)format, encoder, codecType);
+ }
+ else if (format.Type == MediaFormatType.Video)
+ {
+ ConfigureVideo((VideoMediaFormat)format, encoder, codecType);
+ }
+ else
+ {
+ throw new ArgumentException("Only video and audio formats are allowed.");
+ }
+ }
+
+ private void ConfigureAudio(AudioMediaFormat format, bool encoder,
+ MediaCodecTypes supportType)
+ {
+ int codecType = (int)format.MimeType & CodecTypeMask;
+
+ if (!Enum.IsDefined(typeof(SupportedCodecType), codecType))
+ {
+ throw new NotSupportedException("The format is not supported " +
+ $"mime type : { Enum.GetName(typeof(MediaFormatAudioMimeType), format.MimeType) }");
+ }
+
+ DoConfigure(codecType, encoder, supportType);
+
+ if (encoder)
+ {
+ int ret = Interop.MediaCodec.SetAudioEncoderInfo(_handle, format.SampleRate,
+ format.Channel, format.Bit, format.BitRate);
+
+ MultimediaDebug.AssertNoError(ret);
+ }
+ else
+ {
+ int ret = Interop.MediaCodec.SetAudioDecoderInfo(_handle, format.SampleRate,
+ format.Channel, format.Bit);
+
+ MultimediaDebug.AssertNoError(ret);
+ }
+ }
+
+ private void ConfigureVideo(VideoMediaFormat format, bool encoder,
+ MediaCodecTypes supportType)
+ {
+ int codecType = (int)format.MimeType & CodecTypeMask;
+
+ if (!Enum.IsDefined(typeof(SupportedCodecType), codecType))
+ {
+ throw new NotSupportedException("The format is not supported." +
+ $"mime type : { Enum.GetName(typeof(MediaFormatVideoMimeType), format.MimeType) }");
+ }
+
+ DoConfigure(codecType, encoder, supportType);
+
+ if (encoder)
+ {
+ int ret = Interop.MediaCodec.SetVideoEncoderInfo(_handle, format.Size.Width,
+ format.Size.Height, format.FrameRate, format.BitRate / 1000);
+
+ MultimediaDebug.AssertNoError(ret);
+ }
+ else
+ {
+ int ret = Interop.MediaCodec.SetVideoDecoderInfo(_handle, format.Size.Width, format.Size.Height);
+
+ MultimediaDebug.AssertNoError(ret);
+ }
+ }
+
+ private void DoConfigure(int codecType, bool encoder, MediaCodecTypes supportType)
+ {
+ Debug.Assert(Enum.IsDefined(typeof(SupportedCodecType), codecType));
+
+ int flags = (int)(encoder ? MediaCodecCodingType.Encoder : MediaCodecCodingType.Decoder);
+
+ flags |= (int)supportType;
+
+ int ret = Interop.MediaCodec.Configure(_handle, codecType, flags);
+
+ if (ret == (int)MediaCodecErrorCode.NotSupportedOnDevice)
+ {
+ throw new NotSupportedException("The format is not supported.");
+ }
+ MultimediaDebug.AssertNoError(ret);
+ }
+
+ /// <summary>
+ /// Adds the packet to the internal queue of the codec.
+ /// </summary>
+ /// <param name="packet">The packet to be encoded or decoded.</param>
+ /// <exception cref="ArgumentNullException">packet is null.</exception>
+ /// <exception cref="InvalidOperationException">the current codec is not prepared, yet.</exception>
+ /// <remarks>Any attempts to modify the packet will be failed until the <see cref="InputProcessed"/> event for the packet is invoked.</remarks>
+ public void ProcessInput(MediaPacket packet)
+ {
+ ValidateNotDisposed();
+
+ if (packet == null)
+ {
+ throw new ArgumentNullException(nameof(packet));
+ }
+
+ MediaPacket.Lock packetLock = MediaPacket.Lock.Get(packet);
+
+ int ret = Interop.MediaCodec.Process(_handle, packetLock.GetHandle(), 0);
+
+ if (ret == (int)MediaCodecErrorCode.InvalidState)
+ {
+ throw new InvalidOperationException("The codec is in invalid state.");
+ }
+
+ MultimediaDebug.AssertNoError(ret);
+ }
+
+ /// <summary>
+ /// Flushes both input and output buffers.
+ /// </summary>
+ public void FlushBuffers()
+ {
+ ValidateNotDisposed();
+
+ int ret = Interop.MediaCodec.FlushBuffers(_handle);
+
+ MultimediaDebug.AssertNoError(ret);
+ }
+
+ /// <summary>
+ /// Retrieves supported codec types for the specified params.
+ /// </summary>
+ /// <param name="encoder">The value indicating encoder or decoder.</param>
+ /// <param name="type">The mime type to query.</param>
+ /// <returns>The values indicating which codec types are supported on the current device.</returns>
+ /// <exception cref="ArgumentException">type is invalid.</exception>
+ public MediaCodecTypes GetCodecType(bool encoder, MediaFormatVideoMimeType type)
+ {
+ ValidateNotDisposed();
+
+ if (CheckMimeType(typeof(MediaFormatVideoMimeType), (int)type) == false)
+ {
+ return 0;
+ }
+
+ return GetCodecType((int)type, encoder);
+ }
+
+ /// <summary>
+ /// Retrieves supported codec types for the specified params.
+ /// </summary>
+ /// <param name="encoder">The value indicating encoder or decoder.</param>
+ /// <param name="type">The mime type to query.</param>
+ /// <returns>The values indicating which codec types are supported on the current device.</returns>
+ /// <exception cref="ArgumentException">type is invalid.</exception>
+ public MediaCodecTypes GetCodecType(bool encoder, MediaFormatAudioMimeType type)
+ {
+ ValidateNotDisposed();
+
+ if (CheckMimeType(typeof(MediaFormatAudioMimeType), (int)type) == false)
+ {
+ return 0;
+ }
+
+ return GetCodecType((int)type, encoder);
+ }
+
+ private MediaCodecTypes GetCodecType(int mimeType, bool isEncoder)
+ {
+ int codecType = mimeType & CodecTypeMask;
+ int value = 0;
+
+ int ret = Interop.MediaCodec.GetSupportedType(_handle, codecType, isEncoder, out value);
+
+ MultimediaDebug.AssertNoError(ret);
+
+ return (MediaCodecTypes)value;
+ }
+
+ private bool CheckMimeType(Type type, int value)
+ {
+ int codecType = value & CodecTypeMask;
+
+ if (!Enum.IsDefined(type, value))
+ {
+ throw new ArgumentException($"The mime type value is invalid : { value }.");
+ }
+
+ return Enum.IsDefined(typeof(SupportedCodecType), codecType);
+ }
+
+ #region OutputAvailable event
+ private EventHandler<OutputAvailableEventArgs> _outputAvailable;
+ private Interop.MediaCodec.OutputBufferAvailableCallback _outputBufferAvailableCb;
+
+ /// <summary>
+ /// Occurs when an output buffer is available.
+ /// </summary>
+ /// <remarks>The output packet needs to be disposed after it is used to clean up unmanaged resources.</remarks>
+ public event EventHandler<OutputAvailableEventArgs> OutputAvailable
+ {
+ add
+ {
+ ValidateNotDisposed();
+
+ if (_outputAvailable == null)
+ {
+ RegisterOutputAvailableCallback();
+ }
+ _outputAvailable += value;
+
+ }
+ remove
+ {
+ ValidateNotDisposed();
+
+ _outputAvailable -= value;
+ if (_outputAvailable == null)
+ {
+ UnregisterOutputAvailableCallback();
+ }
+ }
+ }
+
+ private void RegisterOutputAvailableCallback()
+ {
+ _outputBufferAvailableCb = (packetHandle, _) =>
+ {
+ OutputAvailableEventArgs args = null;
+
+ try
+ {
+ args = new OutputAvailableEventArgs(packetHandle);
+ }
+ catch (Exception)
+ {
+ Interop.MediaPacket.Destroy(packetHandle);
+
+ // TODO should we throw it to unmanaged code?
+ throw;
+ }
+
+ //TODO dispose if no event handler registered
+ _outputAvailable?.Invoke(this, args);
+ };
+
+ int ret = Interop.MediaCodec.SetOutputBufferAvailableCb(_handle,
+ _outputBufferAvailableCb, IntPtr.Zero);
+
+ MultimediaDebug.AssertNoError(ret);
+ }
+
+ private void UnregisterOutputAvailableCallback()
+ {
+ int ret = Interop.MediaCodec.UnsetOutputBufferAvailableCb(_handle);
+
+ MultimediaDebug.AssertNoError(ret);
+ }
+ #endregion
+
+ #region InputProcessed event
+ private Interop.MediaCodec.InputBufferUsedCallback _inputBufferUsedCb;
+
+ /// <summary>
+ /// Occurs when an input packet is processed.
+ /// </summary>
+ /// <see cref="ProcessInput(MediaPacket)"/>
+ public event EventHandler<InputProcessedEventArgs> InputProcessed;
+
+ private void RegisterInputProcessed()
+ {
+ _inputBufferUsedCb = (lockedPacketHandle, _) =>
+ {
+ MediaPacket packet = null;
+
+ // Lock must be disposed here, note that the packet won't be disposed.
+ using (MediaPacket.Lock packetLock =
+ MediaPacket.Lock.FromHandle(lockedPacketHandle))
+ {
+ Debug.Assert(packetLock != null);
+
+ packet = packetLock.MediaPacket;
+ }
+ Debug.Assert(packet != null);
+
+ InputProcessed?.Invoke(this, new InputProcessedEventArgs(packet));
+ };
+
+ int ret = Interop.MediaCodec.SetInputBufferUsedCb(_handle,
+ _inputBufferUsedCb, IntPtr.Zero);
+
+ MultimediaDebug.AssertNoError(ret);
+ }
+
+ private void UnregisterInputProcessed()
+ {
+ int ret = Interop.MediaCodec.UnsetInputBufferUsedCb(_handle);
+
+ MultimediaDebug.AssertNoError(ret);
+ }
+ #endregion
+
+ #region ErrorOccurred event
+ private Interop.MediaCodec.ErrorCallback _errorCb;
+
+ /// <summary>
+ /// Occurs whenever an error is produced in the codec.
+ /// </summary>
+ public event EventHandler<MediaCodecErrorOccurredEventArgs> ErrorOccurred;
+
+ private void RegisterErrorOccurred()
+ {
+ _errorCb = (errorCode, _) =>
+ {
+ MediaCodecError error = (Enum.IsDefined(typeof(MediaCodecError), errorCode)) ?
+ (MediaCodecError)errorCode : MediaCodecError.InternalError;
+
+ ErrorOccurred?.Invoke(this, new MediaCodecErrorOccurredEventArgs(error));
+ };
+ int ret = Interop.MediaCodec.SetErrorCb(_handle, _errorCb, IntPtr.Zero);
+
+ MultimediaDebug.AssertNoError(ret);
+ }
+
+ private void UnregisterErrorOccurred()
+ {
+ int ret = Interop.MediaCodec.UnsetErrorCb(_handle);
+
+ MultimediaDebug.AssertNoError(ret);
+ }
+ #endregion
+
+ #region EosReached event
+ private EventHandler<EventArgs> _eosReached;
+ private Interop.MediaCodec.EosCallback _eosCb;
+
+ // TODO replace
+ /// <summary>
+ /// Occurs when the codec processes all input data.
+ /// </summary>
+ public event EventHandler<EventArgs> EosReached
+ {
+ add
+ {
+ ValidateNotDisposed();
+
+ if (_eosReached == null)
+ {
+ RegisterEosReached();
+ }
+ _eosReached += value;
+
+ }
+ remove
+ {
+ ValidateNotDisposed();
+
+ _eosReached -= value;
+ if (_eosReached == null)
+ {
+ UnregisterEosReached();
+ }
+ }
+ }
+
+ private void RegisterEosReached()
+ {
+ _eosCb = _ => _eosReached?.Invoke(this, EventArgs.Empty);
+
+ int ret = Interop.MediaCodec.SetEosCb(_handle, _eosCb, IntPtr.Zero);
+
+ MultimediaDebug.AssertNoError(ret);
+ }
+
+ private void UnregisterEosReached()
+ {
+ int ret = Interop.MediaCodec.UnsetEosCb(_handle);
+
+ MultimediaDebug.AssertNoError(ret);
+ }
+ #endregion
+
+ #region BufferStatusChanged event
+ private EventHandler<BufferStatusChangedEventArgs> _bufferStatusChanged;
+ private Interop.MediaCodec.BufferStatusCallback _bufferStatusCb;
+
+ /// <summary>
+ /// Occurs when the codec needs more data or has enough data.
+ /// </summary>
+ public event EventHandler<BufferStatusChangedEventArgs> BufferStatusChanged
+ {
+ add
+ {
+ ValidateNotDisposed();
+
+ if (_bufferStatusChanged == null)
+ {
+ RegisterBufferStatusChanged();
+ }
+ _bufferStatusChanged += value;
+
+ }
+ remove
+ {
+ ValidateNotDisposed();
+
+ _bufferStatusChanged -= value;
+ if (_bufferStatusChanged == null)
+ {
+ UnregisterBufferStatusChanged();
+ }
+ }
+ }
+
+ private void RegisterBufferStatusChanged()
+ {
+ _bufferStatusCb = (statusCode, _) =>
+ {
+ Debug.Assert(Enum.IsDefined(typeof(MediaCodecStatus), statusCode),
+ $"{ statusCode } is not defined in MediaCodecStatus!");
+
+ _bufferStatusChanged?.Invoke(this,
+ new BufferStatusChangedEventArgs((MediaCodecStatus)statusCode));
+ };
+
+ int ret = Interop.MediaCodec.SetBufferStatusCb(_handle, _bufferStatusCb, IntPtr.Zero);
+
+ MultimediaDebug.AssertNoError(ret);
+ }
+
+ private void UnregisterBufferStatusChanged()
+ {
+ int ret = Interop.MediaCodec.UnsetBufferStatusCb(_handle);
+
+ MultimediaDebug.AssertNoError(ret);
+ }
+ #endregion
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaCodec/MediaCodec/MediaCodecError.cs b/src/Tizen.Multimedia.MediaCodec/MediaCodec/MediaCodecError.cs
new file mode 100644
index 0000000..14508f2
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaCodec/MediaCodec/MediaCodecError.cs
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using Tizen.Internals.Errors;
+
+namespace Tizen.Multimedia.MediaCodec
+{
+ internal enum MediaCodecErrorCode
+ {
+ CodecDefinedBase = -0x019B0000,
+
+ None = ErrorCode.None,
+ OutOfMemory = ErrorCode.OutOfMemory,
+ InvalidParameter = ErrorCode.InvalidParameter,
+ InvalidOperation = ErrorCode.InvalidParameter,
+ NotSupportedOnDevice = ErrorCode.NotSupported,
+ PermissionDenied = ErrorCode.PermissionDenied,
+
+ InvalidState = CodecDefinedBase | 0x01,
+ InvalidInBuffer = CodecDefinedBase | 0x02,
+ InvalidOutBuffer = CodecDefinedBase | 0x03,
+ Internal = CodecDefinedBase | 0x04,
+ NotInitialized = CodecDefinedBase | 0x05,
+ InvalidStream = CodecDefinedBase | 0x06,
+ CodecNotFound = CodecDefinedBase | 0x07,
+ DecodingError = CodecDefinedBase | 0x08,
+ OutOfStorage = CodecDefinedBase | 0x09,
+ StreamNotFound = CodecDefinedBase | 0x0a,
+ NotSupportedFormat = CodecDefinedBase | 0x0b,
+ NoAvailableBuffer = CodecDefinedBase | 0x0c,
+ OverflowInBuffer = CodecDefinedBase | 0x0d,
+ }
+
+ public enum MediaCodecError
+ {
+ NotSupportedFormat = MediaCodecErrorCode.NotSupportedFormat,
+ InternalError = MediaCodecErrorCode.Internal,
+ OutOfStorage = MediaCodecErrorCode.OutOfStorage,
+ InvalidStream = MediaCodecErrorCode.InvalidStream,
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaCodec/MediaCodec/MediaCodecErrorOccurredEventArgs.cs b/src/Tizen.Multimedia.MediaCodec/MediaCodec/MediaCodecErrorOccurredEventArgs.cs
new file mode 100644
index 0000000..0113b6a
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaCodec/MediaCodec/MediaCodecErrorOccurredEventArgs.cs
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia.MediaCodec
+{
+ /// <summary>
+ /// Provides data for the <see cref="MediaCodec.ErrorOccurred"/> event.
+ /// </summary>
+ public class MediaCodecErrorOccurredEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Initializes a new instance of the ErrorOccurredEventArgs class.
+ /// </summary>
+ /// <param name="error">The value representing the type of the error.</param>
+ public MediaCodecErrorOccurredEventArgs(MediaCodecError error)
+ {
+ Error = error;
+ }
+
+ /// <summary>
+ /// Gets the value indicating what kind of the error.
+ /// </summary>
+ public MediaCodecError Error { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaCodec/MediaCodec/MediaCodecStatus.cs b/src/Tizen.Multimedia.MediaCodec/MediaCodec/MediaCodecStatus.cs
new file mode 100644
index 0000000..32e453d
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaCodec/MediaCodec/MediaCodecStatus.cs
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia.MediaCodec
+{
+ /// <summary>
+ /// Specifies the status of a codec.
+ /// </summary>
+ public enum MediaCodecStatus
+ {
+ /// <summary>
+ /// Not enough data to decode or encode.
+ /// </summary>
+ LackOfData,
+
+ /// <summary>
+ /// Enough data to decode or encode.
+ /// </summary>
+ EnoughData
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaCodec/MediaCodec/MediaCodecType.cs b/src/Tizen.Multimedia.MediaCodec/MediaCodec/MediaCodecType.cs
new file mode 100644
index 0000000..2aaf82e
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaCodec/MediaCodec/MediaCodecType.cs
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia.MediaCodec
+{
+ [Flags]
+ internal enum MediaCodecCodingType
+ {
+ Encoder = 0x1,
+ Decoder = 0x2
+ }
+
+ /// <summary>
+ /// Specifies types of codec.
+ /// <para>
+ /// This enumeration has a <see cref="FlagsAttribute"/> attribute that allows a bitwise combination of its member values.
+ /// </para>
+ /// </summary>
+ [Flags]
+ public enum MediaCodecTypes
+ {
+ /// <summary>
+ /// The hardware-accelerated codec.
+ /// </summary>
+ Hardware = 0x4,
+
+ /// <summary>
+ /// The software codec.
+ /// </summary>
+ Software = 0x8
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaCodec/MediaCodec/OutputAvailableEventArgs.cs b/src/Tizen.Multimedia.MediaCodec/MediaCodec/OutputAvailableEventArgs.cs
new file mode 100644
index 0000000..9c84828
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaCodec/MediaCodec/OutputAvailableEventArgs.cs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia.MediaCodec
+{
+ /// <summary>
+ /// Provides data for the <see cref="MediaCodec.OutputAvailable"/> event.
+ /// </summary>
+ /// <remarks>The output packet needs to be disposed after it is used to clean up unmanaged resources.</remarks>
+ public class OutputAvailableEventArgs : EventArgs
+ {
+ internal OutputAvailableEventArgs(IntPtr packetHandle)
+ {
+ Packet = MediaPacket.From(packetHandle);
+ }
+
+ /// <summary>
+ /// Gets the result packet.
+ /// </summary>
+ public MediaPacket Packet { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaCodec/MediaCodec/SupportedCodecType.cs b/src/Tizen.Multimedia.MediaCodec/MediaCodec/SupportedCodecType.cs
new file mode 100644
index 0000000..999808f
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaCodec/MediaCodec/SupportedCodecType.cs
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia.MediaCodec
+{
+ internal enum SupportedCodecType
+ {
+ // L16 = 0x1010,
+ // ALaw = 0x1020,
+ // ULaw = 0x1030,
+ Amr = 0x1040,
+ AmrNB = 0x1040,
+ AmrWb = 0x1041,
+ // G729 = 0x1050,
+ Aac = 0x1060,
+ AacLC = 0x1060,
+ AacHE = 0x1061,
+ AacHEPS = 0x1062,
+ MP3 = 0x1070,
+ Vorbis = 0x1080,
+ Flac = 0x1090,
+ Wma1 = 0x10A0,
+ Wma2 = 0x10A1,
+ WmaPro = 0x10A2,
+ WmaLossless = 0x10A3,
+
+ H261 = 0x2010,
+ H263 = 0x2020,
+ H264 = 0x2030,
+ MJpeg = 0x2040,
+ Mpeg1 = 0x2050,
+ Mpeg2 = 0x2060,
+ Mpeg4 = 0x2070,
+ // Hevc = 0x2080,
+ // VP8 = 0x2090,
+ // VP9 = 0x20A0,
+ // VC1 = 0x20B0,
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaCodec/Tizen.Multimedia.MediaCodec.csproj b/src/Tizen.Multimedia.MediaCodec/Tizen.Multimedia.MediaCodec.csproj
new file mode 100644
index 0000000..0e5378c
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaCodec/Tizen.Multimedia.MediaCodec.csproj
@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen.Multimedia\Tizen.Multimedia.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Multimedia.MediaPlayer/Interop/Interop.AudioEffect.cs b/src/Tizen.Multimedia.MediaPlayer/Interop/Interop.AudioEffect.cs
new file mode 100644
index 0000000..10a935e
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaPlayer/Interop/Interop.AudioEffect.cs
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Multimedia;
+
+internal static partial class Interop
+{
+ internal static partial class AudioEffect
+ {
+ [DllImport(Libraries.Player, EntryPoint = "player_audio_effect_get_equalizer_bands_count")]
+ internal static extern PlayerErrorCode GetEqualizerBandsCount(IntPtr player, out int count);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_audio_effect_set_equalizer_band_level")]
+ internal static extern PlayerErrorCode SetEqualizerBandLevel(IntPtr player, int index, int level);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_audio_effect_get_equalizer_band_level")]
+ internal static extern PlayerErrorCode GetEqualizerBandLevel(IntPtr player, int index, out int level);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_audio_effect_set_equalizer_all_bands")]
+ internal static extern PlayerErrorCode SetEqualizerAllBands(IntPtr player, out int band_levels, int length);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_audio_effect_get_equalizer_level_range")]
+ internal static extern PlayerErrorCode GetEqualizerLevelRange(IntPtr player, out int min, out int max);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_audio_effect_get_equalizer_band_frequency")]
+ internal static extern PlayerErrorCode GetEqualizerBandFrequency(IntPtr player, int index, out int frequency);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_audio_effect_get_equalizer_band_frequency_range")]
+ internal static extern PlayerErrorCode GetEqualizerBandFrequencyRange(IntPtr player, int index, out int range);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_audio_effect_equalizer_clear")]
+ internal static extern PlayerErrorCode EqualizerClear(IntPtr player);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_audio_effect_equalizer_is_available")]
+ internal static extern PlayerErrorCode EqualizerIsAvailable(IntPtr player, out bool available);
+ }
+
+}
diff --git a/src/Tizen.Multimedia.MediaPlayer/Interop/Interop.Display.cs b/src/Tizen.Multimedia.MediaPlayer/Interop/Interop.Display.cs
new file mode 100644
index 0000000..c8eea4b
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaPlayer/Interop/Interop.Display.cs
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Multimedia;
+
+internal static partial class Interop
+{
+ internal static partial class Display
+ {
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_display_mode")]
+ internal static extern PlayerErrorCode SetMode(IntPtr player, PlayerDisplayMode mode);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_get_display_mode")]
+ internal static extern PlayerErrorCode GetMode(IntPtr player, out int mode);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_display_visible")]
+ internal static extern PlayerErrorCode SetVisible(IntPtr player, bool visible);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_is_display_visible")]
+ internal static extern PlayerErrorCode IsVisible(IntPtr player, out bool visible);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_display_rotation")]
+ internal static extern PlayerErrorCode SetRotation(IntPtr player, PlayerDisplayRotation rotation);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_get_display_rotation")]
+ internal static extern PlayerErrorCode GetRotation(IntPtr player, out int rotation);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_display_roi_area")]
+ internal static extern PlayerErrorCode SetRoi(IntPtr player, int x, int y, int width, int height);
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaPlayer/Interop/Interop.Libraries.cs b/src/Tizen.Multimedia.MediaPlayer/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..1fd8784
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaPlayer/Interop/Interop.Libraries.cs
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string Player = "libcapi-media-player.so.0";
+ }
+}
+
diff --git a/src/Tizen.Multimedia.MediaPlayer/Interop/Interop.Player.cs b/src/Tizen.Multimedia.MediaPlayer/Interop/Interop.Player.cs
new file mode 100644
index 0000000..b748044
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaPlayer/Interop/Interop.Player.cs
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen;
+using Tizen.Multimedia;
+
+internal static partial class Interop
+{
+ internal static partial class NativePlayer
+ {
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void PlaybackCompletedCallback(IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void PlaybackInterruptedCallback(PlaybackInterruptionReason code, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void PlaybackErrorCallback(int code, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void VideoFrameDecodedCallback(IntPtr packetHandle, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void SubtitleUpdatedCallback(uint duration, string text, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void BufferingProgressCallback(int percent, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void VideoStreamChangedCallback(int width, int height, int fps, int bitrate, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MediaStreamBufferStatusCallback(MediaStreamBufferStatus status, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MediaStreamSeekCallback(ulong offset, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void VideoCaptureCallback(IntPtr data, int width, int height, uint size, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void PrepareCallback(IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void SeekCompletedCallback(IntPtr userData);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_create")]
+ internal static extern PlayerErrorCode Create(out PlayerHandle player);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_destroy")]
+ internal static extern PlayerErrorCode Destroy(IntPtr player);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_prepare")]
+ internal static extern PlayerErrorCode Prepare(IntPtr player);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_unprepare")]
+ internal static extern PlayerErrorCode Unprepare(IntPtr player);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_uri")]
+ internal static extern PlayerErrorCode SetUri(IntPtr player, string uri);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_display")]
+ internal static extern PlayerErrorCode SetDisplay(IntPtr player, DisplayType type, IntPtr display);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_start")]
+ internal static extern PlayerErrorCode Start(IntPtr player);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_stop")]
+ internal static extern PlayerErrorCode Stop(IntPtr player);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_pause")]
+ internal static extern PlayerErrorCode Pause(IntPtr player);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_memory_buffer")]
+ internal static extern PlayerErrorCode SetMemoryBuffer(IntPtr player, byte[] data, int size);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_get_state")]
+ internal static extern PlayerErrorCode GetState(IntPtr player, out int state);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_volume")]
+ internal static extern PlayerErrorCode SetVolume(IntPtr player, float left, float right);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_get_volume")]
+ internal static extern PlayerErrorCode GetVolume(IntPtr player, out float left, out float right);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_sound_stream_info")]
+ internal static extern PlayerErrorCode SetAudioPolicyInfo(IntPtr player, IntPtr streamInfo);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_audio_latency_mode")]
+ internal static extern PlayerErrorCode SetAudioLatencyMode(IntPtr player, AudioLatencyMode latencyMode);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_get_audio_latency_mode")]
+ internal static extern PlayerErrorCode GetAudioLatencyMode(IntPtr player, out AudioLatencyMode latencyMode);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_get_play_position")]
+ internal static extern PlayerErrorCode GetPlayPosition(IntPtr player, out int millisecond);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_play_position")]
+ internal static extern PlayerErrorCode SetPlayPosition(IntPtr player, int millisecond,
+ bool accurate, SeekCompletedCallback cb, IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_mute")]
+ internal static extern PlayerErrorCode SetMute(IntPtr player, bool muted);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_is_muted")]
+ internal static extern PlayerErrorCode IsMuted(IntPtr player, out bool muted);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_looping")]
+ internal static extern PlayerErrorCode SetLooping(IntPtr player, bool looping);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_is_looping")]
+ internal static extern PlayerErrorCode IsLooping(IntPtr player, out bool looping);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_completed_cb")]
+ internal static extern PlayerErrorCode SetCompletedCb(IntPtr player,
+ PlaybackCompletedCallback callback, IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.Player, EntryPoint = "player_unset_completed_cb")]
+ internal static extern PlayerErrorCode UnsetCompletedCb(IntPtr player);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_interrupted_cb")]
+ internal static extern PlayerErrorCode SetInterruptedCb(IntPtr player,
+ PlaybackInterruptedCallback callback, IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.Player, EntryPoint = "player_unset_interrupted_cb")]
+ internal static extern PlayerErrorCode UnsetInterruptedCb(IntPtr player);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_error_cb")]
+ internal static extern PlayerErrorCode SetErrorCb(IntPtr player, PlaybackErrorCallback callback,
+ IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.Player, EntryPoint = "player_unset_error_cb")]
+ internal static extern PlayerErrorCode UnsetErrorCb(IntPtr player);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_capture_video")]
+ internal static extern PlayerErrorCode CaptureVideo(IntPtr player, VideoCaptureCallback callback,
+ IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_media_packet_video_frame_decoded_cb")]
+ internal static extern PlayerErrorCode SetVideoFrameDecodedCb(IntPtr player, VideoFrameDecodedCallback callback,
+ IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.Player, EntryPoint = "player_unset_media_packet_video_frame_decoded_cb")]
+ internal static extern PlayerErrorCode UnsetVideoFrameDecodedCb(IntPtr player);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_streaming_cookie")]
+ internal static extern PlayerErrorCode SetStreamingCookie(IntPtr player, string cookie, int size);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_streaming_user_agent")]
+ internal static extern PlayerErrorCode SetStreamingUserAgent(IntPtr player, string userAgent, int size);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_get_streaming_download_progress")]
+ internal static extern PlayerErrorCode GetStreamingDownloadProgress(IntPtr player, out int start, out int current);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_buffering_cb")]
+ internal static extern PlayerErrorCode SetBufferingCb(IntPtr player,
+ BufferingProgressCallback callback, IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.Player, EntryPoint = "player_unset_buffering_cb")]
+ internal static extern PlayerErrorCode UnsetBufferingCb(IntPtr player);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_playback_rate")]
+ internal static extern PlayerErrorCode SetPlaybackRate(IntPtr player, float rate);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_push_media_stream")]
+ internal static extern PlayerErrorCode PushMediaStream(IntPtr player, IntPtr packet);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_media_stream_info")]
+ internal static extern PlayerErrorCode SetMediaStreamInfo(IntPtr player, int type, IntPtr format);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_media_stream_buffer_status_cb")]
+ internal static extern PlayerErrorCode SetMediaStreamBufferStatusCb(IntPtr player, StreamType type,
+ MediaStreamBufferStatusCallback callback, IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.Player, EntryPoint = "player_unset_media_stream_buffer_status_cb")]
+ internal static extern PlayerErrorCode UnsetMediaStreamBufferStatusCb(IntPtr player, int type);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_media_stream_seek_cb")]
+ internal static extern PlayerErrorCode SetMediaStreamSeekCb(IntPtr player, StreamType type,
+ MediaStreamSeekCallback callback, IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.Player, EntryPoint = "player_unset_media_stream_seek_cb")]
+ internal static extern PlayerErrorCode UnsetMediaStreamSeekCb(IntPtr player, int type);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_media_stream_buffer_max_size")]
+ internal static extern PlayerErrorCode SetMediaStreamBufferMaxSize(IntPtr player, StreamType type, ulong maxSize);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_get_media_stream_buffer_max_size")]
+ internal static extern PlayerErrorCode GetMediaStreamBufferMaxSize(IntPtr player, StreamType type, out ulong maxSize);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_media_stream_buffer_min_threshold")]
+ internal static extern PlayerErrorCode SetMediaStreamBufferMinThreshold(IntPtr player, StreamType type, uint percent);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_get_media_stream_buffer_min_threshold")]
+ internal static extern PlayerErrorCode GetMediaStreamBufferMinThreshold(IntPtr player, int type, out uint percent);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_get_content_info")]
+ internal static extern PlayerErrorCode GetContentInfo(IntPtr player, StreamMetadataKey key, out IntPtr value);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_get_codec_info")]
+ internal static extern PlayerErrorCode GetCodecInfo(IntPtr player, out IntPtr audioCodec, out IntPtr videoCodec);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_get_audio_stream_info")]
+ internal static extern PlayerErrorCode GetAudioStreamInfo(IntPtr player, out int sampleRate, out int channel, out int bitRate);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_get_video_stream_info")]
+ internal static extern PlayerErrorCode GetVideoStreamInfo(IntPtr player, out int fps, out int bitRate);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_get_album_art")]
+ internal static extern PlayerErrorCode GetAlbumArt(IntPtr player, out IntPtr albumArt, out int size);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_get_video_size")]
+ internal static extern PlayerErrorCode GetVideoSize(IntPtr player, out int width, out int height);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_get_duration")]
+ internal static extern PlayerErrorCode GetDuration(IntPtr player, out int duration);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_subtitle_path")]
+ internal static extern PlayerErrorCode SetSubtitlePath(IntPtr player, string path);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_subtitle_updated_cb")]
+ internal static extern PlayerErrorCode SetSubtitleUpdatedCb(IntPtr player,
+ SubtitleUpdatedCallback callback, IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.Player, EntryPoint = "player_unset_subtitle_updated_cb")]
+ internal static extern PlayerErrorCode UnsetSubtitleUpdatedCb(IntPtr player);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_subtitle_position_offset")]
+ internal static extern PlayerErrorCode SetSubtitlePositionOffset(IntPtr player, int millisecond);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_set_video_stream_changed_cb")]
+ internal static extern PlayerErrorCode SetVideoStreamChangedCb(IntPtr player,
+ VideoStreamChangedCallback callback, IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.Player, EntryPoint = "player_unset_video_stream_changed_cb")]
+ internal static extern PlayerErrorCode UnsetVideoStreamChangedCb(IntPtr player);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_get_track_count")]
+ internal static extern PlayerErrorCode GetTrackCount(IntPtr player, int type, out int count);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_select_track")]
+ internal static extern PlayerErrorCode SelectTrack(IntPtr player, int type, int index);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_get_current_track")]
+ internal static extern PlayerErrorCode GetCurrentTrack(IntPtr player, int type, out int index);
+
+ [DllImport(Libraries.Player, EntryPoint = "player_get_track_language_code")]
+ internal static extern PlayerErrorCode GetTrackLanguageCode(IntPtr player, int type, int index, out IntPtr code);
+ }
+
+ internal class PlayerHandle : SafeHandle
+ {
+ protected PlayerHandle() : base(IntPtr.Zero, true)
+ {
+ }
+
+ public override bool IsInvalid => handle == IntPtr.Zero;
+
+ protected override bool ReleaseHandle()
+ {
+ var ret = NativePlayer.Destroy(handle);
+ if (ret != PlayerErrorCode.None)
+ {
+ Log.Debug(GetType().FullName, $"Failed to release native {GetType().Name}");
+ return false;
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaPlayer/Player/AudioEffect.cs b/src/Tizen.Multimedia.MediaPlayer/Player/AudioEffect.cs
new file mode 100644
index 0000000..a9ca7e9
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaPlayer/Player/AudioEffect.cs
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Native = Interop.AudioEffect;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides the ability to control the audio effects for <see cref="Multimedia.Player"/>.
+ /// </summary>
+ public class AudioEffect
+ {
+ private readonly EqualizerBand[] _bands;
+
+ internal AudioEffect(Player owner)
+ {
+ Player = owner;
+
+ bool available = false;
+
+ Native.EqualizerIsAvailable(Player.Handle, out available).
+ ThrowIfFailed("Failed to initialize the AudioEffect");
+
+ IsAvailable = available;
+
+ if (IsAvailable == false)
+ {
+ return;
+ }
+
+ int count = 0;
+ Native.GetEqualizerBandsCount(Player.Handle, out count).
+ ThrowIfFailed("Failed to initialize the AudioEffect");
+
+ int min = 0;
+ int max = 0;
+ Native.GetEqualizerLevelRange(Player.Handle, out min, out max).
+ ThrowIfFailed("Failed to initialize the AudioEffect");
+
+ Count = count;
+ BandLevelRange = new Range(min, max);
+
+ _bands = new EqualizerBand[count];
+ }
+
+ /// <summary>
+ /// Gets a <see cref="EqualizerBand"/> at the specified index.
+ /// </summary>
+ /// <param name="index">The index of the band to get.</param>
+ /// <exception cref="ObjectDisposedException">The <see cref="Player"/> has already been disposed of.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// index is less than zero.\n
+ /// -or-\n
+ /// index is equal to or greater than <see cref="Count"/>.
+ /// </exception>
+ public EqualizerBand this[int index]
+ {
+ get
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ Player.ValidateNotDisposed();
+
+ if (index < 0 || Count <= index)
+ {
+ throw new ArgumentOutOfRangeException(nameof(index), index,
+ $"Valid index is 0 <= x < { nameof(Count) } ");
+ }
+
+ if (_bands[index] == null)
+ {
+ _bands[index] = new EqualizerBand(this, index);
+ }
+ Log.Info(PlayerLog.Tag, "get equalizer band : " + _bands[index]);
+ return _bands[index];
+ }
+ }
+
+ /// <summary>
+ /// Clears the equalizer effect.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">The <see cref="Player"/> has already been disposed of.</exception>
+ public void Clear()
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ Player.ValidateNotDisposed();
+
+ Native.EqualizerClear(Player.Handle).
+ ThrowIfFailed("Failed to clear equalizer effect");
+ Log.Debug(PlayerLog.Tag, PlayerLog.Leave);
+ }
+
+ public int Count{ get; }
+
+ /// <summary>
+ /// Get the band level range of the bands in dB.
+ /// </summary>
+ public Range BandLevelRange { get; }
+
+ /// <summary>
+ /// Gets the value whether the AudioEffect is available or not.
+ /// </summary>
+ public bool IsAvailable { get; }
+
+ /// <summary>
+ /// Gets the player that this AudioEffect belongs to.
+ /// </summary>
+ public Player Player { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaPlayer/Player/BufferingProgressChangedEventArgs.cs b/src/Tizen.Multimedia.MediaPlayer/Player/BufferingProgressChangedEventArgs.cs
new file mode 100644
index 0000000..57c6e15
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaPlayer/Player/BufferingProgressChangedEventArgs.cs
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides data for the <see cref="Player.BufferingProgressChanged"/> event.
+ /// </summary>
+ public class BufferingProgressChangedEventArgs : EventArgs
+ {
+ public BufferingProgressChangedEventArgs(int percent)
+ {
+ Percent = percent;
+ }
+
+ /// <summary>
+ /// Gets the value indicating the buffering percentage.
+ /// </summary>
+ /// <value>The percentage of the buffering.</value>
+ public int Percent { get; }
+
+ public override string ToString()
+ {
+ return $"Percent={ Percent.ToString() }";
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaPlayer/Player/CapturedFrame.cs b/src/Tizen.Multimedia.MediaPlayer/Player/CapturedFrame.cs
new file mode 100644
index 0000000..f9a5157
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaPlayer/Player/CapturedFrame.cs
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System.Diagnostics;
+
+namespace Tizen.Multimedia
+{
+ //TODO we need a better name.
+ /// <summary>
+ /// Represents data for a video frame captured.
+ /// </summary>
+ public class CapturedFrame
+ {
+ internal CapturedFrame(byte[] imageBuffer, int width, int height)
+ {
+ Debug.Assert(imageBuffer != null, "imageBuffer is null!");
+ Debug.Assert(width > 0, $"Width is invalid : {width}!");
+ Debug.Assert(height > 0, $"height is invalid : {height}!");
+
+ Buffer = imageBuffer;
+ Size = new Size(width, height);
+ Log.Debug(PlayerLog.Tag, "width : " + width + ", height : " + height);
+ }
+
+ /// <summary>
+ /// Gets the raw buffer of the captured image.
+ /// </summary>
+ /// <remarks>The color space format is RGB888.</remarks>
+ public byte[] Buffer { get; }
+
+ /// <summary>
+ /// Gets the size.
+ /// </summary>
+ public Size Size { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaPlayer/Player/DownloadProgress.cs b/src/Tizen.Multimedia.MediaPlayer/Player/DownloadProgress.cs
new file mode 100644
index 0000000..d56dce6
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaPlayer/Player/DownloadProgress.cs
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+namespace Tizen.Multimedia
+{
+
+ /// <summary>
+ /// Represents data for a downloading status.
+ /// </summary>
+ public struct DownloadProgress
+ {
+ /// <summary>
+ /// Initializes a new instance of the DownloadProgress struct.
+ /// </summary>
+ /// <param name="start">The position that downloading started in percentage.</param>
+ /// <param name="current">The position indicating the current downloading progress in percentage.</param>
+ public DownloadProgress(int start, int current)
+ {
+ Start = start;
+ Current = current;
+ Log.Debug(PlayerLog.Tag, "start : " + start + ", current : " + current);
+ }
+
+ /// <summary>
+ /// Gets or sets the start position.
+ /// </summary>
+ /// <value>The position that downloading started in percentage.</value>
+ public int Start
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// Gets or sets the current position.
+ /// </summary>
+ /// <value>The position indicating the current downloading progress in percentage.</value>
+ public int Current
+ {
+ get;
+ set;
+ }
+
+ public override string ToString()
+ {
+ return $"Start={ Start.ToString() }, Current={ Current.ToString() }";
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaPlayer/Player/EqualizerBand.cs b/src/Tizen.Multimedia.MediaPlayer/Player/EqualizerBand.cs
new file mode 100644
index 0000000..59dc485
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaPlayer/Player/EqualizerBand.cs
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.Diagnostics;
+using Native = Interop.AudioEffect;
+
+namespace Tizen.Multimedia
+{
+
+ /// <summary>
+ /// Represents a equalizer band of <see cref="AudioEffect"/>.
+ /// </summary>
+ public class EqualizerBand
+ {
+ private readonly AudioEffect _owner;
+ private readonly int _index;
+
+ internal EqualizerBand(AudioEffect owner, int index)
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ Debug.Assert(owner != null);
+
+ _owner = owner;
+ _index = index;
+
+ int frequency = 0;
+ int range = 0;
+
+ Native.GetEqualizerBandFrequency(_owner.Player.Handle, _index, out frequency).
+ ThrowIfFailed("Failed to initialize equalizer band");
+
+ Native.GetEqualizerBandFrequencyRange(_owner.Player.Handle, _index, out range).
+ ThrowIfFailed("Failed to initialize equalizer band");
+
+ Frequency = frequency;
+ FrequencyRange = range;
+ Log.Debug(PlayerLog.Tag, "frequency : " + frequency + ", range : " + range);
+ }
+
+ /// <summary>
+ /// Sets or gets the gain for the equalizer band.
+ /// </summary>
+ /// <param name="value">The value indicating new gain in decibel(dB).</param>
+ /// <exception cref="ObjectDisposedException">The player that this EqualizerBand belongs to has already been disposed of.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="value"/> is less than <see cref="AudioEffect.MinBandLevel"/>.\n
+ /// -or-\n
+ /// <paramref name="value"/> is greater than <see cref="AudioEffect.MaxBandLevel"/>.
+ /// </exception>
+ public int Level
+ {
+ get
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ _owner.Player.ValidateNotDisposed();
+
+ int value = 0;
+ Native.GetEqualizerBandLevel(_owner.Player.Handle, _index, out value).
+ ThrowIfFailed("Failed to get the level of the equalizer band");
+ Log.Info(PlayerLog.Tag, "get level : " + value);
+ return value;
+ }
+ set
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ _owner.Player.ValidateNotDisposed();
+
+ if (value < _owner.BandLevelRange.Min || _owner.BandLevelRange.Max < value)
+ {
+ Log.Error(PlayerLog.Tag, "invalid level : " + value);
+ throw new ArgumentOutOfRangeException(nameof(value), value,
+ $"valid value range is { nameof(AudioEffect.BandLevelRange) }." +
+ $"but got {value}.");
+ }
+
+ Native.SetEqualizerBandLevel(_owner.Player.Handle, _index, value).
+ ThrowIfFailed("Failed to set the level of the equalizer band");
+ }
+ }
+
+
+ /// <summary>
+ /// Gets the frequency in dB.
+ /// </summary>
+ public int Frequency { get; }
+
+ /// <summary>
+ /// Gets the frequency range in dB.
+ /// </summary>
+ public int FrequencyRange { get; }
+
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaPlayer/Player/MediaBufferSource.cs b/src/Tizen.Multimedia.MediaPlayer/Player/MediaBufferSource.cs
new file mode 100644
index 0000000..2fa4cd6
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaPlayer/Player/MediaBufferSource.cs
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using static Interop;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents a media source using memory.
+ /// </summary>
+ /// <remarks>
+ /// The buffer has to be filled with appropriate data which means it must be well-formatted.
+ /// If you provide invalid data, you won't receive an error until <see cref="Player.Start"/> is called.
+ /// </remarks>
+ /// <seealso cref="Player.SetSource(MediaSource)"/>
+ public sealed class MediaBufferSource : MediaSource
+ {
+ private byte[] _buffer;
+
+ /// <summary>
+ /// Initialize a new instance of the MediaBufferSource class with an allocated buffer.
+ /// </summary>
+ /// <param name="length">The value indicating the size of the buffer.</param>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="length"/> is zero.\n
+ /// -or-\n
+ /// <paramref name="length"/> is less than zero.
+ /// </exception>
+ public MediaBufferSource(int length)
+ {
+ if (length <= 0)
+ {
+ Log.Error(PlayerLog.Tag, "invalid length : " + length);
+ throw new ArgumentOutOfRangeException(nameof(length), length,
+ "length can't be equal to or less than zero.");
+ }
+ _buffer = new byte[length];
+ }
+
+ /// <summary>
+ /// Initialize a new instance of the MediaBufferSource class from the buffer.
+ /// </summary>
+ /// <param name="buffer">The source array to be copied into the buffer.</param>
+ /// <exception cref="ArgumentNullException">buffer is null.</exception>
+ public MediaBufferSource(byte[] buffer) : this(buffer, buffer == null ? 0 : buffer.Length)
+ {
+ }
+
+ //TODO remove default parameter.
+ /// <summary>
+ /// Initialize a new instance of the MediaBufferSource class from the buffer
+ /// with the specified length and the specified offset.
+ /// </summary>
+ /// <param name="buffer">The source array to be copied into the buffer.</param>
+ /// <param name="length">The value indicating the number of bytes to copy from the buffer.</param>
+ /// <param name="offset">The value indicating the offset in the buffer of the first byte to copy.</param>
+ /// <exception cref="ArgumentNullException">buffer is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="offset"/> is less than zero.\n
+ /// -or-\n
+ /// <paramref name="length"/> is equal to or less than zero.\n
+ /// -or-\n
+ /// <paramref name="offset"/>+<paramref name="length"/> is greater than buffer.Length.
+ /// </exception>
+ public MediaBufferSource(byte[] buffer, int length, int offset = 0)
+ {
+ if (buffer == null)
+ {
+ Log.Error(PlayerLog.Tag, "invalid buffer");
+ throw new ArgumentNullException(nameof(buffer));
+ }
+ if (offset < 0)
+ {
+ Log.Error(PlayerLog.Tag, "invalid offset : " + offset);
+ throw new ArgumentOutOfRangeException(nameof(offset), offset, "offset can't be less than zero.");
+ }
+ if (length <= 0)
+ {
+ Log.Error(PlayerLog.Tag, "invalid length : " + length);
+ throw new ArgumentOutOfRangeException(nameof(length), length, "length can't be equal to or less than zero.");
+ }
+ if (length + offset > buffer.Length)
+ {
+ Log.Error(PlayerLog.Tag, "invalid total length : " + (int)(length + offset));
+ throw new ArgumentOutOfRangeException($"length + offset can't be greater than the length of the { nameof(buffer) }.");
+ }
+
+ _buffer = new byte[length];
+
+ Array.Copy(buffer, offset, _buffer, 0, length);
+ }
+
+ private MediaBufferSource()
+ {
+ }
+
+ /// <summary>
+ /// Create a MediaBufferSource that wraps a byte array.
+ /// </summary>
+ /// <param name="buffer">The array to be wrapped.</param>
+ /// <returns>A MediaBufferSource wrapping the byte array.</returns>
+ public static MediaBufferSource Wrap(byte[] buffer)
+ {
+ if (buffer == null)
+ {
+ Log.Error(PlayerLog.Tag, "invalid buffer");
+ throw new ArgumentNullException(nameof(buffer));
+ }
+
+ MediaBufferSource source = new MediaBufferSource();
+ source._buffer = buffer;
+ return source;
+ }
+
+ /// <summary>
+ /// Gets the byte array of this buffer.
+ /// </summary>
+ public byte[] Buffer => _buffer;
+
+ internal override void OnAttached(Player player)
+ {
+ NativePlayer.SetMemoryBuffer(player.Handle, _buffer, _buffer.Length).
+ ThrowIfFailed("Failed to set the memory buffer");
+ }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.MediaPlayer/Player/MediaSource.cs b/src/Tizen.Multimedia.MediaPlayer/Player/MediaSource.cs
new file mode 100644
index 0000000..428f1cb
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaPlayer/Player/MediaSource.cs
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// MediaSource is a base class for <see cref="Player"/> sources.
+ /// </summary>
+ public abstract class MediaSource
+ {
+ internal MediaSource()
+ {
+ }
+
+ internal void AttachTo(Player player)
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ OnAttached(player);
+ }
+
+ internal void DetachFrom(Player player)
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ OnDetached(player);
+ }
+
+ internal abstract void OnAttached(Player player);
+
+ internal virtual void OnDetached(Player player)
+ {
+ }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.MediaPlayer/Player/MediaStreamBufferStatusChangedEventArgs.cs b/src/Tizen.Multimedia.MediaPlayer/Player/MediaStreamBufferStatusChangedEventArgs.cs
new file mode 100644
index 0000000..15d8e7a
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaPlayer/Player/MediaStreamBufferStatusChangedEventArgs.cs
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+
+namespace Tizen.Multimedia
+{
+
+ /// <summary>
+ /// Provides data for the <see cref="MediaStreamConfiguration.BufferStatusChanged"/> event.
+ /// </summary>
+ public class MediaStreamBufferStatusChangedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Initializes a new instance of the MediaStreamBufferStatusChangedEventArgs class.
+ /// </summary>
+ /// <param name="status">The value indicating the status of the stream.</param>
+ public MediaStreamBufferStatusChangedEventArgs(MediaStreamBufferStatus status)
+ {
+ Status = status;
+ }
+
+ /// <summary>
+ /// Gets the status.
+ /// </summary>
+ public MediaStreamBufferStatus Status { get; }
+
+ public override string ToString()
+ {
+ return $"Status : { Status.ToString() }";
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaPlayer/Player/MediaStreamConfiguration.cs b/src/Tizen.Multimedia.MediaPlayer/Player/MediaStreamConfiguration.cs
new file mode 100644
index 0000000..5448e4e
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaPlayer/Player/MediaStreamConfiguration.cs
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.Diagnostics;
+using static Interop;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides a means to configure properties and handle events for <see cref="MediaStreamSource"/>.
+ /// </summary>
+ /// <seealso cref="MediaStreamSource"/>
+ public class MediaStreamConfiguration
+ {
+ private const ulong DefaultBufferMaxSize = 200000;
+ private const uint DefaultBufferMinThreshold = 0;
+
+ private readonly MediaStreamSource _owner;
+ private readonly StreamType _streamType;
+
+ private ulong _bufferMaxSize = DefaultBufferMaxSize;
+ private uint _threshold = DefaultBufferMinThreshold;
+
+ internal MediaStreamConfiguration(MediaStreamSource owner, StreamType streamType)
+ {
+ _owner = owner;
+ _streamType = streamType;
+ }
+
+ /// <summary>
+ /// Occurs when the buffer underrun or overflow.
+ /// </summary>
+ /// <remarks>The event handler will be executed on an internal thread.</remarks>
+ /// <seealso cref="BufferMaxSize"/>
+ /// <seealso cref="BufferMinThreshold"/>
+ public event EventHandler<MediaStreamBufferStatusChangedEventArgs> BufferStatusChanged;
+
+ /// <summary>
+ /// Occurs when the seeking is requested.
+ /// </summary>
+ /// <remarks>The event handler will be executed on an internal thread.</remarks>
+ public event EventHandler<MediaStreamSeekingOccurredEventArgs> SeekingOccurred;
+
+ /// <summary>
+ /// Gets the max size of the buffer.
+ /// </summary>
+ /// <value>The max size of the buffer. The default is 200000.</value>
+ /// <remarks>If the buffer level over the max size, <see cref="BufferStatusChanged"/> will be raised with <see cref="MediaStreamBufferStatus.Overflow"/>.</remarks>
+ /// <exception cref="InvalidOperationException">The <see cref="MediaStreamSource"/> is not assigned to a player.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">value is zero.</exception>
+ /// <seealso cref="BufferStatusChanged"/>
+ public ulong BufferMaxSize
+ {
+ get
+ {
+ return _bufferMaxSize;
+ }
+ set
+ {
+ if (_owner.Player == null)
+ {
+ throw new InvalidOperationException("The source is not assigned to a player yet.");
+ }
+
+ Debug.Assert(_owner.Player.IsDisposed == false);
+
+ if (value == 0UL)
+ {
+ throw new ArgumentOutOfRangeException(nameof(value), value, "the buffer max size can't be zero.");
+ }
+
+ NativePlayer.SetMediaStreamBufferMaxSize(_owner.Player.Handle, _streamType, value).
+ ThrowIfFailed("Failed to set the buffer max size");
+
+ _bufferMaxSize = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets the min threshold of the buffer or zero if the <see cref="MediaStreamSource"/> is not assigned to a player.
+ /// </summary>
+ /// <value>The minimum threshold of the buffer in percentage. The default is zero.</value>
+ /// <remarks>If the buffer level drops below the threshold value, <see cref="BufferStatusChanged"/> will be raised with <see cref="MediaStreamBufferStatus.Underrun"/>.</remarks>
+ /// <exception cref="InvalidOperationException">The <see cref="MediaStreamSource"/> is not assigned to a player.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">value is greater than 100.</exception>
+ /// <seealso cref="BufferStatusChanged"/>
+ public uint BufferMinThreshold
+ {
+ get
+ {
+ return _threshold;
+ }
+ set
+ {
+ if (_owner.Player == null)
+ {
+ throw new InvalidOperationException("The source is not assigned to a player yet.");
+ }
+
+ Debug.Assert(_owner.Player.IsDisposed == false);
+
+ if (100 < value)
+ {
+ throw new ArgumentOutOfRangeException(nameof(value), value,
+ $"The threshold can't be greater than 100, but got { value }.");
+ }
+
+ NativePlayer.SetMediaStreamBufferMinThreshold(_owner.Player.Handle, _streamType, value).
+ ThrowIfFailed("Failed to set the buffer minimum threshold");
+
+ _threshold = value;
+ }
+ }
+
+ internal void OnPlayerSet(Player player)
+ {
+ if (_streamType == StreamType.Audio)
+ {
+ player.MediaStreamAudioSeekingOccurred += MediaStreamSeekingOccurred;
+ player.MediaStreamAudioBufferStatusChanged += MediaStreamBufferStatusChanged;
+ }
+ else
+ {
+ player.MediaStreamVideoSeekingOccurred += MediaStreamSeekingOccurred;
+ player.MediaStreamVideoBufferStatusChanged += MediaStreamBufferStatusChanged;
+ }
+
+ NativePlayer.SetMediaStreamBufferMaxSize(player.Handle, _streamType, _bufferMaxSize).
+ ThrowIfFailed("Failed to initialize the media stream configuration");
+
+ NativePlayer.SetMediaStreamBufferMinThreshold(player.Handle, _streamType, _threshold).
+ ThrowIfFailed("Failed to initialize the media stream configuration");
+ }
+
+ internal void OnPlayerUnset(Player player)
+ {
+ if (_streamType == StreamType.Audio)
+ {
+ player.MediaStreamAudioSeekingOccurred -= MediaStreamSeekingOccurred;
+ player.MediaStreamAudioBufferStatusChanged -= MediaStreamBufferStatusChanged;
+ }
+ else
+ {
+ player.MediaStreamVideoSeekingOccurred -= MediaStreamSeekingOccurred;
+ player.MediaStreamVideoBufferStatusChanged -= MediaStreamBufferStatusChanged;
+ }
+ }
+
+ private void MediaStreamBufferStatusChanged(object sender, MediaStreamBufferStatusChangedEventArgs e)
+ {
+ BufferStatusChanged?.Invoke(this, e);
+ }
+
+ private void MediaStreamSeekingOccurred(object sender, MediaStreamSeekingOccurredEventArgs e)
+ {
+ SeekingOccurred?.Invoke(this, e);
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaPlayer/Player/MediaStreamSeekingOccurredEventArgs.cs b/src/Tizen.Multimedia.MediaPlayer/Player/MediaStreamSeekingOccurredEventArgs.cs
new file mode 100644
index 0000000..e962250
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaPlayer/Player/MediaStreamSeekingOccurredEventArgs.cs
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides data for the <see cref="MediaStreamConfiguration.SeekingOccurred"/> event.
+ /// </summary>
+ public class MediaStreamSeekingOccurredEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Initializes a new instance of the MediaStreamSeekingOccurredEventArgs class.
+ /// </summary>
+ /// <param name="offset">The value indicating the new position to seek.</param>
+ public MediaStreamSeekingOccurredEventArgs(ulong offset)
+ {
+ Offset = offset;
+ }
+
+ /// <summary>
+ /// Gets the offset.
+ /// </summary>
+ public ulong Offset { get; }
+
+ public override string ToString() => $"Offset : { Offset.ToString() }";
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaPlayer/Player/MediaStreamSource.cs b/src/Tizen.Multimedia.MediaPlayer/Player/MediaStreamSource.cs
new file mode 100644
index 0000000..45946be
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaPlayer/Player/MediaStreamSource.cs
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using static Interop;
+
+namespace Tizen.Multimedia
+{
+
+ /// <summary>
+ /// Provides the ability to push packets as the source of <see cref="Player"/>
+ /// </summary>
+ /// <remarks>The source must be set as a source to a player before pushing.</remarks>
+ /// <seealso cref="Player.SetSource(MediaSource)"/>
+ public sealed class MediaStreamSource : MediaSource
+ {
+ private readonly MediaFormat _audioMediaFormat;
+ private readonly MediaFormat _videoMediaFormat;
+
+ /// <summary>
+ /// Gets all supported audio types.
+ /// </summary>
+ public static IEnumerable<MediaFormatAudioMimeType> SupportedAudioTypes
+ {
+ get
+ {
+ yield return MediaFormatAudioMimeType.Aac;
+ }
+ }
+
+ /// <summary>
+ /// Gets all supported video types.
+ /// </summary>
+ public static IEnumerable<MediaFormatVideoMimeType> SupportedVideoTypes
+ {
+ get
+ {
+ yield return MediaFormatVideoMimeType.H264SP;
+ }
+ }
+
+ private Player _player;
+
+ private MediaStreamConfiguration CreateAudioConfiguration(AudioMediaFormat format)
+ {
+ if( format == null )
+ {
+ return null;
+ }
+
+ if (!SupportedAudioTypes.Contains(format.MimeType))
+ {
+ Log.Error(PlayerLog.Tag, "The audio format is not supported : " + format.MimeType);
+ throw new ArgumentException($"The audio format is not supported, Type : {format.MimeType}.");
+ }
+
+ return new MediaStreamConfiguration(this, StreamType.Audio);
+ }
+
+ private MediaStreamConfiguration CreateVideoConfiguration(VideoMediaFormat format)
+ {
+ if (format == null)
+ {
+ return null;
+ }
+
+ if (!SupportedVideoTypes.Contains(format.MimeType))
+ {
+ Log.Error(PlayerLog.Tag, "The video format is not supported : " + format.MimeType);
+ throw new ArgumentException($"The video format is not supported, Type : {format.MimeType}.");
+ }
+
+ return new MediaStreamConfiguration(this, StreamType.Video);
+ }
+
+
+ /// <summary>
+ /// Initialize a new instance of the MediaStreamSource class
+ /// with the specified <see cref="AudioMediaFormat"/> and <see cref="VideoMediaFormat"/>.
+ /// </summary>
+ /// <param name="audioMediaFormat">The <see cref="AudioMediaFormat"/> for this source.</param>
+ /// <param name="videoMediaFormat">The <see cref="VideoMediaFormat"/> for this source.</param>
+ /// <remarks>AAC and H.264 are supported.</remarks>
+ /// <exception cref="ArgumentNullException">Both <paramref name="audioMediaFormat"/> and <paramref name="videoMediaFormat"/> are null.</exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="audioMediaFormat"/> is not supported.\n
+ /// -or-\n
+ /// <paramref name="videoMediaFormat"/> is not supported.\n
+ /// </exception>
+ /// <seealso cref="SupportedAudioTypes"/>
+ /// <seealso cref="SupportedVideoTypes"/>
+ public MediaStreamSource(AudioMediaFormat audioMediaFormat, VideoMediaFormat videoMediaFormat)
+ {
+ if (audioMediaFormat == null && videoMediaFormat == null)
+ {
+ throw new ArgumentNullException(nameof(audioMediaFormat) + " and " + nameof(videoMediaFormat));
+ }
+
+ _audioMediaFormat = audioMediaFormat;
+ _videoMediaFormat = videoMediaFormat;
+
+ AudioConfiguration = CreateAudioConfiguration(audioMediaFormat);
+ VideoConfiguration = CreateVideoConfiguration(videoMediaFormat);
+ }
+
+ /// <summary>
+ /// Initialize a new instance of the MediaStreamSource class with the specified <see cref="AudioMediaFormat"/>.
+ /// </summary>
+ /// <param name="audioMediaFormat">The <see cref="AudioMediaFormat"/> for this source.</param>
+ /// <remarks>AAC is supported.</remarks>
+ /// <exception cref="ArgumentNullException"><paramref name="audioMediaFormat"/> is null.</exception>
+ /// <exception cref="ArgumentException"><paramref name="audioMediaFormat"/> is not supported.</exception>
+ /// <seealso cref="SupportedAudioTypes"/>
+ public MediaStreamSource(AudioMediaFormat audioMediaFormat)
+ {
+ if (audioMediaFormat == null)
+ {
+ throw new ArgumentNullException(nameof(audioMediaFormat));
+ }
+
+ _audioMediaFormat = audioMediaFormat;
+
+ AudioConfiguration = CreateAudioConfiguration(audioMediaFormat);
+ }
+ /// <summary>
+ /// Initialize a new instance of the MediaStreamSource class with the specified <see cref="VideoMediaFormat"/>.
+ /// </summary>
+ /// <remarks>H.264 can is supported.</remarks>
+ /// <param name="videoMediaFormat">The <see cref="VideoMediaFormat"/> for this source.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="videoMediaFormat"/> is null.</exception>
+ /// <exception cref="ArgumentException"><paramref name="videoMediaFormat"/> is not supported.</exception>
+ /// <seealso cref="SupportedVideoTypes"/>
+ public MediaStreamSource(VideoMediaFormat videoMediaFormat)
+ {
+ if (videoMediaFormat == null)
+ {
+ throw new ArgumentNullException(nameof(videoMediaFormat));
+ }
+
+ _videoMediaFormat = videoMediaFormat;
+
+ VideoConfiguration = CreateVideoConfiguration(videoMediaFormat);
+ }
+
+ /// <summary>
+ /// Gets the audio configuration or null if no AudioMediaFormat is specified in the constructor.
+ /// </summary>
+ public MediaStreamConfiguration AudioConfiguration { get; }
+
+ /// <summary>
+ /// Gets the video configuration or null if no VideoMediaFormat is specified in the constructor.
+ /// </summary>
+ public MediaStreamConfiguration VideoConfiguration { get; }
+
+ /// <summary>
+ /// Pushes elementary stream to decode audio or video.
+ /// </summary>
+ /// <remarks>This source must be set as a source to a player and the player must be in the <see cref="PlayerState.Ready"/>, <see cref="PlayerState.Playing"/> or <see cref="PlayerState.Paused"/> state.</remarks>
+ /// <param name="packet">The <see cref="MediaPacket"/> to decode.</param>
+ /// <exception cref="InvalidOperationException">
+ /// This source is not set as a source to a player.\n
+ /// -or-\n
+ /// The player is not in the valid state.
+ /// </exception>
+ /// <exception cref="ArgumentNullException">packet is null.</exception>
+ /// <exception cref="ObjectDisposedException">packet has been disposed.</exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="packet"/> is neither video nor audio type.\n
+ /// -or-\n
+ /// The format of packet is not matched with the specified format in the constructor.
+ /// </exception>
+ /// <exception cref="NoBufferSpaceException">the internal buffer reaches limits.</exception>
+ /// <seealso cref="Player.SetSource(MediaSource)"/>
+ /// <seealso cref="MediaStreamConfiguration.BufferMaxSize"/>
+ /// <seealso cref="MediaPacket"/>
+ public void Push(MediaPacket packet)
+ {
+ if (_player == null)
+ {
+ Log.Error(PlayerLog.Tag, "The source is not set as a source to a player yet.");
+ throw new InvalidOperationException("The source is not set as a source to a player yet.");
+ }
+ if (packet == null)
+ {
+ Log.Error(PlayerLog.Tag, "packet is null");
+ throw new ArgumentNullException(nameof(packet));
+ }
+ if (packet.IsDisposed)
+ {
+ Log.Error(PlayerLog.Tag, "packet is disposed");
+ throw new ObjectDisposedException(nameof(packet));
+ }
+
+ if (packet.Format.Type == MediaFormatType.Text || packet.Format.Type == MediaFormatType.Container)
+ {
+ Log.Error(PlayerLog.Tag, "The format of the packet is invalid : " + packet.Format.Type);
+ throw new ArgumentException($"The format of the packet is invalid : { packet.Format.Type }.");
+ }
+
+ if (!packet.Format.Equals(_audioMediaFormat) && !packet.Format.Equals(_videoMediaFormat))
+ {
+ Log.Error(PlayerLog.Tag, "The format of the packet is invalid : Unmatched format.");
+ throw new ArgumentException($"The format of the packet is invalid : Unmatched format.");
+ }
+
+ if (packet.Format.Type == MediaFormatType.Video && _videoMediaFormat == null)
+ {
+ Log.Error(PlayerLog.Tag, "Video is not configured with the current source.");
+ throw new ArgumentException("Video is not configured with the current source.");
+ }
+ if (packet.Format.Type == MediaFormatType.Audio && _audioMediaFormat == null)
+ {
+ Log.Error(PlayerLog.Tag, "Audio is not configured with the current source.");
+ throw new ArgumentException("Audio is not configured with the current source.");
+ }
+
+ _player.ValidatePlayerState(PlayerState.Paused, PlayerState.Playing, PlayerState.Ready);
+
+ NativePlayer.PushMediaStream(_player.Handle, packet.GetHandle()).
+ ThrowIfFailed("Failed to push the packet to the player");
+ }
+
+ private void SetMediaStreamInfo(StreamType streamType, MediaFormat mediaFormat)
+ {
+ if (mediaFormat == null)
+ {
+ Log.Error(PlayerLog.Tag, "invalid media format");
+ return;
+ }
+
+ IntPtr ptr = IntPtr.Zero;
+
+ try
+ {
+ ptr = mediaFormat.AsNativeHandle();
+ NativePlayer.SetMediaStreamInfo(_player.Handle, (int)streamType, ptr).
+ ThrowIfFailed("Failed to set the media stream info");
+ }
+ finally
+ {
+ MediaFormat.ReleaseNativeHandle(ptr);
+ }
+ }
+
+ internal override void OnAttached(Player player)
+ {
+ Debug.Assert(player != null);
+
+ if (_player != null)
+ {
+ Log.Error(PlayerLog.Tag, "The source is has already been assigned to another player.");
+ throw new InvalidOperationException("The source is has already been assigned to another player.");
+ }
+
+ AudioConfiguration?.OnPlayerSet(player);
+ VideoConfiguration?.OnPlayerSet(player);
+
+ _player = player;
+
+ SetMediaStreamInfo(StreamType.Audio, _audioMediaFormat);
+ SetMediaStreamInfo(StreamType.Video, _videoMediaFormat);
+ }
+
+ internal override void OnDetached(Player player)
+ {
+ base.OnDetached(player);
+
+ AudioConfiguration?.OnPlayerUnset(player);
+ VideoConfiguration?.OnPlayerUnset(player);
+
+ _player = null;
+ }
+
+ /// <summary>
+ /// Gets the <see cref="Player"/> that this source is assigned to as a source or null if this source is not assigned.
+ /// </summary>
+ /// <seealso cref="Player.SetSource(MediaSource)"/>
+ public Player Player => _player;
+
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaPlayer/Player/MediaUriSource.cs b/src/Tizen.Multimedia.MediaPlayer/Player/MediaUriSource.cs
new file mode 100644
index 0000000..223a10e
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaPlayer/Player/MediaUriSource.cs
@@ -0,0 +1,56 @@
+/// Media Uri source
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using static Interop;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents a media source with a uri.
+ /// </summary>
+ /// <remarks>
+ /// The internet privilege(http://tizen.org/privilege/internet) must be added if any URLs are used to play from network.
+ /// The mediastorage privilege(http://tizen.org/privilege/mediastorage) must be added if any video/audio files are used to play located in the internal storage.
+ /// The externalstorage privilege(http://tizen.org/privilege/externalstorage) must be added if any video/audio files are used to play located in the external storage.
+ /// </remarks>
+ /// <seealso cref="Player.SetSource(MediaSource)"/>
+ public sealed class MediaUriSource : MediaSource
+ {
+ // TODO consider using Uri class.
+ /// <summary>
+ /// Initializes a new instance of the MediaUriSource class with the specified uri.</summary>
+ /// <param name="uri">The uri string.</param>
+ /// <remarks>For HTTP or RSTP, uri should start with "http://" or "rtsp://".
+ /// The default protocol is "file://".
+ /// If you provide an invalid uri, you won't receive an error until <see cref="Player.Start"/> is called.</remarks>
+ public MediaUriSource(string uri)
+ {
+ Uri = uri ?? throw new ArgumentNullException(nameof(uri));
+ }
+
+ /// <summary>
+ /// Gets the uri.
+ /// </summary>
+ public string Uri { get; }
+
+ internal override void OnAttached(Player player)
+ {
+ NativePlayer.SetUri(player.Handle, Uri).ThrowIfFailed("Failed to set the source with specified uri");
+ }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.MediaPlayer/Player/PlaybackInterruptedEventArgs.cs b/src/Tizen.Multimedia.MediaPlayer/Player/PlaybackInterruptedEventArgs.cs
new file mode 100644
index 0000000..8fe0082
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaPlayer/Player/PlaybackInterruptedEventArgs.cs
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides data for the <see cref="Player.PlaybackInterrupted"/> event.
+ /// </summary>
+ public class PlaybackInterruptedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Initializes a new instance of the PlaybackInterruptedEventArgs class.
+ /// </summary>
+ /// <param name="reason">The enum value indicating the reason.</param>
+ public PlaybackInterruptedEventArgs(PlaybackInterruptionReason reason)
+ {
+ Reason = reason;
+ }
+
+ /// <summary>
+ /// Gets the reason.
+ /// </summary>
+ public PlaybackInterruptionReason Reason { get; }
+
+ public override string ToString()
+ {
+ return $"Reason : { Reason.ToString() }";
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaPlayer/Player/Player.cs b/src/Tizen.Multimedia.MediaPlayer/Player/Player.cs
new file mode 100644
index 0000000..ea85757
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaPlayer/Player/Player.cs
@@ -0,0 +1,1317 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.Threading.Tasks;
+using System.Runtime.InteropServices;
+using System.Diagnostics;
+using System.IO;
+using System.Threading;
+using static Interop;
+
+namespace Tizen.Multimedia
+{
+ static internal class PlayerLog
+ {
+ internal const string Tag = "Tizen.Multimedia.Player";
+ internal const string Enter = "[ENTER]";
+ internal const string Leave = "[LEAVE]";
+ }
+
+ /// <summary>
+ /// Provides the ability to control media playback.
+ /// </summary>
+ /// <remarks>
+ /// The Player provides functions to play a media content.
+ /// It also provides functions to adjust the configurations of the player such as playback rate, volume, looping etc.
+ /// Note that only one video player can be played at one time.
+ /// </remarks>
+ public class Player : IDisposable, IDisplayable<PlayerErrorCode>
+ {
+ private PlayerHandle _handle;
+
+ /// <summary>
+ /// Occurs when playback of a media is finished.
+ /// </summary>
+ public event EventHandler<EventArgs> PlaybackCompleted;
+ private NativePlayer.PlaybackCompletedCallback _playbackCompletedCallback;
+
+ /// <summary>
+ /// Occurs when playback of a media is interrupted.
+ /// </summary>
+ public event EventHandler<PlaybackInterruptedEventArgs> PlaybackInterrupted;
+ private NativePlayer.PlaybackInterruptedCallback _playbackInterruptedCallback;
+
+ /// <summary>
+ /// Occurs when any error occurs.
+ /// </summary>
+ /// <remarks>The event handler will be executed on an internal thread.</remarks>
+ public event EventHandler<PlayerErrorOccurredEventArgs> ErrorOccurred;
+ private NativePlayer.PlaybackErrorCallback _playbackErrorCallback;
+
+ /// <summary>
+ /// Occurs when the video stream changed.
+ /// </summary>
+ /// <remarks>The event handler will be executed on an internal thread.</remarks>
+ public event EventHandler<VideoStreamChangedEventArgs> VideoStreamChanged;
+ private NativePlayer.VideoStreamChangedCallback _videoStreamChangedCallback;
+
+ /// <summary>
+ /// Occurs when the subtitle is updated.
+ /// </summary>
+ /// <remarks>The event handler will be executed on an internal thread.</remarks>
+ public EventHandler<SubtitleUpdatedEventArgs> SubtitleUpdated;
+ private NativePlayer.SubtitleUpdatedCallback _subtitleUpdatedCallback;
+
+ /// <summary>
+ /// Occurs when there is a change in the buffering status of streaming.
+ /// </summary>
+ public event EventHandler<BufferingProgressChangedEventArgs> BufferingProgressChanged;
+ private NativePlayer.BufferingProgressCallback _bufferingProgressCallback;
+
+ internal event EventHandler<MediaStreamBufferStatusChangedEventArgs> MediaStreamAudioBufferStatusChanged;
+ private NativePlayer.MediaStreamBufferStatusCallback _mediaStreamAudioBufferStatusChangedCallback;
+
+ internal event EventHandler<MediaStreamBufferStatusChangedEventArgs> MediaStreamVideoBufferStatusChanged;
+ private NativePlayer.MediaStreamBufferStatusCallback _mediaStreamVideoBufferStatusChangedCallback;
+
+ internal event EventHandler<MediaStreamSeekingOccurredEventArgs> MediaStreamAudioSeekingOccurred;
+ private NativePlayer.MediaStreamSeekCallback _mediaStreamAudioSeekCallback;
+
+ internal event EventHandler<MediaStreamSeekingOccurredEventArgs> MediaStreamVideoSeekingOccurred;
+ private NativePlayer.MediaStreamSeekCallback _mediaStreamVideoSeekCallback;
+
+ /// <summary>
+ /// Initialize a new instance of the Player class.
+ /// </summary>
+ public Player()
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+
+ NativePlayer.Create(out _handle).ThrowIfFailed("Failed to create player");
+
+ Debug.Assert(_handle != null);
+
+ RetrieveProperties();
+
+ if (Features.IsSupported(Features.AudioEffect))
+ {
+ _audioEffect = new AudioEffect(this);
+ }
+
+ if (Features.IsSupported(Features.RawVideo))
+ {
+ RegisterVideoFrameDecodedCallback();
+ }
+ }
+
+ private void RetrieveProperties()
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+
+ NativePlayer.GetAudioLatencyMode(Handle, out _audioLatencyMode).
+ ThrowIfFailed("Failed to initialize the player");
+
+ NativePlayer.IsLooping(Handle, out _isLooping).ThrowIfFailed("Failed to initialize the player");
+
+ Log.Debug(PlayerLog.Tag, PlayerLog.Leave);
+ }
+
+ private bool _callbackRegistered;
+
+ private void RegisterCallbacks()
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+
+ if (_callbackRegistered)
+ {
+ return;
+ }
+ RegisterSubtitleUpdatedCallback();
+ RegisterErrorOccurredCallback();
+ RegisterPlaybackInterruptedCallback();
+ RegisterVideoStreamChangedCallback();
+ RegisterBufferingCallback();
+ RegisterMediaStreamBufferStatusCallback();
+ RegisterMediaStreamSeekCallback();
+ RegisterPlaybackCompletedCallback();
+
+ _callbackRegistered = true;
+ }
+
+ public IntPtr Handle
+ {
+ get
+ {
+ ValidateNotDisposed();
+ return _handle.DangerousGetHandle();
+ }
+ }
+
+ internal void ValidatePlayerState(params PlayerState[] desiredStates)
+ {
+ Debug.Assert(desiredStates.Length > 0);
+
+ ValidateNotDisposed();
+
+ var curState = State;
+ if (curState.IsAnyOf(desiredStates))
+ {
+ return;
+ }
+
+ throw new InvalidOperationException($"The player is not in a valid state. " +
+ $"Current State : { curState }, Valid State : { string.Join(", ", desiredStates) }.");
+ }
+
+ #region Properties
+ #region Network configuration
+ private string _cookie = "";
+ private string _userAgent = "";
+
+ /// <summary>
+ /// Gets or Sets the cookie for streaming playback.
+ /// </summary>
+ /// <remarks>To set, the player must be in the <see cref="PlayerState.Idle"/> state.</remarks>
+ /// <exception cref="InvalidOperationException">The player is not in the valid state.</exception>
+ /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
+ /// <exception cref="ArgumentNullException">The value to set is null.</exception>
+ public string Cookie
+ {
+ get
+ {
+ Log.Info(PlayerLog.Tag, "get cookie : " + _cookie);
+ return _cookie;
+ }
+ set
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ ValidatePlayerState(PlayerState.Idle);
+
+ if (value == null)
+ {
+ Log.Error(PlayerLog.Tag, "cookie can't be null");
+ throw new ArgumentNullException(nameof(value), "Cookie can't be null.");
+ }
+
+ NativePlayer.SetStreamingCookie(Handle, value, value.Length).
+ ThrowIfFailed("Failed to set the cookie to the player");
+
+ _cookie = value;
+ Log.Debug(PlayerLog.Tag, PlayerLog.Leave);
+ }
+ }
+
+ /// <summary>
+ /// Gets or Sets the user agent for streaming playback.
+ /// </summary>
+ /// <remarks>To set, the player must be in the <see cref="PlayerState.Idle"/> state.</remarks>
+ /// <exception cref="InvalidOperationException">The player is not in the valid state.</exception>
+ /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
+ /// <exception cref="ArgumentNullException">The value to set is null.</exception>
+ public string UserAgent
+ {
+ get
+ {
+ Log.Info(PlayerLog.Tag, "get useragent : " + _userAgent);
+ return _userAgent;
+ }
+ set
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ ValidatePlayerState(PlayerState.Idle);
+
+ if (value == null)
+ {
+ Log.Error(PlayerLog.Tag, "UserAgent can't be null");
+ throw new ArgumentNullException(nameof(value), "UserAgent can't be null.");
+ }
+
+ NativePlayer.SetStreamingUserAgent(Handle, value, value.Length).
+ ThrowIfFailed("Failed to set the user agent to the player");
+
+ _userAgent = value;
+ Log.Debug(PlayerLog.Tag, PlayerLog.Leave);
+ }
+ }
+ #endregion
+
+ /// <summary>
+ /// Gets the state of the player.
+ /// </summary>
+ /// <value>The current state of the player.</value>
+ /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
+ public PlayerState State
+ {
+ get
+ {
+ ValidateNotDisposed();
+
+ //TODO is this needed?
+ if (IsPreparing())
+ {
+ return PlayerState.Preparing;
+ }
+
+ int state = 0;
+ NativePlayer.GetState(Handle, out state).ThrowIfFailed("Failed to retrieve the state of the player");
+
+ Debug.Assert(Enum.IsDefined(typeof(PlayerState), state));
+
+ return (PlayerState)state;
+ }
+ }
+
+ private AudioLatencyMode _audioLatencyMode;
+
+ /// <summary>
+ /// Gets or sets the audio latency mode.
+ /// </summary>
+ /// <value>A <see cref="AudioLatencyMode"/> that specifies the mode. The default is <see cref="AudioLatencyMode.Mid"/>.</value>
+ /// <remarks>
+ /// If the mode is <see cref="AudioLatencyMode.High"/>,
+ /// audio output interval can be increased so, it can keep more audio data to play.
+ /// But, state transition like pause or resume can be more slower than default(<see cref="AudioLatencyMode.Mid"/>).
+ /// </remarks>
+ /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
+ /// <exception cref="ArgumentException">The value is not valid.</exception>
+ public AudioLatencyMode AudioLatencyMode
+ {
+ get
+ {
+ Log.Info(PlayerLog.Tag, "get audio latency mode : " + _audioLatencyMode);
+ return _audioLatencyMode;
+ }
+ set
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ ValidateNotDisposed();
+
+ if (_audioLatencyMode == value)
+ {
+ return;
+ }
+ ValidationUtil.ValidateEnum(typeof(AudioLatencyMode), value);
+
+ NativePlayer.SetAudioLatencyMode(Handle, value).
+ ThrowIfFailed("Failed to set the audio latency mode of the player");
+
+ _audioLatencyMode = value;
+ }
+ }
+
+ private bool _isLooping;
+
+ /// <summary>
+ /// Gets or sets the looping state.
+ /// </summary>
+ /// <value>true if the playback is looping; otherwise, false. The default value is false.</value>
+ /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
+ public bool IsLooping
+ {
+ get
+ {
+ Log.Info(PlayerLog.Tag, "get looping : " + _isLooping);
+ return _isLooping;
+ }
+ set
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ ValidateNotDisposed();
+
+ if (_isLooping == value)
+ {
+ return;
+ }
+
+ NativePlayer.SetLooping(Handle, value).ThrowIfFailed("Failed to set the looping state of the player");
+
+ _isLooping = value;
+ }
+ }
+
+ #region Display methods
+ /// <summary>
+ /// Gets the display settings.
+ /// </summary>
+ /// <value>A <see cref="PlayerDisplaySettings"/> that specifies the display settings.</value>
+ public PlayerDisplaySettings DisplaySettings { get; }
+
+ private Display _display;
+
+ private PlayerErrorCode SetDisplay(Display display)
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ if (display == null)
+ {
+ Log.Info(PlayerLog.Tag, "set display to none");
+ return NativePlayer.SetDisplay(Handle, DisplayType.None, IntPtr.Zero);
+ }
+
+ return display.ApplyTo(this);
+ }
+
+ private void ReplaceDisplay(Display newDisplay)
+ {
+ if (_display != null)
+ {
+ _display.Owner = null;
+ }
+ _display = newDisplay;
+ if (_display != null)
+ {
+ _display.Owner = this;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the display.
+ /// </summary>
+ /// <value>A <see cref="Multimedia.Display"/> that specifies the display.</value>
+ /// <remarks>The player must be in the <see cref="PlayerState.Idle"/> state.</remarks>
+ /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
+ /// <exception cref="ArgumentException">The value has already been assigned to another player.</exception>
+ /// <exception cref="InvalidOperationException">The player is not in the valid state.</exception>
+ public Display Display
+ {
+ get
+ {
+ return _display;
+ }
+ set
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ ValidatePlayerState(PlayerState.Idle);
+
+ if (value != null && value.Owner != null)
+ {
+ if (ReferenceEquals(this, value.Owner))
+ {
+ return;
+ }
+ else
+ {
+ throw new ArgumentException("The display has already been assigned to another.");
+ }
+ }
+
+ SetDisplay(value).ThrowIfFailed("Failed to set the display to the player");
+
+ ReplaceDisplay(value);
+ Log.Debug(PlayerLog.Tag, PlayerLog.Leave);
+ }
+ }
+
+ PlayerErrorCode IDisplayable<PlayerErrorCode>.ApplyEvasDisplay(DisplayType type, ElmSharp.EvasObject evasObject)
+ {
+ Debug.Assert(IsDisposed == false);
+
+ Debug.Assert(Enum.IsDefined(typeof(DisplayType), type));
+
+ return NativePlayer.SetDisplay(Handle, type, evasObject);
+ }
+ #endregion
+
+ private PlayerTrackInfo _audioTrack;
+
+ /// <summary>
+ /// Gets the track info for audio.
+ /// </summary>
+ /// <value>A <see cref="PlayerTrackInfo"/> for audio.</value>
+ public PlayerTrackInfo AudioTrackInfo
+ {
+ get
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ if (_audioTrack == null)
+ {
+ _audioTrack = new PlayerTrackInfo(this, StreamType.Audio);
+ }
+ return _audioTrack;
+ }
+ }
+
+ private PlayerTrackInfo _subtitleTrackInfo;
+
+ /// <summary>
+ /// Gets the track info for subtitle.
+ /// </summary>
+ /// <value>A <see cref="PlayerTrackInfo"/> for subtitle.</value>
+ public PlayerTrackInfo SubtitleTrackInfo
+ {
+ get
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ if (_subtitleTrackInfo == null)
+ {
+ _subtitleTrackInfo = new PlayerTrackInfo(this, StreamType.Text);
+ }
+ return _subtitleTrackInfo;
+ }
+ }
+
+ private StreamInfo _streamInfo;
+
+ /// <summary>
+ /// Gets the stream information.
+ /// </summary>
+ /// <value>A <see cref="StreamInfo"/> for this player.</value>
+ public StreamInfo StreamInfo
+ {
+ get
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ if (_streamInfo == null)
+ {
+ _streamInfo = new StreamInfo(this);
+ }
+ return _streamInfo;
+ }
+ }
+
+ private readonly AudioEffect _audioEffect;
+
+ /// <summary>
+ /// Gets the audio effect.
+ /// </summary>
+ /// <feature>http://tizen.org/feature/multimedia.custom_audio_effect</feature>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ public AudioEffect AudioEffect
+ {
+ get
+ {
+ if (_audioEffect == null)
+ {
+ throw new NotSupportedException($"The feature({Features.AudioEffect}) is not supported.");
+ }
+
+ return _audioEffect;
+ }
+ }
+
+ #endregion
+
+ #region Dispose support
+ private bool _disposed;
+
+ public void Dispose()
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ Dispose(true);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ ReplaceDisplay(null);
+
+ if (_source != null)
+ {
+ try
+ {
+ _source.DetachFrom(this);
+ }
+ catch (Exception e)
+ {
+ Log.Error(PlayerLog.Tag, e.ToString());
+ }
+ }
+ _source = null;
+
+ if (_handle != null)
+ {
+ _handle.Dispose();
+ }
+ _disposed = true;
+ }
+ }
+
+ internal void ValidateNotDisposed()
+ {
+ if (_disposed)
+ {
+ Log.Warn(PlayerLog.Tag, "player was disposed");
+ throw new ObjectDisposedException(nameof(Player));
+ }
+ }
+
+ internal bool IsDisposed => _disposed;
+ #endregion
+
+ #region Methods
+
+ /// <summary>
+ /// Gets or sets the mute state.
+ /// </summary>
+ /// <value>true if the player is muted; otherwise, false.</value>
+ /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
+ public bool Muted
+ {
+ get
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+
+ bool value = false;
+ NativePlayer.IsMuted(Handle, out value).ThrowIfFailed("Failed to get the mute state of the player");
+
+ Log.Info(PlayerLog.Tag, "get mute : " + value);
+
+ return value;
+ }
+ set
+ {
+ NativePlayer.SetMute(Handle, value).ThrowIfFailed("Failed to set the mute state of the player");
+ }
+ }
+
+ /// <summary>
+ /// Get Streaming download Progress.
+ /// </summary>
+ /// <remarks>The player must be in the <see cref="PlayerState.Playing"/> or <see cref="PlayerState.Paused"/> state.</remarks>
+ /// <exception cref="InvalidOperationException">
+ /// The player is not streaming.\n
+ /// -or-\n
+ /// The player is not in the valid state.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
+ public DownloadProgress GetDownloadProgress()
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ ValidatePlayerState(PlayerState.Playing, PlayerState.Paused);
+
+ int start = 0;
+ int current = 0;
+ NativePlayer.GetStreamingDownloadProgress(Handle, out start, out current).
+ ThrowIfFailed("Failed to get download progress");
+
+ Log.Info(PlayerLog.Tag, "get download progress : " + start + ", " + current);
+
+ return new DownloadProgress(start, current);
+ }
+
+ #region Volume
+ /// <summary>
+ /// Gets or sets the current volume.
+ /// </summary>
+ /// <remarks>Valid volume range is from 0 to 1.0, inclusive.</remarks>
+ /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="value"/> is less than zero.\n
+ /// -or-\n
+ /// <paramref name="value"/> is greater than 1.0.
+ /// </exception>
+ public float Volume
+ {
+ get
+ {
+ float value = 0.0F;
+ NativePlayer.GetVolume(Handle, out value, out value).
+ ThrowIfFailed("Failed to get the volume of the player");
+ return value;
+ }
+ set
+ {
+ if (value < 0F || 1.0F < value)
+ {
+ throw new ArgumentOutOfRangeException(nameof(value), value,
+ $"Valid volume range is 0 <= value <= 1.0, but got { value }.");
+ }
+
+ NativePlayer.SetVolume(Handle, value, value).
+ ThrowIfFailed("Failed to set the volume of the player");
+ }
+ }
+
+ #endregion
+
+ /// <summary>
+ /// Sets the subtitle path for playback.
+ /// </summary>
+ /// <remarks>Only MicroDVD/SubViewer(*.sub), SAMI(*.smi), and SubRip(*.srt) subtitle formats are supported.
+ /// <para>The mediastorage privilege(http://tizen.org/privilege/mediastorage) must be added if any files are used to play located in the internal storage.
+ /// The externalstorage privilege(http://tizen.org/privilege/externalstorage) must be added if any files are used to play located in the external storage.</para>
+ /// </remarks>
+ /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
+ /// <exception cref="ArgumentException"><paramref name="path"/> is an empty string.</exception>
+ /// <exception cref="FileNotFoundException">The specified path does not exist.</exception>
+ /// <exception cref="ArgumentNullException">The path is null.</exception>
+ public void SetSubtitle(string path)
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ ValidateNotDisposed();
+
+ if (path == null)
+ {
+ throw new ArgumentNullException(nameof(path));
+ }
+
+ if (path.Length == 0)
+ {
+ throw new ArgumentException("The path is empty.", nameof(path));
+ }
+
+ if (!File.Exists(path))
+ {
+ throw new FileNotFoundException($"The specified file does not exist.", path);
+ }
+
+ NativePlayer.SetSubtitlePath(Handle, path).
+ ThrowIfFailed("Failed to set the subtitle path to the player");
+
+ Log.Debug(PlayerLog.Tag, PlayerLog.Leave);
+ }
+
+ /// <summary>
+ /// Removes the subtitle path.
+ /// </summary>
+ /// <remarks>The player must be in the <see cref="PlayerState.Idle"/> state.</remarks>
+ /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
+ /// <exception cref="InvalidOperationException">The player is not in the valid state.</exception>
+ public void ClearSubtitle()
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ ValidatePlayerState(PlayerState.Idle);
+
+ NativePlayer.SetSubtitlePath(Handle, null).
+ ThrowIfFailed("Failed to clear the subtitle of the player");
+ Log.Debug(PlayerLog.Tag, PlayerLog.Leave);
+ }
+
+ /// <summary>
+ /// Sets the offset for the subtitle.
+ /// </summary>
+ /// <remarks>The player must be in the <see cref="PlayerState.Playing"/> or <see cref="PlayerState.Paused"/> state.</remarks>
+ /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
+ /// <exception cref="InvalidOperationException">
+ /// The player is not in the valid state.\n
+ /// -or-\n
+ /// No subtitle is set.
+ /// </exception>
+ /// <seealso cref="SetSubtitle(string)"/>
+ public void SetSubtitleOffset(int offset)
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ ValidatePlayerState(PlayerState.Playing, PlayerState.Paused);
+
+ var err = NativePlayer.SetSubtitlePositionOffset(Handle, offset);
+
+ if (err == PlayerErrorCode.FeatureNotSupported)
+ {
+ throw new InvalidOperationException("No subtitle set");
+ }
+
+ err.ThrowIfFailed("Failed to the subtitle offset of the player");
+ Log.Debug(PlayerLog.Tag, PlayerLog.Leave);
+ }
+
+ private void Prepare()
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ NativePlayer.Prepare(Handle).ThrowIfFailed("Failed to prepare the player");
+ }
+
+ protected virtual void OnPreparing()
+ {
+ RegisterCallbacks();
+ }
+
+ /// <summary>
+ /// Prepares the media player for playback, asynchronously.
+ /// </summary>
+ /// <remarks>To prepare the player, the player must be in the <see cref="PlayerState.Idle"/> state,
+ /// and a source must be set.</remarks>
+ /// <exception cref="InvalidOperationException">No source is set.</exception>
+ /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
+ /// <exception cref="InvalidOperationException">The player is not in the valid state.</exception>
+ public virtual Task PrepareAsync()
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ if (_source == null)
+ {
+ throw new InvalidOperationException("No source is set.");
+ }
+
+ ValidatePlayerState(PlayerState.Idle);
+
+ OnPreparing();
+
+ var completionSource = new TaskCompletionSource<bool>();
+
+ SetPreparing();
+
+ Task.Run(() =>
+ {
+ try
+ {
+ Prepare();
+ ClearPreparing();
+ completionSource.SetResult(true);
+ }
+ catch (Exception e)
+ {
+ ClearPreparing();
+ completionSource.TrySetException(e);
+ }
+ });
+ Log.Debug(PlayerLog.Tag, PlayerLog.Leave);
+
+ return completionSource.Task;
+ }
+
+ /// <summary>
+ /// Unprepares the player.
+ /// </summary>
+ /// <remarks>
+ /// The most recently used source is reset and no longer associated with the player. Playback is no longer possible.
+ /// If you want to use the player again, you have to set a source and call <see cref="PrepareAsync"/> again.
+ /// <para>
+ /// The player must be in the <see cref="PlayerState.Ready"/>, <see cref="PlayerState.Playing"/> or <see cref="PlayerState.Paused"/> state.
+ /// It has no effect if the player is already in the <see cref="PlayerState.Idle"/> state.
+ /// </para>
+ /// </remarks>
+ /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
+ /// <exception cref="InvalidOperationException">The player is not in the valid state.</exception>
+ public virtual void Unprepare()
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ if (State == PlayerState.Idle)
+ {
+ Log.Warn(PlayerLog.Tag, "idle state already");
+ return;
+ }
+ ValidatePlayerState(PlayerState.Ready, PlayerState.Paused, PlayerState.Playing);
+
+ NativePlayer.Unprepare(Handle).ThrowIfFailed("Failed to unprepare the player");
+
+ OnUnprepared();
+ }
+
+ protected virtual void OnUnprepared()
+ {
+ _source?.DetachFrom(this);
+ _source = null;
+ }
+
+ //TODO remarks needs to be updated. see the native reference.
+ /// <summary>
+ /// Starts or resumes playback.
+ /// </summary>
+ /// <remarks>
+ /// The player must be in the <see cref="PlayerState.Ready"/> or <see cref="PlayerState.Paused"/> state.
+ /// It has no effect if the player is already in the <see cref="PlayerState.Playing"/> state.
+ /// </remarks>
+ /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
+ /// <exception cref="InvalidOperationException">The player is not in the valid state.</exception>
+ /// <seealso cref="PrepareAsync"/>
+ /// <seealso cref="Stop"/>
+ /// <seealso cref="Pause"/>
+ /// <seealso cref="PlaybackCompleted"/>
+ public virtual void Start()
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ if (State == PlayerState.Playing)
+ {
+ Log.Warn(PlayerLog.Tag, "playing state already");
+ return;
+ }
+ ValidatePlayerState(PlayerState.Ready, PlayerState.Paused);
+
+ NativePlayer.Start(Handle).ThrowIfFailed("Failed to start the player");
+ Log.Debug(PlayerLog.Tag, PlayerLog.Leave);
+ }
+
+ /// <summary>
+ /// Stops playing media content.
+ /// </summary>
+ /// <remarks>
+ /// The player must be in the <see cref="PlayerState.Playing"/> or <see cref="PlayerState.Paused"/> state.
+ /// It has no effect if the player is already in the <see cref="PlayerState.Ready"/> state.
+ /// </remarks>
+ /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
+ /// <exception cref="InvalidOperationException">The player is not in the valid state.</exception>
+ /// <seealso cref="Start"/>
+ /// <seealso cref="Pause"/>
+ public virtual void Stop()
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ if (State == PlayerState.Ready)
+ {
+ Log.Warn(PlayerLog.Tag, "ready state already");
+ return;
+ }
+ ValidatePlayerState(PlayerState.Paused, PlayerState.Playing);
+
+ NativePlayer.Stop(Handle).ThrowIfFailed("Failed to stop the player");
+ Log.Debug(PlayerLog.Tag, PlayerLog.Leave);
+ }
+
+ /// <summary>
+ /// Pauses the player.
+ /// </summary>
+ /// <remarks>
+ /// The player must be in the <see cref="PlayerState.Playing"/> state.
+ /// It has no effect if the player is already in the <see cref="PlayerState.Paused"/> state.
+ /// </remarks>
+ /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
+ /// <exception cref="InvalidOperationException">The player is not in the valid state.</exception>
+ /// <seealso cref="Start"/>
+ public virtual void Pause()
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ if (State == PlayerState.Paused)
+ {
+ Log.Warn(PlayerLog.Tag, "pause state already");
+ return;
+ }
+
+ ValidatePlayerState(PlayerState.Playing);
+
+ NativePlayer.Pause(Handle).ThrowIfFailed("Failed to pause the player");
+ Log.Debug(PlayerLog.Tag, PlayerLog.Leave);
+ }
+
+ private MediaSource _source;
+
+ /// <summary>
+ /// Sets a media source for the player.
+ /// </summary>
+ /// <param name="source">A <see cref="MediaSource"/> that specifies the source for playback.</param>
+ /// <remarks>The player must be in the <see cref="PlayerState.Idle"/> state.</remarks>
+ /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
+ /// <exception cref="InvalidOperationException">
+ /// The player is not in the valid state.\n
+ /// -or-\n
+ /// It is not able to assign the source to the player.
+ /// </exception>
+ /// <seealso cref="PrepareAsync"/>
+ public void SetSource(MediaSource source)
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ ValidatePlayerState(PlayerState.Idle);
+
+ if (source != null)
+ {
+ source.AttachTo(this);
+ }
+
+ if (_source != null)
+ {
+ _source.DetachFrom(this);
+ }
+
+ _source = source;
+ Log.Debug(PlayerLog.Tag, PlayerLog.Leave);
+ }
+
+ /// <summary>
+ /// Captures a video frame asynchronously.
+ /// </summary>
+ /// <feature>http://tizen.org/feature/multimedia.raw_video</feature>
+ /// <remarks>The player must be in the <see cref="PlayerState.Playing"/> or <see cref="PlayerState.Paused"/> state.</remarks>
+ /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
+ /// <exception cref="InvalidOperationException">The player is not in the valid state.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ public async Task<CapturedFrame> CaptureVideoAsync()
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+
+ ValidationUtil.ValidateFeatureSupported(Features.RawVideo);
+
+ ValidatePlayerState(PlayerState.Playing, PlayerState.Paused);
+
+ TaskCompletionSource<CapturedFrame> t = new TaskCompletionSource<CapturedFrame>();
+
+ NativePlayer.VideoCaptureCallback cb = (data, width, height, size, _) =>
+ {
+ Debug.Assert(size <= int.MaxValue);
+
+ byte[] buf = new byte[size];
+ Marshal.Copy(data, buf, 0, (int)size);
+
+ t.TrySetResult(new CapturedFrame(buf, width, height));
+ };
+
+ using (var cbKeeper = ObjectKeeper.Get(cb))
+ {
+ NativePlayer.CaptureVideo(Handle, cb)
+ .ThrowIfFailed("Failed to capture the video");
+
+ return await t.Task;
+ }
+ }
+
+ /// <summary>
+ /// Gets the play position in milliseconds.
+ /// </summary>
+ /// <remarks>The player must be in the <see cref="PlayerState.Ready"/>, <see cref="PlayerState.Playing"/> or <see cref="PlayerState.Paused"/> state.</remarks>
+ /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
+ /// <exception cref="InvalidOperationException">The player is not in the valid state.</exception>
+ /// <seealso cref="SetPlayPositionAsync(int, bool)"/>
+ public int GetPlayPosition()
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ ValidatePlayerState(PlayerState.Ready, PlayerState.Paused, PlayerState.Playing);
+
+ int playPosition = 0;
+
+ NativePlayer.GetPlayPosition(Handle, out playPosition).
+ ThrowIfFailed("Failed to get the play position of the player");
+
+ Log.Info(PlayerLog.Tag, "get play position : " + playPosition);
+
+ return playPosition;
+ }
+
+ private void SetPlayPosition(int milliseconds, bool accurate,
+ NativePlayer.SeekCompletedCallback cb)
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ var ret = NativePlayer.SetPlayPosition(Handle, milliseconds, accurate, cb, IntPtr.Zero);
+
+ //Note that we assume invalid param error is returned only when the position value is invalid.
+ if (ret == PlayerErrorCode.InvalidArgument)
+ {
+ throw new ArgumentOutOfRangeException(nameof(milliseconds), milliseconds,
+ "The position is not valid.");
+ }
+ if (ret != PlayerErrorCode.None)
+ {
+ Log.Error(PlayerLog.Tag, "Failed to set play position, " + (PlayerError)ret);
+ }
+ ret.ThrowIfFailed("Failed to set play position");
+ }
+
+ /// <summary>
+ /// Sets the seek position for playback, asynchronously.
+ /// </summary>
+ /// <param name="position">The value indicating a desired position in milliseconds.</param>
+ /// <param name="accurate">The value indicating whether the operation performs with accuracy.</param>
+ /// <remarks>
+ /// <para>The player must be in the <see cref="PlayerState.Ready"/>, <see cref="PlayerState.Playing"/> or <see cref="PlayerState.Paused"/> state.</para>
+ /// <para>If the <paramref name="accurate"/> is true, the play position will be adjusted as the specified <paramref name="position"/> value,
+ /// but this might be considerably slow. If false, the play position will be a nearest keyframe position.</para>
+ /// </remarks>
+ /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
+ /// <exception cref="InvalidOperationException">The player is not in the valid state.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">The specified position is not valid.</exception>
+ /// <seealso cref="GetPlayPosition"/>
+ public async Task SetPlayPositionAsync(int position, bool accurate)
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ ValidatePlayerState(PlayerState.Ready, PlayerState.Playing, PlayerState.Paused);
+
+ var taskCompletionSource = new TaskCompletionSource<bool>();
+
+ bool immediateResult = _source is MediaStreamSource;
+
+ NativePlayer.SeekCompletedCallback cb = _ => taskCompletionSource.TrySetResult(true);
+
+ using (var cbKeeper = ObjectKeeper.Get(cb))
+ {
+ SetPlayPosition(position, accurate, cb);
+ if (immediateResult)
+ {
+ taskCompletionSource.TrySetResult(true);
+ }
+
+ await taskCompletionSource.Task;
+ }
+
+ Log.Debug(PlayerLog.Tag, PlayerLog.Leave);
+ }
+
+ /// <summary>
+ /// Sets playback rate.
+ /// </summary>
+ /// <param name="rate">The value for the playback rate. Valid range is -5.0 to 5.0, inclusive.</param>
+ /// <remarks>
+ /// <para>The player must be in the <see cref="PlayerState.Ready"/>, <see cref="PlayerState.Playing"/> or <see cref="PlayerState.Paused"/> state.</para>
+ /// <para>The sound will be muted, when the playback rate is under 0.0 or over 2.0.</para>
+ /// </remarks>
+ /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
+ /// <exception cref="InvalidOperationException">
+ /// The player is not in the valid state.\n
+ /// -or-\n
+ /// Streaming playback.
+ /// </exception>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="rate"/> is less than 5.0.\n
+ /// -or-\n
+ /// <paramref name="rate"/> is greater than 5.0.\n
+ /// -or-\n
+ /// <paramref name="rate"/> is zero.
+ /// </exception>
+ public void SetPlaybackRate(float rate)
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ if (rate < -5.0F || 5.0F < rate || rate == 0.0F)
+ {
+ throw new ArgumentOutOfRangeException(nameof(rate), rate, "Valid range is -5.0 to 5.0 (except 0.0)");
+ }
+
+ ValidatePlayerState(PlayerState.Ready, PlayerState.Playing, PlayerState.Paused);
+
+ NativePlayer.SetPlaybackRate(Handle, rate).ThrowIfFailed("Failed to set the playback rate.");
+ Log.Debug(PlayerLog.Tag, PlayerLog.Leave);
+ }
+
+ /// <summary>
+ /// Applies the audio stream policy.
+ /// </summary>
+ /// <param name="policy">The <see cref="AudioStreamPolicy"/> to apply.</param>
+ /// <remarks>The player must be in the <see cref="PlayerState.Idle"/> state.</remarks>
+ /// <exception cref="ObjectDisposedException">
+ /// The player has already been disposed of.\n
+ /// -or-\n
+ /// <paramref name="policy"/> has already been disposed of.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">The player is not in the valid state.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="policy"/> is null.</exception>
+ public void ApplyAudioStreamPolicy(AudioStreamPolicy policy)
+ {
+ Log.Debug(PlayerLog.Tag, PlayerLog.Enter);
+ if (policy == null)
+ {
+ throw new ArgumentNullException(nameof(policy));
+ }
+
+ if (policy.Handle == IntPtr.Zero)
+ {
+ throw new ObjectDisposedException(nameof(policy));
+ }
+
+ ValidatePlayerState(PlayerState.Idle);
+
+ NativePlayer.SetAudioPolicyInfo(Handle, policy.Handle).
+ ThrowIfFailed("Failed to set the audio stream policy to the player");
+ }
+ #endregion
+
+ #region Callback registrations
+ private void RegisterSubtitleUpdatedCallback()
+ {
+ _subtitleUpdatedCallback = (duration, text, _) =>
+ {
+ Log.Debug(PlayerLog.Tag, "duration : " + duration + ", text : " + text);
+ SubtitleUpdated?.Invoke(this, new SubtitleUpdatedEventArgs(duration, text));
+ };
+
+ NativePlayer.SetSubtitleUpdatedCb(Handle, _subtitleUpdatedCallback).
+ ThrowIfFailed("Failed to initialize the player");
+ }
+
+ private void RegisterPlaybackCompletedCallback()
+ {
+ _playbackCompletedCallback = _ =>
+ {
+ Log.Debug(PlayerLog.Tag, "completed callback");
+ PlaybackCompleted?.Invoke(this, EventArgs.Empty);
+ };
+ NativePlayer.SetCompletedCb(Handle, _playbackCompletedCallback).
+ ThrowIfFailed("Failed to set PlaybackCompleted");
+ }
+
+ private void RegisterPlaybackInterruptedCallback()
+ {
+ _playbackInterruptedCallback = (code, _) =>
+ {
+ if (!Enum.IsDefined(typeof(PlaybackInterruptionReason), code))
+ {
+ return;
+ }
+
+ if (code == PlaybackInterruptionReason.ResourceConflict)
+ {
+ OnUnprepared();
+ }
+
+ Log.Warn(PlayerLog.Tag, "interrupted reason : " + code);
+ PlaybackInterrupted?.Invoke(this, new PlaybackInterruptedEventArgs(code));
+ };
+
+ NativePlayer.SetInterruptedCb(Handle, _playbackInterruptedCallback).
+ ThrowIfFailed("Failed to set PlaybackInterrupted");
+ }
+
+ private void RegisterErrorOccurredCallback()
+ {
+ _playbackErrorCallback = (code, _) =>
+ {
+ //TODO handle service disconnected error.
+ Log.Warn(PlayerLog.Tag, "error code : " + code);
+ ErrorOccurred?.Invoke(this, new PlayerErrorOccurredEventArgs((PlayerError)code));
+ };
+
+ NativePlayer.SetErrorCb(Handle, _playbackErrorCallback).
+ ThrowIfFailed("Failed to set PlaybackError");
+ }
+
+ #region VideoFrameDecoded event
+
+ private EventHandler<VideoFrameDecodedEventArgs> _videoFrameDecoded;
+
+ private NativePlayer.VideoFrameDecodedCallback _videoFrameDecodedCallback;
+
+ /// <summary>
+ /// Occurs when a video frame is decoded.
+ /// </summary>
+ /// <remarks>
+ /// <para>The event handler will be executed on an internal thread.</para>
+ /// <para>The <see cref="VideoFrameDecodedEventArgs.Packet"/> in event args should be disposed after use.</para>
+ /// </remarks>
+ /// <feature>http://tizen.org/feature/multimedia.raw_video</feature>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <seealso cref="VideoFrameDecodedEventArgs.Packet"/>
+ public event EventHandler<VideoFrameDecodedEventArgs> VideoFrameDecoded
+ {
+ add
+ {
+ ValidationUtil.ValidateFeatureSupported(Features.RawVideo);
+
+ _videoFrameDecoded += value;
+ }
+ remove
+ {
+ ValidationUtil.ValidateFeatureSupported(Features.RawVideo);
+
+ _videoFrameDecoded -= value;
+ }
+ }
+
+ private void RegisterVideoFrameDecodedCallback()
+ {
+ _videoFrameDecodedCallback = (packetHandle, _) =>
+ {
+ var handler = _videoFrameDecoded;
+ if (handler != null)
+ {
+ Log.Debug(PlayerLog.Tag, "packet : " + packetHandle);
+ handler.Invoke(this,
+ new VideoFrameDecodedEventArgs(MediaPacket.From(packetHandle)));
+ }
+ else
+ {
+ MediaPacket.From(packetHandle).Dispose();
+ }
+ };
+
+ NativePlayer.SetVideoFrameDecodedCb(Handle, _videoFrameDecodedCallback).
+ ThrowIfFailed("Failed to register the VideoFrameDecoded");
+ }
+ #endregion
+
+ private void RegisterVideoStreamChangedCallback()
+ {
+ ValidatePlayerState(PlayerState.Idle);
+
+ _videoStreamChangedCallback = (width, height, fps, bitrate, _) =>
+ {
+ Log.Debug(PlayerLog.Tag, "height : " + height + ", width : " + width
+ + ", fps : " + fps + ", bitrate : " + bitrate);
+
+ VideoStreamChanged?.Invoke(this, new VideoStreamChangedEventArgs(height, width, fps, bitrate));
+ };
+
+ NativePlayer.SetVideoStreamChangedCb(Handle, _videoStreamChangedCallback).
+ ThrowIfFailed("Failed to set the video stream changed callback");
+ }
+
+ private void RegisterBufferingCallback()
+ {
+ _bufferingProgressCallback = (percent, _) =>
+ {
+ Log.Debug(PlayerLog.Tag, $"Buffering callback with percent { percent }");
+ BufferingProgressChanged?.Invoke(this, new BufferingProgressChangedEventArgs(percent));
+ };
+
+ NativePlayer.SetBufferingCb(Handle, _bufferingProgressCallback).
+ ThrowIfFailed("Failed to set BufferingProgress");
+ }
+
+ private void RegisterMediaStreamBufferStatusCallback()
+ {
+ _mediaStreamAudioBufferStatusChangedCallback = (status, _) =>
+ {
+ Debug.Assert(Enum.IsDefined(typeof(MediaStreamBufferStatus), status));
+ Log.Debug(PlayerLog.Tag, "audio buffer status : " + status);
+ MediaStreamAudioBufferStatusChanged?.Invoke(this,
+ new MediaStreamBufferStatusChangedEventArgs(status));
+ };
+ _mediaStreamVideoBufferStatusChangedCallback = (status, _) =>
+ {
+ Debug.Assert(Enum.IsDefined(typeof(MediaStreamBufferStatus), status));
+ Log.Debug(PlayerLog.Tag, "video buffer status : " + status);
+ MediaStreamVideoBufferStatusChanged?.Invoke(this,
+ new MediaStreamBufferStatusChangedEventArgs(status));
+ };
+
+ RegisterMediaStreamBufferStatusCallback(StreamType.Audio, _mediaStreamAudioBufferStatusChangedCallback);
+ RegisterMediaStreamBufferStatusCallback(StreamType.Video, _mediaStreamVideoBufferStatusChangedCallback);
+ }
+
+ private void RegisterMediaStreamBufferStatusCallback(StreamType streamType,
+ NativePlayer.MediaStreamBufferStatusCallback cb)
+ {
+ NativePlayer.SetMediaStreamBufferStatusCb(Handle, streamType, cb).
+ ThrowIfFailed("Failed to SetMediaStreamBufferStatus");
+ }
+
+ private void RegisterMediaStreamSeekCallback()
+ {
+ _mediaStreamAudioSeekCallback = (offset, _) =>
+ {
+ Log.Debug(PlayerLog.Tag, "audio seeking offset : " + offset);
+ MediaStreamAudioSeekingOccurred?.Invoke(this, new MediaStreamSeekingOccurredEventArgs(offset));
+ };
+ _mediaStreamVideoSeekCallback = (offset, _) =>
+ {
+ Log.Debug(PlayerLog.Tag, "video seeking offset : " + offset);
+ MediaStreamVideoSeekingOccurred?.Invoke(this, new MediaStreamSeekingOccurredEventArgs(offset));
+ };
+
+ RegisterMediaStreamSeekCallback(StreamType.Audio, _mediaStreamAudioSeekCallback);
+ RegisterMediaStreamSeekCallback(StreamType.Video, _mediaStreamVideoSeekCallback);
+ }
+
+ private void RegisterMediaStreamSeekCallback(StreamType streamType, NativePlayer.MediaStreamSeekCallback cb)
+ {
+ NativePlayer.SetMediaStreamSeekCb(Handle, streamType, cb).
+ ThrowIfFailed("Failed to SetMediaStreamSeek");
+ }
+ #endregion
+
+ #region Preparing state
+
+ private int _isPreparing;
+
+ private bool IsPreparing()
+ {
+ return Interlocked.CompareExchange(ref _isPreparing, 1, 1) == 1;
+ }
+
+ private void SetPreparing()
+ {
+ Interlocked.Exchange(ref _isPreparing, 1);
+ }
+
+ private void ClearPreparing()
+ {
+ Interlocked.Exchange(ref _isPreparing, 0);
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaPlayer/Player/PlayerDisplaySettings.cs b/src/Tizen.Multimedia.MediaPlayer/Player/PlayerDisplaySettings.cs
new file mode 100644
index 0000000..e4581d3
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaPlayer/Player/PlayerDisplaySettings.cs
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Diagnostics;
+using Native = Interop.Display;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides a means to configure display settings for video <see cref="Player"/>.
+ /// </summary>
+ public class PlayerDisplaySettings
+ {
+ internal PlayerDisplaySettings(Player player)
+ {
+ Debug.Assert(player != null);
+
+ Player = player;
+ }
+
+ private Player Player
+ {
+ get;
+ }
+
+ private PlayerDisplayMode _displayMode = PlayerDisplayMode.LetterBox;
+
+ /// <summary>
+ /// Gets or sets the <see cref="PlayerDisplayMode"/>.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">
+ /// The display is not assigned.\n
+ /// -or-\n
+ /// Operation failed; internal error.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">The player already has been disposed of.</exception>
+ /// <exception cref="ArgumentException">The specified value to set is invalid.</exception>
+ public PlayerDisplayMode Mode
+ {
+ get
+ {
+ return _displayMode;
+ }
+ set
+ {
+ if (_displayMode == value)
+ {
+ return;
+ }
+
+ ValidationUtil.ValidateEnum(typeof(PlayerDisplayMode), value);
+
+ Native.SetMode(Player.Handle, value).
+ ThrowIfFailed("Failed to set display mode");
+
+ _displayMode = value;
+ }
+ }
+
+ private bool _isVisible = true;
+
+ /// <summary>
+ /// Gets or sets the value indicating whether the display is visible.
+ /// </summary>
+ /// <value></value>
+ /// <exception cref="InvalidOperationException">
+ /// The display is not assigned.\n
+ /// -or-\n
+ /// Operation failed; internal error.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">The player already has been disposed of.</exception>
+ public bool IsVisible
+ {
+ get
+ {
+ return _isVisible;
+ }
+ set
+ {
+ if (_isVisible == value)
+ {
+ return;
+ }
+
+ Native.SetVisible(Player.Handle, value).
+ ThrowIfFailed("Failed to set the visible state of the display");
+
+ _isVisible = value;
+ }
+ }
+
+ private PlayerDisplayRotation _rotation = PlayerDisplayRotation.RotationNone;
+
+ /// <summary>
+ /// Gets or sets the rotation of the display.
+ /// </summary>
+ /// <value><see cref="PlayerDisplayRotation.RotationNone"/>,
+ /// <see cref="PlayerDisplayRotation.Rotation90"/>,
+ /// <see cref="PlayerDisplayRotation.Rotation180"/>,
+ /// <see cref="PlayerDisplayRotation.Rotation270"/></value>
+ /// <exception cref="InvalidOperationException">
+ /// The display is not assigned.\n
+ /// -or-\n
+ /// Operation failed; internal error.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">The player already has been disposed of.</exception>
+ /// <exception cref="ArgumentException">The specified value to set is invalid.</exception>
+ public PlayerDisplayRotation Rotation
+ {
+ get
+ {
+ return _rotation;
+ }
+ set
+ {
+ if (_rotation == value)
+ {
+ return;
+ }
+
+ ValidationUtil.ValidateEnum(typeof(PlayerDisplayRotation), value);
+
+ Native.SetRotation(Player.Handle, value).
+ ThrowIfFailed("Failed to set the rotation state of the display");
+
+ _rotation = value;
+ }
+ }
+
+ /// <summary>
+ /// Sets the roi(region of interest).
+ /// </summary>
+ /// <remarks>
+ /// To set roi, <see cref="Mode"/> must be set to <see cref="PlayerDisplayMode.Roi"/> first.
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">
+ /// The display is not assigned.\n
+ /// -or-\n
+ /// Operation failed; internal error.\n
+ /// -or-\n
+ /// <see cref="Mode"/> is not set to <see cref="PlayerDisplayMode.Roi"/>
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">The player already has been disposed of.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">width or height is less than or equal to zero.</exception>
+ public void SetRoi(Rectangle roi)
+ {
+ if (_displayMode != PlayerDisplayMode.Roi)
+ {
+ throw new InvalidOperationException("Mode is not set to Roi");
+ }
+
+ if (roi.Width <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(roi), roi.Width,
+ $"The width of the roi can't be less than or equal to zero.");
+ }
+ if (roi.Height <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(roi), roi.Height,
+ $"The height of the roi can't be less than or equal to zero.");
+ }
+
+ Native.SetRoi(Player.Handle, roi.X, roi.Y, roi.Width, roi.Height).
+ ThrowIfFailed("Failed to set the roi");
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaPlayer/Player/PlayerEnums.cs b/src/Tizen.Multimedia.MediaPlayer/Player/PlayerEnums.cs
new file mode 100644
index 0000000..72be4b8
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaPlayer/Player/PlayerEnums.cs
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Specifies errors.
+ /// </summary>
+ /// <seealso cref="Player.ErrorOccurred"/>
+ /// <seealso cref="PlayerErrorOccurredEventArgs"/>
+ public enum PlayerError
+ {
+ NoSuchFile = ErrorCode.NoSuchFile,
+ InternalError = ErrorCode.InvalidOperation,
+ NoSpaceOnDevice = PlayerErrorCode.NoSpaceOnDevice,
+ FeatureNotSupported = ErrorCode.NotSupported,
+ PermissionDenied = ErrorCode.PermissionDenied,
+ BufferSpace = ErrorCode.BufferSpace,
+ SeekFailed = PlayerErrorCode.SeekFailed,
+ InvalidState = PlayerErrorCode.InvalidState,
+ NotSupportedFile = PlayerErrorCode.NotSupportedFile,
+ InvalidUri = PlayerErrorCode.InvalidUri,
+ SoundPolicy = PlayerErrorCode.SoundPolicyError,
+ ConnectionFailed = PlayerErrorCode.ConnectionFailed,
+ VideoCaptureFailed = PlayerErrorCode.VideoCaptureFailed,
+ DrmExpired = PlayerErrorCode.DrmExpired,
+ DrmNoLicense = PlayerErrorCode.DrmNoLicense,
+ DrmFutureUse = PlayerErrorCode.DrmFutureUse,
+ DrmNotPermitted = PlayerErrorCode.DrmNotPermitted,
+ ResourceLimit = PlayerErrorCode.ResourceLimit,
+ ServiceDisconnected = PlayerErrorCode.ServiceDisconnected,
+ SubtitleNotSupported = PlayerErrorCode.NotSupportedSubtitle,
+ }
+
+ /// <summary>
+ /// Specifies states that a <see cref="Player"/> can have.
+ /// </summary>
+ public enum PlayerState
+ {
+ /// <summary>
+ /// Initial state, unprepared.
+ /// </summary>
+ /// <seealso cref="Player.Unprepare"/>
+ Idle = 1,
+
+ /// <summary>
+ /// Prepared.
+ /// </summary>
+ /// <seealso cref="Player.PrepareAsync"/>
+ Ready,
+
+ /// <summary>
+ /// Playing.
+ /// </summary>
+ /// <seealso cref="Player.Start"/>
+ Playing,
+
+ /// <summary>
+ /// Paused while playing media.
+ /// </summary>
+ /// <seealso cref="Player.Pause"/>
+ Paused,
+
+ /// <summary>
+ /// Preparing in progress.
+ /// </summary>
+ /// <seealso cref="Player.PrepareAsync"/>/>
+ Preparing,
+ }
+
+ internal static class PlayerStateExtensions
+ {
+ internal static bool IsAnyOf(this PlayerState thisState, params PlayerState[] states)
+ {
+ return Array.IndexOf(states, thisState) != -1;
+ }
+ }
+
+ /// <summary>
+ /// Specifies audio latency modes for <see cref="Player"/> .
+ /// </summary>
+ /// <seealso cref="Player.AudioLatencyMode"/>
+ public enum AudioLatencyMode
+ {
+ /// <summary>
+ /// Low audio latency mode.
+ /// </summary>
+ Low,
+
+ /// <summary>
+ /// Middle audio latency mode.
+ /// </summary>
+ Mid,
+
+ /// <summary>
+ /// High audio latency mode.
+ /// </summary>
+ High,
+ }
+
+
+ /// <summary>
+ /// Specifies display rotation modes for <see cref="Player"/>.
+ /// </summary>
+ /// <seealso cref="Display.Rotation"/>
+ public enum PlayerDisplayRotation
+ {
+ /// <summary>
+ /// Display is not rotated
+ /// </summary>
+ RotationNone,
+
+ /// <summary>
+ /// Display is rotated 90 degrees
+ /// </summary>
+ Rotation90,
+
+ /// <summary>
+ /// Display is rotated 180 degrees
+ /// </summary>
+ Rotation180,
+
+ /// <summary>
+ /// Display is rotated 270 degrees
+ /// </summary>
+ Rotation270
+ }
+
+
+ /// <summary>
+ /// Specifies display modes for <see cref="Player"/>
+ /// </summary>
+ /// <seealso cref="Display.Mode"/>
+ public enum PlayerDisplayMode
+ {
+ /// <summary>
+ /// Letter box.
+ /// </summary>
+ LetterBox,
+
+ /// <summary>
+ /// Original size.
+ /// </summary>
+ OriginalSize,
+
+ /// <summary>
+ /// Full-screen.
+ /// </summary>
+ FullScreen,
+
+ /// <summary>
+ /// Cropped full-screen.
+ /// </summary>
+ CroppedFull,
+
+ /// <summary>
+ /// Origin size (if surface size is larger than video size(width/height)) or
+ /// Letter box (if video size(width/height) is larger than surface size).
+ /// </summary>
+ OriginalOrFull,
+
+ /// <summary>
+ /// Region of interest, See <see cref="Display.SetRoi(Rectangle)"/>.
+ /// </summary>
+ Roi
+ }
+
+ internal enum StreamType
+ {
+ /// <summary>
+ /// Audio element stream type
+ /// </summary>
+ Audio = 1,
+
+ /// <summary>
+ /// Video element stream type
+ /// </summary>
+ Video,
+
+ /// <summary>
+ /// Text type
+ /// </summary>
+ Text
+ }
+
+ /// <summary>
+ /// Specifies the streaming buffer status.
+ /// </summary>
+ /// <seealso cref="MediaStreamConfiguration.BufferStatusChanged"/>
+ /// <seealso cref="MediaStreamBufferStatusChangedEventArgs"/>
+ public enum MediaStreamBufferStatus
+ {
+ /// <summary>
+ /// Underrun.
+ /// </summary>
+ Underrun,
+
+ /// <summary>
+ /// Completed.
+ /// </summary>
+ Overflow,
+ }
+
+ /// <summary>
+ /// Specifies the reason for the playback interruption.
+ /// </summary>
+ /// <seealso cref="Player.PlaybackInterrupted"/>
+ public enum PlaybackInterruptionReason
+ {
+ /// <summary>
+ /// Interrupted by a resource conflict and the <see cref="Player"/> will be unprepared, automatically.
+ /// </summary>
+ ResourceConflict = 4
+ }
+
+ /// <summary>
+ /// Specifies keys for the metadata.
+ /// </summary>
+ /// <seealso cref="StreamInfo.GetMetadata(StreamMetadataKey)"/>
+ public enum StreamMetadataKey
+ {
+ /// <summary>
+ /// Album.
+ /// </summary>
+ Album,
+
+ /// <summary>
+ /// Artists.
+ /// </summary>
+ Artist,
+
+ /// <summary>
+ /// Author.
+ /// </summary>
+ Author,
+
+ /// <summary>
+ /// Genre.
+ /// </summary>
+ Genre,
+
+ /// <summary>
+ /// Title.
+ /// </summary>
+ Title,
+
+ /// <summary>
+ /// Year.
+ /// </summary>
+ Year
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaPlayer/Player/PlayerError.cs b/src/Tizen.Multimedia.MediaPlayer/Player/PlayerError.cs
new file mode 100644
index 0000000..2654a84
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaPlayer/Player/PlayerError.cs
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.IO;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Multimedia
+{
+ internal enum PlayerErrorCode
+ {
+ None = ErrorCode.None,
+ InvalidArgument = ErrorCode.InvalidParameter,
+ OutOfMemory = ErrorCode.OutOfMemory,
+ NoSuchFile = ErrorCode.NoSuchFile,
+ InvalidOperation = ErrorCode.InvalidOperation,
+ NoSpaceOnDevice = ErrorCode.FileNoSpaceOnDevice,
+ FeatureNotSupported = ErrorCode.NotSupported,
+ PermissionDenied = ErrorCode.PermissionDenied,
+ NoBufferSpace = ErrorCode.BufferSpace,
+ TizenPlayerError = -0x01940000,
+ PlayerErrorClass = TizenPlayerError | 0x20,
+ SeekFailed = PlayerErrorClass | 0x01,
+ InvalidState = PlayerErrorClass | 0x02,
+ NotSupportedFile = PlayerErrorClass | 0x03,
+ InvalidUri = PlayerErrorClass | 0x04,
+ SoundPolicyError = PlayerErrorClass | 0x05,
+ ConnectionFailed = PlayerErrorClass | 0x06,
+ VideoCaptureFailed = PlayerErrorClass | 0x07,
+ DrmExpired = PlayerErrorClass | 0x08,
+ DrmNoLicense = PlayerErrorClass | 0x09,
+ DrmFutureUse = PlayerErrorClass | 0x0a,
+ DrmNotPermitted = PlayerErrorClass | 0x0b,
+ ResourceLimit = PlayerErrorClass | 0x0c,
+ ServiceDisconnected = PlayerErrorClass | 0x0d,
+ NotSupportedAudioCodec = PlayerErrorClass | 0x0e,
+ NotSupportedVideoCodec = PlayerErrorClass | 0x0f,
+ NotSupportedSubtitle = PlayerErrorClass | 0x10
+ }
+
+ internal static class PlayerErrorCodeExtensions
+ {
+ internal static void ThrowIfFailed(this PlayerErrorCode err, string message)
+ {
+ if (err == PlayerErrorCode.None)
+ {
+ return;
+ }
+
+ string msg = $"{ (message ?? "Operation failed") } : { err.ToString() }.";
+
+ switch (err)
+ {
+ case PlayerErrorCode.InvalidArgument:
+ case PlayerErrorCode.InvalidUri:
+ throw new ArgumentException(msg);
+
+ case PlayerErrorCode.NoSuchFile:
+ throw new FileNotFoundException(msg);
+
+ case PlayerErrorCode.OutOfMemory:
+ throw new OutOfMemoryException(msg);
+
+ case PlayerErrorCode.NoSpaceOnDevice:
+ throw new IOException(msg);
+
+ case PlayerErrorCode.PermissionDenied:
+ throw new UnauthorizedAccessException(msg);
+
+ case PlayerErrorCode.NotSupportedFile:
+ throw new FileFormatException(msg);
+
+ case PlayerErrorCode.FeatureNotSupported:
+ throw new NotSupportedException(msg);
+
+ case PlayerErrorCode.DrmExpired:
+ case PlayerErrorCode.DrmNoLicense:
+ case PlayerErrorCode.DrmFutureUse:
+ case PlayerErrorCode.DrmNotPermitted:
+ // TODO consider another exception.
+ case PlayerErrorCode.InvalidOperation:
+ case PlayerErrorCode.InvalidState:
+ case PlayerErrorCode.SeekFailed:
+ case PlayerErrorCode.ConnectionFailed:
+ case PlayerErrorCode.VideoCaptureFailed:
+ throw new InvalidOperationException(msg);
+
+ case PlayerErrorCode.NoBufferSpace:
+ throw new NoBufferSpaceException(msg);
+
+ case PlayerErrorCode.ResourceLimit:
+ throw new ResourceLimitException(msg);
+
+ case PlayerErrorCode.NotSupportedAudioCodec:
+ throw new CodecNotSupportedException(CodecKind.Audio);
+
+ case PlayerErrorCode.NotSupportedVideoCodec:
+ throw new CodecNotSupportedException(CodecKind.Video);
+
+ }
+
+ throw new Exception(msg);
+ }
+ }
+
+ /// <summary>
+ /// The exception that is thrown when there is no available space in a buffer.
+ /// </summary>
+ public class NoBufferSpaceException : InvalidOperationException
+ {
+ /// <summary>
+ /// Initializes a new instance of the NoBufferSpaceException class with a specified error message.
+ /// </summary>
+ /// <param name="message">Error description.</param>
+ public NoBufferSpaceException(string message) : base(message)
+ {
+ }
+ }
+
+ /// <summary>
+ /// The exception that is thrown when there is no available resource for internal use.
+ /// </summary>
+ public class ResourceLimitException : InvalidOperationException
+ {
+ /// <summary>
+ /// Initializes a new instance of the ResourceLimitException class with a specified error message.
+ /// </summary>
+ /// <param name="message">Error description.</param>
+ public ResourceLimitException(string message) : base(message)
+ {
+ }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.MediaPlayer/Player/PlayerErrorOccurredEventArgs.cs b/src/Tizen.Multimedia.MediaPlayer/Player/PlayerErrorOccurredEventArgs.cs
new file mode 100644
index 0000000..6e72e95
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaPlayer/Player/PlayerErrorOccurredEventArgs.cs
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides data for the <see cref="Player.ErrorOccurred"/> event.
+ /// </summary>
+ public class PlayerErrorOccurredEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Initializes a new instance of the PlayerErrorOccurredEventArgs class.
+ /// </summary>
+ /// <param name="error">The value indicating what kind of error occurred.</param>
+ public PlayerErrorOccurredEventArgs(PlayerError error)
+ {
+ Error = error;
+ }
+
+ /// <summary>
+ /// Gets the error.
+ /// </summary>
+ public PlayerError Error { get; }
+
+ public override string ToString()
+ {
+ return $"Error={ Error.ToString() }";
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaPlayer/Player/PlayerTrackInfo.cs b/src/Tizen.Multimedia.MediaPlayer/Player/PlayerTrackInfo.cs
new file mode 100644
index 0000000..459f725
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaPlayer/Player/PlayerTrackInfo.cs
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using static Interop;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides a means to retrieve track information.
+ /// </summary>
+ /// <seealso cref="Player.SubtitleTrackInfo"/>
+ /// <seealso cref="Player.AudioTrackInfo"/>
+ public class PlayerTrackInfo
+ {
+ private readonly int _streamType;
+ private readonly Player _owner;
+
+ internal PlayerTrackInfo(Player player, StreamType streamType)
+ {
+ Debug.Assert(player != null);
+
+ Log.Debug(PlayerLog.Tag, "streamType : " + streamType);
+ _streamType = (int)streamType;
+ _owner = player;
+ }
+
+ /// <summary>
+ /// Gets the number of tracks.
+ /// </summary>
+ /// <returns>The number of tracks.</returns>
+ /// <remarks>The <see cref="Player"/> that owns this instance must be in the <see cref="PlayerState.Ready"/>, <see cref="PlayerState.Playing"/> or <see cref="PlayerState.Paused"/> state.</remarks>
+ /// <exception cref="ObjectDisposedException">The <see cref="Player"/> that this instance belongs to has been disposed.</exception>
+ /// <exception cref="InvalidOperationException">The <see cref="Player"/> that this instance belongs to is not in the valid state.</exception>
+ public int GetCount()
+ {
+ _owner.ValidatePlayerState(PlayerState.Ready, PlayerState.Playing, PlayerState.Paused);
+
+ int count = 0;
+ NativePlayer.GetTrackCount(_owner.Handle, _streamType, out count).
+ ThrowIfFailed("Failed to get count of the track");
+ Log.Info(PlayerLog.Tag, "get count : " + count);
+ return count;
+ }
+
+ /// <summary>
+ /// Gets the language code for the specified index or null if the language is undefined.
+ /// </summary>
+ /// <returns>The number of tracks.</returns>
+ /// <remarks>
+ /// <para>The <see cref="Player"/> that owns this instance must be in the <see cref="PlayerState.Ready"/>, <see cref="PlayerState.Playing"/> or <see cref="PlayerState.Paused"/> state.</para>
+ /// <para>The language codes are defined in ISO 639-1.</para>
+ /// </remarks>
+ /// <exception cref="ObjectDisposedException">The <see cref="Player"/> that this instance belongs to has been disposed.</exception>
+ /// <exception cref="InvalidOperationException">The <see cref="Player"/> that this instance belongs to is not in the valid state.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="index"/> is less than zero.\n
+ /// -or-\n
+ /// <paramref name="index"/> is equal to or greater than <see cref="GetCount()"/>
+ /// </exception>
+ public string GetLanguageCode(int index)
+ {
+ _owner.ValidatePlayerState(PlayerState.Ready, PlayerState.Playing, PlayerState.Paused);
+
+ if (index < 0 || GetCount() <= index)
+ {
+ Log.Error(PlayerLog.Tag, "invalid index");
+ throw new ArgumentOutOfRangeException(nameof(index), index,
+ $"valid index range is 0 <= x < {nameof(GetCount)}(), but got { index }.");
+ }
+
+ IntPtr code = IntPtr.Zero;
+
+ try
+ {
+ NativePlayer.GetTrackLanguageCode(_owner.Handle, _streamType, index, out code).
+ ThrowIfFailed("Failed to get the selected language of the player");
+
+ string result = Marshal.PtrToStringAnsi(code);
+
+ if (result == "und")
+ {
+ Log.Error(PlayerLog.Tag, "not defined code");
+ return null;
+ }
+ Log.Info(PlayerLog.Tag, "get language code : " + result);
+ return result;
+ }
+ finally
+ {
+ LibcSupport.Free(code);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the selected track index.
+ /// </summary>
+ /// <value>The currently selected track index.</value>
+ /// <remarks>The <see cref="Player"/> that owns this instance must be in the <see cref="PlayerState.Ready"/>, <see cref="PlayerState.Playing"/> or <see cref="PlayerState.Paused"/> state.</remarks>
+ /// <exception cref="ObjectDisposedException">The <see cref="Player"/> that this instance belongs to has been disposed.</exception>
+ /// <exception cref="InvalidOperationException">The <see cref="Player"/> that this instance belongs to is not in the valid state.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="value"/> is less than zero.\n
+ /// -or-\n
+ /// <paramref name="value"/> is equal to or greater than <see cref="GetCount()"/>
+ /// </exception>
+ public int Selected
+ {
+ get
+ {
+ _owner.ValidatePlayerState(PlayerState.Ready, PlayerState.Playing, PlayerState.Paused);
+
+ int value = 0;
+
+ NativePlayer.GetCurrentTrack(_owner.Handle, _streamType, out value).
+ ThrowIfFailed("Failed to get the selected index of the player");
+ Log.Debug(PlayerLog.Tag, "get selected index : " + value);
+ return value;
+ }
+ set
+ {
+ if (value < 0 || GetCount() <= value)
+ {
+ Log.Error(PlayerLog.Tag, "invalid index");
+ throw new ArgumentOutOfRangeException(nameof(value), value,
+ $"valid index range is 0 <= x < {nameof(GetCount)}(), but got { value }.");
+ }
+
+ _owner.ValidatePlayerState(PlayerState.Ready, PlayerState.Playing, PlayerState.Paused);
+
+ NativePlayer.SelectTrack(_owner.Handle, _streamType, value).
+ ThrowIfFailed("Failed to set the selected index of the player");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaPlayer/Player/StreamInfo.cs b/src/Tizen.Multimedia.MediaPlayer/Player/StreamInfo.cs
new file mode 100644
index 0000000..26da7d0
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaPlayer/Player/StreamInfo.cs
@@ -0,0 +1,317 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.Runtime.InteropServices;
+using static Interop;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents properties for audio stream.
+ /// </summary>
+ public struct AudioStreamProperties
+ {
+ /// <summary>
+ /// Initialize a new instance of the AudioStreamProperties struct with the specified sample rate, channels and bit rate.
+ /// </summary>
+ public AudioStreamProperties(int sampleRate, int channels, int bitRate)
+ {
+ SampleRate = sampleRate;
+ Channels = channels;
+ BitRate = bitRate;
+ Log.Debug(PlayerLog.Tag, "sampleRate : " + sampleRate + ", channels : " + channels + ", bitRate : " + bitRate);
+ }
+
+ /// <summary>
+ /// Gets or sets the sample rate.
+ /// </summary>
+ /// <value>The audio sample rate(Hz).</value>
+ public int SampleRate
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// Gets or sets the channels.
+ /// </summary>
+ public int Channels
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// Gets or sets the bit rate.
+ /// </summary>
+ /// <value>The audio bit rate(Hz).</value>
+ public int BitRate
+ {
+ get;
+ set;
+ }
+
+ public override string ToString() =>
+ $"SampleRate={ SampleRate.ToString() }, Channels={ Channels.ToString() }, BitRate={ BitRate.ToString() }";
+ }
+
+ /// <summary>
+ /// Represents properties for video stream.
+ /// </summary>
+ public struct VideoStreamProperties
+ {
+ /// <summary>
+ /// Initialize a new instance of the VideoStreamProperties struct with the specified fps, bit rate and size.
+ /// </summary>
+ public VideoStreamProperties(int fps, int bitRate, Size size)
+ {
+ Fps = fps;
+ BitRate = bitRate;
+ Size = size;
+ Log.Debug(PlayerLog.Tag, "fps : " + fps + ", bitrate : " + bitRate +
+ ", width : " + size.Width + ", height : " + size.Height);
+ }
+ /// <summary>
+ /// Initialize a new instance of the VideoStreamProperties struct with the specified fps, bit rate, width and height.
+ /// </summary>
+ public VideoStreamProperties(int fps, int bitRate, int width, int height)
+ {
+ Fps = fps;
+ BitRate = bitRate;
+ Size = new Size(width, height);
+ Log.Debug(PlayerLog.Tag, "fps : " + fps + ", bitrate : " + bitRate +
+ ", width : " + width + ", height : " + height);
+ }
+
+ /// <summary>
+ /// Gets or sets the fps.
+ /// </summary>
+ public int Fps
+ {
+ get;
+ set;
+ }
+ /// <summary>
+ /// Gets or sets the bit rate.
+ /// </summary>
+ public int BitRate
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// Gets or sets the size.
+ /// </summary>
+ public Size Size
+ {
+ get;
+ set;
+ }
+
+ public override string ToString()
+ {
+ return $"Fps={ Fps.ToString() }, BitRate={ BitRate.ToString() }, Size=[{ Size.ToString() }]";
+ }
+ }
+
+ /// <summary>
+ /// Provides a means to retrieve stream information.
+ /// </summary>
+ public class StreamInfo
+ {
+ internal StreamInfo(Player owner)
+ {
+ Player = owner;
+ }
+
+ /// <summary>
+ /// Retrieves the album art of the stream or null if there is no album art data.
+ /// </summary>
+ /// <remarks>The <see cref="Multimedia.Player"/> that owns this instance must be in the <see cref="PlayerState.Ready"/>, <see cref="PlayerState.Playing"/> or <see cref="PlayerState.Paused"/> state.</remarks>
+ /// <exception cref="ObjectDisposedException">The <see cref="Multimedia.Player"/> that this instance belongs to has been disposed.</exception>
+ /// <exception cref="InvalidOperationException">The <see cref="Multimedia.Player"/> that this instance belongs to is not in the valid state.</exception>
+ public byte[] GetAlbumArt()
+ {
+ Player.ValidatePlayerState(PlayerState.Ready, PlayerState.Playing, PlayerState.Paused);
+
+ NativePlayer.GetAlbumArt(Player.Handle, out var art, out var size).
+ ThrowIfFailed("Failed to get the album art");
+
+ if (art == IntPtr.Zero || size == 0)
+ {
+ Log.Error(PlayerLog.Tag, "art is null or size is 0 : " + size);
+ return null;
+ }
+
+ byte[] albumArt = new byte[size];
+ Marshal.Copy(art, albumArt, 0, size);
+ return albumArt;
+ }
+
+ private string GetCodecInfo(bool audioInfo)
+ {
+ Player.ValidatePlayerState(PlayerState.Ready, PlayerState.Playing, PlayerState.Paused);
+
+ IntPtr audioPtr = IntPtr.Zero;
+ IntPtr videoPtr = IntPtr.Zero;
+ try
+ {
+ NativePlayer.GetCodecInfo(Player.Handle, out audioPtr, out videoPtr).
+ ThrowIfFailed("Failed to get codec info");
+
+ if (audioInfo)
+ {
+ Log.Debug(PlayerLog.Tag, "it is audio case");
+ return Marshal.PtrToStringAnsi(audioPtr);
+ }
+ else
+ {
+ Log.Debug(PlayerLog.Tag, "it is video case");
+ return Marshal.PtrToStringAnsi(videoPtr);
+ }
+ }
+ finally
+ {
+ LibcSupport.Free(audioPtr);
+ LibcSupport.Free(videoPtr);
+ }
+ }
+
+ /// <summary>
+ /// Retrieves the codec name of audio or null if there is no audio.
+ /// </summary>
+ public string GetAudioCodec()
+ {
+ return GetCodecInfo(true);
+ }
+
+ /// <summary>
+ /// Retrieves the codec name of video or null if there is no video.
+ /// </summary>
+ public string GetVideoCodec()
+ {
+ return GetCodecInfo(false);
+ }
+
+ /// <summary>
+ /// Gets the duration.
+ /// </summary>
+ /// <remarks>The <see cref="Multimedia.Player"/> that owns this instance must be in the <see cref="PlayerState.Ready"/>, <see cref="PlayerState.Playing"/> or <see cref="PlayerState.Paused"/> state.</remarks>
+ /// <exception cref="ObjectDisposedException">The <see cref="Multimedia.Player"/> that this instance belongs to has been disposed.</exception>
+ /// <exception cref="InvalidOperationException">The <see cref="Multimedia.Player"/> that this instance belongs to is not in the valid state.</exception>
+ public int GetDuration()
+ {
+ Player.ValidatePlayerState(PlayerState.Ready, PlayerState.Playing, PlayerState.Paused);
+
+ int duration = 0;
+ NativePlayer.GetDuration(Player.Handle, out duration).
+ ThrowIfFailed("Failed to get the duration");
+
+ Log.Info(PlayerLog.Tag, "get duration : " + duration);
+ return duration;
+ }
+
+ /// <summary>
+ /// Gets the properties of audio.
+ /// </summary>
+ /// <remarks>The <see cref="Multimedia.Player"/> that owns this instance must be in the <see cref="PlayerState.Ready"/>, <see cref="PlayerState.Playing"/> or <see cref="PlayerState.Paused"/> state.</remarks>
+ /// <exception cref="ObjectDisposedException">The <see cref="Multimedia.Player"/> that this instance belongs to has been disposed.</exception>
+ /// <exception cref="InvalidOperationException">The <see cref="Multimedia.Player"/> that this instance belongs to is not in the valid state.</exception>
+ public AudioStreamProperties GetAudioProperties()
+ {
+ Player.ValidatePlayerState(PlayerState.Ready, PlayerState.Playing, PlayerState.Paused);
+
+ int sampleRate = 0;
+ int channels = 0;
+ int bitRate = 0;
+
+ NativePlayer.GetAudioStreamInfo(Player.Handle, out sampleRate, out channels, out bitRate).
+ ThrowIfFailed("Failed to get audio stream info");
+
+ // TODO should we check value is zero and return null?
+
+ return new AudioStreamProperties(sampleRate, channels, bitRate);
+ }
+
+ /// <summary>
+ /// Gets the properties of video.
+ /// </summary>
+ /// <remarks>The <see cref="Multimedia.Player"/> that owns this instance must be in the <see cref="PlayerState.Ready"/>, <see cref="PlayerState.Playing"/> or <see cref="PlayerState.Paused"/> state.</remarks>
+ /// <exception cref="ObjectDisposedException">The <see cref="Multimedia.Player"/> that this instance belongs to has been disposed.</exception>
+ /// <exception cref="InvalidOperationException">The <see cref="Multimedia.Player"/> that this instance belongs to is not in the valid state.</exception>
+ public VideoStreamProperties GetVideoProperties()
+ {
+ Player.ValidatePlayerState(PlayerState.Ready, PlayerState.Playing, PlayerState.Paused);
+
+ int fps = 0;
+ int bitRate = 0;
+
+ NativePlayer.GetVideoStreamInfo(Player.Handle, out fps, out bitRate).
+ ThrowIfFailed("Failed to get the video stream info");
+
+ // TODO should we check value is zero and return null?
+
+ return new VideoStreamProperties(fps, bitRate, GetVideoSize());
+ }
+
+ private Size GetVideoSize()
+ {
+ Player.ValidatePlayerState(PlayerState.Ready, PlayerState.Playing, PlayerState.Paused);
+
+ int height = 0;
+ int width = 0;
+
+ NativePlayer.GetVideoSize(Player.Handle, out width, out height).
+ ThrowIfFailed("Failed to get the video size");
+
+ return new Size(width, height);
+ }
+
+ /// <summary>
+ /// Gets the metadata with the specified key.
+ /// </summary>
+ /// <param name="key">The key to query.</param>
+ /// <remarks>The <see cref="Multimedia.Player"/> that owns this instance must be in the <see cref="PlayerState.Ready"/>, <see cref="PlayerState.Playing"/> or <see cref="PlayerState.Paused"/> state.</remarks>
+ /// <exception cref="ObjectDisposedException">The <see cref="Multimedia.Player"/> that this instance belongs to has been disposed.</exception>
+ /// <exception cref="InvalidOperationException">The <see cref="Multimedia.Player"/> that this instance belongs to is not in the valid state.</exception>
+ public string GetMetadata(StreamMetadataKey key)
+ {
+ Player.ValidatePlayerState(PlayerState.Ready, PlayerState.Playing, PlayerState.Paused);
+
+ ValidationUtil.ValidateEnum(typeof(StreamMetadataKey), key);
+
+ IntPtr ptr = IntPtr.Zero;
+
+ try
+ {
+ NativePlayer.GetContentInfo(Player.Handle, key, out ptr).
+ ThrowIfFailed($"Failed to get the meta data with the key '{ key }'");
+
+ return Marshal.PtrToStringAnsi(ptr);
+ }
+ finally
+ {
+ LibcSupport.Free(ptr);
+ }
+ }
+
+ /// <summary>
+ /// Gets the <see cref="Multimedia.Player"/> that owns this instance.
+ /// </summary>
+ public Player Player { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaPlayer/Player/SubtitleUpdatedEventArgs.cs b/src/Tizen.Multimedia.MediaPlayer/Player/SubtitleUpdatedEventArgs.cs
new file mode 100644
index 0000000..0f1bee8
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaPlayer/Player/SubtitleUpdatedEventArgs.cs
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides data for the <see cref="Player.SubtitleUpdated"/> event.
+ /// </summary>
+ public class SubtitleUpdatedEventArgs : EventArgs
+ {
+ internal SubtitleUpdatedEventArgs(uint duration, string text)
+ {
+ Duration = duration;
+ Text = text;
+ }
+
+ /// <summary>
+ /// Gets the duration of the updated subtitle.
+ /// </summary>
+ public uint Duration { get; }
+
+ /// <summary>
+ /// Gets the text of the updated subtitle.
+ /// </summary>
+ public string Text { get; }
+
+ public override string ToString()
+ {
+ return $"Duration={ Duration.ToString() }, Text={ Text }";
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaPlayer/Player/VideoFrameDecodedEventArgs.cs b/src/Tizen.Multimedia.MediaPlayer/Player/VideoFrameDecodedEventArgs.cs
new file mode 100644
index 0000000..daa545d
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaPlayer/Player/VideoFrameDecodedEventArgs.cs
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides data for the <see cref="Player.VideoFrameDecoded"/> event.
+ /// </summary>
+ public class VideoFrameDecodedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Initializes a new instance of the VideoFrameDecodedEventArgs class.
+ /// </summary>
+ internal VideoFrameDecodedEventArgs(MediaPacket packet)
+ {
+ Packet = packet;
+ }
+
+ /// <summary>
+ /// Gets the packet containing the decoded frame.
+ /// </summary>
+ public MediaPacket Packet { get; }
+
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaPlayer/Player/VideoStreamChangedEventArgs.cs b/src/Tizen.Multimedia.MediaPlayer/Player/VideoStreamChangedEventArgs.cs
new file mode 100644
index 0000000..ea54f34
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaPlayer/Player/VideoStreamChangedEventArgs.cs
@@ -0,0 +1,59 @@
+/// This File contains VideoStreamEventArgs class
+///
+/// Copyright 2016 by Samsung Electronics, Inc.,
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides data for the <see cref="Player.VideoStreamChanged"/> event.
+ /// </summary>
+ public class VideoStreamChangedEventArgs : EventArgs
+ {
+
+ /// <summary>
+ /// Initializes a new instance of the VideoStreamChangedEventArgs class.
+ /// </summary>
+ internal VideoStreamChangedEventArgs(int height, int width, int fps, int bitRate)
+ {
+ Size = new Size(width, height);
+ Fps = fps;
+ BitRate = bitRate;
+ }
+
+ /// <summary>
+ /// Gets the <see cref="Size"/> of new video.
+ /// </summary>
+ public Size Size { get; }
+
+ /// <summary>
+ /// Gets the fps of new video
+ /// </summary>
+ public int Fps { get; }
+
+ /// <summary>
+ /// Gets the bit rate of new video.
+ /// </summary>
+ public int BitRate { get; }
+
+ public override string ToString()
+ {
+ return $"Size=({ Size.ToString() }), Fps={ Fps.ToString() }, BitRate={ BitRate.ToString() }";
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.MediaPlayer/Tizen.Multimedia.MediaPlayer.csproj b/src/Tizen.Multimedia.MediaPlayer/Tizen.Multimedia.MediaPlayer.csproj
new file mode 100644
index 0000000..0e5378c
--- /dev/null
+++ b/src/Tizen.Multimedia.MediaPlayer/Tizen.Multimedia.MediaPlayer.csproj
@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen.Multimedia\Tizen.Multimedia.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Multimedia.Metadata/Interop/Interop.Libc.cs b/src/Tizen.Multimedia.Metadata/Interop/Interop.Libc.cs
new file mode 100644
index 0000000..3ace080
--- /dev/null
+++ b/src/Tizen.Multimedia.Metadata/Interop/Interop.Libc.cs
@@ -0,0 +1,11 @@
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Libc
+ {
+ [DllImport(Libraries.Libc, EntryPoint = "free")]
+ public static extern void Free(IntPtr userData);
+ }
+}
diff --git a/src/Tizen.Multimedia.Metadata/Interop/Interop.Libraries.cs b/src/Tizen.Multimedia.Metadata/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..df5d155
--- /dev/null
+++ b/src/Tizen.Multimedia.Metadata/Interop/Interop.Libraries.cs
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string MetadataEditor = "libcapi-media-metadata-editor.so";
+ public const string MetadataExtractor = "libcapi-media-metadata-extractor.so";
+ public const string Libc = "libc.so.6";
+ }
+}
diff --git a/src/Tizen.Multimedia.Metadata/Interop/Interop.MetadataEditor.cs b/src/Tizen.Multimedia.Metadata/Interop/Interop.MetadataEditor.cs
new file mode 100644
index 0000000..c187e7b
--- /dev/null
+++ b/src/Tizen.Multimedia.Metadata/Interop/Interop.MetadataEditor.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Multimedia;
+
+internal static partial class Interop
+{
+ internal static partial class MetadataEditor
+ {
+ [DllImport(Libraries.MetadataEditor, EntryPoint = "metadata_editor_create")]
+ internal static extern MetadataEditorError Create(out IntPtr handle);
+
+ [DllImport(Libraries.MetadataEditor, EntryPoint = "metadata_editor_set_path")]
+ internal static extern MetadataEditorError SetPath(IntPtr handle, string path);
+
+ [DllImport(Libraries.MetadataEditor, EntryPoint = "metadata_editor_destroy")]
+ internal static extern MetadataEditorError Destroy(IntPtr handle);
+
+ [DllImport(Libraries.MetadataEditor, EntryPoint = "metadata_editor_get_metadata")]
+ internal static extern MetadataEditorError GetMetadata(IntPtr handle, MetadataEditorAttr attribute, out IntPtr value);
+
+ [DllImport(Libraries.MetadataEditor, EntryPoint = "metadata_editor_set_metadata")]
+ internal static extern MetadataEditorError SetMetadata(IntPtr handle, MetadataEditorAttr attribute, string value);
+
+ [DllImport(Libraries.MetadataEditor, EntryPoint = "metadata_editor_update_metadata")]
+ internal static extern MetadataEditorError UpdateMetadata(IntPtr handle);
+
+ [DllImport(Libraries.MetadataEditor, EntryPoint = "metadata_editor_get_picture")]
+ internal static extern MetadataEditorError GetPicture(IntPtr handle, int index, out IntPtr picture, out int size, out IntPtr mimeType);
+
+ [DllImport(Libraries.MetadataEditor, EntryPoint = "metadata_editor_append_picture")]
+ internal static extern MetadataEditorError AddPicture(IntPtr handle, string path);
+
+ [DllImport(Libraries.MetadataEditor, EntryPoint = "metadata_editor_remove_picture")]
+ internal static extern MetadataEditorError RemovePicture(IntPtr handle, int index);
+ }
+}
diff --git a/src/Tizen.Multimedia.Metadata/Interop/Interop.MetadataExtractor.cs b/src/Tizen.Multimedia.Metadata/Interop/Interop.MetadataExtractor.cs
new file mode 100644
index 0000000..54a393f
--- /dev/null
+++ b/src/Tizen.Multimedia.Metadata/Interop/Interop.MetadataExtractor.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Multimedia;
+
+internal static partial class Interop
+{
+ internal static partial class MetadataExtractor
+ {
+ [DllImport(Libraries.MetadataExtractor, EntryPoint = "metadata_extractor_create")]
+ internal static extern MetadataExtractorError Create(out IntPtr handle);
+
+ [DllImport(Libraries.MetadataExtractor, EntryPoint = "metadata_extractor_set_path")]
+ internal static extern MetadataExtractorError SetPath(IntPtr handle, string path);
+
+ [DllImport(Libraries.MetadataExtractor, EntryPoint = "metadata_extractor_set_buffer")]
+ internal static extern MetadataExtractorError SetBuffer(IntPtr handle, IntPtr buffer, int size);
+
+ [DllImport(Libraries.MetadataExtractor, EntryPoint = "metadata_extractor_destroy")]
+ internal static extern MetadataExtractorError Destroy(IntPtr handle);
+
+ [DllImport(Libraries.MetadataExtractor, EntryPoint = "metadata_extractor_get_metadata")]
+ private static extern MetadataExtractorError GetMetadata(IntPtr handle, MetadataExtractorAttr attribute, out IntPtr value);
+
+ internal static string GetMetadata(IntPtr handle, MetadataExtractorAttr attr)
+ {
+ IntPtr valuePtr = IntPtr.Zero;
+
+ try
+ {
+ var ret = GetMetadata(handle, attr, out valuePtr);
+ MetadataExtractorRetValidator.ThrowIfError(ret, "Failed to get value for " + attr);
+ return Marshal.PtrToStringAnsi(valuePtr);
+ }
+ finally
+ {
+ Libc.Free(valuePtr);
+ }
+ }
+
+ [DllImport(Libraries.MetadataExtractor, EntryPoint = "metadata_extractor_get_artwork")]
+ internal static extern MetadataExtractorError GetArtwork(IntPtr handle, out IntPtr artwork,
+ out int size, out IntPtr mimeType);
+
+ [DllImport(Libraries.MetadataExtractor, EntryPoint = "metadata_extractor_get_frame")]
+ internal static extern MetadataExtractorError GetFrame(IntPtr handle, out IntPtr frame, out int size);
+
+ [DllImport(Libraries.MetadataExtractor, EntryPoint = "metadata_extractor_get_synclyrics")]
+ internal static extern MetadataExtractorError GetSynclyrics(IntPtr handle, int index,
+ out uint timeStamp, out IntPtr lyrics);
+
+ [DllImport(Libraries.MetadataExtractor, EntryPoint = "metadata_extractor_get_frame_at_time")]
+ internal static extern MetadataExtractorError GetFrameAtTime(IntPtr handle, uint timeStamp,
+ bool isAccurate, out IntPtr frame, out int size);
+ }
+}
diff --git a/src/Tizen.Multimedia.Metadata/MetadataEditor/MetadataEditor.cs b/src/Tizen.Multimedia.Metadata/MetadataEditor/MetadataEditor.cs
new file mode 100755
index 0000000..18bdaf6
--- /dev/null
+++ b/src/Tizen.Multimedia.Metadata/MetadataEditor/MetadataEditor.cs
@@ -0,0 +1,458 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Multimedia
+{
+ static internal class MetadataEditorLog
+ {
+ internal const string LogTag = "Tizen.Multimedia.MetadataEditor";
+ }
+
+ /// <summary>
+ /// The Metadata editor class provides a set of functions to edit the metadata of the media file
+ /// </summary>
+ /// <privilege>
+ /// If you want to access only internal storage,
+ /// you should add privilege http://tizen.org/privilege/mediastorage. \n
+ /// Or if you want to access only external storage,
+ /// you should add privilege http://tizen.org/privilege/externalstorage. \n
+ /// </privilege>
+ public class MetadataEditor : IDisposable
+ {
+ private bool _disposed = false;
+ private IntPtr _handle = IntPtr.Zero;
+
+ private IntPtr MetadataHandle
+ {
+ get
+ {
+ if (_handle == IntPtr.Zero)
+ {
+ throw new ObjectDisposedException(nameof(MetadataEditor));
+ }
+
+ return _handle;
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MetadataEditor"/> class with the specified path.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="path"> The path of the media file to edit metadata </param>
+ /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
+ /// <exception cref="NotSupportedException">The file is unsupported format.</exception>
+ /// <exception cref="System.IO.FileNotFoundException">The file does not exist.</exception>
+ public MetadataEditor(string path)
+ {
+ if (path == null)
+ {
+ throw new ArgumentNullException(nameof(path));
+ }
+
+ MetadataEditorError ret = Interop.MetadataEditor.Create(out _handle);
+ MetadataEditorErrorFactory.ThrowIfError(ret, "Failed to create metadata");
+
+ try
+ {
+ MetadataEditorErrorFactory.ThrowIfError(
+ Interop.MetadataEditor.SetPath(MetadataHandle, path), "Failed to set path");
+ }
+ catch (Exception)
+ {
+ Interop.MetadataEditor.Destroy(_handle);
+ _handle = IntPtr.Zero;
+ throw;
+ }
+ }
+
+ private string GetParam(MetadataEditorAttr attr)
+ {
+ IntPtr val = IntPtr.Zero;
+
+ try
+ {
+ MetadataEditorError e = Interop.MetadataEditor.GetMetadata(MetadataHandle, attr, out val);
+ MetadataEditorErrorFactory.ThrowIfError(e, "Failed to get metadata");
+
+ return Marshal.PtrToStringAnsi(val);
+ }
+ finally
+ {
+ Interop.Libc.Free(val);
+ }
+ }
+
+ private void SetParam(MetadataEditorAttr attr, string value)
+ {
+ MetadataEditorErrorFactory.ThrowIfError(
+ Interop.MetadataEditor.SetMetadata(MetadataHandle, attr, value), "Fail to set value");
+ }
+
+ /// <summary>
+ /// Artist of media
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Artist
+ {
+ get
+ {
+ return GetParam(MetadataEditorAttr.Artist);
+ }
+
+ set
+ {
+ SetParam(MetadataEditorAttr.Artist, value);
+ }
+ }
+
+ /// <summary>
+ /// Title of media
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Title
+ {
+ get
+ {
+ return GetParam(MetadataEditorAttr.Title);
+ }
+
+ set
+ {
+ SetParam(MetadataEditorAttr.Title, value);
+ }
+ }
+
+ /// <summary>
+ /// Album name of media
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Album
+ {
+ get
+ {
+ return GetParam(MetadataEditorAttr.Album);
+ }
+
+ set
+ {
+ SetParam(MetadataEditorAttr.Album, value);
+ }
+ }
+
+ /// <summary>
+ /// Genre of media
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Genre
+ {
+ get
+ {
+ return GetParam(MetadataEditorAttr.Genre);
+ }
+
+ set
+ {
+ SetParam(MetadataEditorAttr.Genre, value);
+ }
+ }
+
+ /// <summary>
+ /// Author of media
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Author
+ {
+ get
+ {
+ return GetParam(MetadataEditorAttr.Author);
+ }
+
+ set
+ {
+ SetParam(MetadataEditorAttr.Author, value);
+ }
+ }
+
+ /// <summary>
+ /// Copyright of media
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Copyright
+ {
+ get
+ {
+ return GetParam(MetadataEditorAttr.Copyright);
+ }
+
+ set
+ {
+ SetParam(MetadataEditorAttr.Copyright, value);
+ }
+ }
+
+ /// <summary>
+ /// Date of media
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// If the added media contains ID3 tag, This parameter refers to the recording time.
+ /// If the added media is a mp4 format, This parameter refers to the year.
+ /// </remarks>
+ public string Date
+ {
+ get
+ {
+ return GetParam(MetadataEditorAttr.Date);
+ }
+
+ set
+ {
+ SetParam(MetadataEditorAttr.Date, value);
+ }
+ }
+
+ /// <summary>
+ /// Description of media
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Description
+ {
+ get
+ {
+ return GetParam(MetadataEditorAttr.Description);
+ }
+
+ set
+ {
+ SetParam(MetadataEditorAttr.Description, value);
+ }
+ }
+
+ /// <summary>
+ /// Comment of media
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Comment
+ {
+ get
+ {
+ return GetParam(MetadataEditorAttr.Comment);
+ }
+
+ set
+ {
+ SetParam(MetadataEditorAttr.Comment, value);
+ }
+ }
+
+ /// <summary>
+ /// Track number of media
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string TrackNumber
+ {
+ get
+ {
+ return GetParam(MetadataEditorAttr.TrackNumber);
+ }
+
+ set
+ {
+ SetParam(MetadataEditorAttr.TrackNumber, value);
+ }
+ }
+
+ /// <summary>
+ /// Album art count of media
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string PictureCount
+ {
+ get
+ {
+ return GetParam(MetadataEditorAttr.PictureCount);
+ }
+ }
+
+ /// <summary>
+ /// Conductor of media
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Conductor
+ {
+ get
+ {
+ return GetParam(MetadataEditorAttr.Conductor);
+ }
+
+ set
+ {
+ SetParam(MetadataEditorAttr.Conductor, value);
+ }
+ }
+
+ /// <summary>
+ /// Unsynchronized lyric of media
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string UnsyncLyrics
+ {
+ get
+ {
+ return GetParam(MetadataEditorAttr.UnsyncLyrics);
+ }
+
+ set
+ {
+ SetParam(MetadataEditorAttr.UnsyncLyrics, value);
+ }
+ }
+
+ /// <summary>
+ /// Writes the modified metadata to a media file
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="InvalidOperationException"> When internal process error is occured</exception>
+ public void Commit()
+ {
+ MetadataEditorErrorFactory.ThrowIfError(
+ Interop.MetadataEditor.UpdateMetadata(MetadataHandle), "Failed to update file");
+ }
+
+ /// <summary>
+ /// Gets the artwork image in a media file
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="index"> Index of picture to import </param>
+ /// <returns> Artwork included in the media file</returns>
+ /// <exception cref="InvalidOperationException"> When internal process error is occured</exception>
+ /// <exception cref="ArgumentOutOfRangeException"> Wrong index number </exception>
+ public Artwork GetPicture(int index)
+ {
+ if (index < 0)
+ {
+ throw new ArgumentOutOfRangeException("Index should be larger than 0 [" + index + "]");
+ }
+
+ IntPtr data = IntPtr.Zero;
+ int size;
+ IntPtr mimeType = IntPtr.Zero;
+
+ try
+ {
+ MetadataEditorErrorFactory.ThrowIfError(
+ Interop.MetadataEditor.GetPicture(MetadataHandle, index, out data, out size, out mimeType), "Failed to get the value");
+
+ if (size > 0)
+ {
+ byte[] tmpBuf = new byte[size];
+ Marshal.Copy(data, tmpBuf, 0, size);
+
+ return new Artwork(tmpBuf, Marshal.PtrToStringAnsi(mimeType));
+ }
+
+ return null;
+ }
+ finally
+ {
+ if (data != IntPtr.Zero)
+ {
+ Interop.Libc.Free(data);
+ }
+
+ if (mimeType != IntPtr.Zero)
+ {
+ Interop.Libc.Free(mimeType);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Appends the picture to the media file.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="path">The path of picture for adding to the metadata.</param>
+ /// <exception cref="InvalidOperationException">Internal error occurs.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
+ public void AddPicture(string path)
+ {
+ if (path == null)
+ {
+ throw new ArgumentNullException(nameof(path));
+ }
+
+ MetadataEditorErrorFactory.ThrowIfError(
+ Interop.MetadataEditor.AddPicture(MetadataHandle, path), "Failed to append picture");
+ }
+
+ /// <summary>
+ /// Removes the picture from the media file.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="index"> Index of picture to remove </param>
+ /// <exception cref="InvalidOperationException"> When internal process error is occured</exception>
+ /// <exception cref="ArgumentOutOfRangeException"> Wrong index number </exception>
+ public void RemovePicture(int index)
+ {
+ if (index < 0)
+ {
+ throw new ArgumentOutOfRangeException("Index should be larger than 0 [" + index + "]");
+ }
+
+ MetadataEditorErrorFactory.ThrowIfError(
+ Interop.MetadataEditor.RemovePicture(MetadataHandle, index), "Failed to remove picture");
+ }
+
+ /// <summary>
+ /// Metadata Editor destructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ ~MetadataEditor()
+ {
+ Dispose(false);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (disposing)
+ {
+ // To be used if there are any other disposable objects
+ }
+
+ if (_handle != IntPtr.Zero)
+ {
+ Interop.MetadataEditor.Destroy(_handle);
+ _handle = IntPtr.Zero;
+ }
+
+ _disposed = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Metadata/MetadataEditor/MetadataEditorAttr.cs b/src/Tizen.Multimedia.Metadata/MetadataEditor/MetadataEditorAttr.cs
new file mode 100644
index 0000000..30b972b
--- /dev/null
+++ b/src/Tizen.Multimedia.Metadata/MetadataEditor/MetadataEditorAttr.cs
@@ -0,0 +1,35 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+namespace Tizen.Multimedia
+{
+ internal enum MetadataEditorAttr
+ {
+ Artist,
+ Title,
+ Album,
+ Genre,
+ Author,
+ Copyright,
+ Date,
+ Description,
+ Comment,
+ TrackNumber,
+ PictureCount,
+ Conductor,
+ UnsyncLyrics,
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Multimedia.Metadata/MetadataEditor/MetadataEditorErrorFactory.cs b/src/Tizen.Multimedia.Metadata/MetadataEditor/MetadataEditorErrorFactory.cs
new file mode 100644
index 0000000..8875b0f
--- /dev/null
+++ b/src/Tizen.Multimedia.Metadata/MetadataEditor/MetadataEditorErrorFactory.cs
@@ -0,0 +1,66 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+using System;
+using System.IO;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Enumeration for metadata extractor's error codes.
+ /// </summary>
+ internal enum MetadataEditorError
+ {
+ None = ErrorCode.None, // Success
+ InvalidParameter = ErrorCode.InvalidParameter, // Invalid parameter
+ OutOfMemory = ErrorCode.OutOfMemory, // Out of memory
+ FileNotExists = ErrorCode.FileExists, // File does not exist
+ PermissionDenied = ErrorCode.PermissionDenied, // Permission deny
+ NotSupported = ErrorCode.NotSupported, // Unsupported type
+ TizenMetadataEditorError = -0x019C0000,
+ OperationFailed = TizenMetadataEditorError | 0x01 // Invalid operation
+ };
+
+ internal static class MetadataEditorErrorFactory
+ {
+ internal static void ThrowIfError(MetadataEditorError errorCode, string errorMessage)
+ {
+ switch (errorCode)
+ {
+ case MetadataEditorError.InvalidParameter:
+ throw new ArgumentException(errorMessage);
+
+ case MetadataEditorError.OutOfMemory:
+ throw new OutOfMemoryException(errorMessage);
+
+ case MetadataEditorError.FileNotExists:
+ throw new FileNotFoundException(errorMessage);
+
+ case MetadataEditorError.PermissionDenied:
+ throw new UnauthorizedAccessException(errorMessage);
+
+ case MetadataEditorError.NotSupported:
+ throw new NotSupportedException(errorMessage);
+
+ case MetadataEditorError.OperationFailed:
+ throw new InvalidOperationException(errorMessage);
+ }
+ }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Metadata/MetadataExtractor/Artwork.cs b/src/Tizen.Multimedia.Metadata/MetadataExtractor/Artwork.cs
new file mode 100755
index 0000000..e1fcb83
--- /dev/null
+++ b/src/Tizen.Multimedia.Metadata/MetadataExtractor/Artwork.cs
@@ -0,0 +1,48 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents artwork information of media.
+ /// </summary>
+ public class Artwork
+ {
+ /// <summary>
+ /// Initializes a new instance of the Artwork class with the specified data and mimeType.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="data">The data of the artwork to set metadata.</param>
+ /// <param name="mimeType">The mime type of the data of the artwork.</param>
+ public Artwork(byte[] data, string mimeType)
+ {
+ Data = data;
+ MimeType = mimeType;
+ }
+
+ /// <summary>
+ /// The encoded artwork image.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public byte[] Data { get; }
+
+ /// <summary>
+ /// The mime type of artwork.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string MimeType { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia.Metadata/MetadataExtractor/Metadata.cs b/src/Tizen.Multimedia.Metadata/MetadataExtractor/Metadata.cs
new file mode 100755
index 0000000..561bb8b
--- /dev/null
+++ b/src/Tizen.Multimedia.Metadata/MetadataExtractor/Metadata.cs
@@ -0,0 +1,403 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Diagnostics;
+using static Interop.MetadataExtractor;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents video metadata information.
+ /// </summary>
+ public class VideoMetadata
+ {
+
+ protected VideoMetadata()
+ {
+ }
+
+ internal VideoMetadata(IntPtr handle)
+ {
+ Debug.Assert(handle != IntPtr.Zero);
+
+ StreamCount = GetMetadata(handle, MetadataExtractorAttr.VideoStreamCount);
+
+ if (StreamCount == null || (StreamCount != null && StreamCount.Equals("0") == false))
+ {
+ Bitrate = GetMetadata(handle, MetadataExtractorAttr.VideoBitrate);
+ Fps = GetMetadata(handle, MetadataExtractorAttr.VideoFps);
+ Width = GetMetadata(handle, MetadataExtractorAttr.VideoWidth);
+ Height = GetMetadata(handle, MetadataExtractorAttr.VideoHeight);
+ Codec = GetMetadata(handle, MetadataExtractorAttr.VideoCodec);
+ }
+
+ _description = new Lazy<string>(() => ObjectDescriptionBuilder.BuildWithProperties(this));
+ }
+
+ /// <summary>
+ /// Gets the bitrate.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the bitrate, or null if the information does not exists.</value>
+ public string Bitrate { get; }
+
+ /// <summary>
+ /// Gets the video FPS.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the fps, or null if the information does not exists.</value>
+ public string Fps { get; }
+
+ /// <summary>
+ /// Gets the width of the video.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the width, or null if the information does not exists.</value>
+ public string Width { get; }
+
+ /// <summary>
+ /// Gets the height of the video.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the height, or null if the information does not exists.</value>
+ public string Height { get; }
+
+ /// <summary>
+ /// Get the codec type of the video.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the codec type, or null if the information does not exists.</value>
+ public string Codec { get; }
+
+ /// <summary>
+ /// Gets the video stream count.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the video stream count, or null if the information does not exists.</value>
+ public string StreamCount { get; }
+
+ private Lazy<string> _description;
+
+ public override string ToString()
+ {
+ return _description.Value;
+ }
+
+ }
+
+ /// <summary>
+ /// Represents audio metadata information.
+ /// </summary>
+ public class AudioMetadata
+ {
+
+ protected AudioMetadata()
+ {
+ }
+
+ internal AudioMetadata(IntPtr handle)
+ {
+ Debug.Assert(handle != IntPtr.Zero);
+
+ StreamCount = GetMetadata(handle, MetadataExtractorAttr.AudioStreamCount);
+
+ if (StreamCount == null || (StreamCount != null && !StreamCount.Equals("0")))
+ {
+ Bitrate = GetMetadata(handle, MetadataExtractorAttr.AudioBitrate);
+ Channels = GetMetadata(handle, MetadataExtractorAttr.AudioChannels);
+ Samplerate = GetMetadata(handle, MetadataExtractorAttr.AudioSamplerate);
+ BitPerSample = GetMetadata(handle, MetadataExtractorAttr.AudioBitPerSample);
+ Codec = GetMetadata(handle, MetadataExtractorAttr.AudioCodec);
+ }
+
+ _description = new Lazy<string>(() => ObjectDescriptionBuilder.BuildWithProperties(this));
+ }
+
+ /// <summary>
+ /// Gets the audio bitrate.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the bitrate, or null if the information does not exists.</value>
+ public string Bitrate { get; }
+
+ /// <summary>
+ /// Gets the audio channels.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the audio channels, or null if the information does not exists.</value>
+ public string Channels { get; }
+
+ /// <summary>
+ /// Gets the audio sample rate.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the sample rate, or null if the information does not exists.</value>
+ public string Samplerate { get; }
+
+ /// <summary>
+ /// Gets the bit per sample of the audio.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the bit oer sample, or null if the information does not exists.</value>
+ public string BitPerSample { get; }
+
+ /// <summary>
+ /// Gets the audio stream count.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the audio stream count, or null if the information does not exists.</value>
+ public string StreamCount { get; }
+
+ /// <summary>
+ /// Gets the audio codec type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Codec { get; }
+
+ private Lazy<string> _description;
+
+ public override string ToString()
+ {
+ return _description.Value;
+ }
+ }
+
+ /// <summary>
+ /// Represents metadata information of a media.
+ /// </summary>
+ public class Metadata
+ {
+
+ protected Metadata()
+ {
+ }
+
+ internal Metadata(IntPtr handle)
+ {
+ Debug.Assert(handle != IntPtr.Zero);
+
+ Video = new VideoMetadata(handle);
+ Audio = new AudioMetadata(handle);
+
+ Duration = GetMetadata(handle, MetadataExtractorAttr.Duration);
+ Artist = GetMetadata(handle, MetadataExtractorAttr.Artist);
+ Title = GetMetadata(handle, MetadataExtractorAttr.Title);
+ Album = GetMetadata(handle, MetadataExtractorAttr.Album);
+ AlbumArtist = GetMetadata(handle, MetadataExtractorAttr.AlbumArtist);
+ Genre = GetMetadata(handle, MetadataExtractorAttr.Genre);
+ Author = GetMetadata(handle, MetadataExtractorAttr.Author);
+ Copyright = GetMetadata(handle, MetadataExtractorAttr.Copyright);
+ ReleaseDate = GetMetadata(handle, MetadataExtractorAttr.ReleaseDate);
+ Description = GetMetadata(handle, MetadataExtractorAttr.Description);
+ Comment = GetMetadata(handle, MetadataExtractorAttr.Comment);
+ TrackNumber = GetMetadata(handle, MetadataExtractorAttr.TrackNum);
+ Classification = GetMetadata(handle, MetadataExtractorAttr.Classification);
+ Rating = GetMetadata(handle, MetadataExtractorAttr.Rating);
+ Longitude = GetMetadata(handle, MetadataExtractorAttr.Longitude);
+ Latitude = GetMetadata(handle, MetadataExtractorAttr.Latitude);
+ Altitude = GetMetadata(handle, MetadataExtractorAttr.Altitude);
+ Conductor = GetMetadata(handle, MetadataExtractorAttr.Conductor);
+ UnsyncLyric = GetMetadata(handle, MetadataExtractorAttr.UnSyncLyrics);
+ SyncLyricCount = GetMetadata(handle, MetadataExtractorAttr.SyncLyricsNum);
+ RecordingDate = GetMetadata(handle, MetadataExtractorAttr.RecordingDate);
+ Rotation = GetMetadata(handle, MetadataExtractorAttr.Rotate);
+ Content360 = GetMetadata(handle, MetadataExtractorAttr.ContentFor360);
+
+ _description = new Lazy<string>(() => ObjectDescriptionBuilder.BuildWithProperties(this));
+ }
+
+ /// <summary>
+ /// Gets the duration of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the duration, or null if the information does not exists.</value>
+ public string Duration { get; }
+
+ /// <summary>
+ /// Gets the video metadata.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public VideoMetadata Video { get; }
+
+ /// <summary>
+ /// Gets the audio metadata.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public AudioMetadata Audio { get; }
+
+ /// <summary>
+ /// Gets the artist of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the artist, or null if the information does not exists.</value>
+ public string Artist { get; }
+
+ /// <summary>
+ /// Gets the title of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the title, or null if the information does not exists.</value>
+ public string Title { get; }
+
+ /// <summary>
+ /// Gets the album name of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the album name, or null if the information does not exists.</value>
+ public string Album { get; }
+
+ /// <summary>
+ /// Gets the album artist of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the album artist, or null if the information does not exists.</value>
+ public string AlbumArtist { get; }
+
+ /// <summary>
+ /// Gets the genre of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the genre, or null if the information does not exists.</value>
+ public string Genre { get; }
+
+ /// <summary>
+ /// Gets the author of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the author, or null if the information does not exists.</value>
+ public string Author { get; }
+
+ /// <summary>
+ /// Gets the copyright of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the copyright, or null if the information does not exists.</value>
+ public string Copyright { get; }
+
+ /// <summary>
+ /// Gets the release date of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the release date, or null if the information does not exists.</value>
+ public string ReleaseDate { get; }
+
+ /// <summary>
+ /// Gets the description of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the description, or null if the information does not exists.</value>
+ public string Description { get; }
+
+ /// <summary>
+ /// Gets the comment of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the comment, or null if the information does not exists.</value>
+ public string Comment { get; }
+
+ /// <summary>
+ /// Gets the track number of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the track number, or null if the information does not exists.</value>
+ public string TrackNumber { get; }
+
+ /// <summary>
+ /// Gets the classification of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the classification, or null if the information does not exists.</value>
+ public string Classification { get; }
+
+ /// <summary>
+ /// Gets the rating of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the rating, or null if the information does not exists.</value>
+ public string Rating { get; }
+
+ /// <summary>
+ /// Gets the longitude of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the longitude, or null if the information does not exists.</value>
+ public string Longitude { get; }
+
+ /// <summary>
+ /// Gets the latitude of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the latitude, or null if the information does not exists.</value>
+ public string Latitude { get; }
+
+ /// <summary>
+ /// Gets the altitude of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the altitude, or null if the information does not exists.</value>
+ public string Altitude { get; }
+
+ /// <summary>
+ /// Gets the conductor of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the conductor, or null if the information does not exists.</value>
+ public string Conductor { get; }
+
+ /// <summary>
+ /// Gets the unsynchronized lyrics of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the unsynchronized lyrics, or null if the information does not exists.</value>
+ public string UnsyncLyric { get; }
+
+ /// <summary>
+ /// Gets the number of synchronized lyrics of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the number of the synchronized lyrics, or null if the information does not exists.</value>
+ public string SyncLyricCount { get; }
+
+ /// <summary>
+ /// Gets the recording date of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the recording date, or null if the information does not exists.</value>
+ public string RecordingDate { get; }
+
+ /// <summary>
+ /// Gets the rotate(orientation) information of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the rotation information, or null if the information does not exists.</value>
+ public string Rotation { get; }
+
+ /// <summary>
+ /// Gets the information for 360 content of the media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A string representing the information for 360 content, or null if the information does not exists.</value>
+ public string Content360 { get; }
+
+ private Lazy<string> _description;
+
+ public override string ToString()
+ {
+ return _description.Value;
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Metadata/MetadataExtractor/MetadataExtractor.cs b/src/Tizen.Multimedia.Metadata/MetadataExtractor/MetadataExtractor.cs
new file mode 100755
index 0000000..7b49cdf
--- /dev/null
+++ b/src/Tizen.Multimedia.Metadata/MetadataExtractor/MetadataExtractor.cs
@@ -0,0 +1,315 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Multimedia
+{
+ static internal class MetadataExtractorLog
+ {
+ internal const string Tag = "Tizen.Multimedia.MetadataExtractor";
+ }
+
+ /// <summary>
+ /// Provides a set of functions to get the metadata from a media file.
+ /// </summary>
+ public class MetadataExtractor : IDisposable
+ {
+ private bool _disposed = false;
+ private IntPtr _handle = IntPtr.Zero;
+ private IntPtr _buffer = IntPtr.Zero;
+
+ private void Create(Func<MetadataExtractorError> initFunc)
+ {
+ MetadataExtractorRetValidator.ThrowIfError(
+ Interop.MetadataExtractor.Create(out _handle), "Failed to create metadata");
+
+ try
+ {
+ MetadataExtractorRetValidator.ThrowIfError(initFunc(), "Failed to init");
+
+ _metadata = new Lazy<Metadata>(() => new Metadata(Handle));
+ }
+ catch
+ {
+ Release();
+ throw;
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the MetadataExtractor class with the specified path.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="path">The path for the file to extract metadata.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
+ /// <exception cref="FileNotFoundException"><paramref name="path"/> is not exist.</exception>
+ public MetadataExtractor(string path)
+ {
+ if (path == null)
+ {
+ throw new ArgumentNullException(nameof(path));
+ }
+
+ Create(() => Interop.MetadataExtractor.SetPath(_handle, path));
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the MetadataExtractor class with the specified buffer.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="buffer">The buffer to extract metadata.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception>
+ /// <exception cref="ArgumentException">The length of <paramref name="buffer"/> is zero.</exception>
+ public MetadataExtractor(byte[] buffer)
+ {
+ if (buffer == null)
+ {
+ throw new ArgumentNullException(nameof(buffer));
+ }
+
+ if (buffer.Length == 0)
+ {
+ throw new ArgumentException("buffer length is zero.", nameof(buffer));
+ }
+
+ _buffer = Marshal.AllocHGlobal(buffer.Length);
+ Marshal.Copy(buffer, 0, _buffer, buffer.Length);
+
+ try
+ {
+ Create(() => Interop.MetadataExtractor.SetBuffer(_handle, _buffer, buffer.Length));
+ }
+ catch (Exception)
+ {
+ Marshal.FreeHGlobal(_buffer);
+ throw;
+ }
+ }
+
+ private IntPtr Handle
+ {
+ get
+ {
+ if (_disposed)
+ {
+ throw new ObjectDisposedException(nameof(MetadataExtractor));
+ }
+
+ return _handle;
+ }
+ }
+
+ private Lazy<Metadata> _metadata;
+
+ /// <summary>
+ /// Retrieves the <see cref="Metadata"/>.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>A <see cref="Metadata"/> for the given source.</returns>
+ /// <exception cref="InvalidOperationException">Internal process error is occurred.</exception>
+ /// <exception cref="ObjectDisposedException">The <see cref="MetadataExtractor"/> has been already disposed of.</exception>
+ public Metadata GetMetadata()
+ {
+ if (_disposed)
+ {
+ throw new ObjectDisposedException(nameof(MetadataExtractor));
+ }
+
+ return _metadata.Value;
+ }
+
+ /// <summary>
+ /// Gets the artwork image in the source.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>A <see cref="Artwork"/> if it exists, otherwise null.</returns>
+ /// <exception cref="InvalidOperationException">Internal process error is occurred.</exception>
+ /// <exception cref="ObjectDisposedException">The <see cref="MetadataExtractor"/> has been already disposed of.</exception>
+ public Artwork GetArtwork()
+ {
+ IntPtr data = IntPtr.Zero;
+ IntPtr mimeType = IntPtr.Zero;
+
+ try
+ {
+ int size = 0;
+
+ var ret = Interop.MetadataExtractor.GetArtwork(Handle, out data, out size, out mimeType);
+ MetadataExtractorRetValidator.ThrowIfError(ret, "Failed to get value");
+
+ if (size > 0)
+ {
+ var buf = new byte[size];
+ Marshal.Copy(data, buf, 0, size);
+
+ return new Artwork(buf, Marshal.PtrToStringAnsi(mimeType));
+ }
+
+ return null;
+ }
+ finally
+ {
+ Interop.Libc.Free(data);
+ Interop.Libc.Free(mimeType);
+ }
+ }
+
+ /// <summary>
+ /// Gets the sync lyrics of the source.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="index">The index of lyrics to retrieve.</param>
+ /// <returns>A <see cref="SyncLyrics"/> object if <paramref name="index"/> is valid, otherwise null.</returns>
+ /// <exception cref="InvalidOperationException">Internal process error is occurred.</exception>
+ /// <exception cref="ObjectDisposedException">The <see cref="MetadataExtractor"/> has been already disposed of.</exception>
+ public SyncLyrics GetSyncLyrics(int index)
+ {
+ IntPtr lyrics = IntPtr.Zero;
+
+ try
+ {
+ uint timestamp = 0;
+
+ var ret = Interop.MetadataExtractor.GetSynclyrics(Handle, index, out timestamp, out lyrics);
+ MetadataExtractorRetValidator.ThrowIfError(ret, "Failed to get sync lyrics");
+
+ if (lyrics == IntPtr.Zero)
+ {
+ return null;
+ }
+
+ return new SyncLyrics(Marshal.PtrToStringAnsi(lyrics), timestamp);
+ }
+ finally
+ {
+ Interop.Libc.Free(lyrics);
+ }
+ }
+
+ /// <summary>
+ /// Gets the frame of a video media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>The raw thumbnail data in RGB888 if it exists, otherwise null.</returns>
+ /// <exception cref="InvalidOperationException">Internal process error is occurred.</exception>
+ /// <exception cref="ObjectDisposedException">The <see cref="MetadataExtractor"/> has been already disposed of.</exception>
+ public byte[] GetVideoThumbnail()
+ {
+ IntPtr data = IntPtr.Zero;
+
+ try
+ {
+ int size = 0;
+
+ var ret = Interop.MetadataExtractor.GetFrame(Handle, out data, out size);
+ MetadataExtractorRetValidator.ThrowIfError(ret, "Failed to get value");
+
+ if (size == 0)
+ {
+ return null;
+ }
+
+ var buf = new byte[size];
+ Marshal.Copy(data, buf, 0, size);
+
+ return buf;
+ }
+ finally
+ {
+ Interop.Libc.Free(data);
+ }
+ }
+
+ /// <summary>
+ /// Gets the frame of a video media.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="timeStamp">The timestamp in milliseconds.</param>
+ /// <param name="accurate">true to get an accurate frame for the given timestamp,
+ /// otherwise false to get the nearest i-frame of the video rapidly.</param>
+ /// <returns>The raw frame data in RGB888 if a frame at specified time exists, otherwise null.</returns>
+ /// <exception cref="InvalidOperationException"> When internal process error is occured</exception>
+ /// <exception cref="ObjectDisposedException">The <see cref="MetadataExtractor"/> has been already disposed of.</exception>
+ public byte[] GetFrameAt(uint timeStamp, bool accurate)
+ {
+ IntPtr data = IntPtr.Zero;
+
+ try
+ {
+ int size = 0;
+
+ var ret = Interop.MetadataExtractor.GetFrameAtTime(Handle, timeStamp, accurate, out data, out size);
+ MetadataExtractorRetValidator.ThrowIfError(ret, "Failed to get value");
+
+ if (size == 0)
+ {
+ return null;
+ }
+
+ var buf = new byte[size];
+ Marshal.Copy(data, buf, 0, size);
+
+ return buf;
+ }
+ finally
+ {
+ Interop.Libc.Free(data);
+ }
+ }
+
+ /// <summary>
+ /// Metadata Extractor destructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ ~MetadataExtractor()
+ {
+ Dispose(false);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ Release();
+ _disposed = true;
+ }
+ }
+
+ private void Release()
+ {
+ if (_buffer != IntPtr.Zero)
+ {
+ Marshal.FreeHGlobal(_buffer);
+ }
+
+ if (_handle != IntPtr.Zero)
+ {
+ var ret = Interop.MetadataExtractor.Destroy(_handle);
+ Log.Error(MetadataExtractorLog.Tag, $"DestroyHandle failed : {ret}.");
+
+ _handle = IntPtr.Zero;
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Metadata/MetadataExtractor/MetadataExtractorAttr.cs b/src/Tizen.Multimedia.Metadata/MetadataExtractor/MetadataExtractorAttr.cs
new file mode 100644
index 0000000..8388dec
--- /dev/null
+++ b/src/Tizen.Multimedia.Metadata/MetadataExtractor/MetadataExtractorAttr.cs
@@ -0,0 +1,57 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+namespace Tizen.Multimedia
+{
+ internal enum MetadataExtractorAttr
+ {
+ Duration,
+ VideoBitrate,
+ VideoFps,
+ VideoWidth,
+ VideoHeight,
+ VideoStreamCount,
+ AudioBitrate,
+ AudioChannels,
+ AudioSamplerate,
+ AudioBitPerSample,
+ AudioStreamCount,
+ Artist,
+ Title,
+ Album,
+ AlbumArtist,
+ Genre,
+ Author,
+ Copyright,
+ ReleaseDate,
+ Description,
+ Comment,
+ TrackNum,
+ Classification,
+ Rating,
+ Longitude,
+ Latitude,
+ Altitude,
+ Conductor,
+ UnSyncLyrics,
+ SyncLyricsNum,
+ RecordingDate,
+ Rotate,
+ VideoCodec,
+ AudioCodec,
+ ContentFor360,
+ }
+}
diff --git a/src/Tizen.Multimedia.Metadata/MetadataExtractor/MetadataExtractorError.cs b/src/Tizen.Multimedia.Metadata/MetadataExtractor/MetadataExtractorError.cs
new file mode 100644
index 0000000..9902b33
--- /dev/null
+++ b/src/Tizen.Multimedia.Metadata/MetadataExtractor/MetadataExtractorError.cs
@@ -0,0 +1,62 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+using System;
+using System.IO;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Enumeration for metadata extractor's error codes.
+ /// </summary>
+ internal enum MetadataExtractorError
+ {
+ None = ErrorCode.None,
+ InvalidParameter = ErrorCode.InvalidParameter,
+ OutOfMemory = ErrorCode.OutOfMemory,
+ FileExists = ErrorCode.FileExists,
+ PermissionDenied = ErrorCode.PermissionDenied,
+ TizenMetadataExtractorError = -0x01930000,
+ OperationFailed = TizenMetadataExtractorError | 0x01 // Invalid operation
+ };
+
+ internal static class MetadataExtractorRetValidator
+ {
+ internal static void ThrowIfError(MetadataExtractorError error, string errorMessage)
+ {
+ switch (error)
+ {
+ case MetadataExtractorError.InvalidParameter:
+ throw new ArgumentException(errorMessage);
+
+ case MetadataExtractorError.FileExists:
+ throw new FileNotFoundException(errorMessage);
+
+ case MetadataExtractorError.PermissionDenied:
+ throw new UnauthorizedAccessException(errorMessage);
+
+ case MetadataExtractorError.OutOfMemory:
+ throw new OutOfMemoryException();
+
+ case MetadataExtractorError.OperationFailed:
+ throw new InvalidOperationException(errorMessage);
+ }
+ }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Metadata/MetadataExtractor/SyncLyrics.cs b/src/Tizen.Multimedia.Metadata/MetadataExtractor/SyncLyrics.cs
new file mode 100755
index 0000000..a12d730
--- /dev/null
+++ b/src/Tizen.Multimedia.Metadata/MetadataExtractor/SyncLyrics.cs
@@ -0,0 +1,48 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents synchronized lyrics information of media.
+ /// </summary>
+ public class SyncLyrics
+ {
+ /// <summary>
+ /// Initialize a new instance of the MetadataExtractor class with the specified lyrics and timestamp.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="lyrics">The text of synclyrics to set.</param>
+ /// <param name="timestamp">The timestamp of synclyrics to set.</param>
+ public SyncLyrics(string lyrics, uint timestamp)
+ {
+ Lyrics = lyrics;
+ Timestamp = timestamp;
+ }
+
+ /// <summary>
+ /// The text representation of the lyrics.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Lyrics { get; }
+
+ /// <summary>
+ /// The time information of the lyrics.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public uint Timestamp { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia.Metadata/ObjectDescriptionBuilder.cs b/src/Tizen.Multimedia.Metadata/ObjectDescriptionBuilder.cs
new file mode 100644
index 0000000..96f1f68
--- /dev/null
+++ b/src/Tizen.Multimedia.Metadata/ObjectDescriptionBuilder.cs
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Reflection;
+using System.Text;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents a point in 2D space.
+ /// </summary>
+ internal static class ObjectDescriptionBuilder
+ {
+ internal static string BuildWithProperties(object obj)
+ {
+ StringBuilder sb = new StringBuilder();
+
+ foreach (var property in obj.GetType().GetRuntimeProperties())
+ {
+ object value = property.GetValue(obj);
+
+ sb.Append(property.Name).Append("=");
+
+ bool isObjectType = Convert.GetTypeCode(value) == TypeCode.Object;
+
+ if (isObjectType)
+ {
+ sb.Append("[").Append(value).Append("]");
+ }
+ else
+ {
+ sb.Append(value);
+ }
+
+ sb.Append(", ");
+ }
+ if (sb.Length >= 2)
+ {
+ sb.Remove(sb.Length - 1, 2);
+ }
+
+ return sb.ToString();
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Metadata/Tizen.Multimedia.Metadata.csproj b/src/Tizen.Multimedia.Metadata/Tizen.Multimedia.Metadata.csproj
new file mode 100644
index 0000000..0e5378c
--- /dev/null
+++ b/src/Tizen.Multimedia.Metadata/Tizen.Multimedia.Metadata.csproj
@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen.Multimedia\Tizen.Multimedia.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Multimedia.Radio/Interop/Interop.Libraries.cs b/src/Tizen.Multimedia.Radio/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..f237099
--- /dev/null
+++ b/src/Tizen.Multimedia.Radio/Interop/Interop.Libraries.cs
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ internal static partial class Interop
+ {
+ internal static partial class Libraries
+ {
+ public const string Radio = "libcapi-media-radio.so.0";
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Radio/Interop/Interop.Radio.cs b/src/Tizen.Multimedia.Radio/Interop/Interop.Radio.cs
new file mode 100644
index 0000000..929324b
--- /dev/null
+++ b/src/Tizen.Multimedia.Radio/Interop/Interop.Radio.cs
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Multimedia
+{
+ internal static partial class Interop
+ {
+ internal static class Radio
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void SeekCompletedCallback(int frequency, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ScanUpdatedCallback(int frequency, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ScanStoppedCallback(IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ScanCompletedCallback(IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void InterruptedCallback(RadioInterruptedReason reason, IntPtr userData);
+
+
+ [DllImport(Libraries.Radio, EntryPoint = "radio_create")]
+ internal static extern RadioError Create(out RadioHandle radio);
+
+ [DllImport(Libraries.Radio, EntryPoint = "radio_destroy")]
+ internal static extern RadioError Destroy(IntPtr radio);
+
+ [DllImport(Libraries.Radio, EntryPoint = "radio_get_state")]
+ internal static extern RadioError GetState(RadioHandle radio, out RadioState state);
+
+ [DllImport(Libraries.Radio, EntryPoint = "radio_start")]
+ internal static extern RadioError Start(RadioHandle radio);
+
+ [DllImport(Libraries.Radio, EntryPoint = "radio_stop")]
+ internal static extern RadioError Stop(RadioHandle radio);
+
+ [DllImport(Libraries.Radio, EntryPoint = "radio_seek_up")]
+ internal static extern RadioError SeekUp(RadioHandle radio, SeekCompletedCallback callback,
+ IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.Radio, EntryPoint = "radio_seek_down")]
+ internal static extern RadioError SeekDown(RadioHandle radio, SeekCompletedCallback callback,
+ IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.Radio, EntryPoint = "radio_set_frequency")]
+ internal static extern RadioError SetFrequency(RadioHandle radio, int frequency);
+
+ [DllImport(Libraries.Radio, EntryPoint = "radio_get_frequency")]
+ internal static extern RadioError GetFrequency(RadioHandle radio, out int frequency);
+
+ [DllImport(Libraries.Radio, EntryPoint = "radio_get_signal_strength")]
+ internal static extern RadioError GetSignalStrength(RadioHandle radio, out int strength);
+
+ [DllImport(Libraries.Radio, EntryPoint = "radio_scan_start")]
+ internal static extern RadioError ScanStart(RadioHandle radio, ScanUpdatedCallback callback,
+ IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.Radio, EntryPoint = "radio_scan_stop")]
+ internal static extern RadioError ScanStop(RadioHandle radio, ScanStoppedCallback callback,
+ IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.Radio, EntryPoint = "radio_set_mute")]
+ internal static extern RadioError SetMute(RadioHandle radio, bool muted);
+
+ [DllImport(Libraries.Radio, EntryPoint = "radio_is_muted")]
+ internal static extern RadioError GetMuted(RadioHandle radio, out bool muted);
+
+ [DllImport(Libraries.Radio, EntryPoint = "radio_set_scan_completed_cb")]
+ internal static extern RadioError SetScanCompletedCb(RadioHandle radio,
+ ScanCompletedCallback callback, IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.Radio, EntryPoint = "radio_unset_scan_completed_cb")]
+ internal static extern RadioError UnsetScanCompletedCb(RadioHandle radio);
+
+ [DllImport(Libraries.Radio, EntryPoint = "radio_set_interrupted_cb")]
+ internal static extern RadioError SetInterruptedCb(RadioHandle radio,
+ InterruptedCallback callback, IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.Radio, EntryPoint = "radio_unset_interrupted_cb")]
+ internal static extern RadioError UnsetInterruptedCb(RadioHandle radio);
+
+ [DllImport(Libraries.Radio, EntryPoint = "radio_get_frequency_range")]
+ internal static extern RadioError GetFrequencyRange(RadioHandle radio, out int minFreq, out int maxFreq);
+
+ [DllImport(Libraries.Radio, EntryPoint = "radio_get_channel_spacing")]
+ internal static extern RadioError GetChannelSpacing(RadioHandle radio, out int channelSpacing);
+
+ [DllImport(Libraries.Radio, EntryPoint = "radio_set_volume")]
+ internal static extern RadioError SetVolume(RadioHandle radio, float volume);
+
+ [DllImport(Libraries.Radio, EntryPoint = "radio_get_volume")]
+ internal static extern RadioError GetVolume(RadioHandle radio, out float volume);
+ }
+
+ internal class RadioHandle : SafeHandle
+ {
+ protected RadioHandle() : base(IntPtr.Zero, true)
+ {
+ }
+
+ public override bool IsInvalid => handle == IntPtr.Zero;
+
+ protected override bool ReleaseHandle()
+ {
+ var ret = Radio.Destroy(handle);
+ if (ret != RadioError.None)
+ {
+ Log.Debug(GetType().FullName, $"Failed to release native handle.");
+ return false;
+ }
+
+ return true;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Radio/Radio/Radio.cs b/src/Tizen.Multimedia.Radio/Radio/Radio.cs
new file mode 100644
index 0000000..8851afb
--- /dev/null
+++ b/src/Tizen.Multimedia.Radio/Radio/Radio.cs
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+using Tizen.System;
+using static Tizen.Multimedia.Interop.Radio;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides a means for using the radio feature.
+ /// </summary>
+ public class Radio : IDisposable
+ {
+ private Interop.RadioHandle _handle;
+
+ private const string FeatureFmRadio = "http://tizen.org/feature/fmradio";
+
+ /// <summary>
+ /// Initialize a new instance of the Radio class.
+ /// </summary>
+ /// <exception cref="NotSupportedException">Radio feature is not supported</exception>
+ public Radio()
+ {
+ ValidateFeatureSupported(FeatureFmRadio);
+
+ Create(out _handle);
+
+ try
+ {
+ SetScanCompletedCb(_handle, ScanCompleteCallback).ThrowIfFailed("Failed to initialize radio");
+ SetInterruptedCb(_handle, InterruptedCallback).ThrowIfFailed("Failed to initialize radio");
+ }
+ catch (Exception)
+ {
+ _handle.Dispose();
+ throw;
+ }
+ }
+
+ private Interop.RadioHandle Handle
+ {
+ get
+ {
+ if (_disposed)
+ {
+ throw new ObjectDisposedException(GetType().Name);
+ }
+ return _handle;
+ }
+ }
+
+ /// <summary>
+ /// Occurs when radio scan information is updated.
+ /// </summary>
+ public event EventHandler<ScanUpdatedEventArgs> ScanUpdated;
+
+ /// <summary>
+ /// Occurs when radio scanning stops.
+ /// </summary>
+ public event EventHandler ScanStopped;
+
+ /// <summary>
+ /// Occurs when radio scan is completed.
+ /// </summary>
+ public event EventHandler ScanCompleted;
+
+ /// <summary>
+ /// Occurs when radio is interrupted
+ /// </summary>
+ public event EventHandler<RadioInterruptedEventArgs> Interrupted;
+
+ /// <summary>
+ /// Gets the current state of the radio.
+ /// </summary>
+ public RadioState State
+ {
+ get
+ {
+ RadioState state;
+ GetState(Handle, out state);
+ return state;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the radio frequency, in [87500 ~ 108000] (kHz).
+ /// </summary>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="value"/> is less than <see cref="Range.Min"/> of <see cref="FrequencyRange"/>.\n
+ /// - or - \n
+ /// <paramref name="value"/> is greater than <see cref="Range.Max"/> of <see cref="FrequencyRange"/>.\n
+ /// </exception>
+ public int Frequency
+ {
+ get
+ {
+ int value = 0;
+ GetFrequency(Handle, out value).ThrowIfFailed("Failed to get frequency");
+ return value;
+ }
+ set
+ {
+ if (value < FrequencyRange.Min || value > FrequencyRange.Max)
+ {
+ throw new ArgumentOutOfRangeException(nameof(Frequency), value, "Frequency must be within FrequencyRange.");
+ }
+
+ SetFrequency(Handle, value).ThrowIfFailed("Failed to set frequency");
+ }
+ }
+
+ /// <summary>
+ /// Gets the current signal strength, in [-128 ~ 128] (dBm).
+ /// </summary>
+ public int SignalStrength
+ {
+ get
+ {
+ int value = 0;
+ GetSignalStrength(Handle, out value).ThrowIfFailed("Failed to get signal strength");
+ return value;
+ }
+ }
+
+ /// <summary>
+ /// Gets the value indicating if radio is muted.
+ /// </summary>
+ /// <value>
+ /// true if the radio is muted; otherwise, false.
+ /// The default is false.
+ /// </value>
+ public bool IsMuted
+ {
+ get
+ {
+ bool value;
+ GetMuted(Handle, out value).ThrowIfFailed("Failed to get the mute state");
+ return value;
+ }
+ set
+ {
+ SetMute(Handle, value).ThrowIfFailed("Failed to set the mute state");
+ }
+ }
+
+ /// <summary>
+ /// Gets the channel spacing for current region.
+ /// </summary>
+ public int ChannelSpacing
+ {
+ get
+ {
+ int value;
+ GetChannelSpacing(Handle, out value).ThrowIfFailed("Failed to get channel spacing");
+ return value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the radio volume level.
+ /// </summary>
+ /// <remarks>Valid volume range is from 0 to 1.0(100%), inclusive.</remarks>
+ /// <value>The default is 1.0.</value>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="value"/> is less than zero.\n
+ /// - or -\n
+ /// <paramref name="value"/> is greater than 1.0.
+ /// </exception>
+ public float Volume
+ {
+ get
+ {
+ float value;
+ GetVolume(Handle, out value).ThrowIfFailed("Failed to get volume level.");
+ return value;
+ }
+ set
+ {
+ if (value < 0F || 1.0F < value)
+ {
+ throw new ArgumentOutOfRangeException(nameof(value), value,
+ $"Valid volume range is 0 <= value <= 1.0, but got { value }.");
+ }
+
+ SetVolume(Handle, value).ThrowIfFailed("Failed to set volume level");
+ }
+ }
+
+ /// <summary>
+ /// Gets the frequency for the region, in [87500 ~ 108000] (kHz).
+ /// </summary>
+ public Range FrequencyRange
+ {
+ get
+ {
+ int min, max;
+
+ GetFrequencyRange(Handle, out min, out max).ThrowIfFailed("Failed to get frequency range");
+
+ return new Range(min, max);
+ }
+ }
+
+ /// <summary>
+ /// Starts the radio.
+ /// </summary>
+ /// <remarks>The radio must be in the <see cref="RadioState.Ready"/> state.</remarks>
+ /// <exception cref="InvalidOperationException">The radio is not in the valid state.</exception>
+ public void Start()
+ {
+ ValidateRadioState(RadioState.Ready);
+
+ Interop.Radio.Start(Handle).ThrowIfFailed("Failed to start radio");
+ }
+
+ /// <summary>
+ /// Stops the radio.
+ /// </summary>
+ /// <remarks>The radio must be in the <see cref="RadioState.Playing"/> state.</remarks>
+ /// <exception cref="InvalidOperationException">The radio is not in the valid state.</exception>
+ public void Stop()
+ {
+ ValidateRadioState(RadioState.Playing);
+
+ Interop.Radio.Stop(Handle).ThrowIfFailed("Failed to stop radio");
+ }
+
+ /// <summary>
+ /// Starts radio scan, will trigger ScanInformationUpdated event, when scan information is updated
+ /// </summary>
+ /// <remarks>The radio must be in the <see cref="RadioState.Ready"/> or <see cref="RadioState.Playing"/> state.</remarks>
+ /// <exception cref="InvalidOperationException">The radio is not in the valid state.</exception>
+ /// <seealso cref="ScanUpdated"/>
+ /// <seealso cref="ScanCompleted"/>
+ public void StartScan()
+ {
+ ValidateRadioState(RadioState.Ready, RadioState.Playing);
+
+ ScanStart(Handle, ScanUpdatedCallback);
+ }
+
+ /// <summary>
+ /// Stops radio scan.
+ /// </summary>
+ /// <remarks>The radio must be in the <see cref="RadioState.Scanning"/> state.</remarks>
+ /// <exception cref="InvalidOperationException">The radio is not in the valid state.</exception>
+ /// <seealso cref="ScanStopped"/>
+ public void StopScan()
+ {
+ ValidateRadioState(RadioState.Scanning);
+
+ ScanStop(Handle, ScanStoppedCallback);
+ }
+
+ /// <summary>
+ /// Seeks up the effective frequency of the radio.
+ /// </summary>
+ /// <returns>
+ /// A task that represents the asynchronous seeking operation.
+ /// The result value is the current frequency, in range [87500 ~ 108000] (kHz).
+ /// It can be -1 if the seeking operation has failed.
+ /// </returns>
+ /// <remarks>The radio must be in the <see cref="RadioState.Playing/> state.</remarks>
+ /// <exception cref="InvalidOperationException">The radio is not in the valid state.</exception>
+ public async Task<int> SeekUpAsync()
+ {
+ ValidateRadioState(RadioState.Playing);
+
+ TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
+ SeekCompletedCallback callback = (currentFrequency, _) =>
+ {
+ tcs.TrySetResult(currentFrequency);
+ };
+
+ SeekUp(Handle, callback);
+ return await tcs.Task;
+ }
+
+ /// <summary>
+ /// Seeks down the effective frequency of the radio.
+ /// </summary>
+ /// <returns>
+ /// A task that represents the asynchronous seeking operation.
+ /// The result value is the current frequency, in range [87500 ~ 108000] (kHz).
+ /// It can be -1 if the seeking operation has failed.
+ /// </returns>
+ /// <remarks>The radio must be in the <see cref="RadioState.Playing/> state.</remarks>
+ /// <exception cref="InvalidOperationException">The radio is not in the valid state.</exception>
+ public async Task<int> SeekDownAsync()
+ {
+ ValidateRadioState(RadioState.Playing);
+
+ TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
+ SeekCompletedCallback callback = (currentFrequency, _) =>
+ {
+ tcs.TrySetResult(currentFrequency);
+ };
+
+ SeekDown(Handle, callback);
+ return await tcs.Task;
+ }
+
+ private void ValidateFeatureSupported(string featurePath)
+ {
+ bool supported = false;
+ SystemInfo.TryGetValue(featurePath, out supported);
+
+ if (supported == false)
+ {
+ throw new NotSupportedException($"The feature({featurePath}) is not supported.");
+ }
+
+ }
+
+ private void ScanUpdatedCallback(int frequency, IntPtr data)
+ {
+ ScanUpdated?.Invoke(this, new ScanUpdatedEventArgs(frequency));
+ }
+
+ private void ScanStoppedCallback(IntPtr data)
+ {
+ ScanStopped?.Invoke(this, EventArgs.Empty);
+ }
+
+ private void ScanCompleteCallback(IntPtr data)
+ {
+ ScanCompleted?.Invoke(this, EventArgs.Empty);
+ }
+
+ private void InterruptedCallback(RadioInterruptedReason reason, IntPtr data)
+ {
+ Interrupted?.Invoke(this, new RadioInterruptedEventArgs(reason));
+ }
+
+ private void ValidateRadioState(params RadioState[] required)
+ {
+ RadioState curState = State;
+
+ if (required.Contains(curState) == false)
+ {
+ throw new InvalidOperationException($"{curState} is not valid state.");
+ }
+ }
+
+ #region IDisposable Support
+ private bool _disposed = false;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (_handle != null)
+ {
+ _handle.Dispose();
+ }
+ _disposed = true;
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by the <see cref="Radio"/> object.
+ /// </summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+ #endregion
+ }
+}
diff --git a/src/Tizen.Multimedia.Radio/Radio/RadioError.cs b/src/Tizen.Multimedia.Radio/Radio/RadioError.cs
new file mode 100644
index 0000000..631d9c7
--- /dev/null
+++ b/src/Tizen.Multimedia.Radio/Radio/RadioError.cs
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Multimedia
+{
+
+ internal enum RadioError
+ {
+ None = ErrorCode.None,
+ OutOfMemory = ErrorCode.OutOfMemory,
+ InvalidParameter = ErrorCode.InvalidParameter,
+ InvalidOperation = ErrorCode.InvalidOperation,
+ PermissionDenied = ErrorCode.PermissionDenied,
+ NotSupported = ErrorCode.NotSupported,
+
+ InvalidState = -0x019A0000 | 0x01,
+ SoundPolicy = -0x019A0000 | 0x02,
+ NoAntenna = -0x019A0000 | 0x03,
+ }
+
+ internal static class RadioErrorExtensions
+ {
+ internal static void ThrowIfFailed(this RadioError err, string message)
+ {
+ if (err == RadioError.None)
+ {
+ return;
+ }
+
+ string errMessage = $"{message}; {err}.";
+ switch (err)
+ {
+ case RadioError.PermissionDenied:
+ throw new UnauthorizedAccessException(errMessage);
+
+ case RadioError.InvalidParameter:
+ throw new ArgumentException(errMessage);
+
+ case RadioError.OutOfMemory:
+ throw new OutOfMemoryException(errMessage);
+
+ case RadioError.NotSupported:
+ case RadioError.NoAntenna:
+ throw new NotSupportedException(errMessage);
+
+ default:
+ throw new InvalidOperationException(errMessage);
+ }
+ }
+
+ }
+
+}
diff --git a/src/Tizen.Multimedia.Radio/Radio/RadioInterruptedEventArgs.cs b/src/Tizen.Multimedia.Radio/Radio/RadioInterruptedEventArgs.cs
new file mode 100644
index 0000000..b9ba17d
--- /dev/null
+++ b/src/Tizen.Multimedia.Radio/Radio/RadioInterruptedEventArgs.cs
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides data for the <see cref="Radio.Interrupted"/> event.
+ /// </summary>
+ public class RadioInterruptedEventArgs : EventArgs
+ {
+ internal RadioInterruptedEventArgs(RadioInterruptedReason reason)
+ {
+ Reason = reason;
+ }
+
+ /// <summary>
+ /// Gets the reason.
+ /// </summary
+ public RadioInterruptedReason Reason { get; }
+
+ public override string ToString()
+ {
+ return $"Reason={ Reason.ToString() }";
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Radio/Radio/RadioInterruptedReason.cs b/src/Tizen.Multimedia.Radio/Radio/RadioInterruptedReason.cs
new file mode 100644
index 0000000..d6cb24c
--- /dev/null
+++ b/src/Tizen.Multimedia.Radio/Radio/RadioInterruptedReason.cs
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Specifies <see cref="Radio"/> interrupted reasons.
+ /// </summary>
+ public enum RadioInterruptedReason
+ {
+ /// <summary>
+ /// By a resource conflict.
+ /// </summary>
+ ResourceConflict = 4,
+ }
+}
diff --git a/src/Tizen.Multimedia.Radio/Radio/RadioState.cs b/src/Tizen.Multimedia.Radio/Radio/RadioState.cs
new file mode 100644
index 0000000..38db7f0
--- /dev/null
+++ b/src/Tizen.Multimedia.Radio/Radio/RadioState.cs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Specifies states of the <see cref="Radio"/>.
+ /// </summary>
+ public enum RadioState
+ {
+ /// <summary>
+ /// Ready to play or scan.
+ /// </summary>
+ Ready,
+ /// <summary>
+ /// Playing audio from the tuner.
+ /// </summary>
+ Playing,
+ /// <summary>
+ /// Scanning; searching for the next station for signal.
+ /// </summary>
+ Scanning,
+ }
+}
diff --git a/src/Tizen.Multimedia.Radio/Radio/ScanUpdatedEventArgs.cs b/src/Tizen.Multimedia.Radio/Radio/ScanUpdatedEventArgs.cs
new file mode 100644
index 0000000..b4afe78
--- /dev/null
+++ b/src/Tizen.Multimedia.Radio/Radio/ScanUpdatedEventArgs.cs
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides data for the <see cref="Radio.ScanUpdated"/> event.
+ /// </summary>
+ public class ScanUpdatedEventArgs : EventArgs
+ {
+ internal ScanUpdatedEventArgs(int tunedFrequency)
+ {
+ Frequency = tunedFrequency;
+ }
+
+ /// <summary>
+ /// Gets the tuned radio frequency that is scanned, in range [87500 ~ 108000] (kHz).
+ /// </summary>
+ public int Frequency { get; }
+
+
+ public override string ToString()
+ {
+ return $"Frequency={ Frequency.ToString() }";
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Radio/Tizen.Multimedia.Radio.csproj b/src/Tizen.Multimedia.Radio/Tizen.Multimedia.Radio.csproj
new file mode 100644
index 0000000..0e5378c
--- /dev/null
+++ b/src/Tizen.Multimedia.Radio/Tizen.Multimedia.Radio.csproj
@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen.Multimedia\Tizen.Multimedia.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Multimedia.Recorder/Interop/Interop.Libraries.cs b/src/Tizen.Multimedia.Recorder/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..02fd9df
--- /dev/null
+++ b/src/Tizen.Multimedia.Recorder/Interop/Interop.Libraries.cs
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string Recorder = "libcapi-media-recorder.so.0";
+ }
+}
diff --git a/src/Tizen.Multimedia.Recorder/Interop/Interop.Recorder.cs b/src/Tizen.Multimedia.Recorder/Interop/Interop.Recorder.cs
new file mode 100644
index 0000000..b2f7ab8
--- /dev/null
+++ b/src/Tizen.Multimedia.Recorder/Interop/Interop.Recorder.cs
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Multimedia;
+
+internal static partial class Interop
+{
+ internal static partial class Recorder
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void RecorderErrorCallback(RecorderErrorCode error, RecorderState current, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void InterruptedCallback(RecorderPolicy policy, RecorderState previous, RecorderState current, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void RecordingLimitReachedCallback(RecordingLimitType type, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void RecordingProgressCallback(ulong elapsedTime, ulong fileSize, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void AudioStreamCallback(IntPtr stream, int size, AudioSampleType type, int channel, uint timeStamp, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void StatechangedCallback(RecorderState previous, RecorderState current, bool byPolicy, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MuxedStreamCallback(IntPtr stream, int size, ulong offset, IntPtr userData);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_create_audiorecorder")]
+ internal static extern RecorderError Create(out IntPtr handle);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_create_videorecorder")]
+ internal static extern RecorderError CreateVideo(IntPtr cameraHandle, out IntPtr handle);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_destroy")]
+ internal static extern RecorderError Destroy(IntPtr handle);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_prepare")]
+ internal static extern RecorderError Prepare(IntPtr handle);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_unprepare")]
+ internal static extern RecorderError Unprepare(IntPtr handle);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_start")]
+ internal static extern RecorderError Start(IntPtr handle);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_pause")]
+ internal static extern RecorderError Pause(IntPtr handle);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_commit")]
+ internal static extern RecorderError Commit(IntPtr handle);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_cancel")]
+ internal static extern RecorderError Cancel(IntPtr handle);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_get_state")]
+ internal static extern RecorderError GetState(IntPtr handle, out RecorderState state);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_sound_stream_info")]
+ internal static extern RecorderError SetAudioStreamPolicy(IntPtr handle, IntPtr streamInfoHandle);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_error_cb")]
+ internal static extern RecorderError SetErrorCallback(IntPtr handle, RecorderErrorCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_unset_error_cb")]
+ internal static extern RecorderError UnsetErrorCallback(IntPtr handle);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_interrupted_cb")]
+ internal static extern RecorderError SetInterruptedCallback(IntPtr handle, InterruptedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_unset_interrupted_cb")]
+ internal static extern RecorderError UnsetInterruptedCallback(IntPtr handle);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_state_changed_cb")]
+ internal static extern RecorderError SetStateChangedCallback(IntPtr handle, StatechangedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_unset_state_changed_cb")]
+ internal static extern RecorderError UnsetStateChangedCallback(IntPtr handle);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_recording_status_cb")]
+ internal static extern RecorderError SetRecordingProgressCallback(IntPtr handle, RecordingProgressCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_unset_recording_status_cb")]
+ internal static extern RecorderError UnsetRecordingProgressCallback(IntPtr handle);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_audio_stream_cb")]
+ internal static extern RecorderError SetAudioStreamCallback(IntPtr handle, AudioStreamCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_unset_audio_stream_cb")]
+ internal static extern RecorderError UnsetAudioStreamCallback(IntPtr handle);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_recording_limit_reached_cb")]
+ internal static extern RecorderError SetLimitReachedCallback(IntPtr handle, RecordingLimitReachedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_unset_recording_limit_reached_cb")]
+ internal static extern RecorderError UnsetLimitReachedCallback(IntPtr handle);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_muxed_stream_cb")]
+ internal static extern RecorderError SetMuxedStreamCallback(IntPtr handle, MuxedStreamCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_unset_muxed_stream_cb")]
+ internal static extern RecorderError UnsetMuxedStreamCallback(IntPtr handle);
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Multimedia.Recorder/Interop/Interop.RecorderFeatures.cs b/src/Tizen.Multimedia.Recorder/Interop/Interop.RecorderFeatures.cs
new file mode 100644
index 0000000..77d1ec3
--- /dev/null
+++ b/src/Tizen.Multimedia.Recorder/Interop/Interop.RecorderFeatures.cs
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Multimedia;
+
+internal static partial class Interop
+{
+ internal static partial class RecorderFeatures
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool VideoResolutionCallback(int width, int height, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool FileFormatCallback(RecorderFileFormat format, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool AudioEncoderCallback(RecorderAudioCodec codec, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool VideoEncoderCallback(RecorderVideoCodec codec, IntPtr userData);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_foreach_supported_file_format")]
+ internal static extern RecorderError FileFormats(IntPtr handle, FileFormatCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_foreach_supported_audio_encoder")]
+ internal static extern RecorderError AudioEncoders(IntPtr handle, AudioEncoderCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_foreach_supported_video_encoder")]
+ internal static extern RecorderError VideoEncoders(IntPtr handle, VideoEncoderCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_foreach_supported_video_resolution")]
+ internal static extern RecorderError VideoResolution(IntPtr handle, VideoResolutionCallback callback, IntPtr userData);
+ }
+}
diff --git a/src/Tizen.Multimedia.Recorder/Interop/Interop.RecorderSettings.cs b/src/Tizen.Multimedia.Recorder/Interop/Interop.RecorderSettings.cs
new file mode 100644
index 0000000..f0daf01
--- /dev/null
+++ b/src/Tizen.Multimedia.Recorder/Interop/Interop.RecorderSettings.cs
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Multimedia;
+
+internal static partial class Interop
+{
+ internal static partial class RecorderSettings
+ {
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_get_audio_channel")]
+ internal static extern RecorderError GetAudioChannel(IntPtr handle, out int channelCount);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_audio_channel")]
+ internal static extern RecorderError SetAudioChannel(IntPtr handle, int channelCount);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_get_audio_device")]
+ internal static extern RecorderError GetAudioDevice(IntPtr handle, out RecorderAudioDevice device);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_audio_device")]
+ internal static extern RecorderError SetAudioDevice(IntPtr handle, RecorderAudioDevice device);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_get_audio_level")]
+ internal static extern RecorderError GetAudioLevel(IntPtr handle, out double dB);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_get_audio_samplerate")]
+ internal static extern RecorderError GetAudioSampleRate(IntPtr handle, out int sampleRate);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_audio_samplerate")]
+ internal static extern RecorderError SetAudioSampleRate(IntPtr handle, int sampleRate);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_get_audio_encoder_bitrate")]
+ internal static extern RecorderError GetAudioEncoderBitrate(IntPtr handle, out int bitRate);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_audio_encoder_bitrate")]
+ internal static extern RecorderError SetAudioEncoderBitrate(IntPtr handle, int bitRate);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_get_video_encoder_bitrate")]
+ internal static extern RecorderError GetVideoEncoderBitrate(IntPtr handle, out int bitRate);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_video_encoder_bitrate")]
+ internal static extern RecorderError SetVideoEncoderBitrate(IntPtr handle, int bitRate);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_get_audio_encoder")]
+ internal static extern RecorderError GetAudioEncoder(IntPtr handle, out RecorderAudioCodec codec);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_audio_encoder")]
+ internal static extern RecorderError SetAudioEncoder(IntPtr handle, RecorderAudioCodec codec);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_get_video_encoder")]
+ internal static extern RecorderError GetVideoEncoder(IntPtr handle, out RecorderVideoCodec codec);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_video_encoder")]
+ internal static extern RecorderError SetVideoEncoder(IntPtr handle, RecorderVideoCodec codec);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_get_file_format")]
+ internal static extern RecorderError GetFileFormat(IntPtr handle, out RecorderFileFormat format);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_file_format")]
+ internal static extern RecorderError SetFileFormat(IntPtr handle, RecorderFileFormat format);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_get_filename")]
+ internal static extern RecorderError GetFileName(IntPtr handle, out IntPtr path);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_filename")]
+ internal static extern RecorderError SetFileName(IntPtr handle, string path);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_get_size_limit")]
+ internal static extern RecorderError GetSizeLimit(IntPtr handle, out int kbyte);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_size_limit")]
+ internal static extern RecorderError SetSizeLimit(IntPtr handle, int kbyte);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_get_time_limit")]
+ internal static extern RecorderError GetTimeLimit(IntPtr handle, out int second);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_time_limit")]
+ internal static extern RecorderError SetTimeLimit(IntPtr handle, int second);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_is_muted")]
+ [return: MarshalAs(UnmanagedType.I1)]
+ internal static extern bool GetMute(IntPtr handle);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_mute")]
+ internal static extern RecorderError SetMute(IntPtr handle, bool enable);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_get_recording_motion_rate")]
+ internal static extern RecorderError GetMotionRate(IntPtr handle, out double motionRate);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_recording_motion_rate")]
+ internal static extern RecorderError SetMotionRate(IntPtr handle, double motionRate);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_get_orientation_tag")]
+ internal static extern RecorderError GetOrientationTag(IntPtr handle, out RecorderOrientation orientation);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_orientation_tag")]
+ internal static extern RecorderError SetOrientationTag(IntPtr handle, RecorderOrientation orientation);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_get_video_resolution")]
+ internal static extern RecorderError GetVideoResolution(IntPtr handle, out int width, out int height);
+
+ [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_video_resolution")]
+ internal static extern RecorderError SetVideoResolution(IntPtr handle, int width, int height);
+ }
+}
diff --git a/src/Tizen.Multimedia.Recorder/Recorder/AudioStreamDeliveredEventArgs.cs b/src/Tizen.Multimedia.Recorder/Recorder/AudioStreamDeliveredEventArgs.cs
new file mode 100755
index 0000000..f774918
--- /dev/null
+++ b/src/Tizen.Multimedia.Recorder/Recorder/AudioStreamDeliveredEventArgs.cs
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// An extended EventArgs class containing details of audio stream.
+ /// </summary>
+ public class AudioStreamDeliveredEventArgs : EventArgs
+ {
+ internal AudioStreamDeliveredEventArgs(IntPtr stream, int streamSize, AudioSampleType type, int channel, uint recordingTime)
+ {
+ Stream = new byte[streamSize];
+ Marshal.Copy(stream, Stream, 0, streamSize);
+ StreamLength = streamSize;
+ Type = type;
+ Channel = channel;
+ RecordingTime = recordingTime;
+ }
+
+ /// <summary>
+ /// The audio stream data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public byte[] Stream { get; }
+
+ /// <summary>
+ /// The length of audio stream data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int StreamLength { get; }
+
+ /// <summary>
+ /// The audio format type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public AudioSampleType Type { get; }
+
+ /// <summary>
+ /// The number of channels.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Channel { get; }
+
+ /// <summary>
+ /// The recording time of the stream buffer in milliseconds.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public uint RecordingTime { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia.Recorder/Recorder/MuxedStreamEventArgs.cs b/src/Tizen.Multimedia.Recorder/Recorder/MuxedStreamEventArgs.cs
new file mode 100755
index 0000000..7c6ea85
--- /dev/null
+++ b/src/Tizen.Multimedia.Recorder/Recorder/MuxedStreamEventArgs.cs
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// An extended EventArgs class containing details of muxed stream(Audio + Video).
+ /// </summary>
+ public class MuxedStreamDeliveredEventArgs : EventArgs
+ {
+ internal MuxedStreamDeliveredEventArgs(IntPtr stream, int streamLength, ulong offset)
+ {
+ Stream = new byte[streamLength];
+ Marshal.Copy(stream, Stream, 0, streamLength);
+ StreamLength = streamLength;
+ Offset = offset;
+ }
+
+ /// <summary>
+ /// The muexed stream data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public byte[] Stream { get; }
+
+ /// <summary>
+ /// The length of muxed stream data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int StreamLength { get; }
+
+ /// <summary>
+ /// The offset of the stream data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ulong Offset { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia.Recorder/Recorder/Recorder.cs b/src/Tizen.Multimedia.Recorder/Recorder/Recorder.cs
new file mode 100755
index 0000000..701981c
--- /dev/null
+++ b/src/Tizen.Multimedia.Recorder/Recorder/Recorder.cs
@@ -0,0 +1,482 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Diagnostics;
+using System.Linq;
+using Native = Interop.Recorder;
+
+namespace Tizen.Multimedia
+{
+ static internal class RecorderLog
+ {
+ internal const string Tag = "Tizen.Multimedia.Recorder";
+ }
+
+ /// <summary>
+ /// The recorder class provides methods to create audio/video recorder,
+ /// to start, stop and save the recorded content. It also provides methods
+ /// to get/set various attributes and capabilities of recorder.
+ /// </summary>
+ public class Recorder : IDisposable
+ {
+ private IntPtr _handle = IntPtr.Zero;
+ private bool _disposed = false;
+ private RecorderState _state = RecorderState.None;
+
+ /// <summary>
+ /// Audio recorder constructor.
+ /// </summary>
+ public Recorder()
+ {
+ RecorderErrorFactory.ThrowIfError(Native.Create(out _handle),
+ "Failed to create Audio recorder");
+
+ Feature = new RecorderFeatures(this);
+ Setting = new RecorderSettings(this);
+
+ RegisterCallbacks();
+
+ SetState(RecorderState.Created);
+ }
+
+ /// <summary>
+ /// Video recorder constructor.
+ /// </summary>
+ /// <param name="camera">
+ /// The camera object.
+ /// </param>
+ public Recorder(Camera camera)
+ {
+ RecorderErrorFactory.ThrowIfError(Native.CreateVideo(camera.Handle, out _handle),
+ "Failed to create Video recorder.");
+
+ Feature = new RecorderFeatures(this);
+ Setting = new RecorderSettings(this);
+
+ RegisterCallbacks();
+
+ SetState(RecorderState.Created);
+ }
+
+ /// <summary>
+ /// Recorder destructor.
+ /// </summary>
+ ~Recorder()
+ {
+ Dispose (false);
+ }
+
+ internal IntPtr GetHandle()
+ {
+ ValidateNotDisposed();
+ return _handle;
+ }
+
+ #region Dispose support
+ /// <summary>
+ /// Releases the unmanaged resources used by the Recorder.
+ /// </summary>
+ /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (disposing)
+ {
+ // to be used if there are any other disposable objects
+ }
+ if (_handle != IntPtr.Zero)
+ {
+ Native.Destroy(_handle);
+ _handle = IntPtr.Zero;
+ }
+ _disposed = true;
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by the Recorder.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ internal void ValidateNotDisposed()
+ {
+ if (_disposed)
+ {
+ throw new ObjectDisposedException(nameof(Recorder));
+ }
+ }
+ #endregion Dispose support
+
+ #region Check recorder state
+ internal void ValidateState(params RecorderState[] required)
+ {
+ ValidateNotDisposed();
+
+ Debug.Assert(required.Length > 0);
+
+ var curState = _state;
+ if (!required.Contains(curState))
+ {
+ throw new InvalidOperationException($"The recorder is not in a valid state. " +
+ $"Current State : { curState }, Valid State : { string.Join(", ", required) }.");
+ }
+ }
+
+ internal void SetState(RecorderState state)
+ {
+ _state = state;
+ }
+ #endregion Check recorder state
+
+ #region EventHandlers
+ /// <summary>
+ /// Event that occurs when an error occurs during recorder operation.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<RecordingErrorOccurredEventArgs> ErrorOccurred;
+ private Native.RecorderErrorCallback _errorOccuredCallback;
+
+ /// <summary>
+ /// Event that occurs when recorder is interrupted.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<RecorderInterruptedEventArgs> Interrupted;
+ private Native.InterruptedCallback _interruptedCallback;
+
+ /// <summary>
+ /// This event occurs when recorder state is changed.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<RecorderStateChangedEventArgs> StateChanged;
+ private Native.StatechangedCallback _stateChangedCallback;
+
+ /// <summary>
+ /// Event that occurs when recording information changes.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<RecordingProgressEventArgs> RecordingProgress;
+ private Native.RecordingProgressCallback _recordingProgressCallback;
+
+ /// <summary>
+ /// Event that occurs when audio stream data is being delivered.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<AudioStreamDeliveredEventArgs> AudioStreamDelivered;
+ private Native.AudioStreamCallback _audioStreamCallback;
+
+ /// <summary>
+ /// Event that occurs when recording limit is reached.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<RecordingLimitReachedEventArgs> RecordingLimitReached;
+ private Native.RecordingLimitReachedCallback _recordingLimitReachedCallback;
+
+ /// <summary>
+ /// Event that occurs when muxed stream data is being delivered.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<MuxedStreamDeliveredEventArgs> MuxedStreamDelivered;
+ private Native.MuxedStreamCallback _muxedStreamCallback;
+ #endregion EventHandlers
+
+ #region Properties
+ /// <summary>
+ /// Gets the various recorder features.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public RecorderFeatures Feature { get; }
+
+ /// <summary>
+ /// Get/Set the various recorder settings.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public RecorderSettings Setting { get; }
+
+ /// <summary>
+ /// The current state of the recorder.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A <see cref="RecorderState"/> that specifies the state of recorder.</value>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public RecorderState State
+ {
+ get
+ {
+ ValidateNotDisposed();
+
+ RecorderState val = 0;
+
+ RecorderErrorFactory.ThrowIfError(Native.GetState(_handle, out val),
+ "Failed to get recorder state.");
+
+ return val;
+ }
+ }
+ #endregion Properties
+
+ #region Methods
+ /// <summary>
+ /// Prepare the media recorder for recording.
+ /// The recorder must be in the <see cref="RecorderState.Created"/> state.
+ /// After this method is finished without any exception,
+ /// The state of recorder will be changed to <see cref="RecorderState.Ready"/> state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// Before calling the function, it is required to set AudioEncoder,
+ /// videoencoder and fileformat properties of recorder.
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">In case of any invalid operations.</exception>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public void Prepare()
+ {
+ ValidateState(RecorderState.Created);
+
+ RecorderErrorFactory.ThrowIfError(Native.Prepare(_handle),
+ "Failed to prepare media recorder for recording");
+
+ SetState(RecorderState.Ready);
+ }
+
+ /// <summary>
+ /// Resets the media recorder.
+ /// The recorder must be in the <see cref="RecorderState.Ready"/> state.
+ /// After this method is finished without any exception,
+ /// The state of recorder will be changed to <see cref="RecorderState.Created"/> state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="InvalidOperationException">In case of any invalid operations.</exception>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public void Unprepare()
+ {
+ ValidateState(RecorderState.Ready);
+
+ RecorderErrorFactory.ThrowIfError(Native.Unprepare(_handle),
+ "Failed to reset the media recorder");
+
+ SetState(RecorderState.Created);
+ }
+
+ /// <summary>
+ /// Starts the recording.
+ /// The recorder must be in the <see cref="RecorderState.Ready"/> state.
+ /// After this method is finished without any exception,
+ /// The state of recorder will be changed to <see cref="RecorderState.Recording"/> state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// If file path has been set to an existing file, this file is removed automatically and updated by new one.
+ /// In the video recorder, some preview format does not support record mode. It will return InvalidOperation error.
+ /// You should use default preview format or CameraPixelFormatNv12 in the record mode.
+ /// The filename should be set before this function is invoked.
+ /// </remarks>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <exception cref="InvalidOperationException">In case of any invalid operations.</exception>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ /// <exception cref="UnauthorizedAccessException">In case of access to the resources cannot be granted.</exception>
+ public void Start()
+ {
+ ValidateState(RecorderState.Ready, RecorderState.Paused);
+
+ RecorderErrorFactory.ThrowIfError(Native.Start(_handle),
+ "Failed to start the media recorder");
+
+ SetState(RecorderState.Recording);
+ }
+
+ /// <summary>
+ /// Pause the recording.
+ /// The recorder must be in the <see cref="RecorderState.Recording"/> state.
+ /// After this method is finished without any exception,
+ /// The state of recorder will be changed to <see cref="RecorderState.Paused"/> state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// Recording can be resumed with Start().
+ /// </remarks>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <exception cref="InvalidOperationException">In case of any invalid operations.</exception>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ /// <exception cref="UnauthorizedAccessException">In case of access to the resources cannot be granted.</exception>
+ public void Pause()
+ {
+ ValidateState(RecorderState.Recording);
+
+ RecorderErrorFactory.ThrowIfError(Native.Pause(_handle),
+ "Failed to pause the media recorder");
+
+ SetState(RecorderState.Paused);
+ }
+
+ /// <summary>
+ /// Stops recording and saves the result.
+ /// The recorder must be in the <see cref="RecorderState.Recording"/> or <see cref="RecorderState.Paused"/> state.
+ /// After this method is finished without any exception,
+ /// The state of recorder will be changed to <see cref="RecorderState.Ready"/> state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <exception cref="InvalidOperationException">In case of any invalid operations.</exception>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ /// <exception cref="UnauthorizedAccessException">In case of access to the resources cannot be granted.</exception>
+ public void Commit()
+ {
+ ValidateState(RecorderState.Recording, RecorderState.Paused);
+
+ RecorderErrorFactory.ThrowIfError(Native.Commit(_handle),
+ "Failed to save the recorded content");
+
+ SetState(RecorderState.Ready);
+ }
+
+ /// <summary>
+ /// Cancels the recording.
+ /// The recording data is discarded and not written in the recording file.
+ /// The recorder must be in the <see cref="RecorderState.Recording"/> or <see cref="RecorderState.Paused"/> state.
+ /// After this method is finished without any exception,
+ /// The state of recorder will be changed to <see cref="RecorderState.Ready"/> state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <exception cref="InvalidOperationException">In case of any invalid operations.</exception>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ /// <exception cref="UnauthorizedAccessException">In case of access to the resources cannot be granted.</exception>
+ public void Cancel()
+ {
+ ValidateState(RecorderState.Recording, RecorderState.Paused);
+
+ RecorderErrorFactory.ThrowIfError(Native.Cancel(_handle),
+ "Failed to cancel the recording");
+
+ SetState(RecorderState.Ready);
+ }
+
+ /// <summary>
+ /// Sets the audio stream policy.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="policy">Policy.</param>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public void SetAudioStreamPolicy(AudioStreamPolicy policy)
+ {
+ ValidateNotDisposed();
+
+ RecorderErrorFactory.ThrowIfError(Native.SetAudioStreamPolicy(_handle, policy.Handle),
+ "Failed to set audio stream policy");
+ }
+ #endregion Methods
+
+ #region Callback registrations
+ private void RegisterCallbacks()
+ {
+ RegisterErrorCallback();
+ RegisterInterruptedCallback();
+ RegisterStateChangedCallback();
+ RegisterRecordingProgressCallback();
+ RegisterAudioStreamDeliveredCallback();
+ RegisterRecordingLimitReachedEvent();
+ RegisterMuxedStreamEvent();
+ }
+
+ private void RegisterErrorCallback()
+ {
+ _errorOccuredCallback = (RecorderErrorCode error, RecorderState current, IntPtr userData) =>
+ {
+ ErrorOccurred?.Invoke(this, new RecordingErrorOccurredEventArgs(error, current));
+ };
+ RecorderErrorFactory.ThrowIfError(Native.SetErrorCallback(_handle, _errorOccuredCallback, IntPtr.Zero),
+ "Setting Error callback failed");
+ }
+
+ private void RegisterInterruptedCallback()
+ {
+ _interruptedCallback = (RecorderPolicy policy, RecorderState previous, RecorderState current, IntPtr userData) =>
+ {
+ Interrupted?.Invoke(this, new RecorderInterruptedEventArgs(policy, previous, current));
+ };
+ RecorderErrorFactory.ThrowIfError(Native.SetInterruptedCallback(_handle, _interruptedCallback, IntPtr.Zero),
+ "Setting Interrupted callback failed");
+ }
+
+ private void RegisterStateChangedCallback()
+ {
+ _stateChangedCallback = (RecorderState previous, RecorderState current, bool byPolicy, IntPtr userData) =>
+ {
+ SetState(current);
+ Log.Info(RecorderLog.Tag, "Recorder state changed " + previous.ToString() + " -> " + current.ToString());
+ StateChanged?.Invoke(this, new RecorderStateChangedEventArgs(previous, current, byPolicy));
+ };
+ RecorderErrorFactory.ThrowIfError(Native.SetStateChangedCallback(_handle, _stateChangedCallback, IntPtr.Zero),
+ "Setting state changed callback failed");
+ }
+
+ private void RegisterRecordingProgressCallback()
+ {
+ _recordingProgressCallback = (ulong elapsedTime, ulong fileSize, IntPtr userData) =>
+ {
+ RecordingProgress?.Invoke(this, new RecordingProgressEventArgs(elapsedTime, fileSize));
+ };
+ RecorderErrorFactory.ThrowIfError(Native.SetRecordingProgressCallback(_handle, _recordingProgressCallback, IntPtr.Zero),
+ "Setting status changed callback failed");
+ }
+
+ private void RegisterAudioStreamDeliveredCallback()
+ {
+ _audioStreamCallback = (IntPtr stream, int streamSize, AudioSampleType type, int channel, uint recordingTime, IntPtr userData) =>
+ {
+ AudioStreamDelivered?.Invoke(this, new AudioStreamDeliveredEventArgs(stream, streamSize, type, channel, recordingTime));
+ };
+ RecorderErrorFactory.ThrowIfError(Native.SetAudioStreamCallback(_handle, _audioStreamCallback, IntPtr.Zero),
+ "Setting audiostream callback failed");
+ }
+
+ private void RegisterRecordingLimitReachedEvent()
+ {
+ _recordingLimitReachedCallback = (RecordingLimitType type, IntPtr userData) =>
+ {
+ RecordingLimitReached?.Invoke(this, new RecordingLimitReachedEventArgs(type));
+ };
+ RecorderErrorFactory.ThrowIfError(Native.SetLimitReachedCallback(_handle, _recordingLimitReachedCallback, IntPtr.Zero),
+ "Setting limit reached callback failed");
+ }
+
+ private void RegisterMuxedStreamEvent()
+ {
+ _muxedStreamCallback = (IntPtr stream, int streamSize, ulong offset, IntPtr userData) =>
+ {
+ MuxedStreamDelivered?.Invoke(this, new MuxedStreamDeliveredEventArgs(stream, streamSize, offset));
+ };
+ RecorderErrorFactory.ThrowIfError(Native.SetMuxedStreamCallback(_handle, _muxedStreamCallback, IntPtr.Zero),
+ "Setting muxed stream callback failed");
+ }
+ #endregion Callback registrations
+ }
+}
diff --git a/src/Tizen.Multimedia.Recorder/Recorder/RecorderEnums.cs b/src/Tizen.Multimedia.Recorder/Recorder/RecorderEnums.cs
new file mode 100755
index 0000000..308d080
--- /dev/null
+++ b/src/Tizen.Multimedia.Recorder/Recorder/RecorderEnums.cs
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Enumeration for Audio Codec.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum RecorderAudioCodec
+ {
+ /// <summary>
+ /// Disable Audio track.
+ /// </summary>
+ Disable = -1,
+ /// <summary>
+ /// AMR codec.
+ /// </summary>
+ Amr = 0,
+ /// <summary>
+ /// AAC codec.
+ /// </summary>
+ Aac,
+ /// <summary>
+ /// Vorbis codec.
+ /// </summary>
+ Vorbis,
+ /// <summary>
+ /// PCM codec.
+ /// </summary>
+ Pcm,
+ /// <summary>
+ /// The mp3 codec.
+ /// </summary>
+ Mp3
+ }
+
+ /// <summary>
+ /// Enumeration for Audio capture devices.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum RecorderAudioDevice
+ {
+ /// <summary>
+ /// Capture audio from Mic device.
+ /// </summary>
+ Mic,
+ /// <summary>
+ /// Capture audio from modem.
+ /// </summary>
+ Modem
+ }
+
+ /// <summary>
+ /// Enumeration for the file container format.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum RecorderFileFormat
+ {
+ /// <summary>
+ /// 3GP file format.
+ /// </summary>
+ ThreeGp,
+ /// <summary>
+ /// MP4 file format.
+ /// </summary>
+ Mp4,
+ /// <summary>
+ /// AMR file format.
+ /// </summary>
+ Amr,
+ /// <summary>
+ /// ADTS file format.
+ /// </summary>
+ Adts,
+ /// <summary>
+ /// WAV file format.
+ /// </summary>
+ Wav,
+ /// <summary>
+ /// OGG file format.
+ /// </summary>
+ Ogg,
+ /// <summary>
+ /// M2TS file format.
+ /// </summary>
+ M2ts
+ }
+
+ /// <summary>
+ /// Enumeration for the recorder policy.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum RecorderPolicy
+ {
+ /// <summary>
+ /// None.
+ /// </summary>
+ None = 0,
+ /// <summary>
+ /// Security policy.
+ /// </summary>
+ Security = 4,
+ /// <summary>
+ /// Resource conflict policy.
+ /// </summary>
+ ResourceConflict = 5
+ }
+
+ /// <summary>
+ /// Enumeration for the recording limit.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum RecordingLimitType
+ {
+ /// <summary>
+ /// Time limit in seconds of recording file
+ /// </summary>
+ Time,
+ /// <summary>
+ /// Size limit in KB(KiloBytes) of recording file.
+ /// </summary>
+ Size,
+ /// <summary>
+ /// No free space in storage.
+ /// </summary>
+ Space
+ }
+
+ /// <summary>
+ /// Enumeration for the recorder rotation type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum RecorderOrientation
+ {
+ /// <summary>
+ /// No rotation.
+ /// </summary>
+ RotationNone,
+ /// <summary>
+ /// 90 Degree rotation.
+ /// </summary>
+ Rotation90,
+ /// <summary>
+ /// 180 Degree rotation.
+ /// </summary>
+ Rotation180,
+ /// <summary>
+ /// 270 Degree rotation.
+ /// </summary>
+ Rotation270
+ }
+
+ /// <summary>
+ /// Enumeration for recorder states.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum RecorderState
+ {
+ /// <summary>
+ /// Recorder is not created.
+ /// </summary>
+ None,
+ /// <summary>
+ /// Recorder is created, but not prepared.
+ /// </summary>
+ Created,
+ /// <summary>
+ /// Recorder is ready to record. In case of video recorder,
+ /// preview display will be shown.
+ /// </summary>
+ Ready,
+ /// <summary>
+ /// Recorder is recording media.
+ /// </summary>
+ Recording,
+ /// <summary>
+ /// Recorder is paused while recording media.
+ /// </summary>
+ Paused
+ }
+
+ /// <summary>
+ /// Enumeration for video codec.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum RecorderVideoCodec
+ {
+ /// <summary>
+ /// H263 codec.
+ /// </summary>
+ H263,
+ /// <summary>
+ /// H264 codec.
+ /// </summary>
+ H264,
+ /// <summary>
+ /// MPEG4 codec.
+ /// </summary>
+ Mpeg4,
+ /// <summary>
+ /// Theora codec.
+ /// </summary>
+ Theora
+ }
+
+ /// <summary>
+ /// Enumeration for recorder failure error.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum RecorderErrorCode
+ {
+ /// <summary>
+ /// Device Error.
+ /// </summary>
+ DeviceError = RecorderError.DeviceError,
+ /// <summary>
+ /// Internal error.
+ /// </summary>
+ InvalidOperation = RecorderError.InvalidOperation,
+ /// <summary>
+ /// Out of memory.
+ /// </summary>
+ OutOfMemory = RecorderError.OutOfMemory
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Multimedia.Recorder/Recorder/RecorderErrorFactory.cs b/src/Tizen.Multimedia.Recorder/Recorder/RecorderErrorFactory.cs
new file mode 100644
index 0000000..74a8b46
--- /dev/null
+++ b/src/Tizen.Multimedia.Recorder/Recorder/RecorderErrorFactory.cs
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.CompilerServices;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Multimedia
+{
+ internal enum RecorderError
+ {
+ TizenErrorRecorder = -0x01950000,
+ RecorderErrorClass = TizenErrorRecorder | 0x10,
+ None = ErrorCode.None,
+ InvalidParameter = ErrorCode.InvalidParameter,
+ InvalidState = RecorderErrorClass | 0x02,
+ OutOfMemory = ErrorCode.OutOfMemory,
+ DeviceError = RecorderErrorClass | 0x04,
+ InvalidOperation = ErrorCode.InvalidOperation,
+ SecurityRestricted = RecorderErrorClass | 0x07,
+ Esd = RecorderErrorClass | 0x0a,
+ OutOfStorage = RecorderErrorClass | 0x0b,
+ PermissionDenied = ErrorCode.PermissionDenied,
+ NotSupported = ErrorCode.NotSupported,
+ ResourceConflict = RecorderErrorClass | 0x0c,
+ ServiceDisconnected = RecorderErrorClass | 0x0d
+ }
+
+ internal static class RecorderErrorFactory
+ {
+ internal static void ThrowIfError(RecorderError errorCode, string errorMessage = null,
+ [CallerMemberName] string caller = null, [CallerLineNumber] int line = 0)
+ {
+ if (errorCode == RecorderError.None)
+ {
+ return;
+ }
+
+ Log.Info(RecorderLog.Tag, "errorCode : " + errorCode.ToString() + ", Caller : " + caller + ", line " + line.ToString());
+
+ switch (errorCode)
+ {
+ case RecorderError.InvalidParameter:
+ throw new ArgumentException(errorMessage);
+
+ case RecorderError.OutOfMemory:
+ throw new OutOfMemoryException(errorMessage);
+
+ case RecorderError.DeviceError:
+ case RecorderError.Esd:
+ case RecorderError.SecurityRestricted:
+ case RecorderError.PermissionDenied:
+ throw new UnauthorizedAccessException(errorMessage);
+
+ case RecorderError.NotSupported:
+ throw new NotSupportedException(errorMessage);
+
+ case RecorderError.InvalidState:
+ case RecorderError.InvalidOperation:
+ case RecorderError.ResourceConflict:
+ case RecorderError.ServiceDisconnected:
+ case RecorderError.OutOfStorage: //TODO need to alloc new proper exception class
+ throw new InvalidOperationException(errorMessage);
+
+ default:
+ throw new Exception("Unknown error : " + errorCode.ToString());
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Recorder/Recorder/RecorderFeatures.cs b/src/Tizen.Multimedia.Recorder/Recorder/RecorderFeatures.cs
new file mode 100755
index 0000000..f1efa79
--- /dev/null
+++ b/src/Tizen.Multimedia.Recorder/Recorder/RecorderFeatures.cs
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Native = Interop.RecorderFeatures;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// The camera setting class provides methods/properties to get and
+ /// set basic camera attributes.
+ /// </summary>
+ public class RecorderFeatures
+ {
+ internal readonly Recorder _recorder = null;
+
+ private List<RecorderFileFormat> _fileFormats;
+ private List<RecorderAudioCodec> _audioCodec;
+ private List<RecorderVideoCodec> _videoCodec;
+ private List<Size> _videoResolution;
+
+ internal RecorderFeatures(Recorder recorder)
+ {
+ _recorder = recorder;
+ }
+
+ /// <summary>
+ /// Retrieves all the file formats supported by the recorder.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// It returns a list containing all the supported <see cref="RecorderFileFormat"/>.
+ /// </returns>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public IEnumerable<RecorderFileFormat> SupportedFileFormats
+ {
+ get
+ {
+ if (_fileFormats == null)
+ {
+ try
+ {
+ _fileFormats = new List<RecorderFileFormat>();
+
+ Native.FileFormatCallback callback = (RecorderFileFormat format, IntPtr userData) =>
+ {
+ _fileFormats.Add(format);
+ return true;
+ };
+ RecorderErrorFactory.ThrowIfError(Native.FileFormats(_recorder.GetHandle(), callback, IntPtr.Zero),
+ "Failed to get the supported fileformats");
+ }
+ catch
+ {
+ _fileFormats = null;
+ throw;
+ }
+ }
+
+ return _fileFormats;
+ }
+ }
+
+ /// <summary>
+ /// Retrieves all the audio encoders supported by the recorder.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// It returns a list containing all the supported <see cref="RecorderAudioCodec"/>.
+ /// </returns>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public IEnumerable<RecorderAudioCodec> SupportedAudioEncodings
+ {
+ get
+ {
+ if (_audioCodec == null)
+ {
+ try
+ {
+ _audioCodec = new List<RecorderAudioCodec>();
+
+ Native.AudioEncoderCallback callback = (RecorderAudioCodec codec, IntPtr userData) =>
+ {
+ _audioCodec.Add(codec);
+ return true;
+ };
+ RecorderErrorFactory.ThrowIfError(Native.AudioEncoders(_recorder.GetHandle(), callback, IntPtr.Zero),
+ "Failed to get the supported audio encoders");
+ }
+ catch
+ {
+ _audioCodec = null;
+ throw;
+ }
+ }
+
+ return _audioCodec;
+ }
+ }
+
+ /// <summary>
+ /// Retrieves all the video encoders supported by the recorder.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// It returns a list containing all the supported <see cref="RecorderVideoCodec"/>.
+ /// by recorder.
+ /// </returns>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public IEnumerable<RecorderVideoCodec> SupportedVideoEncodings
+ {
+ get
+ {
+ if (_videoCodec == null)
+ {
+ try
+ {
+ _videoCodec = new List<RecorderVideoCodec>();
+
+ Native.VideoEncoderCallback callback = (RecorderVideoCodec codec, IntPtr userData) =>
+ {
+ _videoCodec.Add(codec);
+ return true;
+ };
+ RecorderErrorFactory.ThrowIfError(Native.VideoEncoders(_recorder.GetHandle(), callback, IntPtr.Zero),
+ "Failed to get the supported video encoders");
+ }
+ catch
+ {
+ _videoCodec = null;
+ throw;
+ }
+ }
+
+ return _videoCodec;
+ }
+ }
+
+ /// <summary>
+ /// Retrieves all the video resolutions supported by the recorder.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// It returns videoresolution list containing the width and height of
+ /// different resolutions supported by recorder.
+ /// </returns>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public IEnumerable<Size> SupportedVideoResolutions
+ {
+ get
+ {
+ if (_videoResolution == null)
+ {
+ try
+ {
+ _videoResolution = new List<Size>();
+
+ Native.VideoResolutionCallback callback = (int width, int height, IntPtr userData) =>
+ {
+ _videoResolution.Add(new Size(width, height));
+ return true;
+ };
+ RecorderErrorFactory.ThrowIfError(Native.VideoResolution(_recorder.GetHandle(), callback, IntPtr.Zero),
+ "Failed to get the supported video resolutions.");
+ }
+ catch
+ {
+ _videoResolution = null;
+ throw;
+ }
+ }
+
+ return _videoResolution;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Multimedia.Recorder/Recorder/RecorderInterruptedEventArgs.cs b/src/Tizen.Multimedia.Recorder/Recorder/RecorderInterruptedEventArgs.cs
new file mode 100755
index 0000000..71392fc
--- /dev/null
+++ b/src/Tizen.Multimedia.Recorder/Recorder/RecorderInterruptedEventArgs.cs
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// An extended Eventargs class which contains interrupted policy details, previous and current
+ /// state of the recorder.
+ /// </summary>
+ public class RecorderInterruptedEventArgs : EventArgs
+ {
+ internal RecorderInterruptedEventArgs(RecorderPolicy policy, RecorderState previous, RecorderState current)
+ {
+ Policy = policy;
+ Previous = previous;
+ Current = current;
+ }
+
+ /// <summary>
+ /// The policy that interrupted the recorder.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public RecorderPolicy Policy { get; }
+
+ /// <summary>
+ /// The previous state of the recorder.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public RecorderState Previous { get; }
+
+ /// <summary>
+ /// The current state of the recorder.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public RecorderState Current { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia.Recorder/Recorder/RecorderSettings.cs b/src/Tizen.Multimedia.Recorder/Recorder/RecorderSettings.cs
new file mode 100755
index 0000000..344c6d5
--- /dev/null
+++ b/src/Tizen.Multimedia.Recorder/Recorder/RecorderSettings.cs
@@ -0,0 +1,451 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Linq;
+using System.Runtime.InteropServices;
+using Tizen.Internals.Errors;
+using Native = Interop.RecorderSettings;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// The camera setting class provides methods/properties to get and
+ /// set basic camera attributes.
+ /// </summary>
+ public class RecorderSettings
+ {
+ internal readonly Recorder _recorder = null;
+
+ internal RecorderSettings(Recorder recorder)
+ {
+ _recorder = recorder;
+ }
+
+ /// <summary>
+ /// The number of audio channel.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// For mono recording, set channel to 1.
+ /// For stereo recording, set channel to 2.
+ /// </value>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public int AudioChannel
+ {
+ get
+ {
+ int val = 0;
+
+ RecorderErrorFactory.ThrowIfError(Native.GetAudioChannel(_recorder.GetHandle(), out val),
+ "Failed to get audio channel.");
+
+ return val;
+ }
+
+ set
+ {
+ RecorderErrorFactory.ThrowIfError(Native.SetAudioChannel(_recorder.GetHandle(), value),
+ "Failed to set audio channel");
+ }
+ }
+
+ /// <summary>
+ /// The audio device for recording.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A <see cref="RecorderAudioDevice"/> that specifies the type of audio device.</value>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public RecorderAudioDevice AudioDevice
+ {
+ get
+ {
+ RecorderAudioDevice val = 0;
+
+ RecorderErrorFactory.ThrowIfError(Native.GetAudioDevice(_recorder.GetHandle(), out val),
+ "Failed to get audio device.");
+
+ return val;
+ }
+
+ set
+ {
+ RecorderErrorFactory.ThrowIfError(Native.SetAudioDevice(_recorder.GetHandle(), value),
+ "Failed to set audio device.");
+ }
+ }
+
+ /// <summary>
+ /// Get the peak audio input level in dB
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// 0dB indicates maximum input level, -300dB indicates minimum input level.
+ /// </remarks>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public double AudioLevel
+ {
+ get
+ {
+ double level = 0;
+
+ RecorderErrorFactory.ThrowIfError(Native.GetAudioLevel(_recorder.GetHandle(), out level),
+ "Failed to get Audio level.");
+
+ return level;
+ }
+ }
+
+ /// <summary>
+ /// The sampling rate of an audio stream in hertz.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public int AudioSampleRate
+ {
+ get
+ {
+ int val = 0;
+
+ RecorderErrorFactory.ThrowIfError(Native.GetAudioSampleRate(_recorder.GetHandle(), out val),
+ "Failed to get audio sample rate.");
+
+ return val;
+ }
+
+ set
+ {
+ RecorderErrorFactory.ThrowIfError(Native.SetAudioSampleRate(_recorder.GetHandle(), value),
+ "Failed to set audio sample rate.");
+ }
+ }
+
+ /// <summary>
+ /// The bitrate of an audio encoder in bits per second.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public int AudioBitRate
+ {
+ get
+ {
+ int val = 0;
+
+ RecorderErrorFactory.ThrowIfError(Native.GetAudioEncoderBitrate(_recorder.GetHandle(), out val),
+ "Failed to get audio bitrate.");
+
+ return val;
+ }
+
+ set
+ {
+ RecorderErrorFactory.ThrowIfError(Native.SetAudioEncoderBitrate(_recorder.GetHandle(), value),
+ "Failed to set audio bitrate");
+ }
+ }
+
+ /// <summary>
+ /// The bitrate of an video encoder in bits per second.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public int VideoBitRate
+ {
+ get
+ {
+ int val = 0;
+
+ RecorderErrorFactory.ThrowIfError(Native.GetVideoEncoderBitrate(_recorder.GetHandle(), out val),
+ "Failed to get video bitrate.");
+
+ return val;
+ }
+
+ set
+ {
+ RecorderErrorFactory.ThrowIfError(Native.SetVideoEncoderBitrate(_recorder.GetHandle(), value),
+ "Failed to set video bitrate");
+ }
+ }
+
+ /// <summary>
+ /// The audio codec for encoding an audio stream.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A <see cref="RecorderAudioCodec"/> that specifies the type of audio codec.</value>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public RecorderAudioCodec AudioCodec
+ {
+ get
+ {
+ RecorderAudioCodec val = 0;
+
+ RecorderErrorFactory.ThrowIfError(Native.GetAudioEncoder(_recorder.GetHandle(), out val),
+ "Failed to get audio codec");
+
+ return val;
+ }
+
+ set
+ {
+ RecorderErrorFactory.ThrowIfError(Native.SetAudioEncoder(_recorder.GetHandle(), value),
+ "Failed to set audio codec");
+ }
+ }
+
+ /// <summary>
+ /// The video codec for encoding video stream.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A <see cref="RecorderVideoCodec"/> that specifies the type of video codec.</value>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public RecorderVideoCodec VideoCodec
+ {
+ get
+ {
+ RecorderVideoCodec val = 0;
+
+ RecorderErrorFactory.ThrowIfError(Native.GetVideoEncoder(_recorder.GetHandle(), out val),
+ "Failed to get video codec");
+
+ return val;
+ }
+
+ set
+ {
+ RecorderErrorFactory.ThrowIfError(Native.SetVideoEncoder(_recorder.GetHandle(), value),
+ "Failed to set video codec");
+ }
+ }
+
+ /// <summary>
+ /// The file format for recording media stream.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A <see cref="RecorderFileFormat"/> that specifies the file format.</value>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public RecorderFileFormat FileFormat
+ {
+ get
+ {
+ RecorderFileFormat val = 0;
+
+ RecorderErrorFactory.ThrowIfError(Native.GetFileFormat(_recorder.GetHandle(), out val),
+ "Failed to get file format.");
+
+ return val;
+ }
+
+ set
+ {
+ RecorderErrorFactory.ThrowIfError(Native.SetFileFormat(_recorder.GetHandle(), value),
+ "Failed to set file format");
+ }
+ }
+
+ /// <summary>
+ /// The file path to record.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// If the same file already exists in the file system, then old file
+ /// will be overwritten.
+ /// </remarks>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public string FilePath
+ {
+ get
+ {
+ IntPtr val;
+ RecorderError ret = Native.GetFileName(_recorder.GetHandle(), out val);
+ if (ret != RecorderError.None)
+ {
+ Log.Error(RecorderLog.Tag, "Failed to get filepath, " + (RecorderError)ret);
+ }
+ string result = Marshal.PtrToStringAnsi(val);
+ LibcSupport.Free(val);
+ return result;
+ }
+
+ set
+ {
+ RecorderErrorFactory.ThrowIfError(Native.SetFileName(_recorder.GetHandle(), value),
+ "Failed to set filepath");
+ }
+ }
+
+ /// <summary>
+ /// The maximum size of a recording file in KB(kilobytes). If 0, means
+ /// unlimited recording size.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// After reaching the limitation, the data which is being recorded will
+ /// be discarded and not written to the file.
+ /// The recorder state must be in 'Ready' or 'Created' state.
+ /// </remarks>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public int SizeLimit
+ {
+ get
+ {
+ int val = 0;
+
+ RecorderErrorFactory.ThrowIfError(Native.GetSizeLimit(_recorder.GetHandle(), out val),
+ "Failed to get size limit.");
+
+ return val;
+ }
+
+ set
+ {
+ RecorderErrorFactory.ThrowIfError(Native.SetSizeLimit(_recorder.GetHandle(), value),
+ "Failed to set size limit");
+ }
+ }
+
+ /// <summary>
+ /// The time limit of a recording file in Seconds. If 0, means unlimited recording
+ /// time.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// After reaching the limitation, the data which is being recorded will
+ /// be discarded and not written to the file.
+ /// The recorder state must be in 'Ready' or 'Created' state.
+ /// </remarks>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public int TimeLimit
+ {
+ get
+ {
+ int val = 0;
+
+ RecorderErrorFactory.ThrowIfError(Native.GetTimeLimit(_recorder.GetHandle(), out val),
+ "Failed to get time limit.");
+
+ return val;
+ }
+
+ set
+ {
+ RecorderErrorFactory.ThrowIfError(Native.SetTimeLimit(_recorder.GetHandle(), value),
+ "Failed to set time limit.");
+ }
+ }
+
+ /// <summary>
+ /// The mute state of a recorder.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public bool Mute
+ {
+ get
+ {
+ return Native.GetMute(_recorder.GetHandle());
+ }
+
+ set
+ {
+ RecorderErrorFactory.ThrowIfError(Native.SetMute(_recorder.GetHandle(), value),
+ "Failed to set mute");
+ }
+ }
+
+ /// <summary>
+ /// The video recording motion rate
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// The attribute is valid only in a video recorder.
+ /// If the rate is in range of 0-1, video is recorded in a slow motion mode.
+ /// If the rate is bigger than 1, video is recorded in a fast motion mode.
+ /// </remarks>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public double MotionRate
+ {
+ get
+ {
+ double val = 0.0;
+
+ RecorderErrorFactory.ThrowIfError(Native.GetMotionRate(_recorder.GetHandle(), out val),
+ "Failed to get video motion rate.");
+
+ return val;
+ }
+
+ set
+ {
+ RecorderErrorFactory.ThrowIfError(Native.SetMotionRate(_recorder.GetHandle(), value),
+ "Failed to set video motion rate");
+ }
+ }
+
+ /// <summary>
+ /// The orientation in a video metadata tag.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>A <see cref="RecorderOrientation"/> that specifies the type of orientation.</value>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public RecorderOrientation OrientationTag
+ {
+ get
+ {
+ RecorderOrientation val = 0;
+
+ RecorderErrorFactory.ThrowIfError(Native.GetOrientationTag(_recorder.GetHandle(), out val),
+ "Failed to get recorder orientation.");
+
+ return val;
+ }
+
+ set
+ {
+ RecorderErrorFactory.ThrowIfError(Native.SetOrientationTag(_recorder.GetHandle(), value),
+ "Failed to set recorder orientation");
+ }
+ }
+
+ /// <summary>
+ /// Resolution of the video.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ArgumentException">In case of invalid parameters</exception>
+ /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
+ public Size VideoResolution
+ {
+ get
+ {
+ int width = 0;
+ int height = 0;
+
+ RecorderErrorFactory.ThrowIfError(Native.GetVideoResolution(_recorder.GetHandle(), out width, out height),
+ "Failed to get camera video resolution");
+
+ return new Size(width, height);
+ }
+
+ set
+ {
+ Size res = value;
+
+ RecorderErrorFactory.ThrowIfError(Native.SetVideoResolution(_recorder.GetHandle(), res.Width, res.Height),
+ "Failed to set video resolution.");
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Multimedia.Recorder/Recorder/RecorderStateChangedEventArgs.cs b/src/Tizen.Multimedia.Recorder/Recorder/RecorderStateChangedEventArgs.cs
new file mode 100755
index 0000000..42e3af0
--- /dev/null
+++ b/src/Tizen.Multimedia.Recorder/Recorder/RecorderStateChangedEventArgs.cs
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// An extended EventArgs class which contains details about previous and current state
+ /// of the recorder when its state is changed.
+ /// </summary>
+ public class RecorderStateChangedEventArgs : EventArgs
+ {
+ internal RecorderStateChangedEventArgs(RecorderState previous, RecorderState current, bool byPolicy)
+ {
+ Previous = previous;
+ Current = current;
+ IsStateChangedByPolicy = byPolicy;
+ }
+
+ /// <summary>
+ /// Previous state of the recorder.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public RecorderState Previous { get; }
+
+ /// <summary>
+ /// Current state of the recorder.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public RecorderState Current { get; }
+
+ /// <summary>
+ /// true if the state changed by policy such as Resource Conflict or Security, otherwise false
+ /// in normal state change.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool IsStateChangedByPolicy { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia.Recorder/Recorder/RecordingErrorOccurredEventArgs.cs b/src/Tizen.Multimedia.Recorder/Recorder/RecordingErrorOccurredEventArgs.cs
new file mode 100755
index 0000000..80b6070
--- /dev/null
+++ b/src/Tizen.Multimedia.Recorder/Recorder/RecordingErrorOccurredEventArgs.cs
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// An extended EventArgs class which contains details about error status and
+ /// state of the recorder when it failed.
+ /// </summary>
+ public class RecordingErrorOccurredEventArgs : EventArgs
+ {
+ internal RecordingErrorOccurredEventArgs(RecorderErrorCode error, RecorderState state)
+ {
+ Error = error;
+ State = state;
+ }
+
+ /// <summary>
+ /// The error code.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public RecorderErrorCode Error { get; }
+
+ /// <summary>
+ /// The state of the recorder.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public RecorderState State { get; }
+
+ }
+}
diff --git a/src/Tizen.Multimedia.Recorder/Recorder/RecordingLimitReachedEventArgs.cs b/src/Tizen.Multimedia.Recorder/Recorder/RecordingLimitReachedEventArgs.cs
new file mode 100755
index 0000000..8606748
--- /dev/null
+++ b/src/Tizen.Multimedia.Recorder/Recorder/RecordingLimitReachedEventArgs.cs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// An extended EventArgs class containing details about the recording limit.
+ /// </summary>
+ public class RecordingLimitReachedEventArgs : EventArgs
+ {
+ internal RecordingLimitReachedEventArgs(RecordingLimitType type)
+ {
+ Type = type;
+ }
+
+ /// <summary>
+ /// The limitation type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public RecordingLimitType Type { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia.Recorder/Recorder/RecordingProgressEventArgs.cs b/src/Tizen.Multimedia.Recorder/Recorder/RecordingProgressEventArgs.cs
new file mode 100755
index 0000000..f059fc7
--- /dev/null
+++ b/src/Tizen.Multimedia.Recorder/Recorder/RecordingProgressEventArgs.cs
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// An extened EventArgs class which contain the details of current recording status.
+ /// </summary>
+ public class RecordingProgressEventArgs : EventArgs
+ {
+ public RecordingProgressEventArgs(ulong elapsedTime, ulong fileSize)
+ {
+ ElapsedTime = elapsedTime;
+ FileSize = fileSize;
+ }
+
+ /// <summary>
+ /// The time of recording in milliseconds.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ulong ElapsedTime { get; }
+
+ /// <summary>
+ /// The size of the recording file in Kilobyte.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ulong FileSize { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia.Recorder/Tizen.Multimedia.Recorder.csproj b/src/Tizen.Multimedia.Recorder/Tizen.Multimedia.Recorder.csproj
new file mode 100644
index 0000000..c5b2c24
--- /dev/null
+++ b/src/Tizen.Multimedia.Recorder/Tizen.Multimedia.Recorder.csproj
@@ -0,0 +1,15 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen.Multimedia\Tizen.Multimedia.csproj" />
+ <ProjectReference Include="..\Tizen.Multimedia.AudioIO\Tizen.Multimedia.AudioIO.csproj" />
+ <ProjectReference Include="..\Tizen.Multimedia.Camera\Tizen.Multimedia.Camera.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Multimedia.Remoting/Interop/Interop.Libraries.cs b/src/Tizen.Multimedia.Remoting/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..d479daa
--- /dev/null
+++ b/src/Tizen.Multimedia.Remoting/Interop/Interop.Libraries.cs
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string ScreenMirroring = "libcapi-media-screen-mirroring.so.0";
+ public const string MediaController = "libcapi-media-controller.so.0";
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Remoting/Interop/Interop.MediaController.cs b/src/Tizen.Multimedia.Remoting/Interop/Interop.MediaController.cs
new file mode 100644
index 0000000..7efbf0a
--- /dev/null
+++ b/src/Tizen.Multimedia.Remoting/Interop/Interop.MediaController.cs
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Applications;
+using Tizen.Multimedia;
+using Tizen.Multimedia.MediaController;
+
+internal static partial class Interop
+{
+ internal static partial class MediaControllerClient
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ServerUpdatedCallback(IntPtr serverName, MediaControllerServerState serverState, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void PlaybackUpdatedCallback(IntPtr serverName, IntPtr playback, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MetadataUpdatedCallback(IntPtr serverName, IntPtr metadata, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ShuffleModeUpdatedCallback(IntPtr serverName, MediaControllerShuffleMode shuffleMode, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void RepeatModeUpdatedCallback(IntPtr serverName, MediaControllerRepeatMode repeatMode, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void CommandReplyRecievedCallback(IntPtr serverName, int result, IntPtr bundle, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool SubscribedServerCallback(IntPtr serverName, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool ActivatedServerCallback(IntPtr serverName, IntPtr userData);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_client_create")]
+ internal static extern MediaControllerError Create(out IntPtr handle);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_client_destroy")]
+ internal static extern MediaControllerError Destroy(IntPtr handle);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_server_update_cb")]
+ internal static extern MediaControllerError SetServerUpdatedCb(IntPtr handle, ServerUpdatedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_client_unset_server_update_cb")]
+ internal static extern MediaControllerError UnsetServerUpdatedCb(IntPtr handle);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_playback_update_cb")]
+ internal static extern MediaControllerError SetPlaybackUpdatedCb(IntPtr handle, PlaybackUpdatedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_client_unset_playback_update_cb")]
+ internal static extern MediaControllerError UnsetPlaybackUpdatedCb(IntPtr handle);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_metadata_update_cb")]
+ internal static extern MediaControllerError SetMetadataUpdatedCb(IntPtr handle, MetadataUpdatedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_client_unset_metadata_update_cb")]
+ internal static extern MediaControllerError UnsetMetadataUpdatedCb(IntPtr handle);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_shuffle_mode_update_cb")]
+ internal static extern MediaControllerError SetShuffleModeUpdatedCb(IntPtr handle, ShuffleModeUpdatedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_client_unset_shuffle_mode_update_cb")]
+ internal static extern MediaControllerError UnsetShuffleModeUpdatedCb(IntPtr handle);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_repeat_mode_update_cb")]
+ internal static extern MediaControllerError SetRepeatModeUpdatedCb(IntPtr handle, RepeatModeUpdatedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_client_unset_repeat_mode_update_cb")]
+ internal static extern MediaControllerError UnsetRepeatModeUpdatedCb(IntPtr handle);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_client_subscribe")]
+ internal static extern MediaControllerError Subscribe(IntPtr handle, MediaControllerSubscriptionType subscriptionType, string serverName);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_client_unsubscribe")]
+ internal static extern MediaControllerError Unsubscribe(IntPtr handle, MediaControllerSubscriptionType subscriptionType, string serverName);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_playback_state")]
+ internal static extern MediaControllerError GetPlaybackState(IntPtr playback, out MediaControllerPlaybackState state);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_playback_position")]
+ internal static extern MediaControllerError GetPlaybackPosition(IntPtr playback, out ulong position);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_client_destroy_playback")]
+ internal static extern MediaControllerError DestroyPlayback(IntPtr playback);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_metadata")]
+ private static extern MediaControllerError GetMetadata(IntPtr metadata, MediaControllerAttributes attribute, out IntPtr value);
+
+ internal static string GetMetadata(IntPtr handle, MediaControllerAttributes attr)
+ {
+ IntPtr valuePtr = IntPtr.Zero;
+
+ try
+ {
+ var ret = GetMetadata(handle, attr, out valuePtr);
+ MediaControllerValidator.ThrowIfError(ret, "Failed to get value for " + attr);
+ return Marshal.PtrToStringAnsi(valuePtr);
+ }
+ finally
+ {
+ LibcSupport.Free(valuePtr);
+ }
+ }
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_client_destroy_metadata")]
+ internal static extern MediaControllerError DestroyMetadata(IntPtr metadata);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_latest_server_info")]
+ internal static extern MediaControllerError GetLatestServer(IntPtr handle, out IntPtr serverName, out MediaControllerServerState serverState);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_server_playback_info")]
+ internal static extern MediaControllerError GetServerPlayback(IntPtr handle, string serverName, out IntPtr playback);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_server_metadata")]
+ internal static extern MediaControllerError GetServerMetadata(IntPtr handle, string serverName, out IntPtr metadata);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_server_shuffle_mode")]
+ internal static extern MediaControllerError GetServerShuffleMode(IntPtr handle, string serverName, out MediaControllerShuffleMode mode);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_server_repeat_mode")]
+ internal static extern MediaControllerError GetServerRepeatMode(IntPtr handle, string serverName, out MediaControllerRepeatMode mode);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_client_send_playback_state_command")]
+ internal static extern MediaControllerError SendPlaybackStateCommand(IntPtr handle, string serverName, MediaControllerPlaybackState state);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_client_send_custom_command")]
+ internal static extern MediaControllerError SendCustomCommand(IntPtr handle, string serverName, string command, SafeBundleHandle bundle, CommandReplyRecievedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_client_foreach_server_subscribed")]
+ internal static extern MediaControllerError ForeachSubscribedServer(IntPtr handle, MediaControllerSubscriptionType subscriptionType, SubscribedServerCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_client_foreach_server")]
+ internal static extern MediaControllerError ForeachActivatedServer(IntPtr handle, ActivatedServerCallback callback, IntPtr userData);
+ }
+
+ internal static partial class MediaControllerServer
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void PlaybackStateCommandRecievedCallback(IntPtr clientName, MediaControllerPlaybackState state, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void CustomCommandRecievedCallback(IntPtr clientName, IntPtr command, IntPtr bundle, IntPtr userData);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_server_create")]
+ internal static extern MediaControllerError Create(out IntPtr handle);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_server_destroy")]
+ internal static extern MediaControllerError Destroy(IntPtr handle);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_playback_state")]
+ internal static extern MediaControllerError SetPlaybackState(IntPtr handle, MediaControllerPlaybackState state);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_playback_position")]
+ internal static extern MediaControllerError SetPlaybackPosition(IntPtr handle, ulong position);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_server_update_playback_info")]
+ internal static extern MediaControllerError UpdatePlayback(IntPtr handle);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_metadata")]
+ internal static extern MediaControllerError SetMetadata(IntPtr handle, MediaControllerAttributes attribute, string value);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_server_update_metadata")]
+ internal static extern MediaControllerError UpdateMetadata(IntPtr handle);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_server_update_shuffle_mode")]
+ internal static extern MediaControllerError UpdateShuffleMode(IntPtr handle, MediaControllerShuffleMode mode);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_server_update_repeat_mode")]
+ internal static extern MediaControllerError UpdateRepeatMode(IntPtr handle, MediaControllerRepeatMode mode);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_playback_state_command_received_cb")]
+ internal static extern MediaControllerError SetPlaybackStateCmdRecvCb(IntPtr handle, PlaybackStateCommandRecievedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_server_unset_playback_state_command_received_cb")]
+ internal static extern MediaControllerError UnsetPlaybackStateCmdRecvCb(IntPtr handle);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_custom_command_received_cb")]
+ internal static extern MediaControllerError SetCustomCmdRecvCb(IntPtr handle, CustomCommandRecievedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_server_unset_custom_command_received_cb")]
+ internal static extern MediaControllerError UnsetCustomCmdRecvCb(IntPtr handle);
+
+ [DllImport(Libraries.MediaController, EntryPoint = "mc_server_send_command_reply")]
+ internal static extern MediaControllerError SendCommandReply(IntPtr handle, string clientName, int result, SafeBundleHandle bundle);
+ }
+}
diff --git a/src/Tizen.Multimedia.Remoting/Interop/Interop.ScreenMirroring.cs b/src/Tizen.Multimedia.Remoting/Interop/Interop.ScreenMirroring.cs
new file mode 100644
index 0000000..707a4c2
--- /dev/null
+++ b/src/Tizen.Multimedia.Remoting/Interop/Interop.ScreenMirroring.cs
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class ScreenMirroring
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void StateChangedCallback(IntPtr userData, int state, int error);
+
+ [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_create")]
+ internal static extern int Create(out IntPtr scmirroringSink);
+
+ [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_set_state_changed_cb")]
+ internal static extern int SetStateChangedCb(IntPtr scmirroringSink, StateChangedCallback cb, IntPtr userData);
+
+ [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_set_ip_and_port")]
+ internal static extern int SetIpAndPort(IntPtr scmirroringSink, string ip, string port);
+
+ [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_set_display")]
+ internal static extern int SetDisplay(IntPtr scmirroringSink, int type, IntPtr display);
+
+ [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_set_resolution")]
+ internal static extern int SetResolution(IntPtr scmirroringSink, int resolution);
+
+ [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_prepare")]
+ internal static extern int Prepare(IntPtr scmirroringSink);
+
+ [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_connect")]
+ internal static extern int ConnectAsync(IntPtr scmirroringSink);
+
+ [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_start")]
+ internal static extern int StartAsync(IntPtr scmirroringSink);
+
+ [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_pause")]
+ internal static extern int PauseAsync(IntPtr scmirroringSink);
+
+ [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_resume")]
+ internal static extern int ResumeAsync(IntPtr scmirroringSink);
+
+ [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_disconnect")]
+ internal static extern int Disconnect(IntPtr scmirroringSink);
+
+ [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_unprepare")]
+ internal static extern int Unprepare(IntPtr scmirroringSink);
+
+ [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_unset_state_changed_cb")]
+ internal static extern int UnsetStateChangedCb(IntPtr scmirroringSink);
+
+ [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_destroy")]
+ internal static extern int Destroy(IntPtr scmirroringSink);
+
+ [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_get_negotiated_video_codec")]
+ internal static extern int GetNegotiatedVideoCodec(ref IntPtr scmirroringSink, out int codec);
+
+ [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_get_negotiated_video_resolution")]
+ internal static extern int GetNegotiatedVideoResolution(ref IntPtr scmirroringSink, out int width, out int height);
+
+ [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_get_negotiated_video_frame_rate")]
+ internal static extern int GetNegotiatedVideoFrameRate(ref IntPtr scmirroringSink, out int frameRate);
+
+ [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_get_negotiated_audio_codec")]
+ internal static extern int GetNegotiatedAudioCodec(ref IntPtr scmirroringSink, out int codec);
+
+ [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_get_negotiated_audio_channel")]
+ internal static extern int GetNegotiatedAudioChannel(ref IntPtr scmirroringSink, out int channel);
+
+ [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_get_negotiated_audio_sample_rate")]
+ internal static extern int GetNegotiatedAudioSampleRate(ref IntPtr scmirroringSink, out int sampleRate);
+
+ [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_get_negotiated_audio_bitwidth")]
+ internal static extern int GetNegotiatedAudioBitwidth(ref IntPtr scmirroringSink, out int bitwidth);
+ }
+}
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/CustomCommandEventArgs.cs b/src/Tizen.Multimedia.Remoting/MediaController/CustomCommandEventArgs.cs
new file mode 100755
index 0000000..a485e3f
--- /dev/null
+++ b/src/Tizen.Multimedia.Remoting/MediaController/CustomCommandEventArgs.cs
@@ -0,0 +1,57 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using Tizen.Applications;
+
+namespace Tizen.Multimedia.MediaController
+{
+
+ /// <summary>
+ /// CustomCommandRecieved event arguments
+ /// </summary>
+ /// <remarks>
+ /// CustomCommandRecieved event arguments
+ /// </remarks>
+ public class CustomCommandEventArgs : EventArgs
+ {
+ internal CustomCommandEventArgs(string name, string command, Bundle bundle)
+ {
+ ClientName = name;
+ Command = command;
+ BundleData = bundle;
+ }
+
+ /// <summary>
+ /// Get the Client Name.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string ClientName { get; }
+
+ /// <summary>
+ /// Get the Custom Command.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Command { get; }
+
+ /// <summary>
+ /// Get the Bundle Data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public Bundle BundleData { get; }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/CustomCommandReplyEventArgs.cs b/src/Tizen.Multimedia.Remoting/MediaController/CustomCommandReplyEventArgs.cs
new file mode 100755
index 0000000..e7bac0e
--- /dev/null
+++ b/src/Tizen.Multimedia.Remoting/MediaController/CustomCommandReplyEventArgs.cs
@@ -0,0 +1,57 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using Tizen.Applications;
+
+namespace Tizen.Multimedia.MediaController
+{
+
+ /// <summary>
+ /// CustomCommandRecieved event arguments
+ /// </summary>
+ /// <remarks>
+ /// CustomCommandRecieved event arguments
+ /// </remarks>
+ public class CustomCommandReplyEventArgs : EventArgs
+ {
+ internal CustomCommandReplyEventArgs(string serverName, int result, Bundle bundle)
+ {
+ ServerName = serverName;
+ Result = result;
+ BundleData = bundle;
+ }
+
+ /// <summary>
+ /// Get the Sserver Name.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string ServerName { get; }
+
+ /// <summary>
+ /// Get the Result.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Result { get; }
+
+ /// <summary>
+ /// Get the Bundle Data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public Bundle BundleData { get; }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/MediaControllerClient.cs b/src/Tizen.Multimedia.Remoting/MediaController/MediaControllerClient.cs
new file mode 100755
index 0000000..529719a
--- /dev/null
+++ b/src/Tizen.Multimedia.Remoting/MediaController/MediaControllerClient.cs
@@ -0,0 +1,595 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+using Tizen.Applications;
+using Native = Interop.MediaControllerClient;
+
+namespace Tizen.Multimedia.MediaController
+{
+
+ /// <summary>
+ /// The MediaControllerClient class provides APIs required for media-controller-client.
+ /// </summary>
+ /// <privilege>
+ /// http://tizen.org/privilege/mediacontroller.client
+ /// </privilege>
+ /// <remarks>
+ /// The MediaControllerClient APIs provides functions to get media information from server.
+ /// </remarks>
+ public class MediaControllerClient : IDisposable
+ {
+ internal IntPtr _handle = IntPtr.Zero;
+
+ private bool _disposed = false;
+ private EventHandler<ServerUpdatedEventArgs> _serverUpdated;
+ private Native.ServerUpdatedCallback _serverUpdatedCallback;
+ private EventHandler<PlaybackUpdatedEventArgs> _playbackUpdated;
+ private Native.PlaybackUpdatedCallback _playbackUpdatedCallback;
+ private EventHandler<MetadataUpdatedEventArgs> _metadataUpdated;
+ private Native.MetadataUpdatedCallback _metadataUpdatedCallback;
+ private EventHandler<ShuffleModeUpdatedEventArgs> _shufflemodeUpdated;
+ private Native.ShuffleModeUpdatedCallback _shufflemodeUpdatedCallback;
+ private EventHandler<RepeatModeUpdatedEventArgs> _repeatmodeUpdated;
+ private Native.RepeatModeUpdatedCallback _repeatmodeUpdatedCallback;
+ private EventHandler<CustomCommandReplyEventArgs> _customcommandReply;
+ private Native.CommandReplyRecievedCallback _customcommandReplyCallback;
+
+ private bool IsValidHandle
+ {
+ get { return (_handle != IntPtr.Zero); }
+ }
+
+ private IntPtr SafeHandle
+ {
+ get
+ {
+ if (!IsValidHandle)
+ {
+ throw new ObjectDisposedException(nameof(MediaControllerClient), "Fail to operate MediaControllerClient");
+ }
+
+ return _handle;
+ }
+ }
+
+ /// <summary>
+ /// The constructor of MediaControllerClient class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when the access is denied for media controller client</exception>
+ public MediaControllerClient()
+ {
+ MediaControllerValidator.ThrowIfError(
+ Native.Create(out _handle), "Create client failed");
+ }
+
+ ~MediaControllerClient()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (disposing)
+ {
+ // To be used if there are any other disposable objects
+ }
+
+ if (IsValidHandle)
+ {
+ Native.Destroy(_handle);
+ _handle = IntPtr.Zero;
+ }
+
+ _disposed = true;
+ }
+ }
+
+ /// <summary>
+ /// ServerUpdated event is raised when server is changed
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<ServerUpdatedEventArgs> ServerUpdated
+ {
+ add
+ {
+ if (_serverUpdated == null)
+ {
+ RegisterServerUpdatedEvent();
+ }
+
+ _serverUpdated += value;
+
+ }
+
+ remove
+ {
+ _serverUpdated -= value;
+ if (_serverUpdated == null)
+ {
+ UnregisterServerUpdatedEvent();
+ }
+ }
+ }
+
+ /// <summary>
+ /// PlaybackUpdated event is raised when playback is changed
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<PlaybackUpdatedEventArgs> PlaybackUpdated
+ {
+ add
+ {
+ if (_playbackUpdated == null)
+ {
+ RegisterPlaybackUpdatedEvent();
+ }
+
+ _playbackUpdated += value;
+
+ }
+
+ remove
+ {
+ _playbackUpdated -= value;
+ if (_playbackUpdated == null)
+ {
+ UnregisterPlaybackUpdatedEvent();
+ }
+ }
+ }
+
+ /// <summary>
+ /// MetadataUpdated event is raised when metadata is changed
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<MetadataUpdatedEventArgs> MetadataUpdated
+ {
+ add
+ {
+ if (_metadataUpdated == null)
+ {
+ RegisterMetadataUpdatedEvent();
+ }
+
+ _metadataUpdated += value;
+
+ }
+
+ remove
+ {
+ _metadataUpdated -= value;
+ if (_metadataUpdated == null)
+ {
+ UnregisterMetadataUpdatedEvent();
+ }
+ }
+ }
+
+ /// <summary>
+ /// ShuffleModeUpdated event is raised when shuffle mode is changed
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<ShuffleModeUpdatedEventArgs> ShuffleModeUpdated
+ {
+ add
+ {
+ if (_shufflemodeUpdated == null)
+ {
+ RegisterShuffleModeUpdatedEvent();
+ }
+
+ _shufflemodeUpdated += value;
+
+ }
+
+ remove
+ {
+ _shufflemodeUpdated -= value;
+ if (_shufflemodeUpdated == null)
+ {
+ UnregisterShuffleModeUpdatedEvent();
+ }
+ }
+ }
+
+ /// <summary>
+ /// RepeatModeUpdated event is raised when server is changed
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<RepeatModeUpdatedEventArgs> RepeatModeUpdated
+ {
+ add
+ {
+ if (_repeatmodeUpdated == null)
+ {
+ RegisterRepeatModeUpdatedEvent();
+ }
+
+ _repeatmodeUpdated += value;
+ }
+
+ remove
+ {
+ _repeatmodeUpdated -= value;
+ if (_repeatmodeUpdated == null)
+ {
+ UnregisterRepeatModeUpdatedEvent();
+ }
+ }
+ }
+
+ /// <summary>
+ /// CommandReply event is raised when reply for command is recieved
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<CustomCommandReplyEventArgs> CustomCommandReply
+ {
+ add
+ {
+ if (_customcommandReply == null)
+ {
+ _customcommandReplyCallback = (IntPtr serverName, int result, IntPtr bundle, IntPtr userData) =>
+ {
+ SafeBundleHandle safeBundleHandle = new SafeBundleHandle(bundle, true);
+ Bundle bundleData = new Bundle(safeBundleHandle);
+ CustomCommandReplyEventArgs eventArgs = new CustomCommandReplyEventArgs(Marshal.PtrToStringAnsi(serverName), result, bundleData);
+ _customcommandReply?.Invoke(this, eventArgs);
+ };
+ }
+
+ _customcommandReply += value;
+
+ }
+
+ remove
+ {
+ _customcommandReply -= value;
+ if (_customcommandReply == null)
+ {
+ _customcommandReplyCallback = null;
+ }
+ }
+ }
+
+ /// <summary>
+ /// gets latest server information </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>The name and state of the latest media controller server application: ServerInformation object</returns>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ public ServerInformation GetLatestServer()
+ {
+ IntPtr name = IntPtr.Zero;
+ MediaControllerServerState state = MediaControllerServerState.None;
+
+ try
+ {
+ MediaControllerValidator.ThrowIfError(
+ Native.GetLatestServer(SafeHandle, out name, out state), "Get Latest server failed");
+ return new ServerInformation(Marshal.PtrToStringAnsi(name), (MediaControllerServerState)state);
+ }
+ finally
+ {
+ LibcSupport.Free(name);
+ }
+ }
+
+ /// <summary>
+ /// gets playback information for specific server </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="serverName"> Server Name </param>
+ /// <returns>The playback state and playback position of the specific media controller server application:MediaControllerPlayback object</returns>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ public MediaControllerPlayback GetPlayback(string serverName)
+ {
+ IntPtr playbackHandle = IntPtr.Zero;
+ MediaControllerPlayback playback = null;
+
+ try
+ {
+ MediaControllerValidator.ThrowIfError(
+ Native.GetServerPlayback(SafeHandle, serverName, out playbackHandle), "Get Playback handle failed");
+ playback = new MediaControllerPlayback(playbackHandle);
+ }
+ finally
+ {
+ if (playbackHandle != IntPtr.Zero)
+ {
+ MediaControllerValidator.ThrowIfError(
+ Native.DestroyPlayback(playbackHandle), "Destroy playback failed");
+ }
+ }
+
+ return playback;
+ }
+
+ /// <summary>
+ /// gets metadata information for specific server </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="serverName"> Server Name </param>
+ /// <returns>The metadata information of the specific media controller server application:MediaControllerMetadata object</returns>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ public MediaControllerMetadata GetMetadata(string serverName)
+ {
+ IntPtr metadataHandle = IntPtr.Zero;
+ MediaControllerMetadata metadata = null;
+
+ try
+ {
+ MediaControllerValidator.ThrowIfError(
+ Native.GetServerMetadata(SafeHandle, serverName, out metadataHandle), "Get Metadata handle failed");
+ metadata = new MediaControllerMetadata(metadataHandle);
+ }
+ finally
+ {
+ if (metadataHandle != IntPtr.Zero)
+ {
+ MediaControllerValidator.ThrowIfError(
+ Native.DestroyMetadata(metadataHandle), "Destroy metadata failed");
+ }
+ }
+
+ return metadata;
+ }
+
+ /// <summary>
+ /// gets shuffle mode for specific server </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="serverName"> Server Name </param>
+ /// <returns>The shuffle mode of the specific media controller server application:MediaControllerShuffleMode enum</returns>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ public MediaControllerShuffleMode GetShuffleMode(string serverName)
+ {
+ MediaControllerShuffleMode shuffleMode = MediaControllerShuffleMode.Off;
+
+ MediaControllerValidator.ThrowIfError(
+ Native.GetServerShuffleMode(SafeHandle, serverName, out shuffleMode), "Get ShuffleMode failed");
+
+ return shuffleMode;
+ }
+
+ /// <summary>
+ /// gets repeat mode for specific server </summary>\
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="serverName"> Server Name </param>
+ /// <returns>The repeat mode of the specific media controller server application:MediaControllerRepeatMode enum</returns>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ public MediaControllerRepeatMode GetRepeatMode(string serverName)
+ {
+ MediaControllerRepeatMode repeatMode = MediaControllerRepeatMode.Off;
+
+ MediaControllerValidator.ThrowIfError(
+ Native.GetServerRepeatMode(SafeHandle, serverName, out repeatMode), "Get RepeatMode failed");
+
+ return repeatMode;
+ }
+
+ /// <summary>
+ /// Send command of playback state to server application </summary>
+ /// <param name="serverName"> Server Name </param>
+ /// <param name="state"> Playback State </param>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ public void SendPlaybackStateCommand(string serverName, MediaControllerPlaybackState state)
+ {
+ MediaControllerValidator.ThrowIfError(
+ Native.SendPlaybackStateCommand(SafeHandle, serverName, state), "Send playback state command failed");
+ }
+
+ /// <summary>
+ /// Send customized command to server application </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="serverName"> Server Name </param>
+ /// <param name="command"> Command </param>
+ /// <param name="bundle"> Bundle data </param>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ public void SendCustomCommand(string serverName, string command, Bundle bundle)
+ {
+ MediaControllerValidator.ThrowIfError(
+ Native.SendCustomCommand(SafeHandle, serverName, command, bundle.SafeBundleHandle, _customcommandReplyCallback, IntPtr.Zero),
+ "Send custom command failed");
+ }
+
+ /// <summary>
+ /// Subscribe subscription type from specific server application </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="type"> Subscription Type </param>
+ /// <param name="serverName"> Server Name </param>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ public void Subscribe(MediaControllerSubscriptionType type, string serverName)
+ {
+ MediaControllerValidator.ThrowIfError(
+ Native.Subscribe(SafeHandle, type, serverName), "Subscribe failed");
+ }
+
+ /// <summary>
+ /// Subscribe subscription type from specific server application </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="type"> Subscription Type </param>
+ /// <param name="serverName"> Server Name </param>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ public void Unsubscribe(MediaControllerSubscriptionType type, string serverName)
+ {
+ MediaControllerValidator.ThrowIfError(
+ Native.Unsubscribe(SafeHandle, type, serverName), "Unsubscribe failed");
+ }
+
+ /// <summary>
+ /// gets activated server list </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>The list of activated media controller server applications: IEnumerable of string</returns>
+ public Task<IEnumerable<string>> GetActivatedServerList()
+ {
+ var task = new TaskCompletionSource<IEnumerable<string>>();
+
+ List<string> collectionList = ForEachActivatedServer(SafeHandle);
+ task.TrySetResult((IEnumerable<string>)collectionList);
+
+ return task.Task;
+ }
+
+ /// <summary>
+ /// gets subscribed server list </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="subscriptionType"> Subscription Type </param>
+ /// <returns>The list of subscribed media controller server applications: IEnumerable of string</returns>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ public Task<IEnumerable<string>> GetSubscribedServerList(MediaControllerSubscriptionType subscriptionType)
+ {
+ var task = new TaskCompletionSource<IEnumerable<string>>();
+
+ List<string> collectionList = ForEachSubscribedServer(SafeHandle, subscriptionType);
+ task.TrySetResult((IEnumerable<string>)collectionList);
+
+ return task.Task;
+ }
+
+ private void RegisterServerUpdatedEvent()
+ {
+ _serverUpdatedCallback = (IntPtr serverName, MediaControllerServerState serverState, IntPtr userData) =>
+ {
+ ServerUpdatedEventArgs eventArgs = new ServerUpdatedEventArgs(Marshal.PtrToStringAnsi(serverName), serverState);
+ _serverUpdated?.Invoke(this, eventArgs);
+ };
+ Native.SetServerUpdatedCb(SafeHandle, _serverUpdatedCallback, IntPtr.Zero);
+ }
+
+ private void UnregisterServerUpdatedEvent()
+ {
+ Native.UnsetServerUpdatedCb(SafeHandle);
+ }
+
+ private void RegisterPlaybackUpdatedEvent()
+ {
+ _playbackUpdatedCallback = (IntPtr serverName, IntPtr playback, IntPtr userData) =>
+ {
+ PlaybackUpdatedEventArgs eventArgs = new PlaybackUpdatedEventArgs(Marshal.PtrToStringAnsi(serverName), playback);
+ _playbackUpdated?.Invoke(this, eventArgs);
+ };
+ Native.SetPlaybackUpdatedCb(SafeHandle, _playbackUpdatedCallback, IntPtr.Zero);
+ }
+
+ private void UnregisterPlaybackUpdatedEvent()
+ {
+ Native.UnsetPlaybackUpdatedCb(SafeHandle);
+ }
+
+ private void RegisterMetadataUpdatedEvent()
+ {
+ _metadataUpdatedCallback = (IntPtr serverName, IntPtr metadata, IntPtr userData) =>
+ {
+ MetadataUpdatedEventArgs eventArgs = new MetadataUpdatedEventArgs(Marshal.PtrToStringAnsi(serverName), metadata);
+ _metadataUpdated?.Invoke(this, eventArgs);
+ };
+ Native.SetMetadataUpdatedCb(SafeHandle, _metadataUpdatedCallback, IntPtr.Zero);
+ }
+
+ private void UnregisterMetadataUpdatedEvent()
+ {
+ Native.UnsetMetadataUpdatedCb(SafeHandle);
+ }
+
+ private void RegisterShuffleModeUpdatedEvent()
+ {
+ _shufflemodeUpdatedCallback = (IntPtr serverName, MediaControllerShuffleMode shuffleMode, IntPtr userData) =>
+ {
+ ShuffleModeUpdatedEventArgs eventArgs = new ShuffleModeUpdatedEventArgs(Marshal.PtrToStringAnsi(serverName), shuffleMode);
+ _shufflemodeUpdated?.Invoke(this, eventArgs);
+ };
+
+ MediaControllerValidator.ThrowIfError(
+ Native.SetShuffleModeUpdatedCb(SafeHandle, _shufflemodeUpdatedCallback, IntPtr.Zero),
+ "Set ShuffleModeUpdated callback failed");
+ }
+
+ private void UnregisterShuffleModeUpdatedEvent()
+ {
+ Native.UnsetShuffleModeUpdatedCb(SafeHandle);
+ }
+
+ private void RegisterRepeatModeUpdatedEvent()
+ {
+ _repeatmodeUpdatedCallback = (IntPtr serverName, MediaControllerRepeatMode repeatMode, IntPtr userData) =>
+ {
+ RepeatModeUpdatedEventArgs eventArgs = new RepeatModeUpdatedEventArgs(Marshal.PtrToStringAnsi(serverName), repeatMode);
+ _repeatmodeUpdated?.Invoke(this, eventArgs);
+ };
+
+ MediaControllerValidator.ThrowIfError(
+ Native.SetRepeatModeUpdatedCb(SafeHandle, _repeatmodeUpdatedCallback, IntPtr.Zero),
+ "Set RepeatModeUpdated callback failed");
+ }
+
+ private void UnregisterRepeatModeUpdatedEvent()
+ {
+ Native.UnsetRepeatModeUpdatedCb(SafeHandle);
+ }
+
+ private static List<string> ForEachSubscribedServer(IntPtr handle, MediaControllerSubscriptionType subscriptionType)
+ {
+ List<string> subscribedServerCollections = new List<string>();
+
+ Native.SubscribedServerCallback serverCallback = (IntPtr serverName, IntPtr userData) =>
+ {
+ subscribedServerCollections.Add(Marshal.PtrToStringAnsi(serverName));
+ return true;
+ };
+
+ MediaControllerValidator.ThrowIfError(
+ Native.ForeachSubscribedServer(handle, subscriptionType, serverCallback, IntPtr.Zero),
+ "Foreach Subscribed server failed");
+
+ return subscribedServerCollections;
+ }
+
+ private static List<string> ForEachActivatedServer(IntPtr handle)
+ {
+ List<string> activatedServerCollections = new List<string>();
+
+ Native.ActivatedServerCallback serverCallback = (IntPtr serverName, IntPtr userData) =>
+ {
+ activatedServerCollections.Add(Marshal.PtrToStringAnsi(serverName));
+ return true;
+ };
+
+ MediaControllerValidator.ThrowIfError(
+ Native.ForeachActivatedServer(handle, serverCallback, IntPtr.Zero),
+ "Foreach Activated server failed");
+
+ return activatedServerCollections;
+ }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/MediaControllerEnums.cs b/src/Tizen.Multimedia.Remoting/MediaController/MediaControllerEnums.cs
new file mode 100755
index 0000000..dc12318
--- /dev/null
+++ b/src/Tizen.Multimedia.Remoting/MediaController/MediaControllerEnums.cs
@@ -0,0 +1,236 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+namespace Tizen.Multimedia.MediaController
+{
+ /// <summary>
+ /// Specifies states that a <see cref="ServerInformation"/> can have.
+ /// </summary>
+ public enum MediaControllerServerState
+ {
+ /// <summary>
+ /// Server state is unknown
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ None,
+
+ /// <summary>
+ /// Server is activated
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Activated,
+
+ /// <summary>
+ /// Server is deactivated
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Deactivated,
+ }
+
+ /// <summary>
+ /// Enumeration for playback state
+ /// </summary>
+ public enum MediaControllerPlaybackState
+ {
+ /// <summary>
+ /// Playback state is unknown
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ None,
+
+ /// <summary>
+ /// Playback is playing
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Play,
+
+ /// <summary>
+ /// Playback is paused
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Pause,
+
+ /// <summary>
+ /// Playback is next
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Next,
+
+ /// <summary>
+ /// Playback is prev
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Prev,
+
+ /// <summary>
+ /// Playback is fastforward
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ FastForward,
+
+ /// <summary>
+ /// Playback is rewind
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Rewind,
+ }
+
+ /// <summary>
+ /// Enumeration for shuffle mode
+ /// </summary>
+ public enum MediaControllerShuffleMode
+ {
+ /// <summary>
+ /// Shuffle mode is On
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ On,
+
+ /// <summary>
+ /// Shuffle mode is Off
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Off,
+ }
+
+ /// <summary>
+ /// Enumeration for repeat mode
+ /// </summary>
+ public enum MediaControllerRepeatMode
+ {
+ /// <summary>
+ /// Repeat mode is On
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ On,
+
+ /// <summary>
+ /// Repeat mode is Off
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Off,
+ }
+
+ /// <summary>
+ /// Enumeration for repeat mode
+ /// </summary>
+ public enum MediaControllerSubscriptionType
+ {
+ /// <summary>
+ /// The type of subscription is the state of server
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ ServerState,
+
+ /// <summary>
+ /// The type of subscription is the playback
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Playback,
+
+ /// <summary>
+ /// The type of subscription is the metadata
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Metadata,
+
+ /// <summary>
+ /// The type of subscription is the shuffle mode
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ ShuffleMode,
+
+ /// <summary>
+ /// The type of subscription is the repeat mode
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ RepeatMode,
+ }
+
+ /// <summary>
+ /// Enumeration for metadata attributes
+ /// </summary>
+ internal enum MediaControllerAttributes
+ {
+ /// <summary>
+ /// Attribute is title
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Title,
+
+ /// <summary>
+ /// Attribute is artist
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Artist,
+
+ /// <summary>
+ /// Attribute is album
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Album,
+
+ /// <summary>
+ /// Attribute is author
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Author,
+
+ /// <summary>
+ /// Attribute is genre
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Genre,
+
+ /// <summary>
+ /// Attribute is duration
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Duration,
+
+ /// <summary>
+ /// Attribute is date
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Date,
+
+ /// <summary>
+ /// Attribute is copyright
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Copyright,
+
+ /// <summary>
+ /// Attribute is description
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Description,
+
+ /// <summary>
+ /// Attribute is track number
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ TrackNumber,
+
+ /// <summary>
+ /// Attribute is picture
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Picture,
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/MediaControllerError.cs b/src/Tizen.Multimedia.Remoting/MediaController/MediaControllerError.cs
new file mode 100644
index 0000000..680bedd
--- /dev/null
+++ b/src/Tizen.Multimedia.Remoting/MediaController/MediaControllerError.cs
@@ -0,0 +1,57 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.IO;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Multimedia.MediaController
+{
+ internal enum MediaControllerError
+ {
+ None = ErrorCode.None,
+ InvalidParameter = ErrorCode.InvalidParameter,
+ OutOfMemory = ErrorCode.OutOfMemory,
+ InvalidOperation = ErrorCode.InvalidOperation,
+ NoSpaceOnDevice = ErrorCode.FileNoSpaceOnDevice,
+ PermissionDenied = ErrorCode.PermissionDenied,
+ };
+
+ internal static class MediaControllerValidator
+ {
+ internal static void ThrowIfError(MediaControllerError error, string errorMessage)
+ {
+ switch (error)
+ {
+ case MediaControllerError.InvalidParameter:
+ throw new ArgumentException(errorMessage);
+
+ case MediaControllerError.OutOfMemory:
+ throw new OutOfMemoryException(errorMessage);
+
+ case MediaControllerError.InvalidOperation:
+ throw new InvalidOperationException(errorMessage);
+
+ case MediaControllerError.NoSpaceOnDevice:
+ throw new IOException(errorMessage);
+
+ case MediaControllerError.PermissionDenied:
+ throw new UnauthorizedAccessException(errorMessage);
+ }
+ }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/MediaControllerLog.cs b/src/Tizen.Multimedia.Remoting/MediaController/MediaControllerLog.cs
new file mode 100644
index 0000000..44eac12
--- /dev/null
+++ b/src/Tizen.Multimedia.Remoting/MediaController/MediaControllerLog.cs
@@ -0,0 +1,25 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+
+namespace Tizen.Multimedia.MediaController
+{
+ static internal class MediaControllerLog
+ {
+ internal const string LogTag = "Tizen.Multimedia.MediaController";
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/MediaControllerMetadata.cs b/src/Tizen.Multimedia.Remoting/MediaController/MediaControllerMetadata.cs
new file mode 100755
index 0000000..1b0968b
--- /dev/null
+++ b/src/Tizen.Multimedia.Remoting/MediaController/MediaControllerMetadata.cs
@@ -0,0 +1,123 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using Native = Interop.MediaControllerClient;
+
+namespace Tizen.Multimedia.MediaController
+{
+ /// <summary>
+ /// Metadata represents a metadata of media for server application to play
+ /// </summary>
+ public class MediaControllerMetadata
+ {
+ /// <summary>
+ /// The constructor of MediaControllerMetadata class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public MediaControllerMetadata()
+ {
+ // Do nothing
+ }
+
+ internal MediaControllerMetadata(IntPtr handle)
+ {
+ if (handle == IntPtr.Zero)
+ {
+ throw new InvalidOperationException("MediaControllerMetadata is not valid.");
+ }
+
+ Title = Native.GetMetadata(handle, MediaControllerAttributes.Title);
+ Artist = Native.GetMetadata(handle, MediaControllerAttributes.Artist);
+ Album = Native.GetMetadata(handle, MediaControllerAttributes.Album);
+ Author = Native.GetMetadata(handle, MediaControllerAttributes.Author);
+ Genre = Native.GetMetadata(handle, MediaControllerAttributes.Genre);
+ Duration = Native.GetMetadata(handle, MediaControllerAttributes.Duration);
+ Date = Native.GetMetadata(handle, MediaControllerAttributes.Date);
+ Copyright = Native.GetMetadata(handle, MediaControllerAttributes.Copyright);
+ Description = Native.GetMetadata(handle, MediaControllerAttributes.Description);
+ TrackNumber = Native.GetMetadata(handle, MediaControllerAttributes.TrackNumber);
+ Picture = Native.GetMetadata(handle, MediaControllerAttributes.Picture);
+ }
+
+ /// <summary>
+ /// Set/Get the Title of media
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Title { get; set; }
+
+ /// <summary>
+ /// Set/Get the Artist of media
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Artist { get; set; }
+
+ /// <summary>
+ /// Set/Get the Album of media
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Album { get; set; }
+
+ /// <summary>
+ /// Set/Get the Author of media
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Author { get; set; }
+
+ /// <summary>
+ /// Set/Get the Genre of media
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Genre { get; set; }
+
+ /// <summary>
+ /// Set/Get the Duration of media
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Duration { get; set; }
+
+ /// <summary>
+ /// Set/Get the Date of media
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Date { get; set; }
+
+ /// <summary>
+ /// Set/Get the Copyright of media
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Copyright { get; set; }
+
+ /// <summary>
+ /// Set/Get the Description of media
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Description { get; set; }
+
+ /// <summary>
+ /// Set/Get the Track Number of media
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string TrackNumber { get; set; }
+
+ /// <summary>
+ /// Set/Get the Picture of media
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Picture { get; set; }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/MediaControllerPlayback.cs b/src/Tizen.Multimedia.Remoting/MediaController/MediaControllerPlayback.cs
new file mode 100755
index 0000000..52143e5
--- /dev/null
+++ b/src/Tizen.Multimedia.Remoting/MediaController/MediaControllerPlayback.cs
@@ -0,0 +1,76 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using Native = Interop.MediaControllerClient;
+
+namespace Tizen.Multimedia.MediaController
+{
+ /// <summary>
+ /// Playback represents a playback state and playback position.
+ /// </summary>
+ public class MediaControllerPlayback
+ {
+ /// <summary>
+ /// The constructor of MediaControllerPlayback class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="state">
+ /// The state of the playback which is playing in MediaConttoller server application
+ /// </param>
+ /// <param name="position">
+ /// The position of the playback which is playing in MediaConttoller server application
+ /// </param>
+ public MediaControllerPlayback(MediaControllerPlaybackState state, ulong position)
+ {
+ State = state;
+ Position = position;
+ }
+
+ internal MediaControllerPlayback(IntPtr handle)
+ {
+ MediaControllerPlaybackState state = MediaControllerPlaybackState.None;
+ ulong position = 0L;
+
+ if (handle == IntPtr.Zero)
+ {
+ throw new InvalidOperationException("MediaControllerPlayback is not valid.");
+ }
+
+ MediaControllerValidator.ThrowIfError(
+ Native.GetPlaybackState(handle, out state), "Get Playback state failed");
+
+ MediaControllerValidator.ThrowIfError(
+ Native.GetPlaybackPosition(handle, out position), "Get Playback position failed");
+
+ State = state;
+ Position = position;
+ }
+
+ /// <summary>
+ /// Set/Get the State of playback information
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public MediaControllerPlaybackState State { get; }
+
+ /// <summary>
+ /// Set/Get the Position of playback information
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ulong Position { get; }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/MediaControllerServer.cs b/src/Tizen.Multimedia.Remoting/MediaController/MediaControllerServer.cs
new file mode 100755
index 0000000..9928e53
--- /dev/null
+++ b/src/Tizen.Multimedia.Remoting/MediaController/MediaControllerServer.cs
@@ -0,0 +1,302 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Applications;
+using Native = Interop.MediaControllerServer;
+
+namespace Tizen.Multimedia.MediaController
+{
+
+ /// <summary>
+ /// The MediaControllerServer class provides APIs required for media-controller-server.
+ /// </summary>
+ /// <privilege>
+ /// http://tizen.org/privilege/mediacontroller.server
+ /// </privilege>
+ /// <remarks>
+ /// The MediaControllerServer APIs provides functions to update media information.
+ /// </remarks>
+ public class MediaControllerServer : IDisposable
+ {
+ internal IntPtr _handle = IntPtr.Zero;
+
+ private bool _disposed = false;
+ private EventHandler<PlaybackStateCommandEventArgs> _playbackCommand;
+ private Native.PlaybackStateCommandRecievedCallback _playbackCommandCallback;
+ private EventHandler<CustomCommandEventArgs> _customCommand;
+ private Native.CustomCommandRecievedCallback _customCommandCallback;
+
+ private bool IsValidHandle
+ {
+ get { return (_handle != IntPtr.Zero); }
+ }
+
+ private IntPtr SafeHandle
+ {
+ get
+ {
+ if (!IsValidHandle)
+ {
+ throw new ObjectDisposedException(nameof(MediaControllerServer), "Fail to operate MediaControllerServer");
+ }
+
+ return _handle;
+ }
+ }
+
+ /// <summary>
+ /// The constructor of MediaControllerServer class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when the access is denied for media controller client</exception>
+ public MediaControllerServer()
+ {
+ MediaControllerValidator.ThrowIfError(
+ Native.Create(out _handle), "Create server failed");
+ }
+
+ ~MediaControllerServer()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (disposing)
+ {
+ // To be used if there are any other disposable objects
+ }
+
+ if (IsValidHandle)
+ {
+ Native.Destroy(_handle);
+ _handle = IntPtr.Zero;
+ }
+
+ _disposed = true;
+ }
+ }
+
+ /// <summary>
+ /// PlaybackStateCommandRecieved event is raised when client send command for playback
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<PlaybackStateCommandEventArgs> PlaybackStateCommand
+ {
+ add
+ {
+ if (_playbackCommand == null)
+ {
+ RegisterPlaybackCmdRecvEvent();
+ }
+
+ _playbackCommand += value;
+
+ }
+
+ remove
+ {
+ _playbackCommand -= value;
+ if (_playbackCommand == null)
+ {
+ UnregisterPlaybackCmdRecvEvent();
+ }
+ }
+ }
+
+ /// <summary>
+ /// CustomCommandRecieved event is raised when client send customized command
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<CustomCommandEventArgs> CustomCommand
+ {
+ add
+ {
+ if (_customCommand == null)
+ {
+ RegisterCustomCommandEvent();
+ }
+
+ _customCommand += value;
+
+ }
+
+ remove
+ {
+ _customCommand -= value;
+ if (_customCommand == null)
+ {
+ UnregisterCustomCommandEvent();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Update playback state and playback position</summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="playback"> playback state and playback position </param>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ public void UpdatePlayback(MediaControllerPlayback playback)
+ {
+ if (playback == null)
+ {
+ throw new ArgumentNullException("playback is null");
+ }
+
+ MediaControllerValidator.ThrowIfError(
+ Native.SetPlaybackState(SafeHandle, playback.State), "Set Playback state failed");
+
+ MediaControllerValidator.ThrowIfError(
+ Native.SetPlaybackPosition(SafeHandle, playback.Position), "Set Playback position failed");
+
+ MediaControllerValidator.ThrowIfError(
+ Native.UpdatePlayback(SafeHandle), "Update Playback failed");
+ }
+
+ /// <summary>
+ /// Update metadata information </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="metadata"> metadata information </param>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ public void UpdateMetadata(MediaControllerMetadata metadata)
+ {
+ if (metadata == null)
+ {
+ throw new ArgumentNullException("metadata is null");
+ }
+
+ MediaControllerValidator.ThrowIfError(
+ Native.SetMetadata(SafeHandle, MediaControllerAttributes.Title, metadata.Title), "Set Title failed");
+
+ MediaControllerValidator.ThrowIfError(
+ Native.SetMetadata(SafeHandle, MediaControllerAttributes.Artist, metadata.Artist), "Set Artist failed");
+
+ MediaControllerValidator.ThrowIfError(
+ Native.SetMetadata(SafeHandle, MediaControllerAttributes.Album, metadata.Album), "Set Album failed");
+
+ MediaControllerValidator.ThrowIfError(
+ Native.SetMetadata(SafeHandle, MediaControllerAttributes.Author, metadata.Author), "Set Author failed");
+
+ MediaControllerValidator.ThrowIfError(
+ Native.SetMetadata(SafeHandle, MediaControllerAttributes.Genre, metadata.Genre), "Set Genre failed");
+
+ MediaControllerValidator.ThrowIfError(
+ Native.SetMetadata(SafeHandle, MediaControllerAttributes.Duration, metadata.Duration), "Set Duration failed");
+
+ MediaControllerValidator.ThrowIfError(
+ Native.SetMetadata(SafeHandle, MediaControllerAttributes.Date, metadata.Date), "Set Date failed");
+
+ MediaControllerValidator.ThrowIfError(
+ Native.SetMetadata(SafeHandle, MediaControllerAttributes.Copyright, metadata.Copyright), "Set Copyright failed");
+
+ MediaControllerValidator.ThrowIfError(
+ Native.SetMetadata(SafeHandle, MediaControllerAttributes.Description, metadata.Description), "Set Description failed");
+
+ MediaControllerValidator.ThrowIfError(
+ Native.SetMetadata(SafeHandle, MediaControllerAttributes.TrackNumber, metadata.TrackNumber), "Set TrackNumber failed");
+
+ MediaControllerValidator.ThrowIfError(
+ Native.SetMetadata(SafeHandle, MediaControllerAttributes.Picture, metadata.Picture), "Set Picture failed");
+
+ MediaControllerValidator.ThrowIfError(
+ Native.UpdateMetadata(SafeHandle), "UpdateMetadata Metadata failed");
+ }
+
+ /// <summary>
+ /// Update shuffle mode </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="mode"> shuffle mode </param>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ public void UpdateShuffleMode(MediaControllerShuffleMode mode)
+ {
+ MediaControllerValidator.ThrowIfError(
+ Native.UpdateShuffleMode(SafeHandle, mode), "Update Shuffle Mode failed");
+ }
+
+ /// <summary>
+ /// Update repeat mode </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="mode"> repeat mode </param>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ public void UpdateRepeatMode(MediaControllerRepeatMode mode)
+ {
+ MediaControllerValidator.ThrowIfError(
+ Native.UpdateRepeatMode(SafeHandle, mode), "Update Repeat Mode failed");
+ }
+
+ /// <summary>
+ /// Send reply for command from server to client </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="clientName"> client name to recieve reply </param>
+ /// <param name="result"> result to run command </param>
+ /// <param name="bundle"> Bundle to send various data </param>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ public void SendCustomCommandReply(string clientName, int result, Bundle bundle)
+ {
+ MediaControllerValidator.ThrowIfError(
+ Native.SendCommandReply(SafeHandle, clientName, result, bundle.SafeBundleHandle), "Send reply for command failed");
+ }
+
+ private void RegisterPlaybackCmdRecvEvent()
+ {
+ _playbackCommandCallback = (IntPtr clientName, MediaControllerPlaybackState state, IntPtr userData) =>
+ {
+ PlaybackStateCommandEventArgs eventArgs = new PlaybackStateCommandEventArgs(Marshal.PtrToStringAnsi(clientName), state);
+ _playbackCommand?.Invoke(this, eventArgs);
+ };
+ Native.SetPlaybackStateCmdRecvCb(SafeHandle, _playbackCommandCallback, IntPtr.Zero);
+ }
+
+ private void UnregisterPlaybackCmdRecvEvent()
+ {
+ Native.UnsetPlaybackStateCmdRecvCb(SafeHandle);
+ }
+
+ private void RegisterCustomCommandEvent()
+ {
+ _customCommandCallback = (IntPtr clientName, IntPtr command, IntPtr bundle, IntPtr userData) =>
+ {
+ SafeBundleHandle safeBundleHandle = new SafeBundleHandle(bundle, true);
+ Bundle bundleData = new Bundle(safeBundleHandle);
+ CustomCommandEventArgs eventArgs = new CustomCommandEventArgs(Marshal.PtrToStringAnsi(clientName), Marshal.PtrToStringAnsi(command), bundleData);
+ _customCommand?.Invoke(this, eventArgs);
+ };
+ Native.SetCustomCmdRecvCb(SafeHandle, _customCommandCallback, IntPtr.Zero);
+ }
+
+ private void UnregisterCustomCommandEvent()
+ {
+ Native.UnsetCustomCmdRecvCb(SafeHandle);
+ }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/MetadataUpdatedEventArgs.cs b/src/Tizen.Multimedia.Remoting/MediaController/MetadataUpdatedEventArgs.cs
new file mode 100755
index 0000000..51a718c
--- /dev/null
+++ b/src/Tizen.Multimedia.Remoting/MediaController/MetadataUpdatedEventArgs.cs
@@ -0,0 +1,49 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+
+namespace Tizen.Multimedia.MediaController
+{
+
+ /// <summary>
+ /// MetadataUpdated event arguments
+ /// </summary>
+ /// <remarks>
+ /// MetadataUpdated event arguments
+ /// </remarks>
+ public class MetadataUpdatedEventArgs : EventArgs
+ {
+ internal MetadataUpdatedEventArgs(string name, IntPtr handle)
+ {
+ ServerName = name;
+ Metadata = new MediaControllerMetadata(handle);
+ }
+
+ /// <summary>
+ /// Get the Server Name.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string ServerName { get; }
+
+ /// <summary>
+ /// Get the Metadata information.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public MediaControllerMetadata Metadata { get; }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/PlaybackStateCommandEventArgs.cs b/src/Tizen.Multimedia.Remoting/MediaController/PlaybackStateCommandEventArgs.cs
new file mode 100755
index 0000000..339a90b
--- /dev/null
+++ b/src/Tizen.Multimedia.Remoting/MediaController/PlaybackStateCommandEventArgs.cs
@@ -0,0 +1,49 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+
+namespace Tizen.Multimedia.MediaController
+{
+
+ /// <summary>
+ /// PlaybackStateCommand event arguments
+ /// </summary>
+ /// <remarks>
+ /// PlaybackStateCommand event arguments
+ /// </remarks>
+ public class PlaybackStateCommandEventArgs : EventArgs
+ {
+ internal PlaybackStateCommandEventArgs(string name, MediaControllerPlaybackState state)
+ {
+ ClientName = name;
+ State = state;
+ }
+
+ /// <summary>
+ /// Get the Client Name.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string ClientName { get; }
+
+ /// <summary>
+ /// Get the State of playback.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public MediaControllerPlaybackState State { get; }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/PlaybackUpdatedEventArgs.cs b/src/Tizen.Multimedia.Remoting/MediaController/PlaybackUpdatedEventArgs.cs
new file mode 100755
index 0000000..e6db63d
--- /dev/null
+++ b/src/Tizen.Multimedia.Remoting/MediaController/PlaybackUpdatedEventArgs.cs
@@ -0,0 +1,49 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+
+namespace Tizen.Multimedia.MediaController
+{
+
+ /// <summary>
+ /// PlaybackUpdated event arguments
+ /// </summary>
+ /// <remarks>
+ /// PlaybackUpdated event arguments
+ /// </remarks>
+ public class PlaybackUpdatedEventArgs : EventArgs
+ {
+ internal PlaybackUpdatedEventArgs(string name, IntPtr handle)
+ {
+ ServerName = name;
+ PlaybackInfo = new MediaControllerPlayback(handle);
+ }
+
+ /// <summary>
+ /// Get the Server Name.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string ServerName { get; }
+
+ /// <summary>
+ /// Get the Playback Information.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public MediaControllerPlayback PlaybackInfo { get; }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/RepeatModeUpdatedEventArgs.cs b/src/Tizen.Multimedia.Remoting/MediaController/RepeatModeUpdatedEventArgs.cs
new file mode 100755
index 0000000..e9abebd
--- /dev/null
+++ b/src/Tizen.Multimedia.Remoting/MediaController/RepeatModeUpdatedEventArgs.cs
@@ -0,0 +1,49 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+
+namespace Tizen.Multimedia.MediaController
+{
+
+ /// <summary>
+ /// RepeatModeUpdated event arguments
+ /// </summary>
+ /// <remarks>
+ /// RepeatModeUpdated event arguments
+ /// </remarks>
+ public class RepeatModeUpdatedEventArgs : EventArgs
+ {
+ internal RepeatModeUpdatedEventArgs(string name, MediaControllerRepeatMode mode)
+ {
+ ServerName = name;
+ RepeatMode = mode;
+ }
+
+ /// <summary>
+ /// Get the Server Name.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string ServerName { get; }
+
+ /// <summary>
+ /// Get the Repeat Mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public MediaControllerRepeatMode RepeatMode { get; }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/ServerInformation.cs b/src/Tizen.Multimedia.Remoting/MediaController/ServerInformation.cs
new file mode 100755
index 0000000..39684e8
--- /dev/null
+++ b/src/Tizen.Multimedia.Remoting/MediaController/ServerInformation.cs
@@ -0,0 +1,45 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+
+namespace Tizen.Multimedia.MediaController
+{
+ /// <summary>
+ /// ServerInformation represents a name and state of server application.
+ /// </summary>
+ public class ServerInformation
+ {
+ internal ServerInformation(string name, MediaControllerServerState state)
+ {
+ Name = name;
+ State = state;
+ }
+
+ /// <summary>
+ /// Get the Name of server
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Name { get; }
+
+ /// <summary>
+ /// Get the State of server
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public MediaControllerServerState State { get; }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/ServerUpdatedEventArgs.cs b/src/Tizen.Multimedia.Remoting/MediaController/ServerUpdatedEventArgs.cs
new file mode 100755
index 0000000..1fa8319
--- /dev/null
+++ b/src/Tizen.Multimedia.Remoting/MediaController/ServerUpdatedEventArgs.cs
@@ -0,0 +1,42 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+
+namespace Tizen.Multimedia.MediaController
+{
+
+ /// <summary>
+ /// ServerUpdated event arguments
+ /// </summary>
+ /// <remarks>
+ /// ServerUpdated event arguments
+ /// </remarks>
+ public class ServerUpdatedEventArgs : EventArgs
+ {
+ internal ServerUpdatedEventArgs(string name, MediaControllerServerState state)
+ {
+ ServerInfo = new ServerInformation(name, state);
+ }
+
+ /// <summary>
+ /// Get the Server Information.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ServerInformation ServerInfo { get; }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/ShuffleModeUpdatedEventArgs.cs b/src/Tizen.Multimedia.Remoting/MediaController/ShuffleModeUpdatedEventArgs.cs
new file mode 100755
index 0000000..6d5a5c3
--- /dev/null
+++ b/src/Tizen.Multimedia.Remoting/MediaController/ShuffleModeUpdatedEventArgs.cs
@@ -0,0 +1,49 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+
+namespace Tizen.Multimedia.MediaController
+{
+
+ /// <summary>
+ /// ShuffleModeUpdated event arguments
+ /// </summary>
+ /// <remarks>
+ /// ShuffleModeUpdated event arguments
+ /// </remarks>
+ public class ShuffleModeUpdatedEventArgs : EventArgs
+ {
+ internal ShuffleModeUpdatedEventArgs(string name, MediaControllerShuffleMode mode)
+ {
+ ServerName = name;
+ ShuffleMode = mode;
+ }
+
+ /// <summary>
+ /// Get the Server Name.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string ServerName { get; }
+
+ /// <summary>
+ /// Get the Shuffle Mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public MediaControllerShuffleMode ShuffleMode { get; }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Remoting/ScreenMirroring/AudioInformation.cs b/src/Tizen.Multimedia.Remoting/ScreenMirroring/AudioInformation.cs
new file mode 100644
index 0000000..a1d05a8
--- /dev/null
+++ b/src/Tizen.Multimedia.Remoting/ScreenMirroring/AudioInformation.cs
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Native = Interop.ScreenMirroring;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Audio Information class provides audio information which is negotiated with source device for screen mirroring. e.g codec
+ /// </summary>
+ /// <remarks>
+ /// This class provides properties and API that are required for setting audio information.
+ /// For getting property using this api, we should call it after connectAsync() api.
+ /// </remarks>
+ public class AudioInformation
+ {
+ internal IntPtr _handle;
+ private int _codec;
+ private int _channel;
+ private int _sampleRate;
+ private int _bitWidth;
+
+ internal AudioInformation()
+ {
+ }
+
+ /// <summary>
+ /// Get audio codec.
+ /// </summary>
+ /// <value> Get audio codec which is one of enums in 'AudioCodec' which is negotiaged with source device. </value>
+ /// <exception cref="InvalidOperationException">Thrown when method fail due to an internal error</exception>
+ public AudioCodec Codec
+ {
+ get
+ {
+ int ret;
+ ret = Native.GetNegotiatedAudioCodec(ref _handle, out _codec);
+ if (ret != (int)ScreenMirroringError.None)
+ {
+ Log.Error(ScreenMirroringLog.LogTag, "Failed to get audio codec" + (ScreenMirroringError)ret);
+ ScreenMirroringErrorFactory.ThrowException(ret, "failed to get audio codec");
+ }
+
+ return (AudioCodec)_codec;
+ }
+ }
+
+ /// <summary>
+ /// Get audio channel.
+ /// </summary>
+ /// <value> Get audio channel property of audio information which is negotiated with source device. </value>
+ /// <exception cref="InvalidOperationException">Thrown when method fail due to an internal error</exception>
+ public int Channel
+ {
+ get
+ {
+ int ret;
+ ret = Native.GetNegotiatedAudioChannel(ref _handle, out _channel);
+ if (ret != (int)ScreenMirroringError.None)
+ {
+ Log.Error(ScreenMirroringLog.LogTag, "Failed to get audio channel" + (ScreenMirroringError)ret);
+ ScreenMirroringErrorFactory.ThrowException(ret, "failed to get audio channel");
+ }
+
+ return _channel;
+ }
+ }
+
+ /// <summary>
+ /// Get audio sample rate.
+ /// </summary>
+ /// <value> Get audio sample rate property which is negotiated with source device. </value>
+ /// <exception cref="InvalidOperationException">Thrown when method fail due to an internal error</exception>
+ public int SampleRate
+ {
+ get
+ {
+ int ret;
+ ret = Native.GetNegotiatedAudioSampleRate(ref _handle, out _sampleRate);
+ if (ret != (int)ScreenMirroringError.None)
+ {
+ Log.Error(ScreenMirroringLog.LogTag, "Failed to get audio sample rate" + (ScreenMirroringError)ret);
+ ScreenMirroringErrorFactory.ThrowException(ret, "failed to get audio sample rate");
+ }
+
+ return _sampleRate;
+ }
+ }
+
+ /// <summary>
+ /// Get audio bitwidth.
+ /// </summary>
+ /// <value> Get audio bitwidth property which is negotiated with source device. </value>
+ /// <exception cref="InvalidOperationException">Thrown when method fail due to an internal error</exception>
+ public int BitWidth
+ {
+ get
+ {
+ int ret;
+ ret = Native.GetNegotiatedAudioBitwidth(ref _handle, out _bitWidth);
+ if (ret != (int)ScreenMirroringError.None)
+ {
+ Log.Error(ScreenMirroringLog.LogTag, "Failed to get audio bitwidth" + (ScreenMirroringError)ret);
+ ScreenMirroringErrorFactory.ThrowException(ret, "failed to get audio bitwidth");
+ }
+
+ return _bitWidth;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Remoting/ScreenMirroring/ScreenMirroring.cs b/src/Tizen.Multimedia.Remoting/ScreenMirroring/ScreenMirroring.cs
new file mode 100644
index 0000000..9ef7bd3
--- /dev/null
+++ b/src/Tizen.Multimedia.Remoting/ScreenMirroring/ScreenMirroring.cs
@@ -0,0 +1,497 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.Diagnostics;
+using System.Threading.Tasks;
+using Native = Interop.ScreenMirroring;
+
+namespace Tizen.Multimedia
+{
+ static internal class ScreenMirroringLog
+ {
+ internal const string LogTag = "Tizen.Multimedia.ScreenMirroring";
+ }
+
+ /// <summary>
+ /// ScreenMirroring class provides methods to function as screen mirroring application as sink.
+ /// It gives the ability to connect to and disconnect from a screen mirroring source, and
+ /// start, pause, and resume the screen mirroring sink, set the resolution or display,
+ /// register state change callback function.
+ /// </summary>
+ public class ScreenMirroring : IDisposable, IDisplayable<int>
+ {
+ internal VideoInformation _videoInfo;
+ internal AudioInformation _audioInfo;
+ internal IntPtr _handle;
+ internal string _ip;
+ internal string _port;
+
+ private bool _disposed = false;
+ private EventHandler<StateChangedEventArgs> _stateChanged;
+ private Native.StateChangedCallback _stateChangedCallback;
+
+ /// <summary>
+ /// Initializes a new instance of the ScreenMirroring class with parameters Ip, Port and Display handle.
+ /// Object should be created only when Ip and Port are available.
+ /// Create(i.e constructor) api will create a new handle with the given parameters.
+ /// </summary>
+ /// <param name="display">Display.</param>
+ /// <param name="ip">Ip.</param>
+ /// <param name="port">Port.</param>
+ /// <exception cref="ArgumentException">Thrown when method fail due to an invalid parameter</exception>
+ public ScreenMirroring(Display display, string ip, string port)
+ {
+ int ret = Native.Create(out _handle);
+ if (ret != (int)ScreenMirroringError.None)
+ {
+ ScreenMirroringErrorFactory.ThrowException(ret, "Failed to create Screen Mirroring Sink");
+ }
+
+ // initiate values
+ _ip = ip;
+ _port = port;
+
+ // Set ip and port
+ int ret1 = Native.SetIpAndPort(_handle, _ip, _port);
+ if (ret1 != (int)ScreenMirroringError.None)
+ {
+ Log.Error(ScreenMirroringLog.LogTag, "Set ip and port failed" + (ScreenMirroringError)ret1);
+ ScreenMirroringErrorFactory.ThrowException(ret, "set ip and port failed");
+ }
+
+ Display = display;
+
+ // AudioInfo
+ _audioInfo = new AudioInformation();
+ _audioInfo._handle = _handle;
+ // VideoInfo
+ _videoInfo = new VideoInformation();
+ _videoInfo._handle = _handle;
+
+ Log.Debug(ScreenMirroringLog.LogTag, "screen mirroring sink created : " + _handle);
+ }
+
+ /// <summary>
+ /// Screen Mirroring destructor.
+ /// </summary>
+ ~ScreenMirroring()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// StateChanged event is raised when state change happens.
+ /// Must be called after Create() API.
+ /// </summary>
+ public event EventHandler<StateChangedEventArgs> StateChanged
+ {
+ add
+ {
+ if (_stateChanged == null)
+ {
+ RegisterStateChangedEvent();
+ }
+
+ _stateChanged += value;
+ }
+
+ remove
+ {
+ _stateChanged -= value;
+ if (_stateChanged == null)
+ {
+ UnregisterStateChangedEvent();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Sets the server ip and port.
+ /// This must be called before connect() and after create().
+ /// </summary>
+ /// <example> If only one handle is used for toggling between more than two source devices,
+ /// then this API ahould be used to assign the parameters to the handle.
+ /// </example>
+ /// <param name="ip">Ip.</param>
+ /// <param name="port">Port.</param>
+ /// <exception cref="ArgumentException">Thrown when method fail due to an invalid parameter</exception>
+ public void SetIpAndPort(string ip, string port)
+ {
+ int ret = Native.SetIpAndPort(_handle, ip, port);
+ if (ret != (int)ScreenMirroringError.None)
+ {
+ Log.Error(ScreenMirroringLog.LogTag, "Set ip and port failed" + (ScreenMirroringError)ret);
+ ScreenMirroringErrorFactory.ThrowException(ret, "set ip and port failed");
+ }
+ }
+
+ /// <summary>
+ /// Set Resolution.
+ /// valid state: NULL..
+ /// </summary>
+ /// <param name="resolution"> example: (R1920x1080P30 | R1280x720P30) </param>
+ /// <exception cref="ArgumentException">Thrown when method fail due to an invalid parameter</exception>
+ public void SetResolution(ResolutionType resolution)
+ {
+ int ret = Native.SetResolution(_handle, (int)resolution);
+ if (ret != (int)ScreenMirroringError.None)
+ {
+ Log.Error(ScreenMirroringLog.LogTag, "Set resolution failed" + (ScreenMirroringError)ret);
+ ScreenMirroringErrorFactory.ThrowException(ret, "set resolution failed");
+ }
+ }
+
+ private Display _display;
+
+ private int ApplyDisplay(Display display)
+ {
+ return display.ApplyTo(this);
+ }
+
+ private void ReplaceDisplay(Display newDisplay)
+ {
+ if (_display != null)
+ {
+ _display.Owner = null;
+ }
+ _display = newDisplay;
+ if (_display != null)
+ {
+ _display.Owner = this;
+ }
+ }
+
+ /// <summary>
+ /// Sets the display.
+ /// This must be called before prepare() and after create().
+ /// </summary>
+ /// <example> If only one handle is used for toggling between more than two source devices,
+ /// then this API should be used to assign the parameters to the handle.
+ /// </example>
+ /// <exception cref="ArgumentException">Thrown when method fail due to an invalid parameter</exception>
+ public Display Display
+ {
+ get
+ {
+ return _display;
+ }
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(Display));
+ }
+
+ int ret = ApplyDisplay(value);
+ if (ret != (int)ScreenMirroringError.None)
+ {
+ Log.Error(ScreenMirroringLog.LogTag, "Set display failed" + (ScreenMirroringError)ret);
+ ScreenMirroringErrorFactory.ThrowException(ret, "set display failed");
+ }
+ }
+ }
+
+ int IDisplayable<int>.ApplyEvasDisplay(DisplayType type, ElmSharp.EvasObject evasObject)
+ {
+ Debug.Assert(_disposed == false);
+
+ Debug.Assert(Enum.IsDefined(typeof(DisplayType), type));
+
+ return Native.SetDisplay(_handle, (int)type, evasObject);
+ }
+
+ /// <summary>
+ /// Prepare this instance.
+ /// This must be called after Create().
+ /// </summary>
+ /// <exception cref="InvalidOperationException">Thrown when method fail due to an internal error</exception>
+ public void Prepare()
+ {
+ int ret = Native.Prepare(_handle);
+ if (ret != (int)ScreenMirroringError.None)
+ {
+ ScreenMirroringErrorFactory.ThrowException(ret, "Failed to prepare sink for screen mirroring");
+ }
+ }
+
+ /// <summary>
+ /// Creates connection and prepare for receiving data from ScreenMirroring source.
+ /// This must be called after prepare().
+ /// </summary>
+ /// <remarks> It will not give the current state. Need to subscribe for event to get the current state </remarks>
+ /// <returns>bool value</returns>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ /// <exception cref="InvalidOperationException">Thrown when method fail due to an internal error</exception>
+ public Task<bool> ConnectAsync()
+ {
+ int ret = Native.ConnectAsync(_handle);
+ var task = new TaskCompletionSource<bool>();
+
+ Task.Factory.StartNew(() =>
+ {
+ if (ret == (int)ScreenMirroringError.None)
+ {
+ task.SetResult(true);
+ }
+
+ else if (ret != (int)ScreenMirroringError.None)
+ {
+ Log.Error(ScreenMirroringLog.LogTag, "Failed to start screen mirroring" + (ScreenMirroringError)ret);
+ InvalidOperationException e = new InvalidOperationException("Operation Failed");
+ task.TrySetException(e);
+ }
+ });
+
+ return task.Task;
+ }
+
+ /// <summary>
+ /// Get AudioInfo.
+ /// This must be called after connectasync().
+ /// valid states: connected/playback/paused.
+ /// If audio file changes during playback again
+ /// then the current info should be retrieved from the audio information class.
+ /// </summary>
+ /// <value> AudioInfo object </value>
+ public AudioInformation AudioInfo
+ {
+ get
+ {
+ return _audioInfo;
+ }
+ }
+
+ /// <summary>
+ /// Get VideoInfo.
+ /// This must be called after connectasync().
+ /// valid states: connected/playback/paused.
+ /// If video file changes during playback again
+ /// then the current info should be retrieved from the video information class.
+ /// </summary>
+ /// <value> VideoInfo object </value>
+ public VideoInformation VideoInfo
+ {
+ get
+ {
+ return _videoInfo;
+ }
+ }
+
+ /// <summary>
+ /// Start receiving data from the ScreenMirroring source and display it(Mirror).
+ /// This must be called after connectasync().
+ /// </summary>
+ /// <remarks> It will not give the current state. Need to subscribe for event to get the current state </remarks>
+ /// <returns>bool value<returns>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ /// <exception cref="InvalidOperationException">Thrown when method fail due to an internal error</exception>
+ public Task<bool> StartAsync()
+ {
+ int ret = Native.StartAsync(_handle);
+ var task = new TaskCompletionSource<bool>();
+
+ Task.Factory.StartNew(() =>
+ {
+ if (ret == (int)ScreenMirroringError.None)
+ {
+ task.SetResult(true);
+ }
+
+ else if (ret != (int)ScreenMirroringError.None)
+ {
+ Log.Error(ScreenMirroringLog.LogTag, "Failed to start screen mirroring" + (ScreenMirroringError)ret);
+ InvalidOperationException e = new InvalidOperationException("Operation Failed");
+ task.TrySetException(e);
+ }
+ });
+
+ return task.Task;
+ }
+
+ /// <summary>
+ /// Pauses receiving data from the ScreenMirroring source.
+ /// This must be called after startasync().
+ /// </summary>
+ /// <remarks> It will not give the current state. Need to subscribe for event to get the current state </remarks>
+ /// <returns>bool value</returns>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ /// <exception cref="InvalidOperationException">Thrown when method fail due to an internal error</exception>
+ public Task<bool> PauseAsync()
+ {
+ int ret = Native.PauseAsync(_handle);
+ var task = new TaskCompletionSource<bool>();
+
+ Task.Factory.StartNew(() =>
+ {
+ if (ret == (int)ScreenMirroringError.None)
+ {
+ task.SetResult(true);
+ }
+
+ else if (ret != (int)ScreenMirroringError.None)
+ {
+ Log.Error(ScreenMirroringLog.LogTag, "Failed to start screen mirroring" + (ScreenMirroringError)ret);
+ InvalidOperationException e = new InvalidOperationException("Operation Failed");
+ task.TrySetException(e);
+ }
+ });
+
+ return task.Task;
+ }
+
+ /// <summary>
+ /// Resumes receiving data from the ScreenMirroring source.
+ /// This must be called after pauseasync().
+ /// </summary>
+ /// <remarks> It will not give the current state. Need to subscribe for event to get the current state </remarks>
+ /// <returns>bool value</returns>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ /// <exception cref="InvalidOperationException">Thrown when method fail due to an internal error</exception>
+ public Task<bool> ResumeAsync()
+ {
+ int ret = Native.ResumeAsync(_handle);
+ var task = new TaskCompletionSource<bool>();
+
+ Task.Factory.StartNew(() =>
+ {
+ if (ret == (int)ScreenMirroringError.None)
+ {
+ task.SetResult(true);
+ }
+
+ else if (ret != (int)ScreenMirroringError.None)
+ {
+ Log.Error(ScreenMirroringLog.LogTag, "Failed to start screen mirroring" + (ScreenMirroringError)ret);
+ InvalidOperationException e = new InvalidOperationException("Operation Failed");
+ task.TrySetException(e);
+ }
+ });
+
+ return task.Task;
+ }
+
+ /// <summary>
+ /// Disconnect this instance.
+ /// valid states: connected/playing/paused
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ /// <exception cref="ArgumentException">Thrown when method fail due to no connection between devices</exception>
+ public void Disconnect()
+ {
+ int ret = Native.Disconnect(_handle);
+ if (ret != (int)ScreenMirroringError.None)
+ {
+ ScreenMirroringErrorFactory.ThrowException(ret, "Failed to disconnect sink for screen mirroring");
+ }
+ }
+
+ /// <summary>
+ /// Unprepare this instance.
+ /// valid states: prepared/disconnected.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">Thrown when method fail due to an internal error</exception>
+ public void Unprepare()
+ {
+ int ret = Native.Unprepare(_handle);
+ if (ret != (int)ScreenMirroringError.None)
+ {
+ ScreenMirroringErrorFactory.ThrowException(ret, "Failed to reset the screen mirroring sink");
+ }
+ }
+
+ /// <summary>
+ /// Releases all resource used by the <see cref="Tizen.Multimedia.ScreenMirroring"/> object.
+ /// </summary>
+ /// <remarks>Call <see cref="Dispose"/> when you are finished using the <see cref="Tizen.Multimedia.ScreenMirroring"/>.
+ /// The <see cref="Dispose"/> method leaves the <see cref="Tizen.Multimedia.ScreenMirroring"/> in an unusable
+ /// state. After calling <see cref="Dispose"/>, you must release all references to the
+ /// <see cref="Tizen.Multimedia.ScreenMirroring"/> so the garbage collector can reclaim the memory that the
+ /// <see cref="Tizen.Multimedia.ScreenMirroring"/> was occupying.</remarks>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Dispose the specified handle.
+ /// </summary>
+ /// <param name="disposing">If set to <c>true</c> disposing.</param>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (disposing)
+ {
+ // To be used if there are any other disposable objects
+ }
+
+ if (_handle != IntPtr.Zero)
+ {
+ Native.Destroy(_handle);
+ _handle = IntPtr.Zero;
+ }
+
+ _disposed = true;
+ }
+ }
+
+ /// <summary>
+ /// Invoke the event for state or error.
+ /// </summary>
+ /// <param name="state"> state </param>
+ /// <param name="error"> error </param>
+ private void StateError(int state, int error)
+ {
+ ///if _stateChanged is subscribe, this will be invoke.
+ StateChangedEventArgs eventArgsState = new StateChangedEventArgs(state, error);
+ _stateChanged?.Invoke(this, eventArgsState);
+ }
+
+ /// <summary>
+ /// Registers the state changed event.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">Thrown when method fail due to an internal error</exception>
+ private void RegisterStateChangedEvent()
+ {
+ _stateChangedCallback = (IntPtr userData, int state, int error) =>
+ {
+ StateError(state, error);
+ };
+
+ int ret = Native.SetStateChangedCb(_handle, _stateChangedCallback, IntPtr.Zero);
+ if (ret != (int)ScreenMirroringError.None)
+ {
+ Log.Error(ScreenMirroringLog.LogTag, "Setting StateChanged callback failed" + (ScreenMirroringError)ret);
+ ScreenMirroringErrorFactory.ThrowException(ret, "Setting StateChanged callback failed");
+ }
+ }
+
+ /// <summary>
+ /// Unregisters the state changed event.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">Thrown when method fail due to an internal error</exception>
+ private void UnregisterStateChangedEvent()
+ {
+ int ret = Native.UnsetStateChangedCb(_handle);
+ if (ret != (int)ScreenMirroringError.None)
+ {
+ Log.Error(ScreenMirroringLog.LogTag, "Unsetting StateChnaged callback failed" + (ScreenMirroringError)ret);
+ ScreenMirroringErrorFactory.ThrowException(ret, "Unsetting StateChanged callback failed");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Remoting/ScreenMirroring/ScreenMirroringEnumerations.cs b/src/Tizen.Multimedia.Remoting/ScreenMirroring/ScreenMirroringEnumerations.cs
new file mode 100644
index 0000000..4689538
--- /dev/null
+++ b/src/Tizen.Multimedia.Remoting/ScreenMirroring/ScreenMirroringEnumerations.cs
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Enumeration for audio codec.
+ /// </summary>
+ public enum AudioCodec
+ {
+ /// <summary>
+ /// Screen mirroring is not negotiated yet
+ /// </summary>
+ None,
+ /// <summary>
+ /// AAC codec for audio
+ /// </summary>
+ Aac,
+ /// <summary>
+ /// AC3 codec for audio
+ /// </summary>
+ Ac3,
+ /// <summary>
+ /// LPCM codec for audio
+ /// </summary>
+ Lpcm
+ }
+ /// <summary>
+ /// Enumeration for video codec.
+ /// </summary>
+ public enum VideoCodec
+ {
+ /// <summary>
+ /// Screen mirroring is not negotiated yet
+ /// </summary>
+ None,
+ /// <summary>
+ /// H.264 codec for video
+ /// </summary>
+ H264
+ }
+
+ /// <summary>
+ /// Enumeration for screen mirroring resolution.
+ /// </summary>
+ public enum ResolutionType
+ {
+ /// <summary>
+ /// W-1920, H-1080, 30 fps
+ /// </summary>
+ R1920x1080P30 = (1 << 0),
+ /// <summary>
+ /// W-1280, H-720, 30 fps
+ /// </summary>
+ R1280x720P30 = (1 << 1),
+ /// <summary>
+ /// W-960, H-540, 30 fps
+ /// </summary>
+ R960x540P30 = (1 << 2),
+ /// <summary>
+ /// W-864, H-480, 30 fps
+ /// </summary>
+ R864x480P30 = (1 << 3),
+ /// <summary>
+ /// W-720, H-480, 60 fps
+ /// </summary>
+ R720x480P60 = (1 << 4),
+ /// <summary>
+ /// W-640, H-480, 60 fps
+ /// </summary>
+ R640x480P60 = (1 << 5),
+ /// <summary>
+ /// W-640, H-360, 30 fps
+ /// </summary>
+ R640x360P30 = (1 << 6)
+ }
+
+ /// <summary>
+ /// Enumeration for screen mirroring sink state
+ /// </summary>
+ public enum ScreenMirroringSinkState
+ {
+ /// <summary>
+ /// Screen mirroring is not created yet
+ /// </summary>
+ None,
+ /// <summary>
+ /// Screen mirroring is created, but not prepared yet
+ /// </summary>
+ Null,
+ /// <summary>
+ /// Screen mirroring is prepared to play media
+ /// </summary>
+ Prepared,
+ /// <summary>
+ /// Screen mirroring is connected
+ /// </summary>
+ Connected,
+ /// <summary>
+ /// Screen mirroring is now playing media
+ /// </summary>
+ Playing,
+ /// <summary>
+ /// Screen mirroring is paused while playing media
+ /// </summary>
+ Paused,
+ /// <summary>
+ /// Screen mirroring is disconnected
+ /// </summary>
+ Disconnected
+ }
+
+ /// <summary>
+ /// Enumeration for screen mirroring error.
+ /// </summary>
+ public enum ScreenMirroringErrorCode
+ {
+ /// <summary>
+ /// Successful
+ /// </summary>
+ None = ScreenMirroringError.None,
+ /// <summary>
+ /// Invalid operation
+ /// </summary>
+ InvalidOperation = ScreenMirroringError.InvalidOperation
+ }
+}
diff --git a/src/Tizen.Multimedia.Remoting/ScreenMirroring/ScreenMirroringErrorFactory.cs b/src/Tizen.Multimedia.Remoting/ScreenMirroring/ScreenMirroringErrorFactory.cs
new file mode 100644
index 0000000..01fc2a5
--- /dev/null
+++ b/src/Tizen.Multimedia.Remoting/ScreenMirroring/ScreenMirroringErrorFactory.cs
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Tizen.Internals.Errors;
+namespace Tizen.Multimedia
+{
+ internal enum ScreenMirroringError
+ {
+ None = ErrorCode.None,
+ InvalidParameter = ErrorCode.InvalidParameter,
+ OutOfMemory = ErrorCode.OutOfMemory,
+ InvalidOperation = ErrorCode.InvalidOperation,
+ ConnectionTimeOut = ErrorCode.ConnectionTimeout,
+ PermissionDenied = ErrorCode.PermissionDenied,
+ NotSupported = ErrorCode.NotSupported,
+ Unknown = ErrorCode.Unknown
+ };
+ internal static class ScreenMirroringErrorFactory
+ {
+ private const string LogTag = "Tizen.Multimedia.ScreenMirroring";
+ internal static void ThrowException(int errorCode, string errorMessage = null)
+ {
+ ScreenMirroringError err = (ScreenMirroringError)errorCode;
+
+ if (err == ScreenMirroringError.None)
+ {
+ return;
+ }
+
+ Log.Error(LogTag,"errorCode is : " + errorCode);
+ if (string.IsNullOrEmpty(errorMessage))
+ {
+ errorMessage = err.ToString();
+ }
+
+ switch (err)
+ {
+ case ScreenMirroringError.InvalidParameter:
+ throw new ArgumentException(errorMessage);
+
+ case ScreenMirroringError.OutOfMemory:
+ throw new OutOfMemoryException(errorMessage);
+
+ case ScreenMirroringError.PermissionDenied:
+ throw new UnauthorizedAccessException(errorMessage);
+
+ case ScreenMirroringError.NotSupported:
+ throw new NotSupportedException(errorMessage);
+
+ case ScreenMirroringError.ConnectionTimeOut:
+ case ScreenMirroringError.InvalidOperation:
+ throw new InvalidOperationException(errorMessage);
+
+ default:
+ throw new Exception("Unknown error : " + errorCode);
+ }
+ }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Remoting/ScreenMirroring/StateChangedEventArgs.cs b/src/Tizen.Multimedia.Remoting/ScreenMirroring/StateChangedEventArgs.cs
new file mode 100644
index 0000000..7bf0c32
--- /dev/null
+++ b/src/Tizen.Multimedia.Remoting/ScreenMirroring/StateChangedEventArgs.cs
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Get value of changed state. It provides getting state values which are returned when state is changed.
+ /// </summary>
+ /// <remarks>
+ /// Return error and state code.
+ /// </remarks>
+ public class StateChangedEventArgs : EventArgs
+ {
+ internal int _state;
+ internal int _error;
+
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="state"> State Changed </param>
+ /// <param name="error"> Error Occurred </param>
+ internal StateChangedEventArgs(int state, int error)
+ {
+ _state = state;
+ _error = error;
+ }
+
+ /// <summary>
+ /// Get the error code of screen mirroring.
+ /// </summary>
+ /// <value> Get the error code which is one of enums in 'ScreenMirroringErrorCode' when screen mirroring error is occurred.</value>
+ public ScreenMirroringErrorCode Error
+ {
+ get
+ {
+ return (ScreenMirroringErrorCode)_error;
+ }
+ }
+
+ /// <summary>
+ /// Get the current state of screen mirroring.
+ /// </summary>
+ /// <value> Get state code which is one of enums in 'ScreenMirroringSinkState' when screen mirroring state is changed. </value>
+ public ScreenMirroringSinkState State
+ {
+ get
+ {
+ return (ScreenMirroringSinkState)_state;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Multimedia.Remoting/ScreenMirroring/VideoInformation.cs b/src/Tizen.Multimedia.Remoting/ScreenMirroring/VideoInformation.cs
new file mode 100644
index 0000000..59f9a9c
--- /dev/null
+++ b/src/Tizen.Multimedia.Remoting/ScreenMirroring/VideoInformation.cs
@@ -0,0 +1,126 @@
+/// Video Information
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Native = Interop.ScreenMirroring;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Video Information class provides video information which is negotiated with source device for screen mirroring. e.g codec
+ /// </summary>
+ /// <remarks>
+ /// This class provides properties and API that are required for setting video information.
+ /// For getting property using this api, we should call it after connectAsync() api.
+ /// </remarks>
+ public class VideoInformation
+ {
+ internal IntPtr _handle;
+ private int _codec;
+ private int _height;
+ private int _width;
+ private int _frameRate;
+
+ internal VideoInformation()
+ {
+ }
+
+ /// <summary>
+ /// Get video codec.
+ /// </summary>
+ /// <value> Get video codec which is one of enums in 'VideoCodec' which is negotiaged with source device. </value>
+ /// <exception cref="InvalidOperationException">Thrown when method fail due to an internal error</exception>
+ public VideoCodec Codec
+ {
+ get
+ {
+ int ret;
+ ret = Native.GetNegotiatedVideoCodec(ref _handle, out _codec);
+ if (ret != (int)ScreenMirroringError.None)
+ {
+ Log.Error(ScreenMirroringLog.LogTag, "Failed to get video codec" + (ScreenMirroringError)ret);
+ ScreenMirroringErrorFactory.ThrowException(ret, "failed to get video codec");
+ }
+
+ return (VideoCodec)_codec;
+ }
+ }
+
+ /// <summary>
+ /// Get height of video resolution.
+ /// </summary>
+ /// <value> Get height property of video resolution which is negotiated with source device. </value>
+ /// <exception cref="InvalidOperationException">Thrown when method fail due to an internal error</exception>
+ public int Height
+ {
+ get
+ {
+ int ret;
+ ret = Native.GetNegotiatedVideoResolution(ref _handle, out _width, out _height);
+ if (ret != (int)ScreenMirroringError.None)
+ {
+ Log.Error(ScreenMirroringLog.LogTag, "Failed to get height" + (ScreenMirroringError)ret);
+ ScreenMirroringErrorFactory.ThrowException(ret, "failed to get video height");
+ }
+
+ return _height;
+ }
+ }
+
+ /// <summary>
+ /// Get width of video.
+ /// </summary>
+ /// <value> Get width property of video resolution which is negotiated with source device. </value>
+ /// <exception cref="InvalidOperationException">Thrown when method fail due to an internal error</exception>
+ public int Width
+ {
+ get
+ {
+ int ret;
+ ret = Native.GetNegotiatedVideoResolution(ref _handle, out _width, out _height);
+ if (ret != (int)ScreenMirroringError.None)
+ {
+ Log.Error(ScreenMirroringLog.LogTag, "Failed to get width" + (ScreenMirroringError)ret);
+ ScreenMirroringErrorFactory.ThrowException(ret, "failed to get video width");
+ }
+
+ return _width;
+ }
+ }
+
+ /// <summary>
+ /// Get video frame rate.
+ /// </summary>
+ /// <value> Get video frame rate property which is negotiated with source device. </value>
+ /// <exception cref="InvalidOperationException">Thrown when method fail due to an internal error</exception>
+ public int FrameRate
+ {
+ get
+ {
+ int ret;
+ ret = Native.GetNegotiatedVideoFrameRate(ref _handle, out _frameRate);
+ if (ret != (int)ScreenMirroringError.None)
+ {
+ Log.Error(ScreenMirroringLog.LogTag, "Failed to get frame rate" + (ScreenMirroringError)ret);
+ ScreenMirroringErrorFactory.ThrowException(ret, "failed to get video frame rate");
+ }
+
+ return _frameRate;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Remoting/Tizen.Multimedia.Remoting.csproj b/src/Tizen.Multimedia.Remoting/Tizen.Multimedia.Remoting.csproj
new file mode 100644
index 0000000..0e5378c
--- /dev/null
+++ b/src/Tizen.Multimedia.Remoting/Tizen.Multimedia.Remoting.csproj
@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen.Multimedia\Tizen.Multimedia.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Multimedia.StreamRecorder/Interop/Interop.Libraries.cs b/src/Tizen.Multimedia.StreamRecorder/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..43f15f2
--- /dev/null
+++ b/src/Tizen.Multimedia.StreamRecorder/Interop/Interop.Libraries.cs
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string StreamRecorder = "libcapi-media-streamrecorder.so.0";
+ }
+}
diff --git a/src/Tizen.Multimedia.StreamRecorder/Interop/Interop.StreamRecorder.cs b/src/Tizen.Multimedia.StreamRecorder/Interop/Interop.StreamRecorder.cs
new file mode 100644
index 0000000..dd79eab
--- /dev/null
+++ b/src/Tizen.Multimedia.StreamRecorder/Interop/Interop.StreamRecorder.cs
@@ -0,0 +1,186 @@
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Multimedia;
+
+internal static partial class Interop
+{
+ internal static partial class StreamRecorder
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void RecordingLimitReachedCallback(StreamRecordingLimitType type, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void RecordingStatusCallback(ulong elapsedTime, ulong fileSize, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void NotifiedCallback(StreamRecorderState previous, StreamRecorderState current, StreamRecorderNotify notfication, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void RecorderErrorCallback(StreamRecorderErrorCode error, StreamRecorderState current, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void BufferConsumedCallback(IntPtr buffer, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool VideoResolutionCallback(int width, int height, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool FileFormatCallback(StreamRecorderFileFormat format, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool AudioEncoderCallback(StreamRecorderAudioCodec codec, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool VideoEncoderCallback(StreamRecorderVideoCodec codec, IntPtr userData);
+
+ /* begin of method */
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_create")]
+ internal static extern int Create(out IntPtr handle);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_destroy")]
+ internal static extern int Destroy(IntPtr handle);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_prepare")]
+ internal static extern int Prepare(IntPtr handle);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_unprepare")]
+ internal static extern int Unprepare(IntPtr handle);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_start")]
+ internal static extern int Start(IntPtr handle);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_pause")]
+ internal static extern int Pause(IntPtr handle);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_commit")]
+ internal static extern int Commit(IntPtr handle);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_cancel")]
+ internal static extern int Cancel(IntPtr handle);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_push_stream_buffer")]
+ internal static extern int PushStreamBuffer(IntPtr handle, IntPtr/* media_packet_h */ inbuf);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_enable_source_buffer")]
+ internal static extern int EnableSourceBuffer(IntPtr handle, int type);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_state")]
+ internal static extern int GetState(IntPtr handle, out int state);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_filename")]
+ internal static extern int SetFileName(IntPtr handle, string path);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_filename")]
+ internal static extern int GetFileName(IntPtr handle, out IntPtr path);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_file_format")]
+ internal static extern int SetFileFormat(IntPtr handle, int format);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_file_format")]
+ internal static extern int GetFileFormat(IntPtr handle, out int format);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_audio_encoder")]
+ internal static extern int SetAudioEncoder(IntPtr handle, int codec);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_audio_encoder")]
+ internal static extern int GetAudioEncoder(IntPtr handle, out int codec);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_video_encoder")]
+ internal static extern int SetVideoEncoder(IntPtr handle, int codec);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_video_encoder")]
+ internal static extern int GetVideoEncoder(IntPtr handle, out int codec);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_video_resolution")]
+ internal static extern int SetVideoResolution(IntPtr handle, int width, int height);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_video_resolution")]
+ internal static extern int GetVideoResolution(IntPtr handle, out int width, out int height);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_video_framerate")]
+ internal static extern int SetVideoFramerate(IntPtr handle, int framerate);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_video_framerate")]
+ internal static extern int GetVideoFramerate(IntPtr handle, out int framerate);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_video_source_format")]
+ internal static extern int SetVideoSourceFormat(IntPtr handle, int format);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_video_source_format")]
+ internal static extern int GetVideoSourceFormat(IntPtr handle, out int format);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_recording_limit")]
+ internal static extern int SetRecordingLimit(IntPtr handle, int type, int limit);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_recording_limit")]
+ internal static extern int GetRecordingLimit(IntPtr handle, int type, out int format);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_audio_samplerate")]
+ internal static extern int SetAudioSampleRate(IntPtr handle, int samplerate);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_audio_samplerate")]
+ internal static extern int GetAudioSampleRate(IntPtr handle, out int samplerate);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_audio_encoder_bitrate")]
+ internal static extern int SetAudioEncoderBitrate(IntPtr handle, int bitrate);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_audio_encoder_bitrate")]
+ internal static extern int GetAudioEncoderBitrate(IntPtr handle, out int bitrate);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_video_encoder_bitrate")]
+ internal static extern int SetVideoEncoderBitrate(IntPtr handle, int bitrate);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_video_encoder_bitrate")]
+ internal static extern int GetVideoEncoderBitrate(IntPtr handle, out int bitrate);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_audio_channel")]
+ internal static extern int SetAudioChannel(IntPtr handle, int channel);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_audio_channel")]
+ internal static extern int GetAudioChannel(IntPtr handle, out int channel);
+ /* End of method */
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_foreach_supported_file_format")]
+ internal static extern int FileFormats(IntPtr handle, FileFormatCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_foreach_supported_audio_encoder")]
+ internal static extern int AudioEncoders(IntPtr handle, AudioEncoderCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_foreach_supported_video_encoder")]
+ internal static extern int VideoEncoders(IntPtr handle, VideoEncoderCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_foreach_supported_video_resolution")]
+ internal static extern int VideoResolution(IntPtr handle, VideoResolutionCallback callback, IntPtr userData);
+ /* End of foreach method */
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_notify_cb")]
+ internal static extern int SetNotifiedCallback(IntPtr handle, NotifiedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_unset_notify_cb")]
+ internal static extern int UnsetNotifiedCallback(IntPtr handle);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_recording_status_cb")]
+ internal static extern int SetStatusChangedCallback(IntPtr handle, RecordingStatusCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_unset_recording_status_cb")]
+ internal static extern int UnsetStatusChangedCallback(IntPtr handle);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_recording_limit_reached_cb")]
+ internal static extern int SetLimitReachedCallback(IntPtr handle, RecordingLimitReachedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_unset_recording_limit_reached_cb")]
+ internal static extern int UnsetLimitReachedCallback(IntPtr handle);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_error_cb")]
+ internal static extern int SetErrorCallback(IntPtr handle, RecorderErrorCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_unset_error_cb")]
+ internal static extern int UnsetErrorCallback(IntPtr handle);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_buffer_consume_completed_cb")]
+ internal static extern int SetBufferConsumedCallback(IntPtr handle, BufferConsumedCallback callback, IntPtr userDat);
+
+ [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_unset_buffer_consume_completed_cb")]
+ internal static extern int UnsetBufferConsumedCallback(IntPtr handle);
+ }
+}
diff --git a/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorder.cs b/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorder.cs
new file mode 100644
index 0000000..c534d6c
--- /dev/null
+++ b/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorder.cs
@@ -0,0 +1,1054 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using Tizen.Internals.Errors;
+using Native = Interop.StreamRecorder;
+
+namespace Tizen.Multimedia
+{
+ static internal class StreamRecorderLog
+ {
+ internal const string Tag = "Tizen.Multimedia.StreamRecorder";
+ }
+
+ /// <summary>
+ /// Provides methods to control stream recorder.
+ /// </summary>
+ /// <remarks>
+ /// StreamRecorder class provides functions to record raw image frame
+ /// also provides recording start, stop and save the content etc.
+ /// </remarks>
+ public class StreamRecorder : IDisposable
+ {
+ private IntPtr _handle;
+ private bool _disposed = false;
+ /// <summary>
+ /// Occurred when recording is progressing for recording status.
+ /// </summary>
+ private EventHandler<RecordingProgressEventArgs> _recordingStatusChanged;
+ private Native.RecordingStatusCallback _recordingStatusCallback;
+ /// <summary>
+ /// Occurred when recording time or size reach limit.
+ /// </summary>
+ private EventHandler<StreamRecordingLimitReachedEventArgs> _recordingLimitReached;
+ private Native.RecordingLimitReachedCallback _recordingLimitReachedCallback;
+ /// <summary>
+ /// Occurred when streamrecorder complete to use pushed buffer.
+ /// </summary>
+ private EventHandler<StreamRecordingBufferConsumedEventArgs> _bufferConsumed;
+ private Native.BufferConsumedCallback _bufferConsumedCallback;
+ /// <summary>
+ /// Occurred when streamrecorder state is changed.
+ /// </summary>
+ private EventHandler<StreamRecorderNotifiedEventArgs> _recorderNotified;
+ private Native.NotifiedCallback _notifiedCallback;
+ /// <summary>
+ /// Occurred when error is occured.
+ /// </summary>
+ private EventHandler<StreamRecordingErrorOccurredEventArgs> _recordingErrorOccurred;
+ private Native.RecorderErrorCallback _recorderErrorCallback;
+
+ private List<StreamRecorderFileFormat> _formats;
+ private List<StreamRecorderAudioCodec> _audioCodec;
+ private List<StreamRecorderVideoCodec> _videoCodec;
+ private List<StreamRecorderVideoResolution> _resolutions;
+ StreamRecorderVideoResolution _videoResolution = null;
+
+ /// <summary>
+ /// Stream recorder constructor.
+ /// </summary>
+ public StreamRecorder()
+ {
+ int ret = Native.Create(out _handle);
+ if (ret != (int)StreamRecorderError.None)
+ {
+ StreamRecorderErrorFactory.ThrowException(ret, "Failed to create stream recorder");
+ }
+ _formats = new List<StreamRecorderFileFormat>();
+ _audioCodec = new List<StreamRecorderAudioCodec>();
+ _videoCodec = new List<StreamRecorderVideoCodec>();
+ _resolutions = new List<StreamRecorderVideoResolution>();
+ _videoResolution = new StreamRecorderVideoResolution(_handle);
+ }
+
+ /// <summary>
+ /// Stream recorder destructor.
+ /// </summary>
+ ~StreamRecorder()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Event that occurs when streamrecorder state is changed.
+ /// </summary>
+ public event EventHandler<StreamRecorderNotifiedEventArgs> RecorderNotified
+ {
+ add
+ {
+ if (_recorderNotified == null)
+ {
+ RegisterStreamRecorderNotifiedEvent();
+ }
+ _recorderNotified += value;
+ }
+ remove
+ {
+ _recorderNotified -= value;
+ if (_recorderNotified == null)
+ {
+ UnregisterStreamRecorderNotifiedEvent();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Event that occurs when buffer had comsumed completely.
+ /// </summary>
+ public event EventHandler<StreamRecordingBufferConsumedEventArgs> BufferConsumed
+ {
+ add
+ {
+ if (_bufferConsumed == null)
+ {
+ RegisterBufferComsumedEvent();
+ }
+ _bufferConsumed += value;
+ }
+ remove
+ {
+ _bufferConsumed -= value;
+ if (_bufferConsumed == null)
+ {
+ UnregisterBufferComsumedEvent();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Event that occurs when recording status changed.
+ /// </summary>
+ public event EventHandler<RecordingProgressEventArgs> RecordingStatusChanged
+ {
+ add
+ {
+ if (_recordingStatusChanged == null)
+ {
+ RegisterRecordingStatusChangedEvent();
+ }
+ _recordingStatusChanged += value;
+ }
+ remove
+ {
+ _recordingStatusChanged -= value;
+ if (_recordingStatusChanged == null)
+ {
+ UnregisterRecordingStatusChangedEvent();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Event that occurs when recording limit is reached.
+ /// </summary>
+ public event EventHandler<StreamRecordingLimitReachedEventArgs> RecordingLimitReached
+ {
+ add
+ {
+ if (_recordingLimitReached == null)
+ {
+ RegisterRecordingLimitReachedEvent();
+ }
+ _recordingLimitReached += value;
+ }
+ remove
+ {
+ _recordingLimitReached -= value;
+ if (_recordingLimitReached == null)
+ {
+ UnregisterRecordingLimitReachedEvent();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Event that occurs when an error occured during recorder operation.
+ /// </summary>
+ public event EventHandler<StreamRecordingErrorOccurredEventArgs> RecordingErrorOccurred
+ {
+ add
+ {
+ if (_recordingErrorOccurred == null)
+ {
+ RegisterRecordingErrorOccurredEvent();
+ }
+ _recordingErrorOccurred += value;
+ }
+ remove
+ {
+ _recordingErrorOccurred -= value;
+ if (_recordingErrorOccurred == null)
+ {
+ UnregisterRecordingErrorOccurredEvent();
+ }
+ }
+ }
+
+ /// <summary>
+ /// The file path to record.
+ /// </summary>
+ /// <remarks>
+ /// If the same file already exists in the file system, then old file
+ /// will be overwritten.
+ /// </remarks>
+ public string FilePath
+ {
+ get
+ {
+ IntPtr val;
+ int ret = Native.GetFileName(_handle, out val);
+ if ((StreamRecorderError)ret != StreamRecorderError.None)
+ {
+ Log.Error(StreamRecorderLog.Tag, "Failed to get filepath, " + (StreamRecorderError)ret);
+ }
+ string result = Marshal.PtrToStringAnsi(val);
+ LibcSupport.Free(val);
+ return result;
+ }
+ set
+ {
+ int ret = Native.SetFileName(_handle, value);
+ if ((StreamRecorderError)ret != StreamRecorderError.None)
+ {
+ Log.Error(StreamRecorderLog.Tag, "Failed to set filepath, " + (StreamRecorderError)ret);
+ StreamRecorderErrorFactory.ThrowException(ret, "Failed to set filepath");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Get the current state of the stream recorder.
+ /// </summary>
+ /// <value> The current state of stream recorder.
+ public StreamRecorderState State
+ {
+ get
+ {
+ int val = 0;
+
+ int ret = Native.GetState(_handle, out val);
+ if ((StreamRecorderError)ret != StreamRecorderError.None)
+ {
+ Log.Error(StreamRecorderLog.Tag, "Failed to get stream recorder state, " + (StreamRecorderError)ret);
+ }
+ return (StreamRecorderState)val;
+ }
+ }
+
+ /// <summary>
+ /// Get/Set the file format for recording media stream.
+ /// </summary>
+ /// <remarks>
+ /// Must set <see cref="StreamRecorder.EnableSourceBuffer(StreamRecorderSourceType)"/>.
+ /// The recorder state must be <see cref="StreamRecorderState.Created"/> state.
+ /// </remarks>
+ /// <exception cref="ArgumentException">The format does not valid.</exception>
+ /// <seealso cref="SupportedFileFormats"/>
+ public StreamRecorderFileFormat FileFormat
+ {
+ get
+ {
+ int val = 0;
+
+ int ret = Native.GetFileFormat(_handle, out val);
+ if ((StreamRecorderError)ret != StreamRecorderError.None)
+ {
+ Log.Error(StreamRecorderLog.Tag, "Failed to get file format, " + (StreamRecorderError)ret);
+ }
+ return (StreamRecorderFileFormat)val;
+ }
+ set
+ {
+ int ret = Native.SetFileFormat(_handle, (int)value);
+ if ((StreamRecorderError)ret != StreamRecorderError.None)
+ {
+ Log.Error(StreamRecorderLog.Tag, "Failed to set file format, " + (StreamRecorderError)ret);
+ StreamRecorderErrorFactory.ThrowException(ret);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The audio codec for encoding an audio stream.
+ /// </summary>
+ /// <remarks>
+ /// Must set <see cref="StreamRecorderSourceType.Audio"/> or <see cref="StreamRecorderSourceType.VideoAudio"/>
+ /// by <see cref="StreamRecorder.EnableSourceBuffer(StreamRecorderSourceType)"/>
+ /// </remarks>
+ /// <exception cref="ArgumentException">The codec does not valid.</exception>
+ /// <seealso cref="SupportedAudioEncodings"/>
+ public StreamRecorderAudioCodec AudioCodec
+ {
+ get
+ {
+ int val = 0;
+
+ int ret = Native.GetAudioEncoder(_handle, out val);
+ if ((StreamRecorderError)ret != StreamRecorderError.None)
+ {
+ Log.Error(StreamRecorderLog.Tag, "Failed to get audio codec, " + (StreamRecorderError)ret);
+ }
+ return (StreamRecorderAudioCodec)val;
+ }
+ set
+ {
+ int ret = Native.SetAudioEncoder(_handle, (int)value);
+ if ((StreamRecorderError)ret != StreamRecorderError.None)
+ {
+ Log.Error(StreamRecorderLog.Tag, "Failed to set audio codec, " + (StreamRecorderError)ret);
+ StreamRecorderErrorFactory.ThrowException(ret);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The video codec for encoding video stream.
+ /// </summary>
+ /// <remarks>
+ /// Must set <see cref="StreamRecorderSourceType.Video"/> or <see cref="StreamRecorderSourceType.VideoAudio"/>
+ /// by <see cref="StreamRecorder.EnableSourceBuffer(StreamRecorderSourceType)"/>
+ /// </remarks>
+ /// <exception cref="ArgumentException">The codec does not valid.</exception>
+ /// <seealso cref="SupportedVideoEncodings"/>
+ public StreamRecorderVideoCodec VideoCodec
+ {
+ get
+ {
+ int val = 0;
+
+ int ret = Native.GetVideoEncoder(_handle, out val);
+ if ((StreamRecorderError)ret != StreamRecorderError.None)
+ {
+ Log.Error(StreamRecorderLog.Tag, "Failed to get video codec, " + (StreamRecorderError)ret);
+ }
+ return (StreamRecorderVideoCodec)val;
+ }
+ set
+ {
+ int ret = Native.SetVideoEncoder(_handle, (int)value);
+
+ if ((StreamRecorderError)ret != StreamRecorderError.None)
+ {
+ Log.Error(StreamRecorderLog.Tag, "Failed to set video codec, " + (StreamRecorderError)ret);
+ StreamRecorderErrorFactory.ThrowException(ret);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The maximum size of a recording file in KB(kilobytes). If 0, means
+ /// unlimited recording size.
+ /// </summary>
+ /// <remarks>
+ /// After reaching the limitation, the data which is being recorded will
+ /// be discarded and not written to the file.
+ /// The recorder state must be <see cref="StreamRecorderState.Created"/> state.
+ /// </remarks>
+ /// <exception cref="ArgumentException">The value set to below 0.</exception>
+ /// <seealso cref="StreamRecordingLimitReachedEventArgs"/>
+ public int SizeLimit
+ {
+ get
+ {
+ int val = 0;
+
+ int ret = Native.GetRecordingLimit(_handle, 1, out val);
+ if ((StreamRecorderError)ret != StreamRecorderError.None)
+ {
+ Log.Error(StreamRecorderLog.Tag, "Failed to get size limit, " + (StreamRecorderError)ret);
+ }
+ return val;
+ }
+ set
+ {
+ int ret = Native.SetRecordingLimit(_handle, 1, value);
+ if ((StreamRecorderError)ret != StreamRecorderError.None)
+ {
+ Log.Error(StreamRecorderLog.Tag, "Failed to set sizelimit, " + (StreamRecorderError)ret);
+ StreamRecorderErrorFactory.ThrowException(ret, "Failed to set size limit");
+ }
+ }
+ }
+
+ /// <summary>
+ /// The time limit of a recording file in Seconds. If 0, means unlimited recording
+ /// time.
+ /// </summary>
+ /// <remarks>
+ /// After reaching the limitation, the data which is being recorded will
+ /// be discarded and not written to the file.
+ /// The recorder state must be <see cref="StreamRecorderState.Created"/> state.
+ /// </remarks>
+ /// <exception cref="ArgumentException">The value set to below 0.</exception>
+ /// <seealso cref="StreamRecordingLimitReachedEventArgs"/>
+ public int TimeLimit
+ {
+ get
+ {
+ int val = 0;
+
+ int ret = Native.GetRecordingLimit(_handle, 0, out val);
+ if ((StreamRecorderError)ret != StreamRecorderError.None)
+ {
+ Log.Error(StreamRecorderLog.Tag, "Failed to get time limit, " + (StreamRecorderError)ret);
+ }
+ return val;
+ }
+ set
+ {
+ int ret = Native.SetRecordingLimit(_handle, 0, value);
+ if ((StreamRecorderError)ret != StreamRecorderError.None)
+ {
+ Log.Error(StreamRecorderLog.Tag, "Failed to set timelimit, " + (StreamRecorderError)ret);
+ StreamRecorderErrorFactory.ThrowException(ret, "Failed to set time limit");
+ }
+ }
+ }
+
+ /// <summary>
+ /// The sampling rate of an audio stream in hertz.
+ /// </summary>
+ /// <remarks>
+ /// The recorder state must be <see cref="StreamRecorderState.Created"/> state.
+ /// Must set <see cref="StreamRecorderSourceType.Audio"/> or <see cref="StreamRecorderSourceType.VideoAudio"/>
+ /// by <see cref="StreamRecorder.EnableSourceBuffer(StreamRecorderSourceType)"/>.
+ /// </remarks>
+ /// <exception cref="ArgumentException">The value set to below 0.</exception>
+ public int AudioSampleRate
+ {
+ get
+ {
+ int val = 0;
+
+ int ret = Native.GetAudioSampleRate(_handle, out val);
+ if ((StreamRecorderError)ret != StreamRecorderError.None)
+ {
+ Log.Error(StreamRecorderLog.Tag, "Failed to get audio samplerate, " + (StreamRecorderError)ret);
+ }
+ return val;
+ }
+ set
+ {
+ int ret = Native.SetAudioSampleRate(_handle, value);
+ if ((StreamRecorderError)ret != StreamRecorderError.None)
+ {
+ Log.Error(StreamRecorderLog.Tag, "Failed to set audio samplerate, " + (StreamRecorderError)ret);
+ StreamRecorderErrorFactory.ThrowException(ret, "Failed to set audio samplerate");
+ }
+ }
+ }
+
+ /// <summary>
+ /// The bitrate of an audio encoder in bits per second.
+ /// </summary>
+ /// <remarks>
+ /// The recorder state must be <see cref="StreamRecorderState.Created"/> state.
+ /// Must set <see cref="StreamRecorderSourceType.Audio"/> or <see cref="StreamRecorderSourceType.VideoAudio"/>
+ /// by <see cref="StreamRecorder.EnableSourceBuffer(StreamRecorderSourceType)"/>
+ /// </remarks>
+ /// <exception cref="ArgumentException">The value set to below 0.</exception>
+ public int AudioBitRate
+ {
+ get
+ {
+ int val = 0;
+
+ int ret = Native.GetAudioEncoderBitrate(_handle, out val);
+ if ((StreamRecorderError)ret != StreamRecorderError.None)
+ {
+ Log.Error(StreamRecorderLog.Tag, "Failed to get audio bitrate, " + (StreamRecorderError)ret);
+ }
+ return val;
+ }
+ set
+ {
+ int ret = Native.SetAudioEncoderBitrate(_handle, value);
+ if ((StreamRecorderError)ret != StreamRecorderError.None)
+ {
+ Log.Error(StreamRecorderLog.Tag, "Failed to set audio bitrate, " + (StreamRecorderError)ret);
+ StreamRecorderErrorFactory.ThrowException(ret, "Failed to set audio bitrate");
+ }
+ }
+ }
+
+ /// <summary>
+ /// The bitrate of an video encoder in bits per second.
+ /// </summary>
+ /// <remarks>
+ /// The recorder state must be <see cref="StreamRecorderState.Created"/> state.
+ /// Must set <see cref="StreamRecorderSourceType.Video"/> or <see cref="StreamRecorderSourceType.VideoAudio"/>
+ /// by <see cref="StreamRecorder.EnableSourceBuffer(StreamRecorderSourceType)"/>
+ /// </remarks>
+ /// <exception cref="ArgumentException">The value set to below 0.</exception>
+ public int VideoBitRate
+ {
+ get
+ {
+ int val = 0;
+
+ int ret = Native.GetVideoEncoderBitrate(_handle, out val);
+ if ((StreamRecorderError)ret != StreamRecorderError.None)
+ {
+ Log.Error(StreamRecorderLog.Tag, "Failed to get video bitrate, " + (StreamRecorderError)ret);
+ }
+ return val;
+ }
+ set
+ {
+ int ret = Native.SetVideoEncoderBitrate(_handle, value);
+ if ((StreamRecorderError)ret != StreamRecorderError.None)
+ {
+ Log.Error(StreamRecorderLog.Tag, "Failed to set video bitrate, " + (StreamRecorderError)ret);
+ StreamRecorderErrorFactory.ThrowException(ret, "Failed to set video bitrate");
+ }
+ }
+ }
+
+ /// <summary>
+ /// The video frame rate for recording media stream.
+ /// </summary>
+ /// <remarks>
+ /// The recorder state must be <see cref="StreamRecorderState.Created"/> state.
+ /// Must set <see cref="StreamRecorderSourceType.Video"/> or <see cref="StreamRecorderSourceType.VideoAudio"/>
+ /// by <see cref="StreamRecorder.EnableSourceBuffer(StreamRecorderSourceType)"/>
+ /// </remarks>
+ /// <exception cref="NotSupportedException">The value set to below 0.</exception>
+ public int VideoFrameRate
+ {
+ get
+ {
+ int val = 0;
+
+ int ret = Native.GetVideoFramerate(_handle, out val);
+ if ((StreamRecorderError)ret != StreamRecorderError.None)
+ {
+ Log.Error(StreamRecorderLog.Tag, "Failed to get video framerate, " + (StreamRecorderError)ret);
+ }
+ return val;
+ }
+ set
+ {
+ int ret = Native.SetVideoFramerate(_handle, value);
+ if ((StreamRecorderError)ret != StreamRecorderError.None)
+ {
+ Log.Error(StreamRecorderLog.Tag, "Failed to set video framerate, " + (StreamRecorderError)ret);
+ StreamRecorderErrorFactory.ThrowException(ret);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Get or Set the video source format for recording media stream.
+ /// </summary>
+ /// <exception cref="ArgumentException">The value set to a invalid value.</exception>
+ /// <seealso cref="StreamRecorderVideoSourceFormat"/>
+ public StreamRecorderVideoSourceFormat VideoSourceFormat
+ {
+ get
+ {
+ int val = 0;
+
+ int ret = Native.GetVideoSourceFormat(_handle, out val);
+ if ((StreamRecorderError)ret != StreamRecorderError.None)
+ {
+ Log.Error(StreamRecorderLog.Tag, "Failed to get video framerate, " + (StreamRecorderError)ret);
+ }
+ return (StreamRecorderVideoSourceFormat)val;
+ }
+ set
+ {
+ int ret = Native.SetVideoSourceFormat(_handle, (int)value);
+ if ((StreamRecorderError)ret != StreamRecorderError.None)
+ {
+ Log.Error(StreamRecorderLog.Tag, "Failed to set video framerate, " + (StreamRecorderError)ret);
+ StreamRecorderErrorFactory.ThrowException(ret);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The number of audio channel.
+ /// </summary>
+ /// <remarks>
+ /// The attribute is applied only in Created state.
+ /// For mono recording, set channel to 1.
+ /// For stereo recording, set channel to 2.
+ /// The recorder state must be <see cref="StreamRecorderState.Created"/> state.
+ /// </remarks>
+ /// <exception cref="ArgumentException">The value set to a invalid value.</exception>
+ public int AudioChannel
+ {
+ get
+ {
+ int val = 0;
+
+ int ret = Native.GetAudioChannel(_handle, out val);
+ if ((StreamRecorderError)ret != StreamRecorderError.None)
+ {
+ Log.Error(StreamRecorderLog.Tag, "Failed to get audio channel, " + (StreamRecorderError)ret);
+ }
+ return val;
+ }
+ set
+ {
+ int ret = Native.SetAudioChannel(_handle, value);
+ if ((StreamRecorderError)ret != StreamRecorderError.None)
+ {
+ Log.Error(StreamRecorderLog.Tag, "Failed to set audio channel, " + (StreamRecorderError)ret);
+ StreamRecorderErrorFactory.ThrowException(ret, "Failed to set audio channel");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Video resolution of the video recording.
+ /// </summary>
+ /// <remarks>
+ /// Must set <see cref="StreamRecorderSourceType.Video"/> or <see cref="StreamRecorderSourceType.VideoAudio"/>
+ /// by <see cref="StreamRecorder.EnableSourceBuffer(StreamRecorderSourceType)"/>
+ /// The recorder state must be <see cref="StreamRecorderState.Created"/> state.
+ /// </remarks>
+ /// <exception cref="ArgumentException">The value set to a invalid value.</exception>
+ /// <seealso cref="SupportedVideoResolutions"/>
+ public StreamRecorderVideoResolution Resolution
+ {
+ get
+ {
+ return _videoResolution;
+ }
+ }
+
+ /// <summary>
+ /// Retrieves all the file formats supported by the stream recorder.
+ /// </summary>
+ /// <returns>
+ /// It returns a list containing all the supported file
+ /// formats by Stream recorder.
+ /// </returns>
+ /// <seealso cref="StreamRecorderFileFormat"/>
+ public IEnumerable<StreamRecorderFileFormat> SupportedFileFormats
+ {
+ get
+ {
+ if (_formats.Count == 0)
+ {
+ Native.FileFormatCallback callback = (StreamRecorderFileFormat format, IntPtr userData) =>
+ {
+ _formats.Add(format);
+ return true;
+ };
+ int ret = Native.FileFormats(_handle, callback, IntPtr.Zero);
+ if (ret != (int)StreamRecorderError.None)
+ {
+ StreamRecorderErrorFactory.ThrowException(ret, "Failed to get the supported fileformats");
+ }
+ }
+ return _formats;
+ }
+ }
+
+ /// <summary>
+ /// Retrieves all the audio encoders supported by the recorder.
+ /// </summary>
+ /// <returns>
+ /// It returns a list containing all the supported audio encoders
+ /// by recorder.
+ /// </returns>
+ /// <seealso cref="StreamRecorderAudioCodec"/>
+ public IEnumerable<StreamRecorderAudioCodec> SupportedAudioEncodings
+ {
+ get
+ {
+ if (_audioCodec.Count == 0)
+ {
+ Native.AudioEncoderCallback callback = (StreamRecorderAudioCodec codec, IntPtr userData) =>
+ {
+ _audioCodec.Add(codec);
+ return true;
+ };
+ int ret = Native.AudioEncoders(_handle, callback, IntPtr.Zero);
+ if (ret != (int)StreamRecorderError.None)
+ {
+ StreamRecorderErrorFactory.ThrowException(ret, "Failed to get the supported audio encoders");
+ }
+ }
+ return _audioCodec;
+ }
+ }
+
+ /// <summary>
+ /// Retrieves all the video encoders supported by the recorder.
+ /// </summary>
+ /// <returns>
+ /// It returns a list containing all the supported video encoders
+ /// by recorder.
+ /// </returns>
+ /// <seealso cref="StreamRecorderVideoCodec"/>
+ public IEnumerable<StreamRecorderVideoCodec> SupportedVideoEncodings
+ {
+ get
+ {
+ if (_videoCodec.Count == 0)
+ {
+ Native.VideoEncoderCallback callback = (StreamRecorderVideoCodec codec, IntPtr userData) =>
+ {
+ _videoCodec.Add(codec);
+ return true;
+ };
+ int ret = Native.VideoEncoders(_handle, callback, IntPtr.Zero);
+ if (ret != (int)StreamRecorderError.None)
+ {
+ StreamRecorderErrorFactory.ThrowException(ret, "Failed to get the supported video encoders");
+ }
+ }
+ return _videoCodec;
+ }
+ }
+
+ /// <summary>
+ /// Retrieves all the video resolutions supported by the recorder.
+ /// </summary>
+ /// <returns>
+ /// It returns videoresolution list containing the width and height of
+ /// different resolutions supported by recorder.
+ /// </returns>
+ /// <seealso cref="StreamRecorderVideoResolution"/>
+ public IEnumerable<StreamRecorderVideoResolution> SupportedVideoResolutions
+ {
+ get
+ {
+ if (_resolutions.Count == 0)
+ {
+ Native.VideoResolutionCallback callback = (int width, int height, IntPtr userData) =>
+ {
+ StreamRecorderVideoResolution temp = new StreamRecorderVideoResolution(width, height);
+ _resolutions.Add(temp);
+ return true;
+ };
+ int ret = Native.VideoResolution(_handle, callback, IntPtr.Zero);
+ if (ret != (int)StreamRecorderError.None)
+ {
+ StreamRecorderErrorFactory.ThrowException(ret, "Failed to get the supported video resolutions");
+ }
+ }
+ return _resolutions;
+ }
+ }
+
+ /// <summary>
+ /// Prepare the stream recorder.
+ /// </summary>
+ /// <remarks>
+ /// Before calling the function, it is required to set <see cref="StreamRecorder.EnableSourceBuffer(StreamRecorderSourceType)"/>,
+ /// <see cref="StreamRecorderAudioCodec"/>, <see cref="StreamRecorderVideoCodec"/> and <see cref="StreamRecorderFileFormat"/> properties of recorder.
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">The streamrecorder is not in the valid state.</exception>
+ /// <seealso cref="Unprepare"/>
+ public void Prepare()
+ {
+ int ret = Native.Prepare(_handle);
+ if (ret != (int)StreamRecorderError.None)
+ {
+ StreamRecorderErrorFactory.ThrowException(ret, "Failed to prepare stream recorder");
+ }
+ }
+
+ /// <summary>
+ /// Resets the stream recorder.
+ /// </summary>
+ /// <remarks>
+ /// The recorder state must be <see cref="StreamRecorderState.Prepared"/> state by <see cref="Prepare"/>, <see cref="Cancel"/> and <see cref="Commit"/>.
+ /// The StreamRecorder state will be <see cref="StreamRecorderState.Created"/>.
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">The streamrecorder is not in the valid state.</exception>
+ /// <seealso cref="Prepare"/>
+ public void Unprepare()
+ {
+ int ret = Native.Unprepare(_handle);
+ if (ret != (int)StreamRecorderError.None)
+ {
+ StreamRecorderErrorFactory.ThrowException(ret, "Failed to reset the stream recorder");
+ }
+ }
+
+ /// <summary>
+ /// Starts the recording.
+ /// </summary>
+ /// <remarks>
+ /// If file path has been set to an existing file, this file is removed automatically and updated by new one.
+ /// The filename should be set before this function is invoked.
+ /// The recorder state must be <see cref="StreamRecorderState.Prepared"/> state by <see cref="Prepare"/> or
+ /// <see cref="StreamRecorderState.Paused"/> state by <see cref="Pause"/>.
+ /// The filename shuild be set by <see cref="FilePath"/>
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">The streamrecorder is not in the valid state.</exception>
+ /// <exception cref="UnauthorizedAccessException">The access ot the resources can not be granted.</exception>
+ /// <seealso cref="Pause"/>
+ /// <seealso cref="Commit"/>
+ /// <seealso cref="Cancel"/>
+ /// <seealso cref="FilePath"/>
+ /// <seealso cref="FileFormat"/>
+ public void Start()
+ {
+ int ret = Native.Start(_handle);
+ if (ret != (int)StreamRecorderError.None)
+ {
+ StreamRecorderErrorFactory.ThrowException(ret, "Failed to start the stream recorder");
+ }
+ }
+
+ /// <summary>
+ /// Pause the recording.
+ /// </summary>
+ /// <remarks>
+ /// Recording can be resumed with <see cref="Start"/>.
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">The streamrecorder is not in the valid state.</exception>
+ /// <seealso cref="Start"/>
+ /// <seealso cref="Commit"/>
+ /// <seealso cref="Cancel"/>
+ public void Pause()
+ {
+ int ret = Native.Pause(_handle);
+ if (ret != (int)StreamRecorderError.None)
+ {
+ StreamRecorderErrorFactory.ThrowException(ret, "Failed to pause the stream recorder");
+ }
+ }
+
+ /// <summary>
+ /// Stops recording and saves the result.
+ /// </summary>
+ /// <remarks>
+ /// The recorder state must be <see cref="StreamRecorderState.Recording"/> state by <see cref="Start"/> or
+ /// <see cref="StreamRecorderState.Paused"/> state by <see cref="Pause"/>
+ /// When you want to record audio or video file, you need to add privilege according to rules below additionally.
+ /// <para>
+ /// http://tizen.org/privilege/mediastorage is needed if input or output path are relevant to media storage.
+ /// http://tizen.org/privilege/externalstorage is needed if input or output path are relevant to external storage.
+ /// </para>
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">The streamrecorder is not in the valid state.</exception>
+ /// <exception cref="UnauthorizedAccessException">The access ot the resources can not be granted.</exception>
+ /// <seealso cref="Start"/>
+ /// <seealso cref="Pause"/>
+ public void Commit()
+ {
+ int ret = Native.Commit(_handle);
+ if (ret != (int)StreamRecorderError.None)
+ {
+ StreamRecorderErrorFactory.ThrowException(ret, "Failed to save the recorded content");
+ }
+ }
+
+ /// <summary>
+ /// Cancels the recording.
+ /// The recording data is discarded and not written in the recording file.
+ /// </summary>
+ /// <seealso cref="Start"/>
+ /// <seealso cref="Pause"/>
+ public void Cancel()
+ {
+ int ret = Native.Cancel(_handle);
+ if (ret != (int)StreamRecorderError.None)
+ {
+ StreamRecorderErrorFactory.ThrowException(ret, "Failed to cancel the recording");
+ }
+ }
+
+ /// <summary>
+ /// Push stream buffer as recording raw data.
+ /// </summary>
+ public void PushBuffer(MediaPacket packet)
+ {
+ IntPtr _packet_h = packet.GetHandle();
+
+ Log.Info("Tizen.Multimedia.StreamRecorder", "PUSH stream buffer");
+ int ret = Native.PushStreamBuffer(_handle, _packet_h);
+ if (ret != (int)StreamRecorderError.None)
+ {
+ StreamRecorderErrorFactory.ThrowException(ret, "Failed to push buffer");
+ }
+ Log.Info("Tizen.Multimedia.StreamRecorder", "PUSH stream buffer END");
+ }
+
+ /// <summary>
+ /// Set the source type of pushed data.
+ /// </summary>
+ public void EnableSourceBuffer(StreamRecorderSourceType type)
+ {
+ int ret = Native.EnableSourceBuffer(_handle, (int)type);
+ if (ret != (int)StreamRecorderError.None)
+ {
+ StreamRecorderErrorFactory.ThrowException(ret, "Failed to set EnableSourceBuffer");
+ }
+ }
+
+ /// <summary>
+ /// Release any unmanaged resources used by this object.
+ /// </summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (disposing)
+ {
+ // to be used if there are any other disposable objects
+ }
+ if (_handle != IntPtr.Zero)
+ {
+ Native.Destroy(_handle);
+ _handle = IntPtr.Zero;
+ }
+ _disposed = true;
+ }
+ }
+
+ private void RegisterStreamRecorderNotifiedEvent()
+ {
+ _notifiedCallback = (StreamRecorderState previous, StreamRecorderState current, StreamRecorderNotify notify, IntPtr userData) =>
+ {
+ StreamRecorderNotifiedEventArgs eventArgs = new StreamRecorderNotifiedEventArgs(previous, current, notify);
+ _recorderNotified?.Invoke(this, eventArgs);
+ };
+ int ret = Native.SetNotifiedCallback(_handle, _notifiedCallback, IntPtr.Zero);
+ if (ret != (int)StreamRecorderError.None)
+ {
+ StreamRecorderErrorFactory.ThrowException(ret, "Setting notify callback failed");
+ }
+ }
+
+ private void UnregisterStreamRecorderNotifiedEvent()
+ {
+ int ret = Native.UnsetNotifiedCallback(_handle);
+ if (ret != (int)StreamRecorderError.None)
+ {
+ StreamRecorderErrorFactory.ThrowException(ret, "Unsetting notify callback failed");
+ }
+ }
+
+ private void RegisterBufferComsumedEvent()
+ {
+ _bufferConsumedCallback = (IntPtr buffer, IntPtr userData) =>
+ {
+ StreamRecordingBufferConsumedEventArgs eventArgs = new StreamRecordingBufferConsumedEventArgs(buffer);
+ _bufferConsumed?.Invoke(this, eventArgs);
+ };
+ int ret = Native.SetBufferConsumedCallback(_handle, _bufferConsumedCallback, IntPtr.Zero);
+ if (ret != (int)StreamRecorderError.None)
+ {
+ StreamRecorderErrorFactory.ThrowException(ret, "Setting buffer consumed callback failed");
+ }
+ }
+
+ private void UnregisterBufferComsumedEvent()
+ {
+ int ret = Native.UnsetBufferConsumedCallback(_handle);
+ if (ret != (int)StreamRecorderError.None)
+ {
+ StreamRecorderErrorFactory.ThrowException(ret, "Unsetting buffer consumed callback failed");
+ }
+ }
+
+ private void RegisterRecordingStatusChangedEvent()
+ {
+ _recordingStatusCallback = (ulong elapsedTime, ulong fileSize, IntPtr userData) =>
+ {
+ RecordingProgressEventArgs eventArgs = new RecordingProgressEventArgs(elapsedTime, fileSize);
+ _recordingStatusChanged?.Invoke(this, eventArgs);
+ };
+ int ret = Native.SetStatusChangedCallback(_handle, _recordingStatusCallback, IntPtr.Zero);
+ if (ret != (int)StreamRecorderError.None)
+ {
+ StreamRecorderErrorFactory.ThrowException(ret, "Setting status changed callback failed");
+ }
+ }
+
+ private void UnregisterRecordingStatusChangedEvent()
+ {
+ int ret = Native.UnsetStatusChangedCallback(_handle);
+ if (ret != (int)StreamRecorderError.None)
+ {
+ StreamRecorderErrorFactory.ThrowException(ret, "Unsetting status changed callback failed");
+ }
+ }
+
+ private void RegisterRecordingLimitReachedEvent()
+ {
+ _recordingLimitReachedCallback = (StreamRecordingLimitType type, IntPtr userData) =>
+ {
+ StreamRecordingLimitReachedEventArgs eventArgs = new StreamRecordingLimitReachedEventArgs(type);
+ _recordingLimitReached?.Invoke(this, eventArgs);
+ };
+ int ret = Native.SetLimitReachedCallback(_handle, _recordingLimitReachedCallback, IntPtr.Zero);
+ if (ret != (int)StreamRecorderError.None)
+ {
+ StreamRecorderErrorFactory.ThrowException(ret, "Setting limit reached callback failed");
+ }
+ }
+
+ private void UnregisterRecordingLimitReachedEvent()
+ {
+ int ret = Native.UnsetLimitReachedCallback(_handle);
+ if (ret != (int)StreamRecorderError.None)
+ {
+ StreamRecorderErrorFactory.ThrowException(ret, "Unsetting limit reached callback failed");
+ }
+ }
+
+ private void RegisterRecordingErrorOccurredEvent()
+ {
+ _recorderErrorCallback = (StreamRecorderErrorCode error, StreamRecorderState current, IntPtr userData) =>
+ {
+ StreamRecordingErrorOccurredEventArgs eventArgs = new StreamRecordingErrorOccurredEventArgs(error, current);
+ _recordingErrorOccurred?.Invoke(this, eventArgs);
+ };
+ int ret = Native.SetErrorCallback(_handle, _recorderErrorCallback, IntPtr.Zero);
+ if (ret != (int)StreamRecorderError.None)
+ {
+ StreamRecorderErrorFactory.ThrowException(ret, "Setting Error callback failed");
+ }
+ }
+
+ private void UnregisterRecordingErrorOccurredEvent()
+ {
+ int ret = Native.UnsetErrorCallback(_handle);
+ if (ret != (int)StreamRecorderError.None)
+ {
+ StreamRecorderErrorFactory.ThrowException(ret, "Unsetting Error callback failed");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderEnums.cs b/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderEnums.cs
new file mode 100644
index 0000000..58b6511
--- /dev/null
+++ b/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderEnums.cs
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Enumeration for Audio Codec.
+ /// </summary>
+ public enum StreamRecorderAudioCodec
+ {
+ /// <summary>
+ /// AMR codec.
+ /// </summary>
+ Amr = 0,
+ /// <summary>
+ /// AAC codec.
+ /// </summary>
+ Aac,
+ /// <summary>
+ /// PCM codec.
+ /// </summary>
+ Pcm
+ }
+
+ /// <summary>
+ /// Enumeration for the file container format.
+ /// </summary>
+ public enum StreamRecorderFileFormat
+ {
+ /// <summary>
+ /// 3GP file format.
+ /// </summary>
+ ThreeGp,
+ /// <summary>
+ /// MP4 file format.
+ /// </summary>
+ Mp4,
+ /// <summary>
+ /// AMR file format.
+ /// </summary>
+ Amr,
+ /// <summary>
+ /// ADTS file format.
+ /// </summary>
+ Adts,
+ /// <summary>
+ /// WAV file format.
+ /// </summary>
+ Wav
+ }
+
+ /// <summary>
+ /// Enumeration for the recorder notify type.
+ /// </summary>
+ public enum StreamRecorderNotify
+ {
+ /// <summary>
+ /// None.
+ /// </summary>
+ None = 0,
+ /// <summary>
+ /// State changed noti.
+ /// </summary>
+ StateChanged
+ }
+
+ /// <summary>
+ /// Enumeration for the recording limit type.
+ /// </summary>
+ public enum StreamRecordingLimitType
+ {
+ /// <summary>
+ /// Time limit in seconds of recording file
+ /// </summary>
+ Time,
+ /// <summary>
+ /// Size limit in KB(KiloBytes) of recording file.
+ /// </summary>
+ Size
+ }
+
+ /// <summary>
+ /// Enumeration for stream recorder states.
+ /// </summary>
+ public enum StreamRecorderState
+ {
+ /// <summary>
+ /// Stream recorder is not created.
+ /// </summary>
+ None,
+ /// <summary>
+ /// Stream recorder is created, but not prepared.
+ /// </summary>
+ Created,
+ /// <summary>
+ /// Stream recorder is ready to record.
+ /// </summary>
+ Prepared,
+ /// <summary>
+ /// Stream recorder is recording pushed packet.
+ /// </summary>
+ Recording,
+ /// <summary>
+ /// Stream recorder is paused.
+ /// </summary>
+ Paused
+ }
+
+ /// <summary>
+ /// Enumeration for video codec.
+ /// </summary>
+ public enum StreamRecorderVideoCodec
+ {
+ /// <summary>
+ /// H263 codec.
+ /// </summary>
+ H263,
+ /// <summary>
+ /// MPEG4 codec.
+ /// </summary>
+ Mpeg4
+ }
+
+ /// <summary>
+ /// Enumeration for source type.
+ /// </summary>
+ public enum StreamRecorderSourceType
+ {
+ /// <summary>
+ /// Video source
+ /// </summary>
+ Video,
+ /// <summary>
+ /// Audio source
+ /// </summary>
+ Audio,
+ /// <summary>
+ /// Audio/Video both
+ /// </summary>
+ VideoAudio
+ }
+
+ /// <summary>
+ /// Enumeration for video source format.
+ /// </summary>
+ public enum StreamRecorderVideoSourceFormat
+ {
+ /// <summary>
+ /// Nv12 Video source format
+ /// </summary>
+ Nv12,
+ /// <summary>
+ /// Nv21 video source format
+ /// </summary>
+ Nv21,
+ /// <summary>
+ /// I420 video source format
+ /// </summary>
+ I420
+ }
+
+ /// <summary>
+ /// Enumeration for stream recorder failure error.
+ /// </summary>
+ public enum StreamRecorderErrorCode
+ {
+ /// <summary>
+ /// Sucessful.
+ /// </summary>
+ None = StreamRecorderError.None,
+ /// <summary>
+ /// Internal error.
+ /// </summary>
+ InvalidParameter = StreamRecorderError.InvalidParameter,
+ /// <summary>
+ /// Internal error.
+ /// </summary>
+ InvalidOperation = StreamRecorderError.InvalidOperation,
+ /// <summary>
+ /// Out of memory.
+ /// </summary>
+ OutOfMemory = StreamRecorderError.OutOfMemory
+ }
+}
diff --git a/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderErrorFactory.cs b/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderErrorFactory.cs
new file mode 100644
index 0000000..d16b7c2
--- /dev/null
+++ b/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderErrorFactory.cs
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Multimedia
+{
+ internal enum StreamRecorderError
+ {
+ None = ErrorCode.None,
+ InvalidParameter = ErrorCode.InvalidParameter,
+ TizenErrorStreamRecorder = -0x01A10000,
+ InvalidState = TizenErrorStreamRecorder | 0x01,
+ OutOfMemory = ErrorCode.OutOfMemory,
+ InvalidOperation = ErrorCode.InvalidOperation,
+ OutOfStorage = TizenErrorStreamRecorder | 0x02,
+ PermissionDenied = ErrorCode.PermissionDenied,
+ NotSupported = ErrorCode.NotSupported,
+ }
+
+ internal static class StreamRecorderErrorFactory
+ {
+ internal static void ThrowException(int errorCode, string errorMessage = null, string paramName = null)
+ {
+ StreamRecorderError err = (StreamRecorderError)errorCode;
+ if(string.IsNullOrEmpty(errorMessage)) {
+ errorMessage = err.ToString();
+ }
+ switch((StreamRecorderError)errorCode) {
+ case StreamRecorderError.InvalidParameter:
+ throw new ArgumentException(errorMessage, paramName);
+ case StreamRecorderError.OutOfMemory:
+ throw new OutOfMemoryException(errorMessage);
+ case StreamRecorderError.PermissionDenied:
+ throw new UnauthorizedAccessException(errorMessage);
+ case StreamRecorderError.NotSupported:
+ throw new NotSupportedException(errorMessage);
+ case StreamRecorderError.InvalidState:
+ case StreamRecorderError.InvalidOperation:
+ case StreamRecorderError.OutOfStorage:
+ throw new InvalidOperationException(errorMessage);
+ }
+ }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderNotifiedEventArgs.cs b/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderNotifiedEventArgs.cs
new file mode 100644
index 0000000..0ac92f7
--- /dev/null
+++ b/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderNotifiedEventArgs.cs
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// An extended Eventargs class which contains interrupted policy details, previous and current
+ /// state of the recorder.
+ /// </summary>
+ public class StreamRecorderNotifiedEventArgs : EventArgs
+ {
+ private StreamRecorderState _previous = StreamRecorderState.None;
+ private StreamRecorderState _current = StreamRecorderState.None;
+ private StreamRecorderNotify _notify = StreamRecorderNotify.None;
+
+ internal StreamRecorderNotifiedEventArgs(StreamRecorderState previous, StreamRecorderState current, StreamRecorderNotify notify)
+ {
+ _previous = previous;
+ _current = current;
+ _notify = notify;
+ }
+
+ /// <summary>
+ /// The previous state of the stream recorder.
+ /// </summary>
+ public StreamRecorderState Previous {
+ get {
+ return _previous;
+ }
+ }
+
+ /// <summary>
+ /// The current state of the stream recorder.
+ /// </summary>
+ public StreamRecorderState Current {
+ get {
+ return _current;
+ }
+ }
+
+ /// <summary>
+ /// The notify of the event.
+ /// </summary>
+ public StreamRecorderNotify Notify {
+ get {
+ return _notify;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderVideoResolution.cs b/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderVideoResolution.cs
new file mode 100644
index 0000000..8523098
--- /dev/null
+++ b/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderVideoResolution.cs
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Native = Interop.StreamRecorder;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Resolution for stream recorder.
+ /// </summary>
+ public class StreamRecorderVideoResolution
+ {
+ private int _width, _height;
+ private bool _interopFlag;
+ internal IntPtr _Handle;
+
+ internal StreamRecorderVideoResolution(IntPtr handle)
+ {
+ _Handle = handle;
+ _interopFlag = true;
+ int ret = Native.GetVideoResolution(_Handle, out _width, out _height);
+ StreamRecorderError err = (StreamRecorderError)ret;
+ Log.Info(StreamRecorderLog.Tag, "width " + _width + " height " + _height + "return " + err.ToString());
+ }
+
+ internal StreamRecorderVideoResolution(int width, int height)
+ {
+ _interopFlag = false;
+ _width = width;
+ _height = height;
+ }
+
+ /// <summary>
+ /// The video width.
+ /// </summary>
+ /// <value>The width.</value>
+ public int Width {
+ get {
+ if(_interopFlag == true)
+ Native.GetVideoResolution(_Handle, out _width, out _height);
+ return _width;
+ }
+ set {
+ _width = value;
+ if(_interopFlag == true) {
+ int ret = Native.SetVideoResolution(_Handle, _width, _height);
+ StreamRecorderError err = (StreamRecorderError)ret;
+ Log.Info(StreamRecorderLog.Tag, " set width " + _width + " height " + _height + "set return " + err.ToString());
+ }
+ }
+ }
+
+ /// <summary>
+ /// The video height.
+ /// </summary>
+ /// <value>The height.</value>
+ public int Height {
+ get {
+ if(_interopFlag == true)
+ Native.GetVideoResolution(_Handle, out _width, out _height);
+ return _height;
+ }
+ set {
+ _height = value;
+ if(_interopFlag == true) {
+ int ret = Native.SetVideoResolution(_Handle, _width, _height);
+ StreamRecorderError err = (StreamRecorderError)ret;
+ Log.Info(StreamRecorderLog.Tag, " set width " + _width + " height " + _height + "set return " + err.ToString());
+ }
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecordingBufferConsumedEventArgs.cs b/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecordingBufferConsumedEventArgs.cs
new file mode 100644
index 0000000..3628849
--- /dev/null
+++ b/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecordingBufferConsumedEventArgs.cs
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// An extended EventArgs.
+ /// </summary>
+ public class StreamRecordingBufferConsumedEventArgs : EventArgs
+ {
+ private IntPtr _buffer = IntPtr.Zero;
+
+ internal StreamRecordingBufferConsumedEventArgs(IntPtr buffer)
+ {
+ _buffer = buffer;
+ }
+
+ /// <summary>
+ /// Consumed buffer.
+ /// </summary>
+ public IntPtr Buffer {
+ get {
+ return _buffer;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecordingErrorOccurredEventArgs.cs b/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecordingErrorOccurredEventArgs.cs
new file mode 100644
index 0000000..ea127b7
--- /dev/null
+++ b/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecordingErrorOccurredEventArgs.cs
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// An extended EventArgs class which contains details about error status and
+ /// state of the recorder when it failed.
+ /// </summary>
+ public class StreamRecordingErrorOccurredEventArgs : EventArgs
+ {
+ private StreamRecorderErrorCode _error = StreamRecorderErrorCode.InvalidOperation;
+ private StreamRecorderState _state = StreamRecorderState.None;
+
+ internal StreamRecordingErrorOccurredEventArgs(StreamRecorderErrorCode error, StreamRecorderState state)
+ {
+ _error = error;
+ _state = state;
+ }
+
+ /// <summary>
+ /// The error code.
+ /// </summary>
+ public StreamRecorderErrorCode Error {
+ get {
+ return _error;
+ }
+ }
+
+ /// <summary>
+ /// The state of the recorder.
+ /// </summary>
+ public StreamRecorderState State {
+ get {
+ return _state;
+ }
+ }
+
+ }
+}
diff --git a/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecordingLimitReachedEventArgs.cs b/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecordingLimitReachedEventArgs.cs
new file mode 100644
index 0000000..9b12fdc
--- /dev/null
+++ b/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecordingLimitReachedEventArgs.cs
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// An extended EventArgs class containing details about the recording limit.
+ /// </summary>
+ public class StreamRecordingLimitReachedEventArgs : EventArgs
+ {
+ private StreamRecordingLimitType _type = StreamRecordingLimitType.Size;
+
+ internal StreamRecordingLimitReachedEventArgs(StreamRecordingLimitType type)
+ {
+ _type = type;
+ }
+
+ /// <summary>
+ /// The limitation type.
+ /// </summary>
+ public StreamRecordingLimitType Type {
+ get {
+ return _type;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.StreamRecorder/Tizen.Multimedia.StreamRecorder.csproj b/src/Tizen.Multimedia.StreamRecorder/Tizen.Multimedia.StreamRecorder.csproj
new file mode 100644
index 0000000..cd1ae0f
--- /dev/null
+++ b/src/Tizen.Multimedia.StreamRecorder/Tizen.Multimedia.StreamRecorder.csproj
@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen.Multimedia.Recorder\Tizen.Multimedia.Recorder.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Multimedia.Util/ImageUtil/BitmapFrame.cs b/src/Tizen.Multimedia.Util/ImageUtil/BitmapFrame.cs
new file mode 100644
index 0000000..d964786
--- /dev/null
+++ b/src/Tizen.Multimedia.Util/ImageUtil/BitmapFrame.cs
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Multimedia.Util
+{
+ /// <summary>
+ /// Represents image data returned by a decoder class.
+ /// </summary>
+ public class BitmapFrame
+ {
+ internal BitmapFrame(IntPtr nativeBuffer, int width, int height, int size)
+ {
+ Debug.Assert(nativeBuffer != IntPtr.Zero);
+
+ byte[] buf = new byte[size];
+ Marshal.Copy(nativeBuffer, buf, 0, size);
+
+ Buffer = buf;
+
+ Size = new Size(width, height);
+ }
+
+ /// <summary>
+ /// Gets the raw image data.
+ /// </summary>
+ public byte[] Buffer { get; }
+
+ /// <summary>
+ /// Gets the size of the image.
+ /// </summary>
+ public Size Size { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia.Util/ImageUtil/GifFrame.cs b/src/Tizen.Multimedia.Util/ImageUtil/GifFrame.cs
new file mode 100644
index 0000000..48a8896
--- /dev/null
+++ b/src/Tizen.Multimedia.Util/ImageUtil/GifFrame.cs
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia.Util
+{
+ /// <summary>
+ /// Represent gif image data used to encode a gif image with <see cref="GifEncoder"/>.
+ /// </summary>
+ public class GifFrame
+ {
+
+ /// <summary>
+ /// Initialize a new instance of the <see cref="GifFrame"/> class with a buffer and a delay.
+ /// </summary>
+ /// <param name="buffer">The raw image buffer to be encoded.</param>
+ /// <param name="delay">The delay for this image, in 0.001 sec units.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception>
+ /// <exception cref="ArgumentException">The length of <paramref name="buffer"/> is zero.</exception>
+ public GifFrame(byte[] buffer, uint delay)
+ {
+ if (buffer == null)
+ {
+ throw new ArgumentNullException(nameof(buffer));
+ }
+
+ if (buffer.Length == 0)
+ {
+ throw new ArgumentException("buffer has no element.", nameof(buffer));
+ }
+
+ Buffer = buffer;
+ Delay = delay;
+ }
+
+ /// <summary>
+ /// Gets the raw image data.
+ /// </summary>
+ public byte[] Buffer { get; }
+
+ /// <summary>
+ /// Gets or sets the delay for this image.
+ /// </summary>
+ /// <value>Time delay in 0.001 sec units.</value>
+ public uint Delay { get; set; }
+ }
+}
diff --git a/src/Tizen.Multimedia.Util/ImageUtil/ImageColorSpace.cs b/src/Tizen.Multimedia.Util/ImageUtil/ImageColorSpace.cs
new file mode 100644
index 0000000..0572e09
--- /dev/null
+++ b/src/Tizen.Multimedia.Util/ImageUtil/ImageColorSpace.cs
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Diagnostics;
+
+namespace Tizen.Multimedia.Util
+{
+ internal enum ImageColorSpace
+ {
+ /// <summary>
+ /// YV12 - YCrCb planar format
+ /// </summary>
+ YV12,
+ /// <summary>
+ /// YUV422 - planar
+ /// </summary>
+ Yuv422,
+ /// <summary>
+ /// YUV420 - planar
+ /// </summary>
+ I420,
+ /// <summary>
+ /// NV12- planar
+ /// </summary>
+ NV12,
+ /// <summary>
+ /// UYVY - packed
+ /// </summary>
+ Uyvy,
+ /// <summary>
+ /// YUYV - packed
+ /// </summary>
+ Yuyv,
+ /// <summary>
+ /// RGB565, high-byte is Blue
+ /// </summary>
+ Rgb565,
+ /// <summary>
+ /// RGB888, high-byte is Blue
+ /// </summary>
+ Rgb888,
+ /// <summary>
+ /// ARGB8888, high-byte is Blue
+ /// </summary>
+ Argb8888,
+ /// <summary>
+ /// BGRA8888, high-byte is Alpha
+ /// </summary>
+ Bgra8888,
+ /// <summary>
+ /// RGBA8888, high-byte is Alpha
+ /// </summary>
+ Rgba8888,
+ /// <summary>
+ /// BGRX8888, high-byte is X
+ /// </summary>
+ Bgrx8888,
+ /// <summary>
+ /// NV21- planar
+ /// </summary>
+ NV21,
+ /// <summary>
+ /// NV16- planar
+ /// </summary>
+ NV16,
+ /// <summary>
+ /// NV61- planar
+ /// </summary>
+ NV61,
+ }
+
+ internal static class ImageColorSpaceExtensions
+ {
+ internal static ColorSpace ToCommonColorSpace(this ImageColorSpace value)
+ {
+ Debug.Assert(Enum.IsDefined(typeof(ImageColorSpace), value));
+
+ switch (value)
+ {
+ case ImageColorSpace.YV12: return ColorSpace.YV12;
+
+ case ImageColorSpace.Uyvy: return ColorSpace.Uyvy;
+
+ case ImageColorSpace.Yuyv: return ColorSpace.Yuyv;
+
+ case ImageColorSpace.Yuv422: return ColorSpace.Yuv422;
+
+ case ImageColorSpace.I420: return ColorSpace.I420;
+
+ case ImageColorSpace.Rgb565: return ColorSpace.Rgb565;
+
+ case ImageColorSpace.Rgb888: return ColorSpace.Rgb888;
+
+ case ImageColorSpace.Argb8888: return ColorSpace.Argb8888;
+
+ case ImageColorSpace.Bgra8888: return ColorSpace.Bgra8888;
+
+ case ImageColorSpace.Rgba8888: return ColorSpace.Rgba8888;
+
+ case ImageColorSpace.Bgrx8888: return ColorSpace.Bgrx8888;
+
+ case ImageColorSpace.NV12: return ColorSpace.NV12;
+
+ case ImageColorSpace.NV16: return ColorSpace.NV16;
+
+ case ImageColorSpace.NV21: return ColorSpace.NV21;
+
+ case ImageColorSpace.NV61: return ColorSpace.NV61;
+ }
+
+ Debug.Fail($"Not supported color space : {value.ToString()}!");
+ throw new NotSupportedException("Implementation does not support the specified value.");
+ }
+ }
+
+ internal static class ImageColorSpaceSupport
+ {
+ internal static ImageColorSpace ToImageColorSpace(this ColorSpace colorSpace)
+ {
+ ValidationUtil.ValidateEnum(typeof(ColorSpace), colorSpace, nameof(colorSpace));
+
+ switch (colorSpace)
+ {
+ case ColorSpace.YV12: return ImageColorSpace.YV12;
+
+ case ColorSpace.Uyvy: return ImageColorSpace.Uyvy;
+
+ case ColorSpace.Yuyv: return ImageColorSpace.Yuyv;
+
+ case ColorSpace.Yuv422: return ImageColorSpace.Yuv422;
+
+ case ColorSpace.I420: return ImageColorSpace.I420;
+
+ case ColorSpace.Rgb565: return ImageColorSpace.Rgb565;
+
+ case ColorSpace.Rgb888: return ImageColorSpace.Rgb888;
+
+ case ColorSpace.Argb8888: return ImageColorSpace.Argb8888;
+
+ case ColorSpace.Bgra8888: return ImageColorSpace.Bgra8888;
+
+ case ColorSpace.Rgba8888: return ImageColorSpace.Rgba8888;
+
+ case ColorSpace.Bgrx8888: return ImageColorSpace.Bgrx8888;
+
+ case ColorSpace.NV12: return ImageColorSpace.NV12;
+
+ case ColorSpace.NV16: return ImageColorSpace.NV16;
+
+ case ColorSpace.NV21: return ImageColorSpace.NV21;
+
+ case ColorSpace.NV61: return ImageColorSpace.NV61;
+ }
+
+ throw new NotSupportedException($"The ColorSpace.{colorSpace.ToString()} is not supported.");
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Util/ImageUtil/ImageDecoder.cs b/src/Tizen.Multimedia.Util/ImageUtil/ImageDecoder.cs
new file mode 100644
index 0000000..ce0b612
--- /dev/null
+++ b/src/Tizen.Multimedia.Util/ImageUtil/ImageDecoder.cs
@@ -0,0 +1,380 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+using static Interop;
+using static Interop.Decode;
+
+namespace Tizen.Multimedia.Util
+{
+ /// <summary>
+ /// This is a base class for image decoders.
+ /// </summary>
+ public abstract class ImageDecoder : IDisposable
+ {
+ private ImageDecoderHandle _handle;
+
+ private ColorSpace? _colorSpace;
+
+ internal ImageDecoder(ImageFormat format)
+ {
+ Create(out _handle).ThrowIfFailed("Failed to create ImageDecoder");
+
+ Debug.Assert(_handle != null);
+
+ InputFormat = format;
+ }
+
+ /// <summary>
+ /// Gets the image format of this decoder.
+ /// </summary>
+ public ImageFormat InputFormat { get; }
+
+ private ImageDecoderHandle Handle
+ {
+ get
+ {
+ if (_handle.IsInvalid)
+ {
+ throw new ObjectDisposedException(nameof(ImageDecoder));
+ }
+ return _handle;
+ }
+ }
+
+ /// <summary>
+ /// Sets the color-space to decode into. The default is <see cref="ColorSpace.Rgba8888"/>.
+ /// </summary>
+ /// <exception cref="ArgumentException"><paramref name="colorSpace"/> is invalid.</exception>
+ /// <exception cref="NotSupportedException"><paramref name="colorSpace"/> is not supported by the decoder.</exception>
+ /// <seealso cref="ImageUtil.GetSupportedColorspace(ImageFormat)"/>
+ public void SetColorSpace(ColorSpace colorSpace)
+ {
+ ValidationUtil.ValidateEnum(typeof(ColorSpace), colorSpace, nameof(ColorSpace));
+
+ if (ImageUtil.GetSupportedColorSpaces(InputFormat).Contains(colorSpace) == false)
+ {
+ throw new NotSupportedException($"{colorSpace.ToString()} is not supported for {InputFormat}.");
+ }
+
+ _colorSpace = colorSpace;
+ }
+
+ /// <summary>
+ /// Decodes an image from the specified file.
+ /// </summary>
+ /// <param name="inputFilePath">Input file path from which to decode.</param>
+ /// <returns>A task that represents the asynchronous decoding operation.</returns>
+ /// <remarks>
+ /// Only Graphics Interchange Format(GIF) codec returns more than one frame.\n
+ /// \n
+ /// http://tizen.org/privilege/mediastorage is needed if <paramref name="inputFilePath"/> is relevant to media storage.\n
+ /// http://tizen.org/privilege/externalstorage is needed if <paramref name="inputFilePath"/> is relevant to external storage.
+ /// </remarks>
+ /// <exception cref="ArgumentNullException"><paramref name="inputFilePath"/> is null.</exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="inputFilePath"/> is an empty string.\n
+ /// - or -\n
+ /// <paramref name="inputFilePath"/> is not a image file.\n
+ /// - or -\n
+ /// The format of <paramref name="inputFilePath"/> is not <see cref="InputFormat"/>.
+ /// </exception>
+ /// <exception cref="FileNotFoundException"><paramref name="inputFilePath"/> does not exists.</exception>
+ /// <exception cref="UnauthorizedAccessException">Caller does not have required permission to access the path.</exception>
+ /// <exception cref="FileFormatException">The format of <paramref name="inputFilePath"/> is not <see cref="InputFormat"/>.</exception>
+ /// <exception cref="ObjectDisposedException">The <see cref="ImageDecoder"/> has already been disposed of.</exception>
+ public async Task<IEnumerable<BitmapFrame>> DecodeAsync(string inputFilePath)
+ {
+ if (inputFilePath == null)
+ {
+ throw new ArgumentNullException(nameof(inputFilePath));
+ }
+
+ if (inputFilePath.Length == 0)
+ {
+ throw new ArgumentException("path is empty.", nameof(inputFilePath));
+ }
+
+ if (CheckHeader(inputFilePath) == false)
+ {
+ throw new FileFormatException("The file has an invalid header.");
+ }
+
+ var pathPtr = Marshal.StringToHGlobalAnsi(inputFilePath);
+ try
+ {
+
+ SetInputPath(Handle, pathPtr).ThrowIfFailed("Failed to set input file path for decoding");
+ return await DecodeAsync();
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(pathPtr);
+ }
+ }
+
+ /// <summary>
+ /// Decodes an image from the buffer.
+ /// </summary>
+ /// <param name="inputBuffer">The image buffer from which to decode.</param>
+ /// <returns>A task that represents the asynchronous decoding operation.</returns>
+ /// <remarks>
+ /// Only Graphics Interchange Format(GIF) codec returns more than one frame.\n
+ /// </remarks>
+ /// <exception cref="ArgumentNullException"><paramref name="inputBuffer"/> is null.</exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="inputBuffer"/> is an empty array.\n
+ /// - or -\n
+ /// The format of <paramref name="inputBuffer"/> is not <see cref="InputFormat"/>.
+ /// </exception>
+ /// <exception cref="FileFormatException">The format of <paramref name="inputBuffer"/> is not <see cref="InputFormat"/>.</exception>
+ /// <exception cref="ObjectDisposedException">The <see cref="ImageDecoder"/> has already been disposed of.</exception>
+ public Task<IEnumerable<BitmapFrame>> DecodeAsync(byte[] inputBuffer)
+ {
+ if (inputBuffer == null)
+ {
+ throw new ArgumentNullException(nameof(inputBuffer));
+ }
+
+ if (inputBuffer.Length == 0)
+ {
+ throw new ArgumentException("buffer is empty.", nameof(inputBuffer));
+ }
+
+ if (CheckHeader(inputBuffer) == false)
+ {
+ throw new FileFormatException("buffer has an invalid header.");
+ }
+
+ SetInputBuffer(Handle, inputBuffer, (ulong)inputBuffer.Length).
+ ThrowIfFailed("Failed to set input buffer for decoding");
+
+ return DecodeAsync();
+ }
+
+ private bool CheckHeader(byte[] input)
+ {
+ if (input.Length < Header.Length)
+ {
+ return false;
+ }
+
+ for (int i = 0; i < Header.Length; ++i)
+ {
+ if (input[i] != Header[i])
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private bool CheckHeader(string inputFile)
+ {
+ using (var fs = File.OpenRead(inputFile))
+ {
+ byte[] fileHeader = new byte[Header.Length];
+
+ if (fs.Read(fileHeader, 0, fileHeader.Length) < Header.Length)
+ {
+ return false;
+ }
+ return CheckHeader(fileHeader);
+ }
+ }
+
+ internal Task<IEnumerable<BitmapFrame>> DecodeAsync()
+ {
+ Initialize(Handle);
+
+ IntPtr outBuffer = IntPtr.Zero;
+ SetOutputBuffer(Handle, out outBuffer).ThrowIfFailed("Failed to decode given image");
+
+ var tcs = new TaskCompletionSource<IEnumerable<BitmapFrame>>();
+
+ Task.Run(() =>
+ {
+ try
+ {
+ int width, height;
+ ulong size;
+
+ DecodeRun(Handle, out width, out height, out size).ThrowIfFailed("Failed to decode");
+
+ tcs.SetResult(new[] { new BitmapFrame(outBuffer, width, height, (int)size) });
+ }
+ catch (Exception e)
+ {
+ tcs.TrySetException(e);
+ }
+ finally
+ {
+ LibcSupport.Free(outBuffer);
+ }
+ });
+
+ return tcs.Task;
+ }
+
+ internal virtual void Initialize(ImageDecoderHandle handle)
+ {
+ if (_colorSpace.HasValue)
+ {
+ SetColorspace(Handle, _colorSpace.Value.ToImageColorSpace()).ThrowIfFailed("Failed to set color space");
+ }
+ }
+
+ internal abstract byte[] Header { get; }
+
+ #region IDisposable Support
+ private bool _disposed = false;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (_handle != null)
+ {
+ _handle.Dispose();
+ }
+ _disposed = true;
+ }
+ }
+
+ ~ImageDecoder()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+
+ /// <summary>
+ /// Provides the ability to decode Bitmap (BMP) encoded images.
+ /// </summary>
+ public class BmpDecoder : ImageDecoder
+ {
+ private static readonly byte[] _header = { (byte)'B', (byte)'M' };
+
+ /// <summary>
+ /// Initialize a new instance of the <see cref="BmpDecoder"/> class.
+ /// </summary>
+ /// <remarks><see cref="ImageDecoder.InputFormat"/> will be the <see cref="ImageFormat.Bmp"/>.</remarks>
+ public BmpDecoder() : base(ImageFormat.Bmp)
+ {
+ }
+
+ internal override byte[] Header => _header;
+ }
+
+ /// <summary>
+ /// Provides the ability to decode Portable Network Graphics (PNG) encoded images.
+ /// </summary>
+ public class PngDecoder : ImageDecoder
+ {
+ private static readonly byte[] _header = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a };
+
+ /// <summary>
+ /// Initialize a new instance of the <see cref="PngDecoder"/> class.
+ /// </summary>
+ /// <remarks><see cref="ImageDecoder.InputFormat"/> will be the <see cref="ImageFormat.Png"/>.</remarks>
+ public PngDecoder() : base(ImageFormat.Png)
+ {
+ }
+
+ internal override byte[] Header => _header;
+ }
+
+ /// <summary>
+ /// Provides the ability to decode Joint Photographic Experts Group (JPEG) encoded images.
+ /// </summary>
+ public class JpegDecoder : ImageDecoder
+ {
+ private static readonly byte[] _header = { 0xFF, 0xD8 };
+
+ /// <summary>
+ /// A read-only field that represents the default value of <see cref="Downscale"/>.
+ /// </summary>
+ public static readonly JpegDownscale DefaultJpegDownscale = JpegDownscale.None;
+
+ private JpegDownscale _jpegDownscale = DefaultJpegDownscale;
+
+ /// <summary>
+ /// Initialize a new instance of the <see cref="JpegDecoder"/> class.
+ /// </summary>
+ /// <remarks><see cref="ImageDecoder.InputFormat"/> will be the <see cref="ImageFormat.Jpeg"/>.</remarks>
+ public JpegDecoder() : base(ImageFormat.Jpeg)
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the downscale at which the jpeg image should be decoded.
+ /// </summary>
+ /// <exception cref="ArgumentException"><paramref name="value"/> is invalid.</exception>
+ public JpegDownscale Downscale
+ {
+ get
+ {
+ return _jpegDownscale;
+ }
+ set
+ {
+ ValidationUtil.ValidateEnum(typeof(JpegDownscale), value, nameof(Downscale));
+
+ _jpegDownscale = value;
+ }
+ }
+
+ internal override void Initialize(ImageDecoderHandle handle)
+ {
+ base.Initialize(handle);
+
+ SetJpegDownscale(handle, Downscale).ThrowIfFailed("Failed to set downscale for decoding");
+ }
+
+ internal override byte[] Header => _header;
+ }
+
+ /// <summary>
+ /// Provides the ability to decode Graphics Interchange Format (GIF) encoded images.
+ /// </summary>
+ public class GifDecoder : ImageDecoder
+ {
+ private static readonly byte[] _header = { (byte)'G', (byte)'I', (byte)'F' };
+
+ /// <summary>
+ /// Initialize a new instance of the <see cref="GifDecoder"/> class.
+ /// </summary>
+ /// <remarks><see cref="ImageDecoder.InputFormat"/> will be the <see cref="ImageFormat.Gif"/>.</remarks>
+ public GifDecoder() : base(ImageFormat.Gif)
+ {
+ }
+
+ internal override byte[] Header => _header;
+ }
+}
diff --git a/src/Tizen.Multimedia.Util/ImageUtil/ImageEncoder.cs b/src/Tizen.Multimedia.Util/ImageUtil/ImageEncoder.cs
new file mode 100644
index 0000000..03534a2
--- /dev/null
+++ b/src/Tizen.Multimedia.Util/ImageUtil/ImageEncoder.cs
@@ -0,0 +1,451 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+using static Interop.ImageUtil;
+using Unmanaged = Interop.ImageUtil.Encode;
+
+namespace Tizen.Multimedia.Util
+{
+ /// <summary>
+ /// This is a base class for image encoders.
+ /// </summary>
+ public abstract class ImageEncoder : IDisposable
+ {
+ private ImageEncoderHandle _handle;
+
+ private bool _hasResolution;
+
+ internal ImageEncoder(ImageFormat format)
+ {
+ Unmanaged.Create(format, out _handle).ThrowIfFailed("Failed to create ImageEncoder");
+
+ Debug.Assert(_handle != null);
+
+ OutputFormat = format;
+ }
+
+ private ImageEncoderHandle Handle
+ {
+ get
+ {
+ if (_disposed)
+ {
+ throw new ObjectDisposedException(GetType().Name);
+ }
+
+ return _handle;
+ }
+ }
+
+ /// <summary>
+ /// Gets the image format of this encoder.
+ /// </summary>
+ public ImageFormat OutputFormat { get; }
+
+ /// <summary>
+ /// Sets the resolution of the output image.
+ /// </summary>
+ /// <param name="resolution">The target resolution.</param>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// The width of <paramref name="resolution"/> is less than or equal to zero.\n
+ /// - or -\n
+ /// The height of <paramref name="resolution"/> is less than or equal to zero.
+ /// </exception>
+ public void SetResolution(Size resolution)
+ {
+ if (resolution.Width <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(resolution), resolution.Width,
+ "The width of resolution can't be less than or equal to zero.");
+ }
+ if (resolution.Height <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(resolution), resolution.Height,
+ "The height of resolution can't be less than or equal to zero.");
+ }
+
+ Unmanaged.SetResolution(Handle, (uint)resolution.Width, (uint)resolution.Height).
+ ThrowIfFailed("Failed to set the resolution");
+
+ _hasResolution = true;
+ }
+
+ /// <summary>
+ /// Sets the colorspace of the output image.
+ /// </summary>
+ /// <param name="colorSpace">The target colorspace.</param>
+ /// <exception cref="ArgumentException"><paramref name="colorSpace"/> is invalid.</exception>
+ /// <exception cref="NotSupportedException"><paramref name="colorSpace"/> is not supported by the encoder.</exception>
+ /// <seealso cref="ImageUtil.GetSupportedColorspace(ImageFormat)"/>
+ public void SetColorSpace(ColorSpace colorSpace)
+ {
+ ValidationUtil.ValidateEnum(typeof(ColorSpace), colorSpace, nameof(colorSpace));
+
+ if (ImageUtil.GetSupportedColorSpaces(OutputFormat).Contains(colorSpace) == false)
+ {
+ throw new NotSupportedException($"{colorSpace.ToString()} is not supported for {OutputFormat}.");
+ }
+
+ Unmanaged.SetColorspace(Handle, colorSpace.ToImageColorSpace()).
+ ThrowIfFailed("Failed to set the color space");
+ }
+
+ private Task Run(Stream outStream)
+ {
+ var tcs = new TaskCompletionSource<bool>();
+
+ IntPtr outBuffer = IntPtr.Zero;
+ Unmanaged.SetOutputBuffer(Handle, out outBuffer).ThrowIfFailed("Failed to initialize encoder");
+
+ Task.Run(() =>
+ {
+ try
+ {
+ ulong size = 0;
+ Unmanaged.Run(Handle, out size).ThrowIfFailed("Failed to encode given image");
+
+ byte[] buf = new byte[size];
+ Marshal.Copy(outBuffer, buf, 0, (int)size);
+ outStream.Write(buf, 0, (int)size);
+
+ tcs.TrySetResult(true);
+ }
+ catch (Exception e)
+ {
+ tcs.TrySetException(e);
+ }
+ finally
+ {
+ Interop.Libc.Free(outBuffer);
+ }
+ });
+
+ return tcs.Task;
+ }
+
+ internal Task EncodeAsync(Action<ImageEncoderHandle> settingInputAction, Stream outStream)
+ {
+ Debug.Assert(settingInputAction != null);
+
+ if (outStream == null)
+ {
+ throw new ArgumentNullException(nameof(outStream));
+ }
+
+ if (outStream.CanWrite == false)
+ {
+ throw new ArgumentException("The stream is not writable.", nameof(outStream));
+ }
+
+ Initialize();
+
+ settingInputAction(Handle);
+
+ return Run(outStream);
+ }
+
+ /// <summary>
+ /// Encodes an image from a raw image buffer to a specified <see cref="Stream"/>.
+ /// </summary>
+ /// <param name="inputBuffer">The image buffer to encode.</param>
+ /// <param name="outStream">The stream that the image is encoded to.</param>
+ /// <returns>A task that represents the asynchronous encoding operation.</returns>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="inputBuffer"/> is null.\n
+ /// - or -\n
+ /// <paramref name="outStream"/> is null.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="inputBuffer"/> is an empty array.\n
+ /// - or -\n
+ /// <paramref name="outStream"/> is not writable.\n
+ /// </exception>
+ /// <exception cref="InvalidOperationException">The resolution is not set.</exception>
+ /// <exception cref="ObjectDisposedException">The <see cref="ImageEncoder"/> has already been disposed of.</exception>
+ /// <seealso cref="SetResolution(Size)"/>
+ public Task EncodeAsync(byte[] inputBuffer, Stream outStream)
+ {
+ if (inputBuffer == null)
+ {
+ throw new ArgumentNullException(nameof(inputBuffer));
+ }
+
+ if (inputBuffer.Length == 0)
+ {
+ throw new ArgumentException("buffer is empty.", nameof(inputBuffer));
+ }
+
+ return EncodeAsync(handle =>
+ {
+ Unmanaged.SetInputBuffer(handle, inputBuffer).
+ ThrowIfFailed("Failed to configure encoder; InputBuffer");
+ }, outStream);
+ }
+
+ internal void Initialize()
+ {
+ Configure(Handle);
+
+ if (_hasResolution == false)
+ {
+ throw new InvalidOperationException("Resolution is not set.");
+ }
+ }
+
+ internal abstract void Configure(ImageEncoderHandle handle);
+
+ #region IDisposable Support
+ private bool _disposed = false;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (_handle != null)
+ {
+ _handle.Dispose();
+ }
+ _disposed = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+ #endregion
+ }
+
+ /// <summary>
+ /// Provides the ability to encode Bitmap (BMP) format images.
+ /// </summary>
+ public class BmpEncoder : ImageEncoder
+ {
+ /// <summary>
+ /// Initialize a new instance of the <see cref="BmpEncoder"/> class.
+ /// </summary>
+ /// <remarks><see cref="ImageEncoder.OutputFormat"/> will be the <see cref="ImageFormat.Bmp"/>.</remarks>
+ public BmpEncoder() : base(ImageFormat.Bmp)
+ {
+ }
+
+ internal override void Configure(ImageEncoderHandle handle)
+ {
+ }
+ }
+
+ /// <summary>
+ /// Provides the ability to encode Portable Network Graphics (PNG) format images.
+ /// </summary>
+ public class PngEncoder : ImageEncoder
+ {
+ /// <summary>
+ /// A read-only field that represents the default value of <see cref="Compression"/>.
+ /// </summary>
+ public static readonly PngCompression DefaultCompression = PngCompression.Level6;
+
+ private PngCompression? _compression;
+
+ /// <summary>
+ /// Initialize a new instance of the <see cref="PngEncoder"/> class.
+ /// </summary>
+ /// <remarks><see cref="ImageEncoder.OutputFormat"/> will be the <see cref="ImageFormat.Png"/>.</remarks>
+ public PngEncoder() :
+ base(ImageFormat.Png)
+ {
+ }
+
+ /// <summary>
+ /// Initialize a new instance of the <see cref="PngEncoder"/> class with <see cref="PngCompression"/>.
+ /// </summary>
+ /// <remarks><see cref="ImageEncoder.OutputFormat"/> will be the <see cref="ImageFormat.Png"/>.</remarks>
+ /// <param name="compression">The compression level of the encoder.</param>
+ /// <exception cref="ArgumentException"><paramref name="compression"/> is invalid.</exception>
+ public PngEncoder(PngCompression compression) :
+ base(ImageFormat.Png)
+ {
+ Compression = compression;
+ }
+
+ /// <summary>
+ /// Gets or sets the compression level of the png image.
+ /// </summary>
+ /// <value>The compression level. The default is <see cref="PngCompression.Level6"/>.</value>
+ /// <exception cref="ArgumentException"><paramref name="value"/> is invalid.</exception>
+ public PngCompression Compression
+ {
+ get { return _compression ?? DefaultCompression; }
+ set
+ {
+ ValidationUtil.ValidateEnum(typeof(PngCompression), value, nameof(Compression));
+
+ _compression = value;
+ }
+ }
+
+ internal override void Configure(ImageEncoderHandle handle)
+ {
+ if (_compression.HasValue)
+ {
+ Unmanaged.SetPngCompression(handle, _compression.Value).
+ ThrowIfFailed("Failed to configure encoder; PngCompression");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Provides the ability to encode Joint Photographic Experts Group (JPEG) format images.
+ /// </summary>
+ public class JpegEncoder : ImageEncoder
+ {
+ /// <summary>
+ /// A read-only field that represents the default value of <see cref="Quality"/>.
+ /// </summary>
+ public static readonly int DefaultQuality = 75;
+
+ private int? _quality;
+
+ /// <summary>
+ /// Initialize a new instance of the <see cref="JpegEncoder"/> class.
+ /// </summary>
+ /// <remarks><see cref="ImageEncoder.OutputFormat"/> will be the <see cref="ImageFormat.Jpeg"/>.</remarks>
+ public JpegEncoder() : base(ImageFormat.Jpeg)
+ {
+ }
+
+
+ /// <summary>
+ /// Initialize a new instance of the <see cref="JpegEncoder"/> class with initial quality value.
+ /// </summary>
+ /// <remarks><see cref="ImageEncoder.OutputFormat"/> will be the <see cref="ImageFormat.Jpeg"/>.</remarks>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="quality"/> is less than 0.\n
+ /// - or -\n
+ /// <paramref name="quality"/> is greater than 100.
+ /// </exception>
+ public JpegEncoder(int quality) :
+ base(ImageFormat.Jpeg)
+ {
+ Quality = quality;
+ }
+
+ /// <summary>
+ /// Gets or sets the quality of the encoded image.
+ /// </summary>
+ /// <value>The quality of the output image. The default is 75.</value>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="value"/> is less than 0.\n
+ /// - or -\n
+ /// <paramref name="value"/> is greater than 100.
+ /// </exception>
+ public int Quality
+ {
+ get { return _quality ?? DefaultQuality; }
+ set
+ {
+ if (value < 0 || value > 100)
+ {
+ throw new ArgumentOutOfRangeException(nameof(Quality), value,
+ "Valid range is from 1 to 100, inclusive.");
+ }
+ _quality = value;
+ }
+ }
+
+ internal override void Configure(ImageEncoderHandle handle)
+ {
+ if (_quality.HasValue)
+ {
+ Unmanaged.SetQuality(handle, _quality.Value).
+ ThrowIfFailed("Failed to configure encoder; Quality");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Provides the ability to encode Graphics Interchange Format (GIF) format images.
+ /// </summary>
+ public class GifEncoder : ImageEncoder
+ {
+ /// <summary>
+ /// Initialize a new instance of the <see cref="GifEncoder"/> class.
+ /// </summary>
+ /// <remarks><see cref="ImageEncoder.OutputFormat"/> will be the <see cref="ImageFormat.Gif"/>.</remarks>
+ public GifEncoder() : base(ImageFormat.Gif)
+ {
+ }
+
+ internal override void Configure(ImageEncoderHandle handle)
+ {
+ }
+
+ /// <summary>
+ /// Encodes a Graphics Interchange Format (GIF) image from multiple raw image buffers to a specified <see cref="Stream"/>.
+ /// </summary>
+ /// <param name="inputBuffer">The image buffer to encode.</param>
+ /// <param name="outStream">The stream that the image is encoded to.</param>
+ /// <returns>A task that represents the asynchronous encoding operation.</returns>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="frames"/> is null.\n
+ /// - or -\n
+ /// <paramref name="outStream"/> is null.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="frames"/> has no element(empty).\n
+ /// - or -\n
+ /// <paramref name="outStream"/> is not writable.\n
+ /// </exception>
+ /// <exception cref="InvalidOperationException">The resolution is not set.</exception>
+ /// <exception cref="ObjectDisposedException">The <see cref="ImageEncoder"/> has already been disposed of.</exception>
+ /// <seealso cref="SetResolution(Size)"/>
+ public Task EncodeAsync(IEnumerable<GifFrame> frames, Stream outStream)
+ {
+ if (frames == null)
+ {
+ throw new ArgumentNullException(nameof(frames));
+ }
+
+ if (frames.Count() == 0)
+ {
+ throw new ArgumentException("frames is a empty collection", nameof(frames));
+ }
+
+ return EncodeAsync(handle =>
+ {
+ foreach (GifFrame frame in frames)
+ {
+ if (frame == null)
+ {
+ throw new ArgumentNullException(nameof(frames));
+ }
+ Unmanaged.SetInputBuffer(handle, frame.Buffer).
+ ThrowIfFailed("Failed to configure encoder; Buffer");
+
+ Unmanaged.SetGifFrameDelayTime(handle, (ulong)frame.Delay).
+ ThrowIfFailed("Failed to configure encoder; Delay");
+ }
+ }, outStream);
+ }
+ }
+
+}
diff --git a/src/Tizen.Multimedia.Util/ImageUtil/ImageFormat.cs b/src/Tizen.Multimedia.Util/ImageUtil/ImageFormat.cs
new file mode 100644
index 0000000..b600b82
--- /dev/null
+++ b/src/Tizen.Multimedia.Util/ImageUtil/ImageFormat.cs
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia.Util
+{
+ /// <summary>
+ /// Specifies image formats for <see cref="ImageDecoder"/>, <see cref="ImageEncoder"/> and <see cref="ImageUtil"/>.
+ /// </summary>
+ public enum ImageFormat
+ {
+ /// <summary>
+ /// The Joint Photographic Experts Group format.
+ /// </summary>
+ Jpeg,
+ /// <summary>
+ /// The Portable Network Graphics format.
+ /// </summary>
+ Png,
+ /// <summary>
+ /// The Graphics Interchange Format.
+ /// </summary>
+ Gif,
+ /// <summary>
+ /// The Bitmap format.
+ /// </summary>
+ Bmp,
+ }
+}
diff --git a/src/Tizen.Multimedia.Util/ImageUtil/ImageRotation.cs b/src/Tizen.Multimedia.Util/ImageUtil/ImageRotation.cs
new file mode 100644
index 0000000..daff4e7
--- /dev/null
+++ b/src/Tizen.Multimedia.Util/ImageUtil/ImageRotation.cs
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia.Util
+{
+ /// <summary>
+ /// Specifies how an image is rotated or flipped.
+ /// </summary>
+ /// <seealso cref="RotateTransform"/>
+ public enum ImageRotation
+ {
+ /// <summary>
+ /// No rotation.
+ /// </summary>
+ Rotate0,
+ /// <summary>
+ /// Rotate 90 degree clockwise.
+ /// </summary>
+ Rotate90,
+ /// <summary>
+ /// Rotate 180 degree clockwise.
+ /// </summary>
+ Rotate180,
+ /// <summary>
+ /// Rotate 270 degree clockwise.
+ /// </summary>
+ Rotate270,
+ /// <summary>
+ /// Flip horizontally.
+ /// </summary>
+ FlipHorizontal,
+ /// <summary>
+ /// Flip vertically.
+ /// </summary>
+ FlipVertical,
+ }
+}
diff --git a/src/Tizen.Multimedia.Util/ImageUtil/ImageTransform.cs b/src/Tizen.Multimedia.Util/ImageUtil/ImageTransform.cs
new file mode 100644
index 0000000..e660e9e
--- /dev/null
+++ b/src/Tizen.Multimedia.Util/ImageUtil/ImageTransform.cs
@@ -0,0 +1,486 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+using static Interop.ImageUtil;
+using static Interop.ImageUtil.Transform;
+
+namespace Tizen.Multimedia.Util
+{
+ /// <summary>
+ /// A base class for image transformations.
+ /// </summary>
+ public abstract class ImageTransform
+ {
+ internal async Task<MediaPacket> RunAsync(TransformHandle handle, MediaPacket source)
+ {
+ var tcs = new TaskCompletionSource<MediaPacket>();
+
+ TransformCompletedCallback cb = (nativehandle, errorCode, _) =>
+ {
+ if (errorCode == ImageUtilError.None)
+ {
+ try
+ {
+ tcs.TrySetResult(MediaPacket.From(Marshal.PtrToStructure<IntPtr>(nativehandle)));
+ }
+ catch (Exception e)
+ {
+ tcs.TrySetException(e);
+ }
+ }
+ else
+ {
+ tcs.TrySetException(errorCode.ToException("Image transformation failed"));
+ }
+ };
+
+ using (var cbKeeper = ObjectKeeper.Get(cb))
+ {
+ Run(handle, source.GetHandle(), cb).ThrowIfFailed("Failed to transform given packet with " + GetType());
+
+ return await tcs.Task;
+ }
+ }
+
+ internal abstract void Configure(TransformHandle handle);
+
+ internal virtual Task<MediaPacket> ApplyAsync(TransformHandle handle, MediaPacket source)
+ {
+ Configure(handle);
+
+ return RunAsync(handle, source);
+ }
+ }
+
+ /// <summary>
+ /// Represents a collection of <see cref="ImageTransform"/> objects that can be individually accessed by index.
+ /// </summary>
+ public class ImageTransformCollection : IEnumerable<ImageTransform>, IList<ImageTransform>
+ {
+ private List<ImageTransform> _list = new List<ImageTransform>();
+
+ /// <summary>
+ /// Initializes a new instance of the ImageTransformCollection class.
+ /// </summary>
+ public ImageTransformCollection()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the <see cref="ImageTransform"/> at the specified index.
+ /// </summary>
+ /// <param name="index">The zero-based index of the <see cref="ImageTransform"/> to get or set.</param>
+ /// <value>The <see cref="ImageTransform"/> at the specified index.</value>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// index is less than 0.\n
+ /// - or -\n
+ /// index is equal to or greater than Count.
+ /// </exception>
+ public ImageTransform this[int index]
+ {
+ get { return _list[index]; }
+ set { _list[index] = value; }
+ }
+
+ /// <summary>
+ /// Gets the number of items contained in the TransformCollection.
+ /// </summary>
+ public int Count => _list.Count;
+
+ bool ICollection<ImageTransform>.IsReadOnly => false;
+
+ /// <summary>
+ /// Adds a <see cref="ImageTransform"/> to the end of the collection.
+ /// </summary>
+ /// <param name="item">The <see cref="ImageTransform"/> to add.</param>
+ /// <remarks>
+ /// <see cref="ImageTransformCollection"/> accepts null as a valid value for reference types and allows duplicate elements.
+ /// </remarks>
+ public void Add(ImageTransform item)
+ {
+ if (item == null)
+ {
+ throw new ArgumentNullException(nameof(item));
+ }
+ _list.Add(item);
+ }
+
+ /// <summary>
+ /// Removes all items.
+ /// </summary>
+ public void Clear() => _list.Clear();
+
+ /// <summary>
+ /// Determines whether the <see cref="ImageTransformCollection"/> contains the specified item.
+ /// </summary>
+ /// <param name="item">The <see cref="ImageTransform"/> to locate in the collection.</param>
+ /// <returns>true if the <see cref="ImageTransform"/> is found in the collection; otherwise, false.</returns>
+ public bool Contains(ImageTransform item) => _list.Contains(item);
+
+ /// <summary>
+ /// Copies the items of the collection to an array, starting at the specified array index.
+ /// </summary>
+ /// <param name="array">The one-dimensional array that is the destination of the items copied from the collection.</param>
+ /// <param name="arrayIndex">The zero-based index in array at which copying begins.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="array"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="arrayIndex"/> is less than 0.</exception>
+ /// <exception cref="ArgumentException">
+ /// The number of elements in the source collection is greater than the available space from arrayIndex to the end of the destination array.
+ /// </exception>
+ public void CopyTo(ImageTransform[] array, int arrayIndex) => _list.CopyTo(array, arrayIndex);
+
+ /// <summary>
+ /// Determines the index of the specified item in the collection.
+ /// </summary>
+ /// <param name="item">The <see cref="ImageTransform"/> to locate in the collection.</param>
+ /// <returns>The index of value if found in the <see cref="ImageTransformCollection"/>; otherwise, -1.</returns>
+ public int IndexOf(ImageTransform item) => _list.IndexOf(item);
+
+ /// <summary>
+ /// Inserts a <see cref="ImageTransform"/> into the collection at the specified index.
+ /// </summary>
+ /// <param name="index">The zero-based index at which <paramref name="item"/> should be inserted.</param>
+ /// <param name="item">The <see cref="ImageTransform"/> to insert into the collection.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="item"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// index is less than 0.\n
+ /// -or-\n
+ /// index is greater than <see cref="Count"/>.
+ /// </exception>
+ public void Insert(int index, ImageTransform item)
+ {
+ if (item == null)
+ {
+ throw new ArgumentNullException(nameof(item));
+ }
+ _list.Insert(index, item);
+ }
+
+ /// <summary>
+ /// Removes the first occurrence of the specified <see cref="ImageTransform"/> from the collection.
+ /// </summary>
+ /// <param name="item">The <see cref="ImageTransform"/> to remove.</param>
+ /// <returns>true if <paramref name="item"/> was removed from the collection; otherwise, false.</returns>
+ public bool Remove(ImageTransform item) => _list.Remove(item);
+
+ /// <summary>
+ /// Removes the <see cref="ImageTransform"/> at the specified index.
+ /// </summary>
+ /// <param name="index">The zero-based index to remove.</param>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// index is less than 0.\n
+ /// - or -\n
+ /// index is equal to or greater than <see cref="Count"/>.
+ /// </exception>
+ public void RemoveAt(int index) => _list.RemoveAt(index);
+
+ /// <summary>
+ /// Returns an enumerator that can iterate through the collection.
+ /// </summary>
+ /// <returns>A enumerator that can be used to iterate through the collection.</returns>
+ public IEnumerator<ImageTransform> GetEnumerator() => _list.GetEnumerator();
+
+ IEnumerator IEnumerable.GetEnumerator() => _list.GetEnumerator();
+ }
+
+ // TODO need to improve performance
+ /// <summary>
+ /// Represents a <see cref="ImageTransform"/> that is a composite of the transforms.
+ /// </summary>
+ public class ImageTransformGroup : ImageTransform
+ {
+ /// <summary>
+ /// Gets or sets the <see cref="ImageTransformCollection"/>.
+ /// </summary>
+ public ImageTransformCollection Children { get; set; }
+
+ /// <summary>
+ /// Initializes a new instance of the ImageTransformGroup class.
+ /// </summary>
+ public ImageTransformGroup()
+ {
+ Children = new ImageTransformCollection();
+ }
+
+ internal override void Configure(TransformHandle handle)
+ {
+ // intended blank
+ }
+
+ internal override async Task<MediaPacket> ApplyAsync(TransformHandle handle, MediaPacket source)
+ {
+ if (Children.Count == 0)
+ {
+ return source;
+ }
+
+ var items = Children;
+
+ MediaPacket curPacket = await items[0].ApplyAsync(handle, source);
+
+ for (int i = 1; i < items.Count; ++i)
+ {
+ var item = items[i];
+
+ var oldPacket = curPacket;
+ try
+ {
+ curPacket = await item.ApplyAsync(handle, curPacket);
+ }
+ finally
+ {
+ oldPacket.Dispose();
+ }
+ }
+
+ return curPacket;
+ }
+ }
+
+ /// <summary>
+ /// Rotates or flips an image.
+ /// </summary>
+ /// <seealso cref="ImageRotation"/>
+ public class RotateTransform : ImageTransform
+ {
+ private ImageRotation _rotation;
+
+ /// <summary>
+ /// Initialize a new instance of the <see cref="RotateTransform"/> class.
+ /// </summary>
+ /// <param name="rotation">The value how to rotate an image.</param>
+ /// <exception cref="ArgumentException"><paramref name="rotation"/> is invalid.</exception>
+ public RotateTransform(ImageRotation rotation)
+ {
+ Rotation = rotation;
+ }
+
+ /// <summary>
+ /// Gets or sets the value how to rotate an image.
+ /// </summary>
+ /// <exception cref="ArgumentException"><paramref name="value"/> is invalid.</exception>
+ public ImageRotation Rotation
+ {
+ get { return _rotation; }
+ set
+ {
+ ValidationUtil.ValidateEnum(typeof(ImageRotation), value, nameof(Rotation));
+
+ _rotation = value;
+ }
+ }
+
+ internal override void Configure(TransformHandle handle)
+ {
+ SetRotation(handle, Rotation);
+ }
+ }
+
+ /// <summary>
+ /// Changes colorspace of image.
+ /// </summary>
+ /// <seealso cref="ColorSpace"/>
+ public class ColorSpaceTransform : ImageTransform
+ {
+ private ImageColorSpace _imageColorSpace;
+
+ /// <summary>
+ /// Initialize a new instance of the <see cref="ColorSpaceTransform"/> class.
+ /// </summary>
+ /// <param name="colorSpace">The colorspace of output image.</param>
+ /// <exception cref="ArgumentException"><paramref name="colorSpace"/> is invalid.</exception>
+ /// <exception cref="NotSupportedException"><paramref name="colorSpace"/> is not supported.</exception>
+ /// <seealso cref="SupportedColorSpaces"/>
+ public ColorSpaceTransform(ColorSpace colorSpace)
+ {
+ ColorSpace = colorSpace;
+ }
+
+ /// <summary>
+ /// Gets or sets the colorspace of the result image.
+ /// </summary>
+ /// <exception cref="ArgumentException"><paramref name="value"/> is invalid.</exception>
+ /// <exception cref="NotSupportedException"><paramref name="value"/> is not supported.</exception>
+ /// <seealso cref="SupportedColorSpaces"/>
+ public ColorSpace ColorSpace
+ {
+ get { return _imageColorSpace.ToCommonColorSpace(); }
+ set
+ {
+ ValidationUtil.ValidateEnum(typeof(ColorSpace), value, nameof(ColorSpace));
+
+ _imageColorSpace = value.ToImageColorSpace();
+ }
+ }
+
+ internal override void Configure(TransformHandle handle)
+ {
+ SetColorspace(handle, _imageColorSpace);
+ }
+
+ /// <summary>
+ /// Gets the supported colorspaces for <see cref="ColorSpaceTransform"/>.
+ /// </summary>
+ public static IEnumerable<ColorSpace> SupportedColorSpaces
+ {
+ get
+ {
+ foreach (ImageColorSpace value in Enum.GetValues(typeof(ImageColorSpace)))
+ {
+ yield return value.ToCommonColorSpace();
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Crops an image.
+ /// </summary>
+ public class CropTransform : ImageTransform
+ {
+ private Rectangle _region;
+
+ /// <summary>
+ /// Initialize a new instance of the <see cref="CropTransform"/> class.
+ /// </summary>
+ /// <param name="region">The crop region.</param>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// The X-position of <paramref name="region"/> is less than zero.\n
+ /// - or -\n
+ /// The Y-position of <paramref name="region"/> is less than zero.\n
+ /// - or -\n
+ /// The width of <paramref name="region"/> is less than or equal to zero.\n
+ /// - or -\n
+ /// The height of <paramref name="region"/> is less than or equal to zero.
+ /// </exception>
+ public CropTransform(Rectangle region)
+ {
+ Region = region;
+ }
+
+ /// <summary>
+ /// Gets or sets the crop region.
+ /// </summary>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// The X-position of <paramref name="value"/> is less than zero.\n
+ /// - or -\n
+ /// The Y-position of <paramref name="value"/> is less than zero.\n
+ /// - or -\n
+ /// The width of <paramref name="value"/> is less than or equal to zero.\n
+ /// - or -\n
+ /// The height of <paramref name="value"/> is less than or equal to zero.
+ /// </exception>
+ public Rectangle Region
+ {
+ get { return _region; }
+ set
+ {
+
+ if (value.X < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(Region), value,
+ "X position of the region can't be less than zero.");
+ }
+
+ if (value.Y < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(Region), value,
+ "Y position of the region can't be less than zero.");
+ }
+
+ if (value.Width <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(Region), value,
+ "Width of the region can't be less than or equal zero.");
+ }
+
+ if (value.Height < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(Region), value,
+ "Height of the region can't be less than or equal to zero.");
+ }
+
+ _region = value;
+ }
+ }
+
+ internal override void Configure(TransformHandle handle)
+ {
+ SetCropArea(handle, Region.Left, Region.Top, Region.Right, Region.Bottom);
+ }
+ }
+
+ /// <summary>
+ /// Resizes an image.
+ /// </summary>
+ public class ResizeTransform : ImageTransform
+ {
+ private Size _size;
+
+ /// <summary>
+ /// Initialize a new instance of the <see cref="ResizeTransform"/> class.
+ /// </summary>
+ /// <param name="size">The size that an image is resized to.</param>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// The width of <paramref name="size"/> is less than or equal to zero.\n
+ /// - or -\n
+ /// The height of <paramref name="size"/> is less than or equal to zero.
+ /// </exception>
+ public ResizeTransform(Size size)
+ {
+ Size = size;
+ }
+
+ /// <summary>
+ /// Gets or sets the size that an image is resized to.
+ /// </summary>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// The width of <paramref name="value"/> is less than or equal to zero.\n
+ /// - or -\n
+ /// The height of <paramref name="value"/> is less than or equal to zero.
+ /// </exception>
+ public Size Size
+ {
+ get { return _size; }
+ set
+ {
+ if (value.Width <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(Size), value,
+ "Width of the size can't be less than or equal to zero.");
+ }
+
+ if (value.Height <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(Size), value,
+ "Height of the size can't be less than or equal to zero.");
+ }
+
+ _size = value;
+ }
+ }
+
+ internal override void Configure(TransformHandle handle)
+ {
+ SetResolution(handle, (uint)Size.Width, (uint)Size.Height);
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Util/ImageUtil/ImageTransformer.cs b/src/Tizen.Multimedia.Util/ImageUtil/ImageTransformer.cs
new file mode 100644
index 0000000..f90f235
--- /dev/null
+++ b/src/Tizen.Multimedia.Util/ImageUtil/ImageTransformer.cs
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Diagnostics;
+using System.Threading.Tasks;
+using static Interop.ImageUtil;
+using static Interop.ImageUtil.Transform;
+
+namespace Tizen.Multimedia.Util
+{
+ /// <summary>
+ /// Provides the ability to transform an image.
+ /// </summary>
+ public class ImageTransformer : IDisposable
+ {
+ private TransformHandle _handle = null;
+
+ /// <summary>
+ /// Initialize a new instance of the <see cref="ImageTransformer"/> class.
+ /// </summary>
+ public ImageTransformer()
+ {
+ Create(out _handle).ThrowIfFailed("Failed to create ImageTransformer");
+
+ Debug.Assert(_handle != null);
+ }
+
+ /// <summary>
+ /// Transforms an image with <see cref="ImageTransform"/>.
+ /// </summary>
+ /// <param name="source"><see cref="MediaPacket"/> to transform. The <see cref="MediaPacket.Format"/> of this <paramref name="source"/> must be <see cref="VideoMediaFormat"/>.</param>
+ /// <param name="item"><see cref="ImageTransform"/> to apply.</param>
+ /// <returns>A task that represents the asynchronous transforming operation.</returns>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="source"/> is null.\n
+ /// - or -\n
+ /// <paramref name="item"/> is null.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">The <see cref="ImageTransformer"/> has already been disposed of.</exception>
+ /// <exception cref="InvalidOperationException">Failed to apply <see cref="ImageTransform"/>.</exception>
+ public Task<MediaPacket> TransformAsync(MediaPacket source, ImageTransform item)
+ {
+ if (_disposed)
+ {
+ throw new ObjectDisposedException(nameof(ImageTransformer));
+ }
+
+ if (source == null)
+ {
+ throw new ArgumentNullException(nameof(source));
+ }
+
+ if (item == null)
+ {
+ throw new ArgumentNullException(nameof(item));
+ }
+
+ return item.ApplyAsync(_handle, source);
+ }
+
+ #region IDisposable Support
+ private bool _disposed = false;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (_handle != null)
+ {
+ _handle.Dispose();
+ }
+
+ _disposed = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+ #endregion
+ }
+}
diff --git a/src/Tizen.Multimedia.Util/ImageUtil/ImageUtil.cs b/src/Tizen.Multimedia.Util/ImageUtil/ImageUtil.cs
new file mode 100644
index 0000000..e2db5b2
--- /dev/null
+++ b/src/Tizen.Multimedia.Util/ImageUtil/ImageUtil.cs
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using Tizen.Common;
+using static Interop.ImageUtil;
+
+namespace Tizen.Multimedia.Util
+{
+ /// <summary>
+ /// Provides utilities for images.
+ /// </summary>
+ public static class ImageUtil
+ {
+ /// <summary>
+ /// Retrieves supported colorspaces for a <see cref="ImageFormat"/> that represents formats for <see cref="ImageEncoder"/> and <see cref="ImageDecoder"/>.
+ /// </summary>
+ /// <param name="format"><see cref="ImageFormat"/>.</param>
+ /// <exception cref="ArgumentException"><paramref name="format"/> is invalid.</exception>
+ public static IEnumerable<ColorSpace> GetSupportedColorSpaces(ImageFormat format)
+ {
+ ValidationUtil.ValidateEnum(typeof(ImageFormat), format, nameof(format));
+
+ var colorspaces = new List<ColorSpace>();
+
+ ForeachSupportedColorspace(format,
+ (colorspace, _) => { colorspaces.Add(colorspace.ToCommonColorSpace()); return true; }).
+ ThrowIfFailed("Failed to get supported color-space list from native handle");
+
+ return colorspaces;
+ }
+
+ /// <summary>
+ /// Calculates the size of the image buffer for the specified resolution and color-space.
+ /// </summary>
+ /// <param name="size">Resolution of the image.</param>
+ /// <param name="colorSpace"><see cref="ColorSpace"/> of the image.</param>
+ /// <returns>Buffer size.</returns>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// width of <paramref name="resolution"/> is less than or equal to zero.\n
+ /// - or -\n
+ /// height of <paramref name="resolution"/> is less than or equal to zero.
+ /// </exception>
+ /// <exception cref="ArgumentException"><paramref name="colorSpace"/> is invalid.</exception>
+ public static int CalculateBufferSize(Size resolution, ColorSpace colorSpace)
+ {
+ if (resolution.Width <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(resolution), resolution.Width,
+ "width can't be less than or equal to zero.");
+ }
+ if (resolution.Height <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(resolution), resolution.Height,
+ "height can't be less than or equal to zero.");
+ }
+
+ ValidationUtil.ValidateEnum(typeof(ColorSpace), colorSpace, nameof(colorSpace));
+
+ uint bufferSize;
+ global::Interop.ImageUtil.CalculateBufferSize(resolution.Width, resolution.Height,
+ colorSpace.ToImageColorSpace(), out bufferSize)
+ .ThrowIfFailed("Failed to calculate buffer size for given parameter");
+
+ return (int)bufferSize;
+ }
+
+ /// <summary>
+ /// Extracts representative color from an image buffer.
+ /// </summary>
+ /// <param name="buffer">Raw image buffer.</param>
+ /// <param name="size">Resolution of the image.</param>
+ /// <remarks>The image should be <see cref="ColorSpace.Rgb888"/>.</remarks>
+ /// <returns>The representative color of the image.</returns>
+ /// <see cref="BitmapFrame"/>
+ /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception>
+ /// <exception cref="ArgumentException"><paramref name="buffer"/> is empty.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// width of <paramref name="size"/> is less than or equal to zero.\n
+ /// - or -\n
+ /// height of <paramref name="size"/> is less than or equal to zero.
+ /// </exception>
+ public static Color GetColor(byte[] buffer, Size size)
+ {
+ if (buffer == null)
+ {
+ throw new ArgumentNullException(nameof(buffer));
+ }
+
+ if (buffer.Length == 0)
+ {
+ throw new ArgumentException("buffer is empty.", nameof(buffer));
+ }
+
+ if (size.Width <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(size), size.Width,
+ "width can't be less than or equal to zero.");
+ }
+ if (size.Height <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(size), size.Height,
+ "height can't be less than or equal to zero.");
+ }
+
+
+ byte r, g, b;
+ ExtractColorFromMemory(buffer, size.Width, size.Height, out r, out g, out b)
+ .ThrowIfFailed("Failed to extract color from buffer");
+
+ return Color.FromRgb(r, g, b);
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Util/ImageUtil/ImageUtilError.cs b/src/Tizen.Multimedia.Util/ImageUtil/ImageUtilError.cs
new file mode 100644
index 0000000..efeec4b
--- /dev/null
+++ b/src/Tizen.Multimedia.Util/ImageUtil/ImageUtilError.cs
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Diagnostics;
+using System.IO;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Multimedia.Util
+{
+
+ internal enum ImageUtilError
+ {
+ None = ErrorCode.None,
+ OutOfMemory = ErrorCode.OutOfMemory,
+ InvalidParameter = ErrorCode.InvalidParameter,
+ InvalidOperation = ErrorCode.InvalidOperation,
+ PermissionDenied = ErrorCode.PermissionDenied,
+ NotSupported = ErrorCode.NotSupported,
+ NoSuchFile = ErrorCode.NoSuchFile,
+ NotSupportedFormat = -0x01920000 | 0x01,
+ }
+
+ internal static class ImageUtilErrorExtensions
+ {
+ internal static void ThrowIfFailed(this ImageUtilError err, string message)
+ {
+ if (err == ImageUtilError.None)
+ {
+ return;
+ }
+
+ throw err.ToException(message);
+ }
+
+ internal static Exception ToException(this ImageUtilError err, string message)
+ {
+ Debug.Assert(err != ImageUtilError.None);
+
+ string errMessage = $"{message}; {err}.";
+ switch (err)
+ {
+ case ImageUtilError.PermissionDenied:
+ return new UnauthorizedAccessException(errMessage);
+
+ case ImageUtilError.InvalidParameter:
+ return new ArgumentException(errMessage);
+
+ case ImageUtilError.NoSuchFile:
+ return new FileNotFoundException(errMessage);
+
+ case ImageUtilError.OutOfMemory:
+ return new OutOfMemoryException(errMessage);
+
+ case ImageUtilError.NotSupported:
+ return new NotSupportedException(errMessage);
+
+ case ImageUtilError.NotSupportedFormat:
+ return new FileFormatException(errMessage);
+
+ case ImageUtilError.InvalidOperation:
+ default:
+ return new InvalidOperationException(errMessage);
+ }
+ }
+ }
+
+}
diff --git a/src/Tizen.Multimedia.Util/ImageUtil/JpegDownscale.cs b/src/Tizen.Multimedia.Util/ImageUtil/JpegDownscale.cs
new file mode 100644
index 0000000..842eaf6
--- /dev/null
+++ b/src/Tizen.Multimedia.Util/ImageUtil/JpegDownscale.cs
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia.Util
+{
+ /// <summary>
+ /// Specifies JPEG Downscale options for decoding.
+ /// </summary>
+ public enum JpegDownscale
+ {
+ /// <summary>
+ /// No downscale.
+ /// </summary>
+ None,
+ /// <summary>
+ /// 1/2 downscale.
+ /// </summary>
+ OneHalf,
+ /// <summary>
+ /// 1/4 downscale.
+ /// </summary>
+ OneFourth,
+ /// <summary>
+ /// 1/8 downscale.
+ /// </summary>
+ OneEighth,
+ }
+}
diff --git a/src/Tizen.Multimedia.Util/ImageUtil/PngCompression.cs b/src/Tizen.Multimedia.Util/ImageUtil/PngCompression.cs
new file mode 100644
index 0000000..c2ea191
--- /dev/null
+++ b/src/Tizen.Multimedia.Util/ImageUtil/PngCompression.cs
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia.Util
+{
+ /// <summary>
+ /// Specifies PNG compression levels.
+ /// </summary>
+ public enum PngCompression
+ {
+ /// <summary>
+ /// No Compression.
+ /// </summary>
+ None,
+ /// <summary>
+ /// Compression Level 1. Best speed.
+ /// </summary>
+ Level1,
+ /// <summary>
+ /// Compression Level 2.
+ /// </summary>
+ Level2,
+ /// <summary>
+ /// Compression Level 3.
+ /// </summary>
+ Level3,
+ /// <summary>
+ /// Compression Level 4.
+ /// </summary>
+ Level4,
+ /// <summary>
+ /// Compression Level 5.
+ /// </summary>
+ Level5,
+ /// <summary>
+ /// Compression Level 6.
+ /// </summary>
+ Level6,
+ /// <summary>
+ /// Compression Level 7.
+ /// </summary>
+ Level7,
+ /// <summary>
+ /// Compression Level 8.
+ /// </summary>
+ Level8,
+ /// <summary>
+ /// Compression Level 9.
+ /// </summary>
+ Level9,
+ }
+}
diff --git a/src/Tizen.Multimedia.Util/Interop/Interop.ImageUtil.Decode.cs b/src/Tizen.Multimedia.Util/Interop/Interop.ImageUtil.Decode.cs
new file mode 100644
index 0000000..f7636c6
--- /dev/null
+++ b/src/Tizen.Multimedia.Util/Interop/Interop.ImageUtil.Decode.cs
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen;
+using Tizen.Multimedia.Util;
+
+internal static partial class Interop
+{
+ internal static class Decode
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void DecodeCompletedCallback(ImageUtilError error, IntPtr userData, int width, int height, ulong size);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_decode_create")]
+ public static extern ImageUtilError Create(out ImageDecoderHandle handle);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_decode_destroy")]
+ internal static extern ImageUtilError Destroy(IntPtr handle);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_decode_set_input_path")]
+ internal static extern ImageUtilError SetInputPath(ImageDecoderHandle handle, IntPtr path);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_decode_set_input_buffer")]
+ internal static extern ImageUtilError SetInputBuffer(ImageDecoderHandle handle, byte[] srcBuffer, ulong srcSize);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_decode_set_output_buffer")]
+ internal static extern ImageUtilError SetOutputBuffer(ImageDecoderHandle handle, out IntPtr dstBuffer);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_decode_set_colorspace")]
+ internal static extern ImageUtilError SetColorspace(ImageDecoderHandle handle, ImageColorSpace colorspace);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_decode_set_jpeg_downscale")]
+ internal static extern ImageUtilError SetJpegDownscale(ImageDecoderHandle handle, JpegDownscale downscale);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_decode_run_async")]
+ internal static extern ImageUtilError DecodeRunAsync(ImageDecoderHandle handle, DecodeCompletedCallback callback,
+ IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_decode_run")]
+ internal static extern ImageUtilError DecodeRun(ImageDecoderHandle handle, out int width,
+ out int height, out ulong size);
+ }
+
+ internal class ImageDecoderHandle : SafeHandle
+ {
+ protected ImageDecoderHandle() : base(IntPtr.Zero, true)
+ {
+ }
+
+ public override bool IsInvalid => handle == IntPtr.Zero;
+
+ protected override bool ReleaseHandle()
+ {
+ var ret = Decode.Destroy(handle);
+ if (ret != ImageUtilError.None)
+ {
+ Log.Debug(GetType().FullName, $"Failed to release native {GetType()}");
+ return false;
+ }
+
+ return true;
+ }
+
+ }
+}
diff --git a/src/Tizen.Multimedia.Util/Interop/Interop.ImageUtil.Encode.cs b/src/Tizen.Multimedia.Util/Interop/Interop.ImageUtil.Encode.cs
new file mode 100644
index 0000000..ada1c39
--- /dev/null
+++ b/src/Tizen.Multimedia.Util/Interop/Interop.ImageUtil.Encode.cs
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen;
+using Tizen.Multimedia.Util;
+
+internal static partial class Interop
+{
+ internal static partial class ImageUtil
+ {
+ internal static class Encode
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void EncodeCompletedCallback(ImageUtilError ImageUtilError, IntPtr userData, ulong size);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_run_async")]
+ internal static extern ImageUtilError EncodeRunAsync(ImageEncoderHandle handle,
+ EncodeCompletedCallback callback, IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_create")]
+ internal static extern ImageUtilError Create(ImageFormat type, out ImageEncoderHandle handle);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_destroy")]
+ internal static extern ImageUtilError Destroy(IntPtr handle);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_set_resolution")]
+ internal static extern ImageUtilError SetResolution(ImageEncoderHandle handle, uint width, uint height);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_set_colorspace")]
+ internal static extern ImageUtilError SetColorspace(ImageEncoderHandle handle, ImageColorSpace colorspace);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_set_quality")]
+ internal static extern ImageUtilError SetQuality(ImageEncoderHandle handle, int quality);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_set_png_compression")]
+ internal static extern ImageUtilError SetPngCompression(ImageEncoderHandle handle, PngCompression compression);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_set_gif_frame_delay_time")]
+ internal static extern ImageUtilError SetGifFrameDelayTime(ImageEncoderHandle handle, ulong delayTime);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_set_output_path")]
+ internal static extern ImageUtilError SetOutputPath(ImageEncoderHandle handle, string path);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_set_input_buffer")]
+ internal static extern ImageUtilError SetInputBuffer(ImageEncoderHandle handle, byte[] srcBuffer);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_set_output_buffer")]
+ internal static extern ImageUtilError SetOutputBuffer(ImageEncoderHandle handle, out IntPtr dstBuffer);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_run")]
+ internal static extern ImageUtilError Run(ImageEncoderHandle handle, out ulong size);
+ }
+
+ internal class ImageEncoderHandle : SafeHandle
+ {
+ protected ImageEncoderHandle() : base(IntPtr.Zero, true)
+ {
+ }
+
+ public override bool IsInvalid => handle == IntPtr.Zero;
+
+
+ protected override bool ReleaseHandle()
+ {
+ var ret = Encode.Destroy(handle);
+ if (ret != ImageUtilError.None)
+ {
+ Log.Debug(GetType().FullName, $"Failed to release native {GetType().Name}");
+ return false;
+ }
+
+ return true;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Util/Interop/Interop.ImageUtil.Transform.cs b/src/Tizen.Multimedia.Util/Interop/Interop.ImageUtil.Transform.cs
new file mode 100644
index 0000000..186b2c0
--- /dev/null
+++ b/src/Tizen.Multimedia.Util/Interop/Interop.ImageUtil.Transform.cs
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen;
+using Tizen.Multimedia.Util;
+
+internal static partial class Interop
+{
+ internal static partial class ImageUtil
+ {
+ internal static class Transform
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void TransformCompletedCallback(IntPtr resultPacket, ImageUtilError errorCode,
+ IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_run")]
+ internal static extern ImageUtilError Run(TransformHandle handle, IntPtr srcPacket,
+ TransformCompletedCallback callback, IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_create")]
+ internal static extern ImageUtilError Create(out TransformHandle handle);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_destroy")]
+ internal static extern ImageUtilError Destroy(IntPtr handle);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_get_colorspace")]
+ internal static extern ImageUtilError GetColorspace(TransformHandle handle, out ImageColorSpace colorspace);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_set_colorspace")]
+ internal static extern ImageUtilError SetColorspace(TransformHandle handle, ImageColorSpace colorspace);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_set_hardware_acceleration")]
+ internal static extern ImageUtilError SetHardwareAcceleration(TransformHandle handle, bool mode);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_get_rotation")]
+ internal static extern ImageUtilError GetRotation(TransformHandle handle, out ImageRotation rotation);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_set_rotation")]
+ internal static extern ImageUtilError SetRotation(TransformHandle handle, ImageRotation rotation);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_get_crop_area")]
+ internal static extern ImageUtilError GetCropArea(TransformHandle handle, out uint startX, out uint startY, out uint endX, out uint endY);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_set_crop_area")]
+ internal static extern ImageUtilError SetCropArea(TransformHandle handle, int startX, int startY, int endX, int endY);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_get_resolution")]
+ internal static extern ImageUtilError GetResolution(TransformHandle handle, out uint width, out uint height);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_set_resolution")]
+ internal static extern ImageUtilError SetResolution(TransformHandle handle, uint width, uint height);
+ }
+
+ internal class TransformHandle : SafeHandle
+ {
+ protected TransformHandle() : base(IntPtr.Zero, true)
+ {
+ }
+
+ public override bool IsInvalid => handle == IntPtr.Zero;
+
+ protected override bool ReleaseHandle()
+ {
+ var ret = Transform.Destroy(handle);
+ if (ret != ImageUtilError.None)
+ {
+ Log.Debug(GetType().FullName, $"Failed to release native {GetType().Name}");
+ return false;
+ }
+
+ return true;
+ }
+ }
+ }
+
+}
diff --git a/src/Tizen.Multimedia.Util/Interop/Interop.ImageUtil.cs b/src/Tizen.Multimedia.Util/Interop/Interop.ImageUtil.cs
new file mode 100644
index 0000000..728f4c0
--- /dev/null
+++ b/src/Tizen.Multimedia.Util/Interop/Interop.ImageUtil.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Multimedia.Util;
+
+internal static partial class Interop
+{
+ internal static partial class ImageUtil
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool SupportedColorspaceCallback(ImageColorSpace colorspace, IntPtr userData);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_foreach_supported_colorspace")]
+ internal static extern ImageUtilError ForeachSupportedColorspace(ImageFormat type, SupportedColorspaceCallback callback,
+ IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_calculate_buffer_size")]
+ internal static extern ImageUtilError CalculateBufferSize(int width, int height, ImageColorSpace colorspace, out uint size);
+
+ [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_extract_color_from_memory")]
+ internal static extern ImageUtilError ExtractColorFromMemory(byte[] buffer, int width, int height, out byte rgbR, out byte rgbG, out byte rgbB);
+ }
+}
diff --git a/src/Tizen.Multimedia.Util/Interop/Interop.Libraries.cs b/src/Tizen.Multimedia.Util/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..3b5ae55
--- /dev/null
+++ b/src/Tizen.Multimedia.Util/Interop/Interop.Libraries.cs
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string ImageUtil = "libcapi-media-image-util.so.0";
+ public const string ThumbnailExtractor = "libcapi-media-thumbnail-util.so";
+ }
+}
diff --git a/src/Tizen.Multimedia.Util/Interop/Interop.ThumbnailExtractor.cs b/src/Tizen.Multimedia.Util/Interop/Interop.ThumbnailExtractor.cs
new file mode 100644
index 0000000..b7ae4b0
--- /dev/null
+++ b/src/Tizen.Multimedia.Util/Interop/Interop.ThumbnailExtractor.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Multimedia;
+
+internal static partial class Interop
+{
+ internal static partial class ThumbnailExtractor
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate void ThumbnailExtractCallback(ThumbnailExtractorError error, string requestId, int thumbWidth, int thumbHeight, IntPtr thumbData, int thumbSize, IntPtr userData);
+
+ [DllImport(Libraries.ThumbnailExtractor, EntryPoint = "thumbnail_util_create")]
+ internal static extern ThumbnailExtractorError Create(out IntPtr handle);
+
+ [DllImport(Libraries.ThumbnailExtractor, EntryPoint = "thumbnail_util_extract")]
+ internal static extern ThumbnailExtractorError Extract(IntPtr handle, ThumbnailExtractCallback callback, IntPtr userData, out IntPtr requestId);
+
+ [DllImport(Libraries.ThumbnailExtractor, EntryPoint = "thumbnail_util_set_path")]
+ internal static extern ThumbnailExtractorError SetPath(IntPtr handle, string path);
+
+ [DllImport(Libraries.ThumbnailExtractor, EntryPoint = "thumbnail_util_set_size")]
+ internal static extern ThumbnailExtractorError SetSize(IntPtr handle, int width, int height);
+
+ [DllImport(Libraries.ThumbnailExtractor, EntryPoint = "thumbnail_util_destroy")]
+ internal static extern ThumbnailExtractorError Destroy(IntPtr handle);
+ }
+}
diff --git a/src/Tizen.Multimedia.Util/ThumbnailExtractor/ThumbnailData.cs b/src/Tizen.Multimedia.Util/ThumbnailExtractor/ThumbnailData.cs
new file mode 100755
index 0000000..3e2018a
--- /dev/null
+++ b/src/Tizen.Multimedia.Util/ThumbnailExtractor/ThumbnailData.cs
@@ -0,0 +1,49 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// This class provides properties of the thumbnail of the given media
+ /// </summary>
+ public class ThumbnailData
+ {
+ internal ThumbnailData(byte[] thumbnailData, int width, int height)
+ {
+ Thumbnail = thumbnailData;
+ Width = width;
+ Height = height;
+ }
+ /// <summary>
+ /// The thumbnail data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public byte[] Thumbnail { get; }
+
+ /// <summary>
+ /// The width of the thumbnail.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Width { get; }
+
+ /// <summary>
+ /// The height of the thumbnail.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Height { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia.Util/ThumbnailExtractor/ThumbnailExtractor.cs b/src/Tizen.Multimedia.Util/ThumbnailExtractor/ThumbnailExtractor.cs
new file mode 100755
index 0000000..6666c2d
--- /dev/null
+++ b/src/Tizen.Multimedia.Util/ThumbnailExtractor/ThumbnailExtractor.cs
@@ -0,0 +1,245 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Threading.Tasks;
+using System.Runtime.InteropServices;
+using Native = Interop.ThumbnailExtractor;
+
+namespace Tizen.Multimedia
+{
+ static internal class ThumbnailExtractorLog
+ {
+ internal const string LogTag = "Tizen.Multimedia.ThumbnailExtractor";
+ }
+
+ /// <summary>
+ /// The Thumbnail extractor class provides a set of functions to extract the thumbnail data of the input media file
+ /// </summary>
+ public class ThumbnailExtractor : IDisposable
+ {
+ private bool _disposed = false;
+ internal IntPtr _handle = IntPtr.Zero;
+
+ /// <summary>
+ /// Thumbnail extractor constructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// If you need the thumbnail of the specified size, use ThumbnailExtractor(path, width, height) or ThumbnailExtractor(path, size).
+ /// </remarks>
+ /// <param name="path"> The path of the media file to extract the thumbnail </param>
+ /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
+ public ThumbnailExtractor(string path)
+ {
+ if (path == null)
+ {
+ throw new ArgumentNullException(nameof(path));
+ }
+
+ ThumbnailExtractorError ret = Native.Create(out _handle);
+ ThumbnailExtractorErrorFactory.ThrowIfError(ret, "Failed to create constructor");
+
+ try
+ {
+ ThumbnailExtractorErrorFactory.ThrowIfError(
+ Native.SetPath(_handle, path), "Failed to set the path");
+ }
+ catch (Exception)
+ {
+ Native.Destroy(_handle);
+ _handle = IntPtr.Zero;
+ throw;
+ }
+ }
+
+ private void Create(String path, int width, int height)
+ {
+ if (path == null)
+ {
+ throw new ArgumentNullException(nameof(path));
+ }
+
+ if (width <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(width), "The width must be greater than zero:[" + width + "]");
+ }
+
+ if (height <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(height), "The height must be greater than zero:[" + height + "]");
+ }
+
+ ThumbnailExtractorError ret = Native.Create(out _handle);
+ ThumbnailExtractorErrorFactory.ThrowIfError(ret, "Failed to create constructor");
+
+ try
+ {
+ ThumbnailExtractorErrorFactory.ThrowIfError(
+ Native.SetPath(_handle, path), "Failed to set the path");
+
+ ThumbnailExtractorErrorFactory.ThrowIfError(
+ Native.SetSize(_handle, width, height), "Failed to set the size");
+ }
+ catch (Exception)
+ {
+ Native.Destroy(_handle);
+ _handle = IntPtr.Zero;
+ throw;
+ }
+ }
+
+ /// <summary>
+ /// Thumbnail extractor constructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// If you need the thumbnail of the default size, use ThumbnailExtractor(path). The default size is 320x240. \n
+ /// If the set width is not a multiple of 8, it can be changed by inner process. \n
+ /// The width will be a multiple of 8 greater than the set value.
+ /// </remarks>
+ /// <param name="path"> The path of the media file to extract the thumbnail </param>
+ /// <param name="width"> The width of the thumbnail </param>
+ /// <param name="height"> The height of the thumbnail </param>
+ /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="width"/> or <paramref name="height"/> is less than zero.
+ /// </exception>
+ public ThumbnailExtractor(string path, int width, int height)
+ {
+ Create(path, width, height);
+ }
+
+ /// <summary>
+ /// Thumbnail extractor constructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// If you need the thumbnail of the default size, use ThumbnailExtractor(path). The default size is 320x240. \n
+ /// If the set width is not a multiple of 8, it can be changed by inner process. \n
+ /// The width will be a multiple of 8 greater than the set value.
+ /// </remarks>
+ /// <param name="path"> The path of the media file to extract the thumbnail </param>
+ /// <param name="size"> The size to extract the thumbnail </param>
+ /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// A value of <paramref name="size"/> is less than zero.
+ /// </exception>
+ public ThumbnailExtractor(string path, Size size)
+ {
+ Create(path, size.Width, size.Height);
+ }
+
+ /// <summary>
+ /// Extracts the thumbnail for the given media, asynchronously
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// Task for creation of Thumbnail. See <see cref="ThumbnailData"/> details.
+ /// </returns>
+ /// <exception cref="ArgumentException">Requested <paramref name="path"/> does not exist.</exception>
+ /// <exception cref="OutOfMemoryException">Memory allocation failed.</exception>
+ /// <exception cref="InvalidOperationException">Internal processing failed.</exception>
+ /// <exception cref="UnauthorizedAccessException">Inaccessible for the requested <paramref name="path"/>.</exception>
+ public Task<ThumbnailData> Extract()
+ {
+ if (_handle == IntPtr.Zero)
+ {
+ throw new ObjectDisposedException(nameof(ThumbnailExtractor), "Failed to extract thumbnail");
+ }
+
+ var task = new TaskCompletionSource<ThumbnailData>();
+
+ Native.ThumbnailExtractCallback extractCallback = (ThumbnailExtractorError error,
+ string requestId,
+ int thumbWidth,
+ int thumbHeight,
+ IntPtr thumbData,
+ int thumbSize,
+ IntPtr userData) =>
+ {
+ if (error == ThumbnailExtractorError.None)
+ {
+ try
+ {
+ byte[] tmpBuf = new byte[thumbSize];
+ Marshal.Copy(thumbData, tmpBuf, 0, thumbSize);
+
+ task.SetResult(new ThumbnailData(tmpBuf, thumbWidth, thumbHeight));
+ }
+ catch (Exception)
+ {
+ task.SetException(new InvalidOperationException("[" + error + "] Fail to copy data"));
+ }
+ finally
+ {
+ LibcSupport.Free(thumbData);
+ }
+ }
+ else
+ {
+ task.SetException(new InvalidOperationException("[" + error + "] Fail to create thumbnail"));
+ }
+ };
+
+ IntPtr id = IntPtr.Zero;
+ ThumbnailExtractorError res = Native.Extract(_handle, extractCallback, IntPtr.Zero, out id);
+ if (id != IntPtr.Zero)
+ {
+ LibcSupport.Free(id);
+ id = IntPtr.Zero;
+ }
+
+ ThumbnailExtractorErrorFactory.ThrowIfError(res, "Failed to extract thumbnail");
+
+ return task.Task;
+ }
+
+ /// <summary>
+ /// Thumbnail Utility destructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ ~ThumbnailExtractor()
+ {
+ Dispose(false);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (disposing)
+ {
+ // To be used if there are any other disposable objects
+ }
+
+ if (_handle != IntPtr.Zero)
+ {
+ Native.Destroy(_handle);
+ _handle = IntPtr.Zero;
+ }
+
+ _disposed = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Util/ThumbnailExtractor/ThumbnailExtractorErrorFactory.cs b/src/Tizen.Multimedia.Util/ThumbnailExtractor/ThumbnailExtractorErrorFactory.cs
new file mode 100644
index 0000000..7b4e429
--- /dev/null
+++ b/src/Tizen.Multimedia.Util/ThumbnailExtractor/ThumbnailExtractorErrorFactory.cs
@@ -0,0 +1,63 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+using System;
+using System.IO;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Enumeration for thumbnail extractor's error codes.
+ /// </summary>
+ internal enum ThumbnailExtractorError
+ {
+ None = ErrorCode.None, // Success
+ InvalidParameter = ErrorCode.InvalidParameter, // Invalid parameter
+ OutOfMemory = ErrorCode.OutOfMemory, // Out of memory
+ InvalidOperation = ErrorCode.InvalidOperation, // Invalid operation
+ FileNoSpaceOnDevice = ErrorCode.FileNoSpaceOnDevice, // No space left on device
+ PermissionDenied = ErrorCode.PermissionDenied, // Permission deny
+ TizenThumbnailUtilError = -0x02F90000,
+ UnsupportedContent = TizenThumbnailUtilError | 0x01, // Unsupported content
+ };
+
+ internal static class ThumbnailExtractorErrorFactory
+ {
+ internal static void ThrowIfError(ThumbnailExtractorError errorCode, string errorMessage)
+ {
+ switch (errorCode)
+ {
+ case ThumbnailExtractorError.InvalidParameter:
+ throw new ArgumentException("[" + errorCode.ToString() + "]" + errorMessage);
+
+ case ThumbnailExtractorError.OutOfMemory:
+ throw new OutOfMemoryException("[" + errorCode.ToString() + "]" + errorMessage);
+
+ case ThumbnailExtractorError.InvalidOperation:
+ throw new InvalidOperationException("[" + errorCode.ToString() + "]" + errorMessage);
+
+ case ThumbnailExtractorError.FileNoSpaceOnDevice:
+ throw new IOException("[" + errorCode.ToString() + "] No space to write on the device");
+
+ case ThumbnailExtractorError.PermissionDenied:
+ throw new UnauthorizedAccessException("[" + errorCode.ToString() + "]" + errorMessage);
+ }
+ }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Util/Tizen.Multimedia.Util.csproj b/src/Tizen.Multimedia.Util/Tizen.Multimedia.Util.csproj
new file mode 100644
index 0000000..0e5378c
--- /dev/null
+++ b/src/Tizen.Multimedia.Util/Tizen.Multimedia.Util.csproj
@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen.Multimedia\Tizen.Multimedia.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Multimedia.Vision/Interop/Interop.Libraries.cs b/src/Tizen.Multimedia.Vision/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..c48de1c
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/Interop/Interop.Libraries.cs
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string MediaVision = "libcapi-media-vision.so.0";
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/Interop/Interop.MediaVision.BarCode.cs b/src/Tizen.Multimedia.Vision/Interop/Interop.MediaVision.BarCode.cs
new file mode 100644
index 0000000..03a0013
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/Interop/Interop.MediaVision.BarCode.cs
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Multimedia;
+
+/// <summary>
+/// Interop APIs
+/// </summary>
+internal static partial class Interop
+{
+ /// <summary>
+ /// Interop for media vision APIs
+ /// </summary>
+ internal static partial class MediaVision
+ {
+ /// <summary>
+ /// Interop for barcode detector APIs
+ /// </summary>
+ internal static partial class BarcodeDetector
+ {
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_barcode_detect")]
+ internal static extern MediaVisionError Detect(IntPtr source, IntPtr engineCfg, Rectangle roi,
+ DetectedCallback detectCb, IntPtr userData = default(IntPtr));
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void DetectedCallback(
+ IntPtr source,
+ IntPtr engineCfg,
+ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 5)]
+ Quadrangle[] locations,
+ [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr, SizeParamIndex = 5)]
+ string[] messages,
+ BarcodeType[] types,
+ int numberOfBarcodes,
+ IntPtr userData);
+ }
+
+ /// <summary>
+ /// Interop for barcode generator APIs
+ /// </summary>
+ internal static partial class BarcodeGenerator
+ {
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_barcode_generate_source")]
+ internal static extern MediaVisionError GenerateSource(IntPtr engineCfg, string message,
+ BarcodeType type, int qrEncMode, int qrEcc, int qrVersion, IntPtr source);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_barcode_generate_image")]
+ internal static extern MediaVisionError GenerateImage(IntPtr engineCfg,
+ string message, int imageWidth, int imageHeight, BarcodeType type,
+ int qrEncMode, int qrEcc, int qrVersion, string imagePath, BarcodeImageFormat imageFormat);
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/Interop/Interop.MediaVision.Common.cs b/src/Tizen.Multimedia.Vision/Interop/Interop.MediaVision.Common.cs
new file mode 100644
index 0000000..771749f
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/Interop/Interop.MediaVision.Common.cs
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Multimedia;
+
+/// <summary>
+/// Interop APIs
+/// </summary>
+internal static partial class Interop
+{
+ internal static Tizen.Multimedia.Point ToApiStruct(this MediaVision.Point pt)
+ {
+ return new Tizen.Multimedia.Point(pt.x, pt.y);
+ }
+
+ internal static MediaVision.Point ToMarshalable(this Tizen.Multimedia.Point pt)
+ {
+ return new MediaVision.Point() { x = pt.X, y = pt.Y };
+ }
+
+ internal static MediaVision.Point[] ToMarshalable(Tizen.Multimedia.Point[] pts)
+ {
+ var result = new MediaVision.Point[pts.Length];
+ for (int i = 0; i < pts.Length; ++i)
+ {
+ result[i] = pts[i].ToMarshalable();
+ }
+ return result;
+ }
+
+
+ internal static Tizen.Multimedia.Quadrangle ToApiStruct(this MediaVision.Quadrangle quadrangle)
+ {
+ Tizen.Multimedia.Point[] points = new Tizen.Multimedia.Point[4];
+ for (int i = 0; i < 4; ++i)
+ {
+ points[i] = quadrangle.points[i].ToApiStruct();
+ }
+ return new Tizen.Multimedia.Quadrangle(points);
+ }
+
+ internal static MediaVision.Quadrangle ToMarshalable(this Tizen.Multimedia.Quadrangle quadrangle)
+ {
+ MediaVision.Point[] points = new MediaVision.Point[4];
+ for (int i = 0; i < 4; ++i)
+ {
+ points[i] = quadrangle.Points[i].ToMarshalable();
+ }
+ return new MediaVision.Quadrangle() { points = points };
+ }
+
+ internal static Tizen.Multimedia.Rectangle ToApiStruct(this MediaVision.Rectangle rectangle)
+ {
+ return new Tizen.Multimedia.Rectangle(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
+ }
+
+ internal static MediaVision.Rectangle ToMarshalable(this Tizen.Multimedia.Rectangle rectangle)
+ {
+ return new MediaVision.Rectangle()
+ {
+ x = rectangle.X,
+ y = rectangle.Y,
+ width = rectangle.Width,
+ height = rectangle.Height
+ };
+ }
+
+ internal static Tizen.Multimedia.Rectangle[] ToApiStruct(MediaVision.Rectangle[] rects)
+ {
+ var result = new Tizen.Multimedia.Rectangle[rects.Length];
+
+ for (int i = 0; i < rects.Length; i++)
+ {
+ result[i] = rects[i].ToApiStruct();
+ }
+ return result;
+ }
+
+ /// <summary>
+ /// Interop for media vision APIs
+ /// </summary>
+ internal static partial class MediaVision
+ {
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct Point
+ {
+ internal int x;
+ internal int y;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct Rectangle
+ {
+ internal int x;
+ internal int y;
+ internal int width;
+ internal int height;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct Quadrangle
+ {
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
+ internal Point[] points;
+ }
+
+ /// <summary>
+ /// Interop for media vision source APIs
+ /// </summary>
+ internal static partial class MediaSource
+ {
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_create_source")]
+ internal static extern MediaVisionError Create(out IntPtr source);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_destroy_source")]
+ internal static extern int Destroy(IntPtr /* mv_source_h */ source);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_source_fill_by_media_packet")]
+ internal static extern MediaVisionError FillMediaPacket(IntPtr source, IntPtr mediaPacket);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_source_fill_by_buffer")]
+ internal static extern MediaVisionError FillBuffer(IntPtr source, byte[] buffer,
+ int bufferSize, uint imageWidth, uint imageHeight, Colorspace colorspace);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_source_clear")]
+ internal static extern int Clear(IntPtr /* mv_source_h */ source);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_source_get_buffer")]
+ internal static extern MediaVisionError GetBuffer(IntPtr source, out IntPtr buffer, out int bufferSize);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_source_get_height")]
+ internal static extern int GetHeight(IntPtr source, out uint imageHeight);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_source_get_width")]
+ internal static extern int GetWidth(IntPtr source, out uint imageWidth);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_source_get_colorspace")]
+ internal static extern int GetColorspace(IntPtr /* mv_source_h */ source, out Tizen.Multimedia.Colorspace colorspace);
+ }
+
+ /// <summary>
+ /// Interop for engine configuration APIs
+ /// </summary>
+ internal static partial class EngineConfig
+ {
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_create_engine_config")]
+ internal static extern MediaVisionError Create(out IntPtr handle);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_destroy_engine_config")]
+ internal static extern int Destroy(IntPtr handle);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_engine_config_set_double_attribute")]
+ internal static extern Tizen.Multimedia.MediaVisionError SetDouble(IntPtr handle, string name, double value);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_engine_config_set_int_attribute")]
+ internal static extern Tizen.Multimedia.MediaVisionError SetInt(IntPtr handle, string name, int value);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_engine_config_set_bool_attribute")]
+ internal static extern Tizen.Multimedia.MediaVisionError SetBool(IntPtr handle, string name, bool value);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_engine_config_set_string_attribute")]
+ internal static extern Tizen.Multimedia.MediaVisionError SetString(IntPtr handle, string name, string value);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_engine_config_get_double_attribute")]
+ internal static extern Tizen.Multimedia.MediaVisionError GetDouble(IntPtr handle, string name, out double value);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_engine_config_get_int_attribute")]
+ internal static extern Tizen.Multimedia.MediaVisionError GetInt(IntPtr handle, string name, out int value);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_engine_config_get_bool_attribute")]
+ internal static extern Tizen.Multimedia.MediaVisionError GetBool(IntPtr handle, string name, out bool value);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_engine_config_get_string_attribute")]
+ internal static extern Tizen.Multimedia.MediaVisionError GetString(IntPtr handle, string name, out IntPtr value);
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/Interop/Interop.MediaVision.Face.cs b/src/Tizen.Multimedia.Vision/Interop/Interop.MediaVision.Face.cs
new file mode 100644
index 0000000..224caa8
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/Interop/Interop.MediaVision.Face.cs
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Multimedia;
+
+/// <summary>
+/// Interop APIs
+/// </summary>
+internal static partial class Interop
+{
+ /// <summary>
+ /// Interop for media vision APIs
+ /// </summary>
+ internal static partial class MediaVision
+ {
+ /// <summary>
+ /// Interop for Face APIs
+ /// </summary>
+ internal static partial class Face
+ {
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_face_detect")]
+ internal static extern MediaVisionError Detect(IntPtr source, IntPtr engineCfg,
+ DetectedCallback detectedCb, IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_face_recognize")]
+ internal static extern MediaVisionError Recognize(IntPtr source, IntPtr recognitionModel, IntPtr engineCfg,
+ IntPtr faceLocation, RecognizedCallback recognizedCb, IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_face_recognize")]
+ internal static extern MediaVisionError Recognize(IntPtr source, IntPtr recognitionModel, IntPtr engineCfg,
+ ref Rectangle faceLocation, RecognizedCallback recognizedCb, IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_face_track")]
+ internal static extern MediaVisionError Track(IntPtr source, IntPtr trackingModel, IntPtr engineCfg,
+ TrackedCallback trackedCb, bool doLearn, IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_face_eye_condition_recognize")]
+ internal static extern MediaVisionError RecognizeEyeCondition(IntPtr source, IntPtr engineCfg,
+ Rectangle faceLocation, EyeConditionRecognizedCallback eyeConditionRecognizedCb, IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_face_facial_expression_recognize")]
+ internal static extern MediaVisionError RecognizeFacialExpression(IntPtr source, IntPtr engineCfg,
+ Rectangle faceLocation, MvFaceFacialExpressionRecognizedCallback expressionRecognizedCb,
+ IntPtr userData = default(IntPtr));
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void DetectedCallback(IntPtr source, IntPtr engineCfg,
+ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] Rectangle[] facesLocations,
+ int numberOfFaces, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void RecognizedCallback(IntPtr source, IntPtr recognitionModel,
+ IntPtr engineCfg, IntPtr faceLocation, IntPtr faceLabel, double confidence, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void TrackedCallback(IntPtr source, IntPtr trackingModel, IntPtr engineCfg,
+ IntPtr location, double confidence, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void EyeConditionRecognizedCallback(IntPtr source, IntPtr engineCfg,
+ Rectangle faceLocation, EyeCondition eyeCondition, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MvFaceFacialExpressionRecognizedCallback(IntPtr source,
+ IntPtr engineCfg, Rectangle faceLocation, FacialExpression facialExpression, IntPtr userData);
+ }
+
+ /// <summary>
+ /// Interop for FaceRecognitionModel APIs
+ /// </summary>
+ internal static partial class FaceRecognitionModel
+ {
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_face_recognition_model_create")]
+ internal static extern MediaVisionError Create(out IntPtr handle);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_face_recognition_model_destroy")]
+ internal static extern int Destroy(IntPtr handle);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_face_recognition_model_clone")]
+ internal static extern int Clone(IntPtr src, out IntPtr dst);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_face_recognition_model_save")]
+ internal static extern MediaVisionError Save(string fileName, IntPtr handle);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_face_recognition_model_load")]
+ internal static extern MediaVisionError Load(string fileName, out IntPtr handle);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_face_recognition_model_add")]
+ internal static extern MediaVisionError Add(IntPtr source, IntPtr recognitionModel,
+ ref Rectangle exampleLocation, int faceLabel);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_face_recognition_model_add")]
+ internal static extern MediaVisionError Add(IntPtr source, IntPtr recognitionModel,
+ IntPtr exampleLocation, int faceLabel);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_face_recognition_model_reset")]
+ internal static extern MediaVisionError Reset(IntPtr recognitionModel, IntPtr faceLabel = default(IntPtr));
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_face_recognition_model_reset")]
+ internal static extern MediaVisionError Remove(IntPtr recognitionModel, ref int faceLabel);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_face_recognition_model_learn")]
+ internal static extern MediaVisionError Learn(IntPtr engineCfg, IntPtr handle);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_face_recognition_model_query_labels")]
+ internal static extern MediaVisionError QueryLabels(IntPtr handle, out IntPtr labels, out uint numberOfLabels);
+ }
+
+ /// <summary>
+ /// Interop for FaceTrackingModel APIs
+ /// </summary>
+ internal static partial class FaceTrackingModel
+ {
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_face_tracking_model_create")]
+ internal static extern MediaVisionError Create(out IntPtr handle);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_face_tracking_model_destroy")]
+ internal static extern int Destroy(IntPtr handle);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_face_tracking_model_prepare")]
+ internal static extern MediaVisionError Prepare(IntPtr trackingModel, IntPtr engineCfg,
+ IntPtr source, ref Quadrangle location);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_face_tracking_model_prepare")]
+ internal static extern MediaVisionError Prepare(IntPtr trackingModel, IntPtr engineCfg,
+ IntPtr source, IntPtr location);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_face_tracking_model_clone")]
+ internal static extern int Clone(IntPtr src, out IntPtr dst);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_face_tracking_model_save")]
+ internal static extern MediaVisionError Save(string fileName, IntPtr handle);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_face_tracking_model_load")]
+ internal static extern MediaVisionError Load(string fileName, out IntPtr handle);
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/Interop/Interop.MediaVision.Image.cs b/src/Tizen.Multimedia.Vision/Interop/Interop.MediaVision.Image.cs
new file mode 100644
index 0000000..215331b
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/Interop/Interop.MediaVision.Image.cs
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Multimedia;
+
+/// <summary>
+/// Interop APIs
+/// </summary>
+internal static partial class Interop
+{
+ /// <summary>
+ /// Interop for Media vision APIs
+ /// </summary>
+ internal static partial class MediaVision
+ {
+ /// <summary>
+ /// Interop for Image APIs
+ /// </summary>
+ internal static partial class Image
+ {
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_image_recognize")]
+ internal static extern MediaVisionError Recognize(IntPtr source, IntPtr[] imageObjects,
+ int numberOfObjects, IntPtr engineCfg, RecognizedCallback recognizedCb, IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_image_track")]
+ internal static extern MediaVisionError Track(IntPtr source, IntPtr imageTrackingModel,
+ IntPtr engineCfg, TrackedCallback trackedCb, IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_image_object_create")]
+ internal static extern MediaVisionError Create(out IntPtr handle);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_image_object_destroy")]
+ internal static extern int Destroy(IntPtr handle);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_image_object_fill")]
+ internal static extern MediaVisionError Fill(IntPtr handle, IntPtr engineCfg, IntPtr source, ref Rectangle location);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_image_object_fill")]
+ internal static extern MediaVisionError Fill(IntPtr handle, IntPtr engineCfg, IntPtr source, IntPtr location);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_image_object_get_recognition_rate")]
+ internal static extern MediaVisionError GetRecognitionRate(IntPtr handle, out double recognitionRate);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_image_object_set_label")]
+ internal static extern MediaVisionError SetLabel(IntPtr handle, int label);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_image_object_get_label")]
+ internal static extern MediaVisionError GetLabel(IntPtr handle, out int label);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_image_object_clone")]
+ internal static extern int Clone(IntPtr src, out IntPtr dst);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_image_object_save")]
+ internal static extern MediaVisionError Save(string fileName, IntPtr handle);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_image_object_load")]
+ internal static extern MediaVisionError Load(string fileName, out IntPtr handle);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void RecognizedCallback(IntPtr source, IntPtr engineCfg, IntPtr imageObjects,
+ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)]
+ IntPtr[] locations, uint numberOfObjects, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void TrackedCallback(IntPtr source, IntPtr imageTrackingModel,
+ IntPtr engineCfg, IntPtr location, IntPtr userData);
+ }
+
+ /// <summary>
+ /// Interop for ImageTrackingModel APIs
+ /// </summary>
+ internal static partial class ImageTrackingModel
+ {
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_image_tracking_model_create")]
+ internal static extern MediaVisionError Create(out IntPtr imageTrackingModel);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_image_tracking_model_set_target")]
+ internal static extern MediaVisionError SetTarget(IntPtr handle, IntPtr imageTrackingModel);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_image_tracking_model_destroy")]
+ internal static extern int Destroy(IntPtr imageTrackingModel);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_image_tracking_model_refresh")]
+ internal static extern MediaVisionError Refresh(IntPtr imageTrackingModel, IntPtr engineCfg);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_image_tracking_model_clone")]
+ internal static extern int Clone(IntPtr src, out IntPtr dest);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_image_tracking_model_save")]
+ internal static extern MediaVisionError Save(string fileName, IntPtr imageTrackingModel);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_image_tracking_model_load")]
+ internal static extern MediaVisionError Load(string fileName, out IntPtr imageTrackingModel);
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/Interop/Interop.MediaVision.Surveillance.cs b/src/Tizen.Multimedia.Vision/Interop/Interop.MediaVision.Surveillance.cs
new file mode 100644
index 0000000..5119730
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/Interop/Interop.MediaVision.Surveillance.cs
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Multimedia;
+
+/// <summary>
+/// Interop APIs
+/// </summary>
+internal static partial class Interop
+{
+ /// <summary>
+ /// Interop for media vision APIs
+ /// </summary>
+ internal static partial class MediaVision
+ {
+ /// <summary>
+ /// Interop for surveillance APIs
+ /// </summary>
+ internal static partial class Surveillance
+ {
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_surveillance_event_trigger_create")]
+ internal static extern MediaVisionError EventTriggerCreate(string eventType, out IntPtr trigger);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_surveillance_event_trigger_destroy")]
+ internal static extern int EventTriggerDestroy(IntPtr trigger);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_surveillance_get_event_trigger_type")]
+ internal static extern int GetEventTriggerType(IntPtr trigger, out string eventType);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_surveillance_set_event_trigger_roi")]
+ internal static extern MediaVisionError SetEventTriggerRoi(IntPtr trigger, int numberOfPoints, Point[] roi);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_surveillance_get_event_trigger_roi")]
+ internal static extern MediaVisionError GetEventTriggerRoi(IntPtr trigger, out int numberOfPoints, out IntPtr roi);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_surveillance_subscribe_event_trigger")]
+ internal static extern MediaVisionError SubscribeEventTrigger(IntPtr trigger, int videoStreamId,
+ IntPtr engineCfg, EventOccurredCallback callback, IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_surveillance_unsubscribe_event_trigger")]
+ internal static extern MediaVisionError UnsubscribeEventTrigger(IntPtr trigger, int videoStreamId);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_surveillance_push_source")]
+ internal static extern MediaVisionError PushSource(IntPtr source, int videoStreamId);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_surveillance_foreach_supported_event_type")]
+ internal static extern int ForeachSupportedEventType(EventTypeCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_surveillance_foreach_event_result_name")]
+ internal static extern int ForeachEventResultName(string eventType, EventResultNameCallback callback,
+ IntPtr userData);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_surveillance_get_result_value")]
+ internal static extern MediaVisionError GetResultValue(IntPtr result, string name, out int value);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_surveillance_get_result_value")]
+ internal static extern MediaVisionError GetResultValue(IntPtr result, string name, [Out] int[] value);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_surveillance_get_result_value")]
+ internal static extern MediaVisionError GetResultValue(IntPtr result, string name, [Out] double[] value);
+
+ [DllImport(Libraries.MediaVision, EntryPoint = "mv_surveillance_get_result_value")]
+ internal static extern MediaVisionError GetResultValue(IntPtr result, string name, [Out] Rectangle[] value);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void EventOccurredCallback(IntPtr trigger, IntPtr source,
+ int videoStreamId, IntPtr eventResult, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool EventTypeCallback(string eventType, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool EventResultNameCallback(string name, IntPtr userData);
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/Barcode.cs b/src/Tizen.Multimedia.Vision/MediaVision/Barcode.cs
new file mode 100755
index 0000000..6a44d7d
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/Barcode.cs
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents a detected barcode.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public class Barcode
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Barcode"/> class.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public Barcode(Quadrangle region, string message, BarcodeType type)
+ {
+ Region = region;
+ Message = message;
+ Type = type;
+ }
+
+ /// <summary>
+ /// The quadrangle location of detected barcode.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public Quadrangle Region { get; }
+
+ /// <summary>
+ /// The decoded message of barcode.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public string Message { get; }
+
+ /// <summary>
+ /// The type of detected barcode.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public BarcodeType Type { get; }
+
+ public override string ToString() =>
+ $"Region={Region}, Message={Message}, Type={Type.ToString()}";
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/BarcodeDetectionConfiguration.cs b/src/Tizen.Multimedia.Vision/MediaVision/BarcodeDetectionConfiguration.cs
new file mode 100755
index 0000000..1da6986
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/BarcodeDetectionConfiguration.cs
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents a configuration of <see cref="BarcodeDetector"/>.
+ /// </summary>
+ /// <seealso cref="BarcodeDetector"/>
+ /// <since_tizen> 3</since_tizen>
+ public class BarcodeDetectionConfiguration : EngineConfiguration
+ {
+ private const string KeyAttrTarget = "MV_BARCODE_DETECT_ATTR_TARGET";
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="BarcodeDetectionConfiguration"/> class.
+ /// </summary>
+ /// <exception cref="System.NotSupportedException">The feature is not supported.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public BarcodeDetectionConfiguration() : base("barcode_detection")
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the target of the barcode detection.
+ /// </summary>
+ /// <exception cref="System.ArgumentException"><paramref name="value"/> is not valid.</exception>
+ /// <exception cref="System.ObjectDisposedException">The <see cref="BarcodeDetectionConfiguration"/> already has been disposed of.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public BarcodeDetectionTarget Target
+ {
+ get
+ {
+ return (BarcodeDetectionTarget)GetInt(KeyAttrTarget);
+ }
+ set
+ {
+ ValidationUtil.ValidateEnum(typeof(BarcodeDetectionTarget), value);
+ Set(KeyAttrTarget, (int)value);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/BarcodeDetectionTarget.cs b/src/Tizen.Multimedia.Vision/MediaVision/BarcodeDetectionTarget.cs
new file mode 100755
index 0000000..231dce5
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/BarcodeDetectionTarget.cs
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Specifies the target of <see cref="BarcodeDetector"/>.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public enum BarcodeDetectionTarget
+ {
+ /// <summary>
+ /// 1D and 2D.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ All,
+
+ /// <summary>
+ /// 1D barcode only.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Barcode1D,
+
+ /// <summary>
+ /// 2D barcode only.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Barcode2D,
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/BarcodeDetector.cs b/src/Tizen.Multimedia.Vision/MediaVision/BarcodeDetector.cs
new file mode 100755
index 0000000..df4d6da
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/BarcodeDetector.cs
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using InteropBarcode = Interop.MediaVision.BarcodeDetector;
+using Unmanaged = Interop.MediaVision;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides the ability to detect barcodes on image sources.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public static class BarcodeDetector
+ {
+ /// <summary>
+ /// Detects barcodes on source and reads message from it.
+ /// </summary>
+ /// <param name="source">The <see cref="MediaVisionSource"/> instance.</param>
+ /// <param name="roi">Region of interest - rectangular area on the source which will be used for
+ /// barcode detection. Note that roi should be inside area on the source.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <exception cref="ObjectDisposedException"><paramref name="source"/> already has been disposed of.</exception>
+ /// <returns>A task that represents the asynchronous detect operation.</returns>
+ /// <seealso cref="Barcode"/>
+ /// <since_tizen> 3</since_tizen>
+ public static async Task<IEnumerable<Barcode>> DetectAsync(MediaVisionSource source,
+ Rectangle roi)
+ {
+ return await DetectAsync(source, roi, null);
+ }
+
+ /// <summary>
+ /// Detects barcodes on source and reads message from it with <see cref="BarcodeDetectionConfiguration"/>.
+ /// </summary>
+ /// <param name="source">The <see cref="MediaVisionSource"/> instance.</param>
+ /// <param name="roi">Region of interest - rectangular area on the source which will be used for
+ /// barcode detection. Note that roi should be inside area on the source.</param>
+ /// <param name="config">The configuration of the barcode detector. This value can be null.</param>
+ /// <returns>A task that represents the asynchronous detect operation.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <exception cref="ObjectDisposedException">
+ /// <paramref name="source"/> already has been disposed of.\n
+ /// -or-\n
+ /// <paramref name="config"/> already has been disposed of.
+ /// </exception>
+ /// <seealso cref="Barcode"/>
+ /// <since_tizen> 3</since_tizen>
+ public static async Task<IEnumerable<Barcode>> DetectAsync(MediaVisionSource source,
+ Rectangle roi, BarcodeDetectionConfiguration config)
+ {
+ if (source == null)
+ {
+ throw new ArgumentNullException(nameof(source));
+ }
+
+ var tcs = new TaskCompletionSource<IEnumerable<Barcode>>();
+
+ using (var cb = ObjectKeeper.Get(GetCallback(tcs)))
+ {
+ InteropBarcode.Detect(source.Handle, EngineConfiguration.GetHandle(config),
+ roi.ToMarshalable(), cb.Target).Validate("Failed to detect barcode.");
+
+ return await tcs.Task;
+ }
+ }
+
+ private static Barcode[] CreateBarcodes(Unmanaged.Quadrangle[] locations, string[] messages,
+ BarcodeType[] types, int numberOfBarcodes)
+ {
+ Barcode[] barcodes = new Barcode[numberOfBarcodes];
+
+ for (int i = 0; i < numberOfBarcodes; i++)
+ {
+ barcodes[i] = new Barcode(locations[i].ToApiStruct(), messages[i], types[i]);
+
+ Log.Info(MediaVisionLog.Tag, barcodes[i].ToString());
+ }
+
+ return barcodes;
+ }
+
+ private static InteropBarcode.DetectedCallback GetCallback(TaskCompletionSource<IEnumerable<Barcode>> tcs)
+ {
+ return (IntPtr mvSource, IntPtr engineCfg, Unmanaged.Quadrangle[] locations, string[] messages,
+ BarcodeType[] types, int numberOfBarcodes, IntPtr userData) =>
+ {
+ Log.Info(MediaVisionLog.Tag, $"Barcodes detected, count : {numberOfBarcodes}");
+
+ try
+ {
+ tcs.TrySetResult(CreateBarcodes(locations, messages, types, numberOfBarcodes));
+ }
+ catch (Exception e)
+ {
+ MultimediaLog.Error(MediaVisionLog.Tag, "Failed to handle barcode detection callback", e);
+ tcs.TrySetException(e);
+ }
+ };
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/BarcodeGenerationConfiguration.cs b/src/Tizen.Multimedia.Vision/MediaVision/BarcodeGenerationConfiguration.cs
new file mode 100755
index 0000000..eb29a04
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/BarcodeGenerationConfiguration.cs
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using Tizen.Common;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents a configuration of <see cref="BarcodeGenerator"/> instances.
+ /// </summary>
+ /// <seealso cref="BarcodeGenerator"/>
+ /// <since_tizen> 3</since_tizen>
+ public class BarcodeGenerationConfiguration : EngineConfiguration
+ {
+ private const string KeyTextAttr = "MV_BARCODE_GENERATE_ATTR_TEXT";
+ private const string KeyForegroundColorAttr = "MV_BARCODE_GENERATE_ATTR_COLOR_FRONT";
+ private const string KeyBackgroundColorAttr = "MV_BARCODE_GENERATE_ATTR_COLOR_BACK";
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="BarcodeGenerationConfiguration"/> class.
+ /// </summary>
+ /// <exception cref="System.NotSupportedException">The feature is not supported.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public BarcodeGenerationConfiguration() : base("barcode_generation")
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the text visibility of the barcode to be generated.
+ /// </summary>
+ /// <exception cref="System.ArgumentException"><paramref name="value"/> is not valid.</exception>
+ /// <exception cref="ObjectDisposedException">The <see cref="BarcodeGenerationConfiguration"/> already has been disposed of.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public Visibility TextVisibility
+ {
+ get
+ {
+ return (Visibility)GetInt(KeyTextAttr);
+ }
+ set
+ {
+ ValidationUtil.ValidateEnum(typeof(Visibility), value);
+ Set(KeyTextAttr, (int)value);
+ }
+ }
+
+ private Color _foregroundColor = Color.Black;
+
+ /// <summary>
+ /// Gets or sets the foreground color of the barcode to be generated.
+ /// </summary>
+ /// <remarks>
+ /// The alpha value of the color will be ignored.
+ /// </remarks>
+ /// <exception cref="ObjectDisposedException">The <see cref="BarcodeGenerationConfiguration"/> already has been disposed of.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public Color ForegroundColor
+ {
+ get
+ {
+ return _foregroundColor;
+ }
+ set
+ {
+ Set(KeyForegroundColorAttr, string.Format("{0:x2}{1:x2}{2:x2}", value.R, value.G, value.B));
+ _foregroundColor = value;
+ }
+ }
+
+ private Color _backgroundColor = Color.White;
+
+ /// <summary>
+ /// Gets or sets the background color of the barcode to be generated.
+ /// </summary>
+ /// <remarks>
+ /// The alpha value of the color will be ignored.
+ /// </remarks>
+ /// <exception cref="ObjectDisposedException">The <see cref="BarcodeGenerationConfiguration"/> already has been disposed of.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public Color BackgroundColor
+ {
+ get
+ {
+ return _backgroundColor;
+ }
+ set
+ {
+ Set(KeyBackgroundColorAttr, string.Format("{0:x2}{1:x2}{2:x2}", value.R, value.G, value.B));
+ _backgroundColor = value;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/BarcodeGenerator.cs b/src/Tizen.Multimedia.Vision/MediaVision/BarcodeGenerator.cs
new file mode 100755
index 0000000..2d4269d
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/BarcodeGenerator.cs
@@ -0,0 +1,357 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using InteropBarcode = Interop.MediaVision.BarcodeGenerator;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides the ability to generate barcodes and QR codes.
+ /// Different encoding types <see cref="QrMode"/> , error correction codes <see cref="ErrorCorrectionLevel"/>
+ /// and code versions are supported for QRCodes.
+ /// </summary>
+ /// <seealso cref="BarcodeGenerationConfiguration"/>
+ /// <since_tizen> 3</since_tizen>
+ public static class BarcodeGenerator
+ {
+ private const int NoneErrorCorrection = (int)ErrorCorrectionLevel.High + 1;
+ private const int NoneQrMode = (int)QrMode.Utf8 + 1;
+
+ private static MediaVisionSource GenerateSource(BarcodeGenerationConfiguration config,
+ string message, BarcodeType type, int qrMode, int qrEcc, int qrVersion)
+ {
+ if (message == null)
+ {
+ throw new ArgumentNullException(nameof(message));
+ }
+
+ ValidationUtil.ValidateEnum(typeof(BarcodeType), type);
+
+ MediaVisionSource source = new MediaVisionSource();
+ try
+ {
+ InteropBarcode.GenerateSource(EngineConfiguration.GetHandle(config),
+ message, type, qrMode, qrEcc, qrVersion, source.Handle).
+ Validate("Failed to generate source");
+ }
+ catch (Exception)
+ {
+ source.Dispose();
+ throw;
+ }
+ return source;
+ }
+
+ /// <summary>
+ /// Generates a QR image with the specified message.
+ /// </summary>
+ /// <param name="message">The message to be encoded in the barcode.</param>
+ /// <param name="qrConfig">The <see cref="QrConfiguration"/> instance.</param>
+ /// <returns><see cref="MediaVisionSource"/> containing the generated QR image.</returns>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="qrConfig"/> is null.\n
+ /// -or-\n
+ /// <paramref name="message"/> is null.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="message"/> is too long.\n
+ /// -or-\n
+ /// <paramref name="message"/> contains characters which are illegal by the <see cref="QrMode"/>.
+ /// </exception>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <seealso cref="QrMode"/>
+ /// <since_tizen> 3</since_tizen>
+ public static MediaVisionSource GenerateSource(string message, QrConfiguration qrConfig)
+ {
+ return GenerateSource(message, qrConfig, null);
+ }
+
+ /// <summary>
+ /// Generates a QR image with the specified message with <see cref="BarcodeGenerationConfiguration"/>.
+ /// </summary>
+ /// <param name="message">The message to be encoded in the barcode.</param>
+ /// <param name="qrConfig">The <see cref="QrConfiguration"/> instance.</param>
+ /// <param name="config">The configuration of the barcode generator. This value can be null.</param>
+ /// <returns><see cref="MediaVisionSource"/> containing the generated QR image.</returns>
+ /// <remarks>
+ /// <see cref="BarcodeGenerationConfiguration.TextVisibility"/> must be <see cref="Visibility.Invisible"/>,
+ /// because the text visibility is not supported in the QR code.
+ /// </remarks>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="qrConfig"/> is null.\n
+ /// -or-\n
+ /// <paramref name="message"/> is null.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="message"/> is too long.\n
+ /// -or-\n
+ /// <paramref name="message"/> contains characters which are illegal by the <see cref="QrMode"/>.
+ /// </exception>
+ /// <exception cref="NotSupportedException">
+ /// The feature is not supported.\n
+ /// -or-\n
+ /// <see cref="BarcodeGenerationConfiguration.TextVisibility"/> is the <see cref="Visibility.Visible"/>.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException"><paramref name="config"/> already has been disposed of.</exception>
+ /// <seealso cref="QrMode"/>
+ /// <since_tizen> 3</since_tizen>
+ public static MediaVisionSource GenerateSource(string message, QrConfiguration qrConfig,
+ BarcodeGenerationConfiguration config)
+ {
+ if (qrConfig == null)
+ {
+ throw new ArgumentNullException(nameof(qrConfig));
+ }
+
+ if (config != null)
+ {
+ if (config.TextVisibility == Visibility.Visible)
+ {
+ throw new NotSupportedException("Text can't be visible in QR.");
+ }
+ }
+
+ return GenerateSource(config, message, BarcodeType.QR, (int)qrConfig.Mode,
+ (int)qrConfig.ErrorCorrectionLevel, qrConfig.Version);
+ }
+
+ /// <summary>
+ /// Generates a barcode image with the specified message.
+ /// </summary>
+ /// <param name="message">The message to be encoded in the barcode.</param>
+ /// <param name="type">Type of the barcode to be generated.</param>
+ /// <returns><see cref="MediaVisionSource"/> containing the generated barcode image.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="message"/> is null.</exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="message"/> is too long.\n
+ /// -or-\n
+ /// <paramref name="type"/> is <see cref="BarcodeType.QR"/>.\n
+ /// -or-\n
+ /// <paramref name="type"/> is invalid.
+ /// -or-\n
+ /// <paramref name="message"/> contains illegal characters.
+ /// </exception>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public static MediaVisionSource GenerateSource(string message, BarcodeType type)
+ {
+ return GenerateSource(message, type, null);
+ }
+
+ /// <summary>
+ /// Generates a barcode image with the specified message and <see cref="BarcodeGenerationConfiguration"/>.
+ /// </summary>
+ /// <param name="message">The message to be encoded in the barcode.</param>
+ /// <param name="type">Type of the barcode to be generated.</param>
+ /// <param name="config">The configuration of the barcode generator. This value can be null.</param>
+ /// <returns><see cref="MediaVisionSource"/> containing the generated barcode image.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="message"/> is null.</exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="message"/> is too long.\n
+ /// -or-\n
+ /// <paramref name="type"/> is <see cref="BarcodeType.QR"/>.
+ /// -or-\n
+ /// <paramref name="type"/> is invalid.
+ /// -or-\n
+ /// <paramref name="message"/> contains illegal characters.
+ /// </exception>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <exception cref="ObjectDisposedException"><paramref name="config"/> already has been disposed of.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public static MediaVisionSource GenerateSource(string message, BarcodeType type,
+ BarcodeGenerationConfiguration config)
+ {
+ if (type == BarcodeType.QR)
+ {
+ throw new ArgumentException($"Invalid barcode type : {type}.");
+ }
+
+ return GenerateSource(config, message, type, NoneQrMode, NoneErrorCorrection, 0);
+ }
+
+ private static void GenerateImage(BarcodeGenerationConfiguration config,
+ string message, BarcodeType type, BarcodeImageConfiguration imageConfig,
+ int qrMode, int qrEcc, int qrVersion)
+ {
+ if (message == null)
+ {
+ throw new ArgumentNullException(nameof(message));
+ }
+
+ if (imageConfig == null)
+ {
+ throw new ArgumentNullException(nameof(imageConfig));
+ }
+
+ ValidationUtil.ValidateEnum(typeof(BarcodeType), type);
+
+ InteropBarcode.GenerateImage(EngineConfiguration.GetHandle(config), message,
+ imageConfig.Width, imageConfig.Height, type, qrMode, qrEcc, qrVersion,
+ imageConfig.Path, imageConfig.Format).
+ Validate("Failed to generate image");
+ }
+
+ /// <summary>
+ /// Generates a QR image file with the specified message.
+ /// </summary>
+ /// <remarks>
+ /// <see cref="BarcodeGenerationConfiguration.TextVisibility"/> must be <see cref="Visibility.Invisible"/>,
+ /// because the text visibility is not supported in the QR code.
+ /// </remarks>
+ /// <param name="message">The message to be encoded in the barcode.</param>
+ /// <param name="qrConfig">The <see cref="QrConfiguration"/> instance.</param>
+ /// <param name="imageConfig">The <see cref="BarcodeImageConfiguration"/> that contains information about the file to be generated.</param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="messsage"/> is null.\n
+ /// -or-\n
+ /// <paramref name="qrConfig"/> is null.\n
+ /// -or-\n
+ /// <paramref name="imageConfig"/> is null.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="message"/> is too long.\n
+ /// -or-\n
+ /// <paramref name="message"/> contains characters which are illegal by the <see cref="QrMode"/>.
+ /// </exception>
+ /// <exception cref="UnauthorizedAccessException">No permission to write a file.</exception>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <seealso cref="QrMode"/>
+ /// <since_tizen> 3</since_tizen>
+ public static void GenerateImage(string message, QrConfiguration qrConfig,
+ BarcodeImageConfiguration imageConfig)
+ {
+ GenerateImage(message, qrConfig, imageConfig, null);
+ }
+
+ /// <summary>
+ /// Generates a QR image file with the specified message and <see cref="BarcodeGenerationConfiguration"/>.
+ /// </summary>
+ /// <remarks>
+ /// <see cref="BarcodeGenerationConfiguration.TextVisibility"/> must be <see cref="Visibility.Invisible"/>,
+ /// because the text visibility is not supported in the QR code.
+ /// </remarks>
+ /// <param name="message">The message to be encoded in the barcode.</param>
+ /// <param name="qrConfig">The <see cref="QrConfiguration"/> instance.</param>
+ /// <param name="imageConfig">The <see cref="BarcodeImageConfiguration"/> that contains
+ /// information about the file to be generated.</param>
+ /// <param name="config">The configuration of the barcode generator. This value can be null.</param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="messsage"/> is null.\n
+ /// -or-\n
+ /// <paramref name="qrConfig"/> is null.\n
+ /// -or-\n
+ /// <paramref name="imageConfig"/> is null.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="message"/> is too long.\n
+ /// -or-\n
+ /// <paramref name="message"/> contains characters which are illegal by the <see cref="QrMode"/>.
+ /// </exception>
+ /// <exception cref="UnauthorizedAccessException">No permission to write a file.</exception>
+ /// <exception cref="NotSupportedException">
+ /// The feature is not supported.\n
+ /// -or-\n
+ /// <see cref="BarcodeGenerationConfiguration.TextVisibility"/> is the <see cref="Visibility.Visible"/>.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException"><paramref name="config"/> already has been disposed of.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public static void GenerateImage(string message, QrConfiguration qrConfig,
+ BarcodeImageConfiguration imageConfig, BarcodeGenerationConfiguration config)
+ {
+ if (qrConfig == null)
+ {
+ throw new ArgumentNullException(nameof(qrConfig));
+ }
+
+ if (config != null)
+ {
+ if (config.TextVisibility == Visibility.Visible)
+ {
+ throw new NotSupportedException("Text can't be visible in QR.");
+ }
+ }
+
+ GenerateImage(config, message, BarcodeType.QR, imageConfig, (int)qrConfig.Mode,
+ (int)qrConfig.ErrorCorrectionLevel, qrConfig.Version);
+ }
+
+ /// <summary>
+ /// Generates a barcode image file with the specified message.
+ /// </summary>
+ /// <param name="message">The message to be encoded in the barcode.</param>
+ /// <param name="type">Type of the barcode to be generated.</param>
+ /// <param name="imageConfig">The <see cref="BarcodeImageConfiguration"/> that contains
+ /// information about the file to be generated.</param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="messsage"/> is null.\n
+ /// -or-\n
+ /// <paramref name="imageConfig"/> is null.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="message"/> is too long.\n
+ /// -or-\n
+ /// <paramref name="type"/> is <see cref="BarcodeType.QR"/>.
+ /// -or-\n
+ /// <paramref name="type"/> is invalid.
+ /// -or-\n
+ /// <paramref name="message"/> contains illegal characters.
+ /// </exception>
+ /// <exception cref="UnauthorizedAccessException">No permission to write a file.</exception>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public static void GenerateImage(string message, BarcodeType type, BarcodeImageConfiguration imageConfig)
+ {
+ GenerateImage(message, type, imageConfig, null);
+ }
+
+ /// <summary>
+ /// Generates a barcode image file with the specified message and <see cref="BarcodeGenerationConfiguration"/>.
+ /// </summary>
+ /// <param name="message">The message to be encoded in the barcode.</param>
+ /// <param name="type">Type of the barcode to be generated.</param>
+ /// <param name="imageConfig">The <see cref="BarcodeImageConfiguration"/> that contains
+ /// information about the file to be generated.</param>
+ /// <param name="config">The configuration of the barcode generator. This value can be null.</param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="messsage"/> is null.\n
+ /// -or-\n
+ /// <paramref name="imageConfig"/> is null.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="message"/> is too long.\n
+ /// -or-\n
+ /// <paramref name="type"/> is <see cref="BarcodeType.QR"/>.
+ /// -or-\n
+ /// <paramref name="type"/> is invalid.
+ /// -or-\n
+ /// <paramref name="message"/> contains illegal characters.
+ /// </exception>
+ /// <exception cref="UnauthorizedAccessException">No permission to write a file.</exception>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <exception cref="ObjectDisposedException"><paramref name="config"/> already has been disposed of.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public static void GenerateImage(string message,
+ BarcodeType type, BarcodeImageConfiguration imageConfig, BarcodeGenerationConfiguration config)
+ {
+ if (type == BarcodeType.QR)
+ {
+ throw new ArgumentException($"Invalid barcode type : {type}.");
+ }
+ GenerateImage(config, message, type, imageConfig, NoneQrMode, NoneErrorCorrection, 0);
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/BarcodeImageConfiguration.cs b/src/Tizen.Multimedia.Vision/MediaVision/BarcodeImageConfiguration.cs
new file mode 100755
index 0000000..6227c88
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/BarcodeImageConfiguration.cs
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents a configuration for the image to be generated by <see cref="BarcodeGenerator"/>.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public class BarcodeImageConfiguration
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="BarcodeImageConfiguration"/> class.
+ /// </summary>
+ /// <remarks>
+ /// The mediastorage privilege(http://tizen.org/privilege/mediastorage) is needed if image path is relevant to media storage.\n
+ /// The externalstorage privilege(http://tizen.org/privilege/externalstorage) is needed if image path is relevant to external storage.
+ /// </remarks>
+ /// <param name="size">The <see cref="Size"/> of the generated image.</param>
+ /// <param name="path">The path to the file to be generated.</param>
+ /// <param name="imageFormat">The format of the output image.</param>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// The width of <paramref name="size"/> is less than or equal to zero.\n
+ /// -or-\n
+ /// The height of <paramref name="size"/> is less than or equal to zero.
+ /// </exception>
+ /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
+ /// <exception cref="ArgumentException"><paramref name="imageFormat"/> is invalid.</exception>
+ /// <code>
+ /// BarcodeImageConfiguration imageConfig = new BarcodeImageConfiguration(new Size(500, 400), "/opt/usr/test-barcode-generate-new", BarcodeImageFormat.JPG);
+ /// </code>
+ /// <since_tizen> 3</since_tizen>
+ public BarcodeImageConfiguration(Size size, string path, BarcodeImageFormat imageFormat)
+ {
+ if (size.Width <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(Size.Width), size.Width,
+ "width can't be less than or equal to zero.");
+ }
+
+ if (size.Height <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(Size.Height), size.Height,
+ "height can't be less than or equal to zero.");
+ }
+
+ if (path == null)
+ {
+ throw new ArgumentNullException(nameof(path));
+ }
+
+ ValidationUtil.ValidateEnum(typeof(BarcodeImageFormat), imageFormat);
+
+ Size = size;
+ Path = path;
+ Format = imageFormat;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="BarcodeImageConfiguration"/> class.
+ /// </summary>
+ /// <remarks>
+ /// The mediastorage privilege(http://tizen.org/privilege/mediastorage) is needed if image path is relevant to media storage.\n
+ /// The externalstorage privilege(http://tizen.org/privilege/externalstorage) is needed if image path is relevant to external storage.
+ /// </remarks>
+ /// <param name="width">The width of the image to be generated.</param>
+ /// <param name="height">The height of the image to be generated.</param>
+ /// <param name="path">The path to the file to be generated.</param>
+ /// <param name="imageFormat">The format of the output image.</param>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="width"/> is less than or equal to zero.\n
+ /// -or-\n
+ /// <paramref name="height"/> is less than or equal to zero.
+ /// </exception>
+ /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
+ /// <exception cref="ArgumentException"><paramref name="imageFormat"/> is invalid.</exception>
+ /// <code>
+ /// BarcodeImageConfiguration imageConfig = new BarcodeImageConfiguration(500, 400, "/opt/usr/test-barcode-generate-new", BarcodeImageFormat.JPG);
+ /// </code>
+ /// <since_tizen> 3</since_tizen>
+ public BarcodeImageConfiguration(int width, int height, string path, BarcodeImageFormat imageFormat)
+ : this(new Size(width, height), path, imageFormat)
+ {
+ }
+
+ /// <summary>
+ /// Gets the size of the image.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public Size Size { get; }
+
+ /// <summary>
+ /// Gets the width of the image.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public int Width => Size.Width;
+
+ /// <summary>
+ /// Gets the height of the image.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public int Height => Size.Height;
+
+ /// <summary>
+ /// Gets the path to the file that has to be generated.
+ /// </summary>
+ /// <remarks>
+ /// The mediastorage privilege http://tizen.org/privilege/mediastorage is needed if image path is relevant to media storage.\n
+ /// The externalstorage privilege http://tizen.org/privilege/externalstorage is needed if image path is relevant to external storage.
+ /// </remarks>
+ /// <since_tizen> 3</since_tizen>
+ public string Path { get; }
+
+ /// <summary>
+ /// Gets the format of the output image.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public BarcodeImageFormat Format { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/BarcodeImageFormat.cs b/src/Tizen.Multimedia.Vision/MediaVision/BarcodeImageFormat.cs
new file mode 100755
index 0000000..5481510
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/BarcodeImageFormat.cs
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Specifies supported image formats for <see cref="BarcodeGenerator"/>
+ /// </summary>
+ /// <seealso cref="BarcodeImageConfiguration"/>
+ /// <since_tizen> 3</since_tizen>
+ public enum BarcodeImageFormat
+ {
+ /// <summary>
+ /// BMP image format.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Bmp,
+ /// <summary>
+ /// JPEG image format.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Jpeg,
+ /// <summary>
+ /// PNG image format.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Png
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/BarcodeType.cs b/src/Tizen.Multimedia.Vision/MediaVision/BarcodeType.cs
new file mode 100755
index 0000000..2cc4283
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/BarcodeType.cs
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Specifies the supported barcode types.
+ /// </summary>
+ /// <remarks>
+ /// QR codes (versions 1 to 40) and set of 1D barcodes are supported
+ /// </remarks>
+ /// <seealso cref="BarcodeDetector"/>
+ /// <seealso cref="BarcodeGenerator"/>
+ /// <since_tizen> 3</since_tizen>
+ public enum BarcodeType
+ {
+ /// <summary>
+ /// 2D barcode - Quick Response code.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ QR,
+ /// <summary>
+ /// 1D barcode - Universal Product Code with 12-digit.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ UpcA,
+ /// <summary>
+ /// 1D barcode - Universal Product Code with 6-digit.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ UpcE,
+ /// <summary>
+ /// 1D barcode - International Article Number with 8-digit.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Ean8,
+ /// <summary>
+ /// 1D barcode - International Article Number with 13-digit.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Ean13,
+ /// <summary>
+ /// 1D barcode - Code 128.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Code128,
+ /// <summary>
+ /// 1D barcode - Code 39.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Code39,
+ /// <summary>
+ /// 1D barcode - Interleaved Two of Five.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ I25
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/Colorspace.cs b/src/Tizen.Multimedia.Vision/MediaVision/Colorspace.cs
new file mode 100755
index 0000000..79135e0
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/Colorspace.cs
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Specifies colorspaces for MediaVision.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public enum Colorspace
+ {
+ /// <summary>
+ /// The colorspace type is invalid.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Invalid,
+ /// <summary>
+ /// The colorspace type is Y800.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Y800,
+ /// <summary>
+ /// The colorspace type is I420.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ I420,
+ /// <summary>
+ /// The colorspace type is NV12.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ NV12,
+ /// <summary>
+ /// The colorspace type is YV12.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ YV12,
+ /// <summary>
+ /// The colorspace type is NV21.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ NV21,
+ /// <summary>
+ /// The colorspace type is YUYV.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Yuyv,
+ /// <summary>
+ /// The colorspace type is UYVY.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Uyvy,
+ /// <summary>
+ /// The colorspace type is 422P.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Yuv422P,
+ /// <summary>
+ /// The colorspace type is RGB565.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Rgb565,
+ /// <summary>
+ /// The colorspace type is RGB888.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Rgb888,
+ /// <summary>
+ /// The colorspace type is RGBA.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Rgba
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/EngineConfiguration.cs b/src/Tizen.Multimedia.Vision/MediaVision/EngineConfiguration.cs
new file mode 100755
index 0000000..7d59ccf
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/EngineConfiguration.cs
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Tizen.System;
+using System.Runtime.InteropServices;
+using static Interop.MediaVision;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// A base class for configuration classes.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public abstract class EngineConfiguration : IDisposable
+ {
+ private IntPtr _handle = IntPtr.Zero;
+ private bool _disposed = false;
+
+ private const string _featurePath = "http://tizen.org/feature/vision.";
+
+ private bool IsSupportedEngineType(string type)
+ {
+ bool isSupported = false;
+
+ string featureType = _featurePath + type;
+
+ bool ret = SystemInfo.TryGetValue(featureType, out isSupported);
+
+ return (isSupported && ret) ? true : false;
+ }
+
+ private bool IsSupportedEngineType(string type1, string type2)
+ {
+ return (IsSupportedEngineType(type1) && IsSupportedEngineType(type2)) ? true : false;
+ }
+
+ internal EngineConfiguration(string engineType)
+ {
+ if (IsSupportedEngineType(engineType) == false)
+ {
+ throw new NotSupportedException($"{engineType} : Not Supported");
+ }
+
+ EngineConfig.Create(out _handle).Validate("Failed to create media vision engine.");
+ }
+
+ internal EngineConfiguration(string engineType1, string engineType2)
+ {
+
+ if (IsSupportedEngineType(engineType1, engineType2) == false)
+ {
+ throw new NotSupportedException($"{engineType1} or {engineType2} : Not Supported");
+ }
+
+ EngineConfig.Create(out _handle).Validate("Failed to create media vision engine.");
+ }
+
+ ~EngineConfiguration()
+ {
+ Dispose(false);
+ }
+
+ internal static IntPtr GetHandle(EngineConfiguration config)
+ {
+ if (config == null)
+ {
+ return IntPtr.Zero;
+ }
+
+ if (config._disposed)
+ {
+ throw new ObjectDisposedException(config.GetType().Name);
+ }
+
+ return config._handle;
+ }
+
+ internal void Set(string key, double value)
+ {
+ EngineConfig.SetDouble(Handle, key, value).Validate("Failed to set attribute");
+ }
+
+ internal void Set(string key, int value)
+ {
+ EngineConfig.SetInt(Handle, key, value).Validate("Failed to set attribute");
+ }
+
+
+ internal void Set(string key, bool value)
+ {
+ EngineConfig.SetBool(Handle, key, value).Validate("Failed to set attribute");
+ }
+
+ internal void Set(string key, string value)
+ {
+ EngineConfig.SetString(Handle, key, value).Validate("Failed to set attribute");
+ }
+
+ internal int GetInt(string key)
+ {
+ int value = 0;
+ EngineConfig.GetInt(Handle, key, out value).Validate("Failed to get the value");
+ return value;
+ }
+
+ internal double GetDouble(string key)
+ {
+ double value = 0;
+ EngineConfig.GetDouble(Handle, key, out value).Validate("Failed to get the value");
+ return value;
+ }
+
+ internal bool GetBool(string key)
+ {
+ bool value = false;
+ EngineConfig.GetBool(Handle, key, out value).Validate("Failed to get the value");
+ return value;
+ }
+
+ internal string GetString(string key)
+ {
+ IntPtr ptr = IntPtr.Zero;
+
+ try
+ {
+ EngineConfig.GetString(Handle, key, out ptr).Validate("Failed to get the value");
+ return Marshal.PtrToStringAnsi(ptr);
+ }
+ finally
+ {
+ LibcSupport.Free(ptr);
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_disposed)
+ {
+ return;
+ }
+
+ EngineConfig.Destroy(_handle);
+ _disposed = true;
+ }
+
+ internal IntPtr Handle
+ {
+ get
+ {
+ if (_disposed)
+ {
+ throw new ObjectDisposedException(nameof(EngineConfiguration));
+ }
+ return _handle;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/ErrorCorrectionLevel.cs b/src/Tizen.Multimedia.Vision/MediaVision/ErrorCorrectionLevel.cs
new file mode 100755
index 0000000..7388c4f
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/ErrorCorrectionLevel.cs
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Specifies the supported QR code error correction level.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public enum ErrorCorrectionLevel
+ {
+ /// <summary>
+ /// Recovery up to 7% losses.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Low,
+ /// <summary>
+ /// Recovery up to 15% losses.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Medium,
+ /// <summary>
+ /// Recovery up to 25% losses.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Quartile,
+ /// <summary>
+ /// Recovery up to 30% losses.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ High
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/EyeCondition.cs b/src/Tizen.Multimedia.Vision/MediaVision/EyeCondition.cs
new file mode 100755
index 0000000..7cf912f
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/EyeCondition.cs
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Specifies the eyes state types.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public enum EyeCondition
+ {
+ /// <summary>
+ /// Eyes are open.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Open,
+
+ /// <summary>
+ /// Eyes are closed.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Closed,
+
+ /// <summary>
+ /// The eyes condition wasn't determined.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ NotFound
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/FaceDetectionConfiguration.cs b/src/Tizen.Multimedia.Vision/MediaVision/FaceDetectionConfiguration.cs
new file mode 100755
index 0000000..cd08d30
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/FaceDetectionConfiguration.cs
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents a configuration of <see cref="FaceDetector"/> instances.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public class FaceDetectionConfiguration : EngineConfiguration
+ {
+ private const string KeyModelFilePath = "MV_FACE_DETECTION_MODEL_FILE_PATH";
+ private const string KeyRoiX = "MV_FACE_DETECTION_ROI_X";
+ private const string KeyRoiY = "MV_FACE_DETECTION_ROI_Y";
+ private const string KeyRoiWidth = "MV_FACE_DETECTION_ROI_WIDTH";
+ private const string KeyRoiHeight = "MV_FACE_DETECTION_ROI_HEIGHT";
+ private const string KeyMinWidth = "MV_FACE_DETECTION_MIN_SIZE_WIDTH";
+ private const string KeyMinHeight = "MV_FACE_DETECTION_MIN_SIZE_HEIGHT";
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="FaceDetectionConfiguration"/> class.
+ /// </summary>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public FaceDetectionConfiguration() : base("face_recognition")
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the face detection haarcascade xml file for face detection.
+ /// </summary>
+ /// <exception cref="ArgumentNullException"><paramref name="value"/> is null.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public string ModelFilePath
+ {
+ get
+ {
+ return GetString(KeyModelFilePath);
+ }
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(ModelFilePath), "ModeFilePath can't be null.");
+ }
+ Set(KeyModelFilePath, value);
+ }
+ }
+
+
+ /// <summary>
+ /// Gets or sets minimum height of face which will be detected.
+ /// </summary>
+ /// <remarks>
+ /// Default value is null (all detected faces will be applied), can be changed to specify the minimum face height.
+ /// </remarks>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="value"/> is less than zero.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public int? MinHeight
+ {
+ get
+ {
+ int value = GetInt(KeyMinHeight);
+ if (value == -1) return null;
+ return value;
+ }
+ set
+ {
+ if (value.HasValue && value < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(MinHeight), value,
+ $"{nameof(MinHeight)} can't be less than zero.");
+ }
+
+ Set(KeyMinHeight, value ?? -1);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets minimum width of face which will be detected.
+ /// </summary>
+ /// <remarks>
+ /// Default value is null (all detected faces will be applied), can be changed to specify the minimum face width.
+ /// </remarks>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="value"/> is less than zero.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public int? MinWidth
+ {
+ get
+ {
+ int value = GetInt(KeyMinWidth);
+ if (value == -1) return null;
+ return value;
+ }
+ set
+ {
+ if (value.HasValue && value < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(MinWidth), value,
+ $"{nameof(MinWidth)} can't be less than zero.");
+ }
+
+ Set(KeyMinWidth, value ?? -1);
+ }
+ }
+
+ private static readonly Rectangle DefaultRoi = new Rectangle(-1, -1, -1, -1);
+
+ private Rectangle? _roi;
+
+ /// <summary>
+ /// Gets or sets the roi of the face detection.
+ /// </summary>
+ /// <remarks>
+ /// Default value is null (the roi will be a full image) can be changed to specify the roi for face detection.
+ /// </remarks>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// The width of <paramref name="value"/> is less than or equal to zero.\n
+ /// -or-\n
+ /// The height of <paramref name="value"/> is less than or equal to zero.\n
+ /// -or-\n
+ /// The x position of <paramref name="value"/> is less than zero.\n
+ /// -or-\n
+ /// The y position of <paramref name="value"/> is less than zero.\n
+ /// </exception>
+ /// <since_tizen> 3</since_tizen>
+ public Rectangle? Roi
+ {
+ get
+ {
+ return _roi;
+ }
+ set
+ {
+ if (value != null)
+ {
+ ValidateRoi(value.Value);
+ }
+
+ SetRoi(value ?? DefaultRoi);
+
+ _roi = value;
+ }
+ }
+
+ private static void ValidateRoi(Rectangle roi)
+ {
+ if (roi.Width <= 0)
+ {
+ throw new ArgumentOutOfRangeException("Roi.Width", roi.Width,
+ "The width of roi can't be less than or equal to zero.");
+ }
+
+ if (roi.Height <= 0)
+ {
+ throw new ArgumentOutOfRangeException("Roi.Height", roi.Height,
+ "The height of roi can't be less than or equal to zero.");
+ }
+
+ if (roi.X < 0)
+ {
+ throw new ArgumentOutOfRangeException("Roi.X", roi.X,
+ "The x position of roi can't be less than zero.");
+ }
+
+ if (roi.Y < 0)
+ {
+ throw new ArgumentOutOfRangeException("Roi.Y", roi.Y,
+ "The y position of roi can't be less than zero.");
+ }
+ }
+
+ private void SetRoi(Rectangle roi)
+ {
+ Set(KeyRoiX, roi.X);
+ Set(KeyRoiY, roi.Y);
+ Set(KeyRoiWidth, roi.Width);
+ Set(KeyRoiHeight, roi.Height);
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/FaceDetector.cs b/src/Tizen.Multimedia.Vision/MediaVision/FaceDetector.cs
new file mode 100755
index 0000000..c99d966
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/FaceDetector.cs
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Threading.Tasks;
+using InteropFace = Interop.MediaVision.Face;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides the ability to detect faces on image sources.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public static class FaceDetector
+ {
+
+ /// <summary>
+ /// Detects faces on the source.\n
+ /// Each time when DetectAsync is called, a set of the detected faces at the media source are received asynchronously.
+ /// </summary>
+ /// <param name="source">The source of the media where faces will be detected.</param>
+ /// <returns>A task that represents the asynchronous detect operation.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="NotSupportedException">
+ /// The feature is not supported.\n
+ /// -or-\n
+ /// The format of <paramref name="source"/> is not supported.
+ /// </exception>
+ /// <since_tizen> 3</since_tizen>
+ public static async Task<Rectangle[]> DetectAsync(MediaVisionSource source)
+ {
+ return await DetectAsync(source, null);
+ }
+
+ /// <summary>
+ /// Detects faces on the source.\n
+ /// Each time when DetectAsync is called, a set of the detected faces at the media source are received asynchronously.
+ /// </summary>
+ /// <param name="source">The source of the media where faces will be detected.</param>
+ /// <param name="config">The configuration of engine will be used for detecting. This value can be null.</param>
+ /// <returns>A task that represents the asynchronous detect operation.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public static async Task<Rectangle[]> DetectAsync(MediaVisionSource source,
+ FaceDetectionConfiguration config)
+ {
+ if (source == null)
+ {
+ throw new ArgumentNullException(nameof(source));
+ }
+
+ TaskCompletionSource<Rectangle[]> tcs = new TaskCompletionSource<Rectangle[]>();
+
+ using (var cb = ObjectKeeper.Get(GetCallback(tcs)))
+ {
+ InteropFace.Detect(source.Handle, EngineConfiguration.GetHandle(config), cb.Target).
+ Validate("Failed to perform face detection");
+
+ return await tcs.Task;
+ }
+ }
+
+ private static InteropFace.DetectedCallback GetCallback(TaskCompletionSource<Rectangle[]> tcs)
+ {
+ return (IntPtr sourceHandle, IntPtr engineConfig, global::Interop.MediaVision.Rectangle[] facesLocations,
+ int numberOfFaces, IntPtr _) =>
+ {
+ try
+ {
+ Log.Info(MediaVisionLog.Tag, $"Faces detected, count : {numberOfFaces}.");
+ Rectangle[] locations = new Rectangle[numberOfFaces];
+ for (int i = 0; i < numberOfFaces; i++)
+ {
+ locations[i] = facesLocations[i].ToApiStruct();
+ Log.Info(MediaVisionLog.Tag, $"Face {0} detected : {locations}.");
+ }
+
+ if (!tcs.TrySetResult(locations))
+ {
+ Log.Error(MediaVisionLog.Tag, "Failed to set face detection result.");
+ }
+ }
+ catch (Exception e)
+ {
+ MultimediaLog.Info(MediaVisionLog.Tag, "Failed to handle face detection.", e);
+ tcs.TrySetException(e);
+ }
+ };
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/FaceRecognitionConfiguration.cs b/src/Tizen.Multimedia.Vision/MediaVision/FaceRecognitionConfiguration.cs
new file mode 100755
index 0000000..d3451f8
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/FaceRecognitionConfiguration.cs
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents a configuration of <see cref="FaceRecognizer"/> instances.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public class FaceRecognitionConfiguration : EngineConfiguration
+ {
+ private const string KeyModelType = "MV_FACE_RECOGNITION_MODEL_TYPE";
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="FaceRecognitionConfiguration"/> class.
+ /// </summary>
+ /// <exception cref="System.NotSupportedException">The feature is not supported.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public FaceRecognitionConfiguration() : base("face_recognition")
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the method used for face recognition model learning.
+ /// Default value is <see cref="FaceRecognitionModelType.Lbph"/>.
+ /// </summary>
+ /// <exception cref="System.ArgumentException"><paramref name="value"/> is not valid.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public FaceRecognitionModelType ModelType
+ {
+ get
+ {
+ return (FaceRecognitionModelType)GetInt(KeyModelType);
+ }
+ set
+ {
+ ValidationUtil.ValidateEnum(typeof(FaceRecognitionModelType), value);
+ Set(KeyModelType, (int)value);
+ }
+ }
+
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/FaceRecognitionModel.cs b/src/Tizen.Multimedia.Vision/MediaVision/FaceRecognitionModel.cs
new file mode 100755
index 0000000..5b6a8bb
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/FaceRecognitionModel.cs
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+using InteropModel = Interop.MediaVision.FaceRecognitionModel;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents the face recognition model interface.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public class FaceRecognitionModel : IDisposable
+ {
+ private IntPtr _handle = IntPtr.Zero;
+ private bool _disposed = false;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="FaceRecognitionModel"/> class.
+ /// </summary>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public FaceRecognitionModel()
+ {
+ InteropModel.Create(out _handle).Validate("Failed to create FaceRecognitionModel");
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="FaceRecognitionModel"/> class withe the specified path.
+ /// </summary>
+ /// <remarks>
+ /// Models have been saved by <see cref="Save()"/> can be loaded.
+ /// </remarks>
+ /// <param name="modelPath">Path to the model to load.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="modelPath"/> is null.</exception>
+ /// <exception cref="FileNotFoundException"><paramref name="modelPath"/> is invalid.</exception>
+ /// <exception cref="NotSupportedException">
+ /// The feature is not supported.\n
+ /// -or-\n
+ /// <paramref name="modelPath"/> is not supported format.
+ /// </exception>
+ /// <exception cref="UnauthorizedAccessException">No permission to access the specified file.</exception>
+ /// <seealso cref="Save(string)"/>
+ /// <since_tizen> 3</since_tizen>
+ public FaceRecognitionModel(string modelPath)
+ {
+ if (modelPath == null)
+ {
+ throw new ArgumentNullException(nameof(modelPath));
+ }
+
+ InteropModel.Load(modelPath, out _handle).
+ Validate("Failed to load FaceRecognitionModel from file");
+ }
+
+ ~FaceRecognitionModel()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Gets labels that had been learned by the model.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public int[] Labels
+ {
+ get
+ {
+ IntPtr unmangedArray = IntPtr.Zero;
+ try
+ {
+ uint numOfLabels = 0;
+
+ InteropModel.QueryLabels(Handle, out unmangedArray, out numOfLabels).
+ Validate("Failed to retrieve face labels.");
+
+ int[] labels = new int[numOfLabels];
+ Marshal.Copy(unmangedArray, labels, 0, (int)numOfLabels);
+
+ return labels;
+ }
+ finally
+ {
+ if (unmangedArray != IntPtr.Zero)
+ {
+ LibcSupport.Free(unmangedArray);
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Saves the recognition model to the file.
+ /// </summary>
+ /// <param name="path">Path to the file to save the model.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
+ /// <exception cref="UnauthorizedAccessException">No permission to write to the specified path.</exception>
+ /// <exception cref="ObjectDisposedException">The <see cref="FaceRecognitionModel"/> has already been disposed of.</exception>
+ /// <exception cref="DirectoryNotFoundException">The directory for <paramref name="path"/> does not exist.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public void Save(string path)
+ {
+ if (path == null)
+ {
+ throw new ArgumentNullException(nameof(path));
+ }
+
+ var ret = InteropModel.Save(path, Handle);
+
+ if (ret == MediaVisionError.InvalidPath)
+ {
+ throw new DirectoryNotFoundException($"The directory for the path({path}) does not exist.");
+ }
+
+ ret.Validate("Failed to save recognition model to file");
+ }
+
+ private MediaVisionError InvokeAdd(MediaVisionSource source, int label, Rectangle? area)
+ {
+ if (area != null)
+ {
+ var rect = area.Value.ToMarshalable();
+ return InteropModel.Add(source.Handle, Handle, ref rect, label);
+ }
+
+ return InteropModel.Add(source.Handle, Handle, IntPtr.Zero, label);
+ }
+
+ /// <summary>
+ /// Adds face image example to be used for face recognition model learning.
+ /// </summary>
+ /// <param name="source">The <see cref="MediaVisionSource"/> that contains face image.</param>
+ /// <param name="label">The label that identifies face for which example is adding.
+ /// Specify the same labels for the face images of a single person when calling this method.
+ /// Has to be unique for each face.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="FaceRecognitionModel"/> has already been disposed of.\n
+ /// -or-\n
+ /// <paramref name="source"/> has already been dispose of.
+ /// </exception>
+ /// <seealso cref="Learn(FaceRecognitionConfiguration)"/>
+ /// <since_tizen> 3</since_tizen>
+ public void Add(MediaVisionSource source, int label)
+ {
+ if (source == null)
+ {
+ throw new ArgumentNullException(nameof(source));
+ }
+
+ InvokeAdd(source, label, null).Validate("Failed to add face example image");
+ }
+
+ /// <summary>
+ /// Adds face image example to be used for face recognition model learning.
+ /// </summary>
+ /// <param name="source">The <see cref="MediaVisionSource"/> that contains face image.</param>
+ /// <param name="label">The label that identifies face for which example is adding.
+ /// Specify the same labels for the face images of a single person when calling this method.
+ /// Has to be unique for each face.</param>
+ /// <param name="area">The rectangular region of the face image at the source image.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="FaceRecognitionModel"/> has already been disposed of.\n
+ /// -or-\n
+ /// <paramref name="source"/> has already been dispose of.
+ /// </exception>
+ /// <seealso cref="Learn(FaceRecognitionConfiguration)"/>
+ /// <since_tizen> 3</since_tizen>
+ public void Add(MediaVisionSource source, int label, Rectangle area)
+ {
+ if (source == null)
+ {
+ throw new ArgumentNullException(nameof(source));
+ }
+
+ InvokeAdd(source, label, area).Validate("Failed to add face example image");
+ }
+
+ /// <summary>
+ /// Removes all face examples added with the specified label.
+ /// </summary>
+ /// <param name="label">The label that identifies face for which examples will be removed.</param>
+ /// <exception cref="ObjectDisposedException">The <see cref="FaceRecognitionModel"/> has already been disposed of.</exception>
+ /// <returns>true if the examples are successfully removed; otherwise, false if there is no example labeled with the specified label.</returns>
+ /// <seealso cref="Add(MediaVisionSource, int)"/>
+ /// <seealso cref="Add(MediaVisionSource, int, Rectangle)"/>
+ /// <since_tizen> 3</since_tizen>
+ public bool Remove(int label)
+ {
+ var ret = InteropModel.Remove(Handle, ref label);
+
+ if (ret == MediaVisionError.KeyNotAvailable)
+ {
+ return false;
+ }
+
+ ret.Validate("Failed to remove image example");
+ return true;
+ }
+
+ /// <summary>
+ /// Removes all face examples.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">The <see cref="FaceRecognitionModel"/> has already been disposed of.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public void Reset()
+ {
+ InteropModel.Reset(Handle).Validate("Failed to reset image example");
+ }
+
+
+ /// <summary>
+ /// Learns face recognition model.
+ /// </summary>
+ /// <remarks>
+ /// Before you start learning process, face recognition models has to be filled with training data - face image examples.
+ /// These examples has to be provided by <see cref="Add(MediaVisionSource, int)"/> or <see cref="Add(MediaVisionSource, int, Rectangle)"/>.
+ /// Recognition accuracy is usually increased when the different examples of the identical face are added more and more.
+ /// But it depends on the used learning algorithm.
+ /// </remarks>
+ /// <exception cref="ObjectDisposedException">The <see cref="FaceRecognitionModel"/> has already been disposed of.</exception>
+ /// <exception cref="InvalidOperationException">No examples added.</exception>
+ /// <seealso cref="Add(MediaVisionSource, int)"/>
+ /// <seealso cref="Add(MediaVisionSource, int, Rectangle)"/>
+ /// <since_tizen> 3</since_tizen>
+ public void Learn()
+ {
+ Learn(null);
+ }
+
+ /// <summary>
+ /// Learns face recognition model with <see cref="FaceRecognitionConfiguration"/>.
+ /// </summary>
+ /// <remarks>
+ /// Before you start learning process, face recognition models has to be filled with training data - face image examples.
+ /// These examples has to be provided by <see cref="Add(MediaVisionSource, int)"/> or <see cref="Add(MediaVisionSource, int, Rectangle)"/>.
+ /// Recognition accuracy is usually increased when the different examples of the identical face are added more and more.
+ /// But it depends on the used learning algorithm.
+ /// </remarks>
+ /// <param name="config">The configuration used for learning of the recognition models. This value can be null.</param>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="FaceRecognitionModel"/> has already been disposed of.\n
+ /// -or-\n
+ /// <paramref name="config"/> has already been disposed of.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">No examples added.</exception>
+ /// <seealso cref="Add(MediaVisionSource, int)"/>
+ /// <seealso cref="Add(MediaVisionSource, int, Rectangle)"/>
+ /// <since_tizen> 3</since_tizen>
+ public void Learn(FaceRecognitionConfiguration config)
+ {
+ InteropModel.Learn(EngineConfiguration.GetHandle(config), Handle).
+ Validate("Failed to learn");
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_disposed)
+ {
+ return;
+ }
+
+ InteropModel.Destroy(_handle);
+ _disposed = true;
+ }
+
+ internal IntPtr Handle
+ {
+ get
+ {
+ if (_disposed)
+ {
+ throw new ObjectDisposedException(nameof(FaceRecognitionModel));
+ }
+ return _handle;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/FaceRecognitionModelType.cs b/src/Tizen.Multimedia.Vision/MediaVision/FaceRecognitionModelType.cs
new file mode 100755
index 0000000..f701f9e
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/FaceRecognitionModelType.cs
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Specifies the face recognition model learning algorithms.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public enum FaceRecognitionModelType
+ {
+ /// <summary>
+ /// Eigenfaces.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ EigenFaces = 1,
+
+ /// <summary>
+ /// Fisherfaces.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ FisherFaces,
+
+ /// <summary>
+ /// Local Binary Patterns Histograms (LBPH); The default type.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Lbph
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/FaceRecognitionResult.cs b/src/Tizen.Multimedia.Vision/MediaVision/FaceRecognitionResult.cs
new file mode 100755
index 0000000..63d2fca
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/FaceRecognitionResult.cs
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents result of <see cref="FaceRecognizer"/> operations.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public class FaceRecognitionResult
+ {
+ internal FaceRecognitionResult(bool recognized, double confidence, int label, Rectangle? area)
+ {
+ Success = recognized;
+ Label = label;
+ Area = area;
+ Confidence = confidence;
+ }
+
+ /// <summary>
+ /// Gets the value indicating the recognition is successful.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public bool Success { get; }
+
+ /// <summary>
+ /// Gets the label of the recognized face.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public int Label { get; }
+
+ /// <summary>
+ /// Gets the location of the recognized face.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public Rectangle? Area { get; }
+
+ /// <summary>
+ /// The confidence of the recognition model that face has been recognized correctly (value from 0.0 to 1.0).
+ /// No faces were recognized if confidence was 0.0. When model has been learned on large amount of examples,
+ /// threshold for this value can be high (0.85-0.95). If model was learned for small amount of examples,
+ /// then threshold can be reduced (0.5-0.85).
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public double Confidence { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/FaceRecognizer.cs b/src/Tizen.Multimedia.Vision/MediaVision/FaceRecognizer.cs
new file mode 100755
index 0000000..ba52619
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/FaceRecognizer.cs
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+using InteropFace = Interop.MediaVision.Face;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides the ability to recognize faces, face expressions and eye condition on image sources.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public static class FaceRecognizer
+ {
+
+ /// <summary>
+ /// Performs face recognition on the source with <see cref="FaceRecognitionModel"/>.
+ /// </summary>
+ /// <param name="source">The <see cref="MediaVisionSource"/> of the media to recognize faces for.</param>
+ /// <param name="recognitionModel">The <see cref="FaceRecognitionConfiguration"/> to be used for recognition.</param>
+ /// <returns>A task that represents the asynchronous recognition operation.</returns>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="source"/> is null.\n
+ /// -or-\n
+ /// <paramref name="recognitionModel"/> is null.
+ /// </exception>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <exception cref="ObjectDisposedException"><paramref name="source"/> has already been disposed of.</exception>
+ /// <exception cref="InvalidOperationException"><paramref name="recognitionModel"/> is untrained model.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public static async Task<FaceRecognitionResult> RecognizeAsync(MediaVisionSource source,
+ FaceRecognitionModel recognitionModel)
+ {
+ return await InvokeRecognizeAsync(source, recognitionModel, null, null);
+ }
+
+ /// <summary>
+ /// Performs face recognition on the source with <see cref="FaceRecognitionModel"/> and a bounding box.
+ /// </summary>
+ /// <param name="source">The <see cref="MediaVisionSource"/> of the media to recognize faces for.</param>
+ /// <param name="recognitionModel">The <see cref="FaceRecognitionModel"/> to be used for recognition.</param>
+ /// <param name="bound">Rectangular box bounding face image on the source.</param>
+ /// <returns>A task that represents the asynchronous recognition operation.</returns>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="source"/> is null.\n
+ /// -or-\n
+ /// <paramref name="recognitionModel"/> is null.
+ /// </exception>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <exception cref="ObjectDisposedException"><paramref name="source"/> has already been disposed of.</exception>
+ /// <exception cref="InvalidOperationException"><paramref name="recognitionModel"/> is untrained model.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public static async Task<FaceRecognitionResult> RecognizeAsync(MediaVisionSource source,
+ FaceRecognitionModel recognitionModel, Rectangle bound)
+ {
+ return await InvokeRecognizeAsync(source, recognitionModel, bound, null);
+ }
+
+ /// <summary>
+ /// Performs face recognition on the source with <see cref="FaceRecognitionModel"/> and <see cref="FaceRecognitionConfiguration"/>.
+ /// </summary>
+ /// <param name="source">The <see cref="MediaVisionSource"/> of the media to recognize faces for.</param>
+ /// <param name="recognitionModel">The <see cref="FaceRecognitionModel"/> to be used for recognition.</param>
+ /// <param name="config">The configuration used for recognition. This value can be null.</param>
+ /// <returns>A task that represents the asynchronous recognition operation.</returns>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="source"/> is null.\n
+ /// -or-\n
+ /// <paramref name="recognitionModel"/> is null.
+ /// </exception>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <exception cref="ObjectDisposedException">
+ /// <paramref name="source"/> has already been disposed of.\n
+ /// -or-\n
+ /// <paramref name="config"/> has already been disposed of.
+ /// </exception>
+ /// <exception cref="InvalidOperationException"><paramref name="recognitionModel"/> is untrained model.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public static async Task<FaceRecognitionResult> RecognizeAsync(MediaVisionSource source,
+ FaceRecognitionModel recognitionModel, FaceRecognitionConfiguration config)
+ {
+ return await InvokeRecognizeAsync(source, recognitionModel, null, config);
+ }
+
+
+ /// <summary>
+ /// Performs face recognition on the source with <see cref="FaceRecognitionModel"/>, <see cref="FaceRecognitionConfiguration"/>
+ /// and a bounding box.
+ /// </summary>
+ /// <param name="source">The <see cref="MediaVisionSource"/> of the media to recognize faces for.</param>
+ /// <param name="recognitionModel">The <see cref="FaceRecognitionModel"/> to be used for recognition.</param>
+ /// <param name="bound">Rectangular box bounding face image on the source.</param>
+ /// <param name="config">The <see cref="FaceRecognitionConfiguration"/> used for recognition. This value can be null.</param>
+ /// <returns>A task that represents the asynchronous recognition operation.</returns>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="source"/> is null.\n
+ /// -or-\n
+ /// <paramref name="recognitionModel"/> is null.
+ /// </exception>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <exception cref="ObjectDisposedException">
+ /// <paramref name="source"/> has already been disposed of.\n
+ /// -or-\n
+ /// <paramref name="config"/> has already been disposed of.
+ /// </exception>
+ /// <exception cref="InvalidOperationException"><paramref name="recognitionModel"/> is untrained model.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public static async Task<FaceRecognitionResult> RecognizeAsync(MediaVisionSource source,
+ FaceRecognitionModel recognitionModel, Rectangle bound, FaceRecognitionConfiguration config)
+ {
+ return await InvokeRecognizeAsync(source, recognitionModel, bound, config);
+ }
+
+ private static MediaVisionError InvokeRecognize(IntPtr sourceHandle, IntPtr modelHandle,
+ IntPtr configHandle, InteropFace.RecognizedCallback cb, Rectangle? area)
+ {
+ if (area == null)
+ {
+ return InteropFace.Recognize(sourceHandle, modelHandle, configHandle, IntPtr.Zero, cb);
+ }
+
+ var rect = area.Value.ToMarshalable();
+ return InteropFace.Recognize(sourceHandle, modelHandle, configHandle, ref rect, cb);
+ }
+
+ private static async Task<FaceRecognitionResult> InvokeRecognizeAsync(MediaVisionSource source,
+ FaceRecognitionModel recognitionModel, Rectangle? area,
+ FaceRecognitionConfiguration config)
+ {
+ if (source == null)
+ {
+ throw new ArgumentNullException(nameof(source));
+ }
+ if (recognitionModel == null)
+ {
+ throw new ArgumentNullException(nameof(recognitionModel));
+ }
+
+ TaskCompletionSource<FaceRecognitionResult> tcs = new TaskCompletionSource<FaceRecognitionResult>();
+
+ using (var cb = ObjectKeeper.Get(GetRecognizedCallback(tcs)))
+ {
+ InvokeRecognize(source.Handle, recognitionModel.Handle, EngineConfiguration.GetHandle(config),
+ cb.Target, area).Validate("Failed to perform face recognition.");
+
+ return await tcs.Task;
+ }
+ }
+
+ private static FaceRecognitionResult CreateRecognitionResult(
+ IntPtr faceLocationPtr, IntPtr faceLabelPtr, double confidence)
+ {
+ int faceLabel = 0;
+ if (faceLabelPtr != IntPtr.Zero)
+ {
+ faceLabel = Marshal.ReadInt32(faceLabelPtr);
+ }
+
+ Rectangle? faceLocation = null;
+ if (faceLocationPtr != IntPtr.Zero)
+ {
+ var area = Marshal.PtrToStructure<global::Interop.MediaVision.Rectangle>(faceLocationPtr);
+ faceLocation = area.ToApiStruct();
+ }
+
+ return new FaceRecognitionResult(faceLabelPtr != IntPtr.Zero, confidence, faceLabel, faceLocation);
+ }
+
+ private static InteropFace.RecognizedCallback GetRecognizedCallback(
+ TaskCompletionSource<FaceRecognitionResult> tcs)
+ {
+ return (IntPtr sourceHandle, IntPtr recognitionModelHandle,
+ IntPtr engineCfgHandle, IntPtr faceLocationPtr, IntPtr faceLabelPtr, double confidence, IntPtr _) =>
+ {
+ try
+ {
+ if (!tcs.TrySetResult(CreateRecognitionResult(faceLocationPtr, faceLabelPtr, confidence)))
+ {
+ Log.Error(MediaVisionLog.Tag, "Failed to set result");
+ }
+ }
+ catch (Exception e)
+ {
+ MultimediaLog.Error(MediaVisionLog.Tag, "Setting recognition result failed.", e);
+ tcs.TrySetException(e);
+ }
+ };
+ }
+
+ /// <summary>
+ /// Determines eye-blink condition on media source.
+ /// </summary>
+ /// <param name="source">The source of the media to recognize eye-blink condition for.</param>
+ /// <param name="bound">The bounding the face at the source.</param>
+ /// <returns>A task that represents the asynchronous recognition operation.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ObjectDisposedException"><paramref name="source"/> has already been disposed of.</exception>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public static async Task<EyeCondition> RecognizeEyeConditionAsync(MediaVisionSource source,
+ Rectangle bound)
+ {
+ return await RecognizeEyeConditionAsync(source, bound, null);
+ }
+
+ /// <summary>
+ /// Determines eye-blink condition on media source.
+ /// </summary>
+ /// <param name="source">The source of the media to recognize eye-blink condition for.</param>
+ /// <param name="bound">The bounding the face at the source.</param>
+ /// <param name="config">The configuration used for eye-blink condition recognition. This value can be null.</param>
+ /// <returns>A task that represents the asynchronous recognition operation.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ObjectDisposedException">
+ /// <paramref name="source"/> has already been disposed of.\n
+ /// -or-\n
+ /// <paramref name="config"/> has already been disposed of.
+ /// </exception>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public static async Task<EyeCondition> RecognizeEyeConditionAsync(MediaVisionSource source,
+ Rectangle bound, FaceRecognitionConfiguration config)
+ {
+ if (source == null)
+ {
+ throw new ArgumentNullException(nameof(source));
+ }
+
+ TaskCompletionSource<EyeCondition> tcs = new TaskCompletionSource<EyeCondition>();
+
+ InteropFace.EyeConditionRecognizedCallback cb = (IntPtr sourceHandle, IntPtr engineCfgHandle,
+ global::Interop.MediaVision.Rectangle faceLocation, EyeCondition eyeCondition, IntPtr _) =>
+ {
+ Log.Info(MediaVisionLog.Tag, $"Eye condition recognized, eye condition : {eyeCondition}");
+ if (!tcs.TrySetResult(eyeCondition))
+ {
+ Log.Error(MediaVisionLog.Tag, "Failed to set eye condition result");
+ }
+ };
+
+ using (var cbKeeper = ObjectKeeper.Get(cb))
+ {
+ InteropFace.RecognizeEyeCondition(source.Handle, EngineConfiguration.GetHandle(config),
+ bound.ToMarshalable(), cb).Validate("Failed to perform eye condition recognition.");
+
+ return await tcs.Task;
+ }
+ }
+
+ /// <summary>
+ /// Determines facial expression on media source.
+ /// </summary>
+ /// <param name="source">The source of the media to recognize facial expression for.</param>
+ /// <param name="bound">The location bounding the face at the source.</param>
+ /// <returns>A task that represents the asynchronous recognition operation.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ObjectDisposedException"><paramref name="source"/> has already been disposed of.</exception>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public static async Task<FacialExpression> RecognizeFacialExpressionAsync(MediaVisionSource source,
+ Rectangle bound)
+ {
+ return await RecognizeFacialExpressionAsync(source, bound, null);
+ }
+
+ /// <summary>
+ /// Determines facial expression on media source.
+ /// </summary>
+ /// <param name="source">The source of the media to recognize facial expression for.</param>
+ /// <param name="bound">The location bounding the face at the source.</param>
+ /// <param name="config">The configuration used for expression recognition. This value can be null.</param>
+ /// <returns>A task that represents the asynchronous recognition operation.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ObjectDisposedException">
+ /// <paramref name="source"/> has already been disposed of.\n
+ /// -or-\n
+ /// <paramref name="config"/> has already been disposed of.
+ /// </exception>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public static async Task<FacialExpression> RecognizeFacialExpressionAsync(MediaVisionSource source,
+ Rectangle bound, FaceRecognitionConfiguration config)
+ {
+ if (source == null)
+ {
+ throw new ArgumentNullException(nameof(source));
+ }
+
+ TaskCompletionSource<FacialExpression> tcsResult = new TaskCompletionSource<FacialExpression>();
+
+ InteropFace.MvFaceFacialExpressionRecognizedCallback cb = (IntPtr sourceHandle, IntPtr engineCfgHandle,
+ global::Interop.MediaVision.Rectangle faceLocation, FacialExpression facialExpression, IntPtr _) =>
+ {
+ Log.Info(MediaVisionLog.Tag, $"Facial expression recognized, expression : {facialExpression}");
+ if (!tcsResult.TrySetResult(facialExpression))
+ {
+ Log.Error(MediaVisionLog.Tag, "Failed to set facial result");
+ }
+ };
+
+ using (var cbKeeper = ObjectKeeper.Get(cb))
+ {
+ InteropFace.RecognizeFacialExpression(source.Handle, EngineConfiguration.GetHandle(config),
+ bound.ToMarshalable(), cb).
+ Validate("Failed to perform facial expression recognition.");
+
+ return await tcsResult.Task;
+ }
+ }
+ }
+}
+
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/FaceTracker.cs b/src/Tizen.Multimedia.Vision/MediaVision/FaceTracker.cs
new file mode 100755
index 0000000..4824579
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/FaceTracker.cs
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+using InteropFace = Interop.MediaVision.Face;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides the ability to track faces on image sources.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public static class FaceTracker
+ {
+
+ /// <summary>
+ /// Performs face tracking on the source with the trackingModel.
+ /// </summary>
+ /// <param name="source">The source of the media to recognize face for.</param>
+ /// <param name="trackingModel">The model will be used for tracking.</param>
+ /// <param name="doLearn">The value indicating whether model learning while tracking. If it is true then model will try to learn
+ /// (if it supports learning feature), otherwise model will be not learned during the invoking tracking iteration.
+ /// Learning process improves tracking correctness, but can decrease tracking performance.</param>
+ /// <returns>A task that represents the asynchronous tracking operation.</returns>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="source"/> is null.\n
+ /// -or-\n
+ /// <paramref name="trackingModel"/> is null.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// <paramref name="source"/> has already been disposed of.\n
+ /// -or-\n
+ /// <paramref name="trackingModel"/> has already been disposed of.
+ /// </exception>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <exception cref="InvalidOperationException"><paramref name="trackingModel"/> is not prepared.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public static async Task<FaceTrackingResult> TrackAsync(MediaVisionSource source,
+ FaceTrackingModel trackingModel, bool doLearn)
+ {
+ if (source == null)
+ {
+ throw new ArgumentNullException(nameof(source));
+ }
+ if (trackingModel == null)
+ {
+ throw new ArgumentNullException(nameof(trackingModel));
+ }
+
+ TaskCompletionSource<FaceTrackingResult> tcs = new TaskCompletionSource<FaceTrackingResult>();
+
+ using (var cb = ObjectKeeper.Get(GetTrackCallback(tcs)))
+ {
+ InteropFace.Track(source.Handle, trackingModel.Handle, IntPtr.Zero,
+ cb.Target, doLearn).Validate("Failed to perform face tracking.");
+
+ return await tcs.Task;
+ }
+ }
+
+ private static InteropFace.TrackedCallback GetTrackCallback(TaskCompletionSource<FaceTrackingResult> tcs)
+ {
+ return (IntPtr sourceHandle, IntPtr trackingModelHandle, IntPtr engineCfgHandle,
+ IntPtr locationPtr, double confidence, IntPtr _) =>
+ {
+ try
+ {
+ Quadrangle area = null;
+ if (locationPtr != IntPtr.Zero)
+ {
+ area = Marshal.PtrToStructure<global::Interop.MediaVision.Quadrangle>(locationPtr).ToApiStruct();
+ }
+
+ Log.Info(MediaVisionLog.Tag, $"Tracked area : {area}, confidence : {confidence}");
+
+ if (!tcs.TrySetResult(new FaceTrackingResult(locationPtr != IntPtr.Zero, confidence, area)))
+ {
+ Log.Error(MediaVisionLog.Tag, "Failed to set tracking result");
+ }
+ }
+ catch (Exception e)
+ {
+ MultimediaLog.Error(MediaVisionLog.Tag, "Setting tracking result failed.", e);
+ tcs.TrySetException(e);
+ }
+ };
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/FaceTrackingModel.cs b/src/Tizen.Multimedia.Vision/MediaVision/FaceTrackingModel.cs
new file mode 100755
index 0000000..bc54478
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/FaceTrackingModel.cs
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.IO;
+using InteropModel = Interop.MediaVision.FaceTrackingModel;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents face tracking model.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public class FaceTrackingModel : IDisposable
+ {
+ private IntPtr _handle = IntPtr.Zero;
+ private bool _disposed = false;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="FaceTrackingModel"/> class.
+ /// </summary>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public FaceTrackingModel()
+ {
+ InteropModel.Create(out _handle).Validate("Failed to create FaceTrackingModel.");
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="FaceTrackingModel"/> class with the specified path.
+ /// </summary>
+ /// <remarks>
+ /// Models has been saved by <see cref="Save()"/> can be loaded.
+ /// </remarks>
+ /// <param name="modelPath">Path to the model to load.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="modelPath"/> is null.</exception>
+ /// <exception cref="FileNotFoundException"><paramref name="modelPath"/> is invalid.</exception>
+ /// <exception cref="NotSupportedException">
+ /// The feature is not supported.\n
+ /// -or-\n
+ /// <paramref name="modelPath"/> is not supported format.
+ /// </exception>
+ /// <exception cref="UnauthorizedAccessException">No permission to access the specified file.</exception>
+ /// <seealso cref="Save()"/>
+ /// <since_tizen> 3</since_tizen>
+ public FaceTrackingModel(string modelPath)
+ {
+ if (modelPath == null)
+ {
+ throw new ArgumentNullException(nameof(modelPath));
+ }
+ InteropModel.Load(modelPath, out _handle).Validate("Failed to load FaceTrackingModel from file.");
+ }
+
+ ~FaceTrackingModel()
+ {
+ Dispose(false);
+ }
+
+ private MediaVisionError InvokePrepare(MediaVisionSource source, Quadrangle region)
+ {
+ if (region != null)
+ {
+ var quad = region.ToMarshalable();
+ return InteropModel.Prepare(Handle, IntPtr.Zero, source.Handle, ref quad);
+ }
+
+ return InteropModel.Prepare(Handle, IntPtr.Zero, source.Handle, IntPtr.Zero);
+ }
+
+ /// <summary>
+ /// Initializes tracking model by the location of the face to be tracked.
+ ///
+ /// It is usually called once after tracking model is created and each time before tracking
+ /// is started for the new sequence of sources which is not the direct continuation of
+ /// the sequence for which tracking has been performed before. But it is allowed to call it
+ /// between tracking sessions to allow Media Vision start to track more accurately.
+ /// </summary>
+ /// <remarks>
+ /// <paramref name="region"/> needs to be the position of the face to be tracked when called first time for the tracking model.
+ /// <paramref name="region"/> is fitted to the valid region of <paramref name="source"/> if <paramref name="region"/> has invalid points.
+ /// </remarks>
+ /// <param name="source">The source where face location is specified.
+ /// Usually it is the first frame of the video or the first image in the continuous
+ /// image sequence planned to be used for tracking.</param>
+ /// <param name="region">The region determining position of the face to be tracked on the source.
+ /// If null, then tracking model will try to find previously tracked face by itself.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="FaceTrackingModel"/> has already been disposed of.\n
+ /// -or-\n
+ /// <paramref name="source"/> has already bean disposed of.
+ /// </exception>
+ /// <since_tizen> 3</since_tizen>
+ public void Prepare(MediaVisionSource source, Quadrangle region)
+ {
+ if (source == null)
+ {
+ throw new ArgumentNullException(nameof(source));
+ }
+
+ InvokePrepare(source, region).Validate("Failed to prepare tracking model.");
+ }
+
+ /// <summary>
+ /// Saves the tracking model to the file.
+ /// </summary>
+ /// <param name="path">Path to the file to save the model.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
+ /// <exception cref="UnauthorizedAccessException">No permission to write to the specified path.</exception>
+ /// <exception cref="ObjectDisposedException">The <see cref="FaceRecognitionModel"/> has already been disposed of.</exception>
+ /// <exception cref="DirectoryNotFoundException">The directory for <paramref name="path"/> does not exist.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public void Save(string path)
+ {
+ if (path == null)
+ {
+ throw new ArgumentNullException(nameof(path));
+ }
+
+ var ret = InteropModel.Save(path, Handle);
+
+ if (ret == MediaVisionError.InvalidPath)
+ {
+ throw new DirectoryNotFoundException($"The directory for the path({path}) does not exist.");
+ }
+
+ ret.Validate("Failed to save tracking model to file");
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_disposed)
+ {
+ return;
+ }
+
+ InteropModel.Destroy(_handle);
+ _disposed = true;
+ }
+
+ internal IntPtr Handle
+ {
+ get
+ {
+ if (_disposed)
+ {
+ throw new ObjectDisposedException(nameof(FaceTrackingModel));
+ }
+ return _handle;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/FaceTrackingResult.cs b/src/Tizen.Multimedia.Vision/MediaVision/FaceTrackingResult.cs
new file mode 100755
index 0000000..3ee5f6b
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/FaceTrackingResult.cs
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents result of face tracking operation.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public class FaceTrackingResult
+ {
+ internal FaceTrackingResult(bool success, double confidence, Quadrangle region)
+ {
+ Success = success;
+ Confidence = confidence;
+ Region = region;
+ }
+
+ /// <summary>
+ /// Gets the value indicating the recognition is successful.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public bool Success { get; }
+
+ /// <summary>
+ /// Gets the region which determines new position of the tracked face on the source.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public Quadrangle Region { get; }
+
+ /// <summary>
+ /// The confidence of the tracking model that new location of the face was determined correctly
+ /// (value from 0.0 to 1.0). If no location was determined during last track iteration, then value is 0.0.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public double Confidence { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/FacialExpression.cs b/src/Tizen.Multimedia.Vision/MediaVision/FacialExpression.cs
new file mode 100755
index 0000000..c136d97
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/FacialExpression.cs
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Specifies the expression types for faces.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public enum FacialExpression
+ {
+ /// <summary>
+ /// Unknown face expression.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Unknown,
+
+ /// <summary>
+ /// Face expression is neutral.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Neutral,
+
+ /// <summary>
+ /// Face expression is smiling.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Smile,
+
+ /// <summary>
+ /// Face expression is sadness.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Sadness,
+
+ /// <summary>
+ /// Face expression is surprise.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Surprise,
+
+ /// <summary>
+ /// Face expression is anger.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Anger,
+
+ /// <summary>
+ /// Face expression is fear.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Fear,
+
+ /// <summary>
+ /// Face expression is disgust.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Disgust
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/ImageFillConfiguration.cs b/src/Tizen.Multimedia.Vision/MediaVision/ImageFillConfiguration.cs
new file mode 100755
index 0000000..3b22467
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/ImageFillConfiguration.cs
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents a configuration of fill operations of <see cref="ImageObject"/> instances.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public class ImageFillConfiguration : EngineConfiguration
+ {
+ private const string KeyScaleFactor = "MV_IMAGE_RECOGNITION_OBJECT_SCALE_FACTOR";
+ private const string KeyMaxKeypoints = "MV_IMAGE_RECOGNITION_OBJECT_MAX_KEYPOINTS_NUM";
+
+ /// <summary>
+ /// A read-only field that represents the default value of <see cref="ObjectScaleFactor"/>.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public static readonly double DefaultScaleFactor = 1.2;
+
+ /// <summary>
+ /// A read-only field that represents the default value of <see cref="ObjectMaxKeyPoints"/>.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public static readonly int DefaultMaxKeypoints = 1000;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ImageFillConfiguration"/> class.
+ /// </summary>
+ /// <exception cref="System.NotSupportedException">The feature is not supported.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public ImageFillConfiguration() : base("image_recognition")
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the scale factor the image to be recognized.\n
+ /// The value of the factor will be used for resizing of the images (objects) for recognition.
+ /// The default value is 1.2.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">The <see cref="ImageFillConfiguration"/> already has been disposed of.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public double ObjectScaleFactor
+ {
+ get
+ {
+ return GetDouble(KeyScaleFactor);
+ }
+ set
+ {
+ Set(KeyScaleFactor, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the maximum key points should be detected on the image.\n
+ /// The maximal number of key points can be selected on the image object to calculate descriptors.
+ /// This key points will be used for image (object) recognition and has to be specified as integer number.
+ /// The default value is 1000.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">The <see cref="ImageFillConfiguration"/> already has been disposed of.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public int ObjectMaxKeyPoints
+ {
+ get
+ {
+ return GetInt(KeyMaxKeypoints);
+ }
+ set
+ {
+ Set(KeyMaxKeypoints, value);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/ImageObject.cs b/src/Tizen.Multimedia.Vision/MediaVision/ImageObject.cs
new file mode 100755
index 0000000..e56967e
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/ImageObject.cs
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.IO;
+using InteropImage = Interop.MediaVision.Image;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents an image object.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public class ImageObject : IDisposable
+ {
+ private IntPtr _handle = IntPtr.Zero;
+ private bool _disposed = false;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ImageObject"/> class.
+ /// </summary>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public ImageObject()
+ {
+ InteropImage.Create(out _handle).Validate("Failed to create image object");
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ImageObject"/> class from the specified file.
+ /// </summary>
+ /// <remarks>
+ /// ImageObject has been saved by <see cref="Save()"/> can be loaded.
+ /// </remarks>
+ /// <param name="path">Path to the image object to load.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
+ /// <exception cref="FileNotFoundException"><paramref name="path"/> is invalid.</exception>
+ /// <exception cref="NotSupportedException">
+ /// The feature is not supported.\n
+ /// -or-\n
+ /// <paramref name="path"/> is not supported file.
+ /// </exception>
+ /// <exception cref="UnauthorizedAccessException">No permission to access the specified file.</exception>
+ /// <seealso cref="Save(string)"/>
+ /// <since_tizen> 3</since_tizen>
+ public ImageObject(string path)
+ {
+ if (path == null)
+ {
+ throw new ArgumentNullException(nameof(path));
+ }
+ InteropImage.Load(path, out _handle).Validate("Failed to load image object from file");
+ }
+
+ ~ImageObject()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Gets a value that determines how well an image object can be recognized.
+ /// </summary>
+ /// <remarks>
+ /// If recognition rate is too low, try to use another image or change some configuration parameters
+ /// and fill the image object again.
+ /// </remarks>
+ /// <value>
+ /// Recognition rate determines how well an image object can be recognized. This value can be from 0 to 1.
+ /// If the recognition rate is 0 object can not be recognized and the bigger it is the more likely to recognize the object.
+ /// </value>
+ /// <exception cref="ObjectDisposedException">The <see cref="ImageObject"/> has already been disposed of.</exception>
+ /// <seealso cref="ImageFillConfiguration"/>
+ /// <seealso cref="Fill(MediaVisionSource)"/>
+ /// <seealso cref="Fill(MediaVisionSource, ImageFillConfiguration)"/>
+ /// <seealso cref="Fill(MediaVisionSource, Rectangle)"/>
+ /// <seealso cref="Fill(MediaVisionSource, ImageFillConfiguration, Rectangle)"/>
+ /// <since_tizen> 3</since_tizen>
+ public double RecognitionRate
+ {
+ get
+ {
+ InteropImage.GetRecognitionRate(Handle, out var rate).Validate("Failed to get recognition rate");
+ return rate;
+ }
+ }
+
+ #region Methods
+ /// <summary>
+ /// Gets the label for the image object.
+ /// </summary>
+ /// <returns>
+ /// The label value if the <see cref="ImageObject"/> has label, otherwise null.
+ /// </returns>
+ /// <exception cref="ObjectDisposedException">The <see cref="ImageObject"/> has already been disposed of.</exception>
+ /// <seealso cref="SetLabel(int)"/>
+ /// <since_tizen> 3</since_tizen>
+ public int? GetLabel()
+ {
+ var ret = InteropImage.GetLabel(Handle, out var label);
+
+ if (ret == MediaVisionError.NoData)
+ {
+ return null;
+ }
+
+ ret.Validate("Failed to get label");
+ return label;
+ }
+
+ /// <summary>
+ /// Sets the label for the <see cref="ImageObject"/>.
+ /// </summary>
+ /// <seealso cref="GetLabel"/>
+ /// <since_tizen> 3</since_tizen>
+ public void SetLabel(int label)
+ {
+ InteropImage.SetLabel(Handle, label).Validate("Failed to set label");
+ }
+
+ /// <summary>
+ /// Fills the image object.\n
+ /// Extracts data from @a source image which will be needed for recognition of depicted object in @a location.
+ /// </summary>
+ /// <param name="source">The source image where image object is depicted.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="ImageObject"/> has already been disposed of.\n
+ /// -or-\n
+ /// <paramref name="source"/> has already been disposed of.
+ /// </exception>
+ /// <since_tizen> 3</since_tizen>
+ public void Fill(MediaVisionSource source)
+ {
+ InvokeFill(source, null, null);
+ }
+
+ /// <summary>
+ /// Fills the image object.\n
+ /// Extracts data from @a source image which will be needed for recognition of depicted object in @a location.
+ /// </summary>
+ /// <param name="source">The source image where image object is depicted.</param>
+ /// <param name="config">The configuration used for extract recognition data from source. This value can be null.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="ImageObject"/> has already been disposed of.\n
+ /// -or-\n
+ /// <paramref name="source"/> has already been disposed of.\n
+ /// -or-\n
+ /// <paramref name="config"/> has already been disposed of.
+ /// </exception>
+ /// <since_tizen> 3</since_tizen>
+ public void Fill(MediaVisionSource source, ImageFillConfiguration config)
+ {
+ InvokeFill(source, config, null);
+ }
+
+ /// <summary>
+ /// Fills the image object.\n
+ /// Extracts data from @a source image which will be needed for recognition of depicted object in @a location.
+ /// </summary>
+ /// <param name="source">The source image where image object is depicted.</param>
+ /// <param name="rect">Rectangular bound of the image object on the source image.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="ImageObject"/> has already been disposed of.\n
+ /// -or-\n
+ /// <paramref name="source"/> has already been disposed of.\n
+ /// </exception>
+ /// <since_tizen> 3</since_tizen>
+ public void Fill(MediaVisionSource source, Rectangle rect)
+ {
+ InvokeFill(source, null, rect);
+ }
+
+ /// <summary>
+ /// Fills the image object.\n
+ /// Extracts data from @a source image which will be needed for recognition of depicted object in @a location.
+ /// </summary>
+ /// <param name="source">The source image where image object is depicted.</param>
+ /// <param name="config">The configuration used for extract recognition data from source. This value can be null.</param>
+ /// <param name="rect">Rectangular bound of the image object on the source image.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="ImageObject"/> has already been disposed of.\n
+ /// -or-\n
+ /// <paramref name="source"/> has already been disposed of.\n
+ /// -or-\n
+ /// <paramref name="config"/> has already been disposed of.
+ /// </exception>
+ /// <since_tizen> 3</since_tizen>
+ public void Fill(MediaVisionSource source, ImageFillConfiguration config, Rectangle rect)
+ {
+ InvokeFill(source, config, rect);
+ }
+
+ private MediaVisionError InvokeFill(IntPtr source, IntPtr config, Rectangle? area)
+ {
+ if (area == null)
+ {
+ return InteropImage.Fill(Handle, config, source, IntPtr.Zero);
+ }
+
+ var rect = area.Value.ToMarshalable();
+
+ return InteropImage.Fill(Handle, config, source, ref rect);
+ }
+
+ private void InvokeFill(MediaVisionSource source, ImageFillConfiguration config, Rectangle? area)
+ {
+ if (source == null)
+ {
+ throw new ArgumentNullException(nameof(source));
+ }
+
+ InvokeFill(source.Handle, EngineConfiguration.GetHandle(config), area).
+ Validate("Failed to fill the image object");
+ }
+
+ /// <summary>
+ /// Saves the image object.
+ /// </summary>
+ /// <param name="path">Path to the file to save the model.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
+ /// <exception cref="UnauthorizedAccessException">No permission to write to the specified path.</exception>
+ /// <exception cref="ObjectDisposedException">The <see cref="FaceRecognitionModel"/> has already been disposed of.</exception>
+ /// <exception cref="DirectoryNotFoundException">The directory for <paramref name="path"/> does not exist.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public void Save(string path)
+ {
+ if (path == null)
+ {
+ throw new ArgumentNullException(nameof(path));
+ }
+
+ var ret = InteropImage.Save(path, Handle);
+
+ if (ret == MediaVisionError.InvalidPath)
+ {
+ throw new DirectoryNotFoundException($"The directory for the path({path}) does not exist.");
+ }
+
+ ret.Validate("Failed to save the image object");
+ }
+ #endregion
+
+ #region IDisposable-support
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_disposed)
+ {
+ return;
+ }
+
+ InteropImage.Destroy(_handle);
+ _disposed = true;
+ }
+
+ internal IntPtr Handle
+ {
+ get
+ {
+ if (_disposed)
+ {
+ throw new ObjectDisposedException(nameof(ImageObject));
+ }
+ return _handle;
+ }
+ }
+ #endregion
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/ImageRecognitionConfiguration.cs b/src/Tizen.Multimedia.Vision/MediaVision/ImageRecognitionConfiguration.cs
new file mode 100755
index 0000000..15dbd2e
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/ImageRecognitionConfiguration.cs
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents a configuration of <see cref="ImageRecognizer"/>.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public class ImageRecognitionConfiguration : EngineConfiguration
+ {
+ private const string KeySceneScaleFactor = "MV_IMAGE_RECOGNITION_SCENE_SCALE_FACTOR";
+ private const string KeySceneMaxKeypoints = "MV_IMAGE_RECOGNITION_SCENE_MAX_KEYPOINTS_NUM";
+
+ private const string KeyMinKeypointsMatch = "MV_IMAGE_RECOGNITION_MIN_MATCH_NUM";
+ private const string KeyReqMatchPartKey = "MV_IMAGE_RECOGNITION_REQ_MATCH_PART";
+ private const string KeyTolerantPartMatchingError = "MV_IMAGE_RECOGNITION_TOLERANT_MATCH_PART_ERR";
+
+ /// <summary>
+ /// A read-only field that represents the default value of <see cref="KeySceneScaleFactor"/>.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public static readonly double DefaultSceneScaleFactor = 1.2;
+
+ /// <summary>
+ /// A read-only field that represents the default value of <see cref="SceneMaxKeyPoints"/>.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public static readonly int DefaultSceneMaxKeypoints = 5000;
+
+ /// <summary>
+ /// A read-only field that represents the default value of <see cref="MinKeyPointMatches"/>.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public static readonly int DefaultMinKeyPointMatches = 30;
+
+ /// <summary>
+ /// A read-only field that represents the default value of <see cref="RequiredMatchingPart"/>.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public static readonly double DefaultRequiredMatchPart = 0.05;
+
+ /// <summary>
+ /// A read-only field that represents the default value of <see cref="TolerantPartMatchError"/>.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public static readonly double DefaultTolerantPartMatchError = 0.1;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ImageRecognitionConfiguration"/> class.
+ /// </summary>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public ImageRecognitionConfiguration() : base("image_recognition")
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the scene scale factor.
+ /// </summary>
+ /// <value>
+ /// The value indicating the factor will be used for resizing of the scene including the images (objects) for recognition.
+ /// The default is 1.2.
+ /// </value>
+ /// <exception cref="ObjectDisposedException">The <see cref="ImageRecognitionConfiguration"/> already has been disposed of.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public double SceneScaleFactor
+ {
+ get
+ {
+ return GetDouble(KeySceneScaleFactor);
+ }
+ set
+ {
+ Set(KeySceneScaleFactor, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the maximum key points that should be detected on the scene.
+ /// The maximal number of key points can be selected on the scene including the images (objects) to calculate descriptors.
+ /// </summary>
+ /// <value>
+ /// The maximal key points for image recognition.
+ /// The default is 5000.
+ /// </value>
+ /// <exception cref="ObjectDisposedException">The <see cref="ImageRecognitionConfiguration"/> already has been disposed of.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="value"/> is less than zero.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public int SceneMaxKeyPoints
+ {
+ get
+ {
+ return GetInt(KeySceneMaxKeypoints);
+ }
+ set
+ {
+ if (value < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(SceneMaxKeyPoints), value,
+ $"{nameof(SceneMaxKeyPoints)} can't be less than zero.");
+ }
+ Set(KeySceneMaxKeypoints, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the minimum number of key points matches required for recognition.
+ /// </summary>
+ /// <value>
+ /// The minimal number of key points should be matched between an image and a scene for image objects recognition.
+ /// The default is 30.
+ /// </value>
+ /// <exception cref="ObjectDisposedException">The <see cref="ImageRecognitionConfiguration"/> already has been disposed of.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="value"/> is less than zero.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public int MinKeyPointMatches
+ {
+ get
+ {
+ return GetInt(KeyMinKeypointsMatch);
+ }
+ set
+ {
+ if (value < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(MinKeyPointMatches), value,
+ $"{nameof(MinKeyPointMatches)} can't be less than zero.");
+ }
+ Set(KeyMinKeypointsMatch, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the required matching part for the image recognition.
+ /// To recognize occluded or hidden an image by other images, required relative part of the matches in respect to the total
+ /// amount of matching keypoints required for image recognition. Too low value will result in unsustainable behavior,
+ /// but effect of object overlapping will be reduced.
+ /// </summary>
+ /// <value>
+ /// The value indicating required relative part of the matches; can be from 0 to 1, inclusive.
+ /// The default is 0.05.
+ /// </value>
+ /// <exception cref="ObjectDisposedException">The <see cref="ImageRecognitionConfiguration"/> already has been disposed of.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="value"/> is less than zero.\n
+ /// -or-\n
+ /// <paramref name="value"/> is greater than one.
+ /// </exception>
+ /// <since_tizen> 3</since_tizen>
+ public double RequiredMatchingPart
+ {
+ get
+ {
+ return GetDouble(KeyReqMatchPartKey);
+ }
+ set
+ {
+ if (value < 0 || value > 1)
+ {
+ throw new ArgumentOutOfRangeException(nameof(value), value, "Valid range is 0 to 1 inclusive,");
+ }
+ Set(KeyReqMatchPartKey, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the part matching error for the image recognition.\n
+ /// Allowable error of matches number.
+ /// </summary>
+ /// <value>
+ /// The value indicating allowable error of matches; can be from 0 to 1, inclusive.
+ /// The default is 0.1.
+ /// </value>
+ /// <exception cref="ObjectDisposedException">The <see cref="ImageRecognitionConfiguration"/> already has been disposed of.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="value"/> is less than zero.\n
+ /// -or-\n
+ /// <paramref name="value"/> is greater than one.
+ /// </exception>
+ /// <since_tizen> 3</since_tizen>
+ public double TolerantPartMatchError
+ {
+ get
+ {
+ return GetDouble(KeyTolerantPartMatchingError);
+ }
+ set
+ {
+ if (value < 0 || value > 1)
+ {
+ throw new ArgumentOutOfRangeException(nameof(value), value, "Valid range is 0 to 1 inclusive.");
+ }
+
+ Set(KeyTolerantPartMatchingError, value);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/ImageRecognitionResult.cs b/src/Tizen.Multimedia.Vision/MediaVision/ImageRecognitionResult.cs
new file mode 100755
index 0000000..0eafa1a
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/ImageRecognitionResult.cs
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents a result of RecognizeAsync operations of <see cref="ImageRecognizer"/>.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public class ImageRecognitionResult
+ {
+
+ internal ImageRecognitionResult(bool success, Quadrangle region)
+ {
+ Success = success;
+ Region = region;
+ }
+
+ /// <summary>
+ /// The region of recognized image object on the source image.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public Quadrangle Region { get; }
+
+ /// <summary>
+ /// Gets the value indicating the recognition is successful.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public bool Success { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/ImageRecognizer.cs b/src/Tizen.Multimedia.Vision/MediaVision/ImageRecognizer.cs
new file mode 100755
index 0000000..ef9c27e
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/ImageRecognizer.cs
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+using InteropImage = Interop.MediaVision.Image;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides the ability to recognize images on image sources.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public static class ImageRecognizer
+ {
+ /// <summary>
+ /// Recognizes the given image objects on the source image.\n
+ /// </summary>
+ /// <param name="source">The source image on which image objects will be recognized.</param>
+ /// <param name="imageObjects">The array of image objects which will be processed as targets of recognition.</param>
+ /// <returns>A task that represents the asynchronous recognition operation.</returns>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="source"/> is null.\n
+ /// -or-\n
+ /// <paramref name="imageObjects"/> is null.\n
+ /// -or-\n
+ /// <paramref name="imageObjects"/> contains null reference.
+ /// </exception>
+ /// <exception cref="ArgumentException"><paramref name="imageObjects"/> has no elements.(The length is zero.)</exception>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <exception cref="ObjectDisposedException"><paramref name="source"/> has already been disposed of.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public static async Task<IEnumerable<ImageRecognitionResult>> RecognizeAsync(
+ MediaVisionSource source, ImageObject[] imageObjects)
+ {
+ return await RecognizeAsync(source, imageObjects, null);
+ }
+
+ /// <summary>
+ /// Recognizes the given image objects on the source image.\n
+ /// </summary>
+ /// <param name="source">The source image on which image objects will be recognized.</param>
+ /// <param name="imageObjects">The array of image objects which will be processed as targets of recognition.</param>
+ /// <param name="config">The configuration used for recognition. This value can be null.</param>
+ /// <returns>A task that represents the asynchronous recognition operation.</returns>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="source"/> is null.\n
+ /// -or-\n
+ /// <paramref name="imageObjects"/> is null.\n
+ /// -or-\n
+ /// <paramref name="imageObjects"/> contains null elements.
+ /// </exception>
+ /// <exception cref="ArgumentException"><paramref name="imageObjects"/> has no elements.(The length is zero.)</exception>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <exception cref="ObjectDisposedException">
+ /// <paramref name="source"/> has already been disposed of.\n
+ /// -or-\n
+ /// <paramref name="config"/> has already been disposed of.
+ /// </exception>
+ /// <since_tizen> 3</since_tizen>
+ public static async Task<IEnumerable<ImageRecognitionResult>> RecognizeAsync(MediaVisionSource source,
+ ImageObject[] imageObjects, ImageRecognitionConfiguration config)
+ {
+ if (source == null)
+ {
+ throw new ArgumentNullException(nameof(source));
+ }
+ if (imageObjects == null)
+ {
+ throw new ArgumentNullException(nameof(imageObjects));
+ }
+ if (imageObjects.Length == 0)
+ {
+ throw new ArgumentException("No image object to recognize.", nameof(imageObjects));
+ }
+
+ var tcs = new TaskCompletionSource<IEnumerable<ImageRecognitionResult>>();
+
+ using (var cb = ObjectKeeper.Get(GetCallback(tcs)))
+ using (var imageHandles = ObjectKeeper.Get(GetHandles(imageObjects)))
+ {
+ InteropImage.Recognize(source.Handle, imageHandles.Target, imageHandles.Target.Length,
+ EngineConfiguration.GetHandle(config), cb.Target).
+ Validate("Failed to perform image recognition.");
+
+ return await tcs.Task;
+ }
+ }
+
+ private static ImageRecognitionResult[] CreateResults(IntPtr[] locations, uint numOfObjects)
+ {
+ ImageRecognitionResult[] results = new ImageRecognitionResult[numOfObjects];
+
+ for (int i = 0; i < numOfObjects; i++)
+ {
+ Quadrangle quadrangle = locations[i] != IntPtr.Zero ?
+ Marshal.PtrToStructure<global::Interop.MediaVision.Quadrangle>(locations[i]).ToApiStruct() : null;
+
+ results[i] = new ImageRecognitionResult(locations[i] != IntPtr.Zero, quadrangle);
+ }
+
+ return results;
+ }
+
+ private static InteropImage.RecognizedCallback GetCallback(
+ TaskCompletionSource<IEnumerable<ImageRecognitionResult>> tcs)
+ {
+ return (IntPtr source, IntPtr engineConfig, IntPtr imageObjectHandles,
+ IntPtr[] locations, uint numOfObjects, IntPtr _) =>
+ {
+ try
+ {
+ if (!tcs.TrySetResult(CreateResults(locations, numOfObjects)))
+ {
+ Log.Info(MediaVisionLog.Tag, "Failed to set recognition result");
+ }
+ }
+ catch (Exception e)
+ {
+ MultimediaLog.Error(MediaVisionLog.Tag, "Failed to handle recognition result", e);
+ tcs.TrySetException(e);
+ }
+ };
+ }
+
+ private static IntPtr[] GetHandles(ImageObject[] imageObjects)
+ {
+ IntPtr[] imageHandles = new IntPtr[imageObjects.Length];
+ for (int i = 0; i < imageObjects.Length; i++)
+ {
+ if (imageObjects[i] == null)
+ {
+ throw new ArgumentNullException($"{nameof(imageObjects)}[{i}]");
+ }
+
+ imageHandles[i] = imageObjects[i].Handle;
+ }
+
+ return imageHandles;
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/ImageTracker.cs b/src/Tizen.Multimedia.Vision/MediaVision/ImageTracker.cs
new file mode 100755
index 0000000..bcf07c1
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/ImageTracker.cs
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+using InteropImage = Interop.MediaVision.Image;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides the ability to track images on image sources.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public static class ImageTracker
+ {
+ /// <summary>
+ /// Tracks the given image tracking model on the current frame.
+ /// </summary>
+ /// <param name="source">The current image of sequence where image tracking model will be tracked.</param>
+ /// <param name="trackingModel">The image tracking model which processed as target of tracking.</param>
+ /// <returns>A task that represents the asynchronous tracking operation.</returns>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="source"/> is null.\n
+ /// -or-\n
+ /// <paramref name="trackingModel"/> is null.
+ /// </exception>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <exception cref="ObjectDisposedException">
+ /// <paramref name="source"/> has already been disposed of.\n
+ /// -or-\n
+ /// <paramref name="trackingModel"/> has already been disposed of.
+ /// </exception>
+ /// <exception cref="ArgumentException"><paramref name="trackingModel"/> has no target.</exception>
+ /// <seealso cref="ImageTrackingModel.SetTarget(ImageObject)"/>
+ /// <since_tizen> 3</since_tizen>
+ public static async Task<Quadrangle> TrackAsync(MediaVisionSource source,
+ ImageTrackingModel trackingModel)
+ {
+ return await TrackAsync(source, trackingModel, null);
+ }
+
+ /// <summary>
+ /// Tracks the given image tracking model on the current frame and <see cref="ImageTrackingConfiguration"/>.
+ /// </summary>
+ /// <param name="source">The current image of sequence where image tracking model will be tracked.</param>
+ /// <param name="trackingModel">The image tracking model which processed as target of tracking.</param>
+ /// <param name="config">The configuration used for tracking. This value can be null.</param>
+ /// <returns>A task that represents the asynchronous tracking operation.</returns>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="source"/> is null.\n
+ /// -or-\n
+ /// <paramref name="trackingModel"/> is null.
+ /// </exception>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <exception cref="ObjectDisposedException">
+ /// <paramref name="source"/> has already been disposed of.\n
+ /// -or-\n
+ /// <paramref name="trackingModel"/> has already been disposed of.\n
+ /// -or-\n
+ /// <paramref name="config"/> has already been disposed of.
+ /// </exception>
+ /// <exception cref="ArgumentException"><paramref name="trackingModel"/> has no target.</exception>
+ /// <seealso cref="ImageTrackingModel.SetTarget(ImageObject)"/>
+ /// <since_tizen> 3</since_tizen>
+ public static async Task<Quadrangle> TrackAsync(MediaVisionSource source,
+ ImageTrackingModel trackingModel, ImageTrackingConfiguration config)
+ {
+ if (source == null)
+ {
+ throw new ArgumentNullException(nameof(source));
+ }
+ if (trackingModel == null)
+ {
+ throw new ArgumentNullException(nameof(trackingModel));
+ }
+
+ TaskCompletionSource<Quadrangle> tcs = new TaskCompletionSource<Quadrangle>();
+
+ using (var cb = ObjectKeeper.Get(GetCallback(tcs)))
+ {
+ InteropImage.Track(source.Handle, trackingModel.Handle, EngineConfiguration.GetHandle(config),
+ cb.Target).Validate("Failed to perform image tracking.");
+
+ return await tcs.Task;
+ }
+ }
+
+ private static InteropImage.TrackedCallback GetCallback(TaskCompletionSource<Quadrangle> tcs)
+ {
+ return (IntPtr sourceHandle, IntPtr imageTrackingModelHandle, IntPtr engineCfgHandle, IntPtr locationPtr, IntPtr _) =>
+ {
+ try
+ {
+ Quadrangle region = null;
+ if (locationPtr != IntPtr.Zero)
+ {
+ region = Marshal.PtrToStructure<global::Interop.MediaVision.Quadrangle>(locationPtr).ToApiStruct();
+ }
+
+ Log.Info(MediaVisionLog.Tag, $"Image tracked, region : {region}");
+
+ if (!tcs.TrySetResult(region))
+ {
+ Log.Info(MediaVisionLog.Tag, "Failed to set track result");
+ }
+ }
+ catch (Exception e)
+ {
+ MultimediaLog.Error(MediaVisionLog.Tag, "Failed to handle track result", e);
+ tcs.TrySetException(e);
+ }
+ };
+
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/ImageTrackingConfiguration.cs b/src/Tizen.Multimedia.Vision/MediaVision/ImageTrackingConfiguration.cs
new file mode 100755
index 0000000..042b64b
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/ImageTrackingConfiguration.cs
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents a configuration of <see cref="ImageTracker"/>.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public class ImageTrackingConfiguration : ImageRecognitionConfiguration
+ {
+ private const string KeyHistoryAmount = "MV_IMAGE_TRACKING_HISTORY_AMOUNT";
+ private const string KeyExpectedOffset = "MV_IMAGE_TRACKING_EXPECTED_OFFSET";
+ private const string KeyUseStabilization = "MV_IMAGE_TRACKING_USE_STABLIZATION";
+ private const string KeyStabilizationTolerantShift = "MV_IMAGE_TRACKING_STABLIZATION_TOLERANT_SHIFT";
+ private const string KeyStabilizationSpeed = "MV_IMAGE_TRACKING_STABLIZATION_SPEED";
+ private const string KeyStabilizationAcceleration = "MV_IMAGE_TRACKING_STABLIZATION_ACCELERATION";
+
+ /// <summary>
+ /// A read-only field that represents the default value of <see cref="HistoryAmount"/>.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public static readonly int DefaultHistoryAmount = 3;
+
+ /// <summary>
+ /// A read-only field that represents the default value of <see cref="ExpectedOffset"/>.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public static readonly double DefaultExpectedOffset = 0;
+
+ /// <summary>
+ /// A read-only field that represents the default value of <see cref="IsStabilizationEnabled"/>.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public static readonly bool DefaultStabilizationEnabled = true;
+
+ /// <summary>
+ /// A read-only field that represents the default value of <see cref="StabilizationTolerantShift"/>.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public static readonly double DefaultStabilizationTolerantShift = 0.00006;
+
+ /// <summary>
+ /// A read-only field that represents the default value of <see cref="StabilizationSpeed"/>.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public static readonly double DefaultStabilizationSpeed = 0.3;
+
+ /// <summary>
+ /// A read-only field that represents the default value of <see cref="StabilizationAcceleration"/>.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public static readonly double DefaultStabilizationAcceleration = 0.1;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ImageTrackingConfiguration"/> class.
+ /// </summary>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public ImageTrackingConfiguration()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the number of recognition results in the tracking history.
+ /// </summary>
+ /// <value>
+ /// The number of previous recognition results, which will influence the stabilization.\n
+ /// The default is 3.
+ /// </value>
+ /// <exception cref="ObjectDisposedException">The <see cref="ImageTrackingConfiguration"/> already has been disposed of.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="value"/> is less than zero.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public int HistoryAmount
+ {
+ get
+ {
+ return GetInt(KeyHistoryAmount);
+ }
+ set
+ {
+ if (value < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(HistoryAmount), value,
+ $"{nameof(HistoryAmount)} can't be less than zero.");
+ }
+ Set(KeyHistoryAmount, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the expected tracking offset.
+ /// </summary>
+ /// <value>
+ /// Relative offset value, for which the object offset is expected (relative to the object size in the current frame).\n
+ /// The default is 0.
+ /// </value>
+ /// <exception cref="ObjectDisposedException">The <see cref="ImageTrackingConfiguration"/> already has been disposed of.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public double ExpectedOffset
+ {
+ get
+ {
+ return GetDouble(KeyExpectedOffset);
+ }
+ set
+ {
+ Set(KeyExpectedOffset, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the acceleration of the tracking stabilization.
+ /// </summary>
+ /// <value>
+ /// Acceleration will be used for image stabilization (relative to the distance from current location to stabilized location);
+ /// from 0 to 1, inclusive.\n
+ /// The default is 0.1.
+ /// </value>
+ /// <exception cref="ObjectDisposedException">The <see cref="ImageTrackingConfiguration"/> already has been disposed of.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="value"/> is less than zero.\n
+ /// -or-\n
+ /// <paramref name="value"/> is greater than one.
+ /// </exception>
+ /// <since_tizen> 3</since_tizen>
+ public double StabilizationAcceleration
+ {
+ get
+ {
+ return GetDouble(KeyStabilizationAcceleration);
+ }
+ set
+ {
+ if (value < 0 || value > 1)
+ {
+ throw new ArgumentOutOfRangeException(nameof(value), value, "Valid range is 0 to 1 inclusive.");
+ }
+
+ Set(KeyStabilizationAcceleration, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the speed of the tracking stabilization.
+ /// </summary>
+ /// <value>
+ /// The start speed value used for image stabilization.\n
+ /// The default is 0.3.
+ /// </value>
+ /// <exception cref="ObjectDisposedException">The <see cref="ImageTrackingConfiguration"/> already has been disposed of.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public double StabilizationSpeed
+ {
+ get
+ {
+ return GetDouble(KeyStabilizationSpeed);
+ }
+ set
+ {
+ Set(KeyStabilizationSpeed, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the relative tolerant shift for the tracking stabilization.
+ /// </summary>
+ /// <value>
+ /// It is component of tolerant shift which will be ignored by stabilization process.
+ /// (this value is relative to the object size in the current frame).
+ /// Tolerant shift will be computed like R * S + C, where R is the value set to <see cref="StabilizationTolerantShift"/>,
+ /// S is the area of object location on frame, C is a constant value 1.3.\n
+ /// \n
+ /// The default is 0.00006.
+ /// </value>
+ /// <exception cref="ObjectDisposedException">The <see cref="ImageTrackingConfiguration"/> already has been disposed of.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public double StabilizationTolerantShift
+ {
+ get
+ {
+ return GetDouble(KeyStabilizationTolerantShift);
+ }
+ set
+ {
+ Set(KeyStabilizationTolerantShift, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the state of the contour stabilization during tracking process.
+ /// </summary>
+ /// <value>
+ /// true if the contour stabilization is enabled; otherwise, false.\n
+ /// The default is true.
+ /// </value>
+ /// <exception cref="ObjectDisposedException">The <see cref="ImageTrackingConfiguration"/> already has been disposed of.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public bool IsStabilizationEnabled
+ {
+ get
+ {
+ return GetBool(KeyUseStabilization);
+ }
+ set
+ {
+ Set(KeyUseStabilization, value);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/ImageTrackingModel.cs b/src/Tizen.Multimedia.Vision/MediaVision/ImageTrackingModel.cs
new file mode 100755
index 0000000..c727d28
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/ImageTrackingModel.cs
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.IO;
+using InteropModel = Interop.MediaVision.ImageTrackingModel;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents the image tracking model interface.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public class ImageTrackingModel : IDisposable
+ {
+ private IntPtr _handle = IntPtr.Zero;
+ private bool _disposed = false;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ImageTrackingModel"/> class.
+ /// </summary>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public ImageTrackingModel()
+ {
+ InteropModel.Create(out _handle).Validate("Failed to create FaceTrackingModel");
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ImageTrackingModel"/> class with the specified path.
+ /// </summary>
+ /// <remarks>
+ /// Model have been saved by <see cref="Save()"/> can be loaded.
+ /// </remarks>
+ /// <param name="modelPath">Path to the model to load.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="modelPath"/> is null.</exception>
+ /// <exception cref="FileNotFoundException"><paramref name="modelPath"/> is invalid.</exception>
+ /// <exception cref="NotSupportedException">
+ /// The feature is not supported.\n
+ /// -or-\n
+ /// <paramref name="modelPath"/> is not supported format.
+ /// </exception>
+ /// <exception cref="UnauthorizedAccessException">No permission to access the specified file.</exception>
+ /// <seealso cref="Save()"/>
+ /// <since_tizen> 3</since_tizen>
+ public ImageTrackingModel(string modelPath)
+ {
+ if (modelPath == null)
+ {
+ throw new ArgumentNullException(nameof(modelPath));
+ }
+ InteropModel.Load(modelPath, out _handle).Validate("Failed to load ImageTrackingModel from file");
+ }
+
+ ~ImageTrackingModel()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Sets target of image tracking model.\n
+ /// Sets image object which will be tracked by using tracking functionality with this tracking model.
+ /// </summary>
+ /// <param name="imageObject">Image object which will be set as the target for tracking.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="imageObject"/> is null.</exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="ImageTrackingModel"/> has already been disposed of.\n
+ /// -or-\n
+ /// <paramref name="imageObject"/> has already been disposed of.
+ /// </exception>
+ /// <since_tizen> 3</since_tizen>
+ public void SetTarget(ImageObject imageObject)
+ {
+ if (imageObject == null)
+ {
+ throw new ArgumentNullException(nameof(imageObject));
+ }
+
+ InteropModel.SetTarget(imageObject.Handle, Handle).
+ Validate("Failed to set target of image tracking model");
+ }
+
+ /// <summary>
+ /// Refreshes the state of image tracking model.\n
+ /// Clears moving history and change state to undetected. It is usually called each time before tracking is started
+ /// for the new sequence of sources which is not the direct continuation of the sequence for which tracking has been performed before.
+ /// Tracking algorithm will try to find image by itself.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">The <see cref="ImageTrackingModel"/> has already been disposed of.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public void Refresh()
+ {
+ InteropModel.Refresh(Handle, IntPtr.Zero).Validate("Failed to refresh state");
+ }
+
+ /// <summary>
+ /// Saves tracking model to the file.
+ /// </summary>
+ /// <param name="path">Path to the file to save the model.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
+ /// <exception cref="UnauthorizedAccessException">No permission to write to the specified path.</exception>
+ /// <exception cref="ObjectDisposedException">The <see cref="ImageTrackingModel"/> has already been disposed of.</exception>
+ /// <exception cref="DirectoryNotFoundException">The directory for <paramref name="path"/> does not exist.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public void Save(string path)
+ {
+ if (path == null)
+ {
+ throw new ArgumentNullException(path);
+ }
+
+ var ret = InteropModel.Save(path, Handle);
+
+ if (ret == MediaVisionError.InvalidPath)
+ {
+ throw new DirectoryNotFoundException($"The directory for the path({path}) does not exist.");
+ }
+
+ ret.Validate("Failed to save tracking model to file");
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_disposed)
+ {
+ return;
+ }
+
+ InteropModel.Destroy(_handle);
+ _disposed = true;
+ }
+
+ internal IntPtr Handle
+ {
+ get
+ {
+ if (_disposed)
+ {
+ throw new ObjectDisposedException(nameof(ImageTrackingModel));
+ }
+ return _handle;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/MediaVisionError.cs b/src/Tizen.Multimedia.Vision/MediaVision/MediaVisionError.cs
new file mode 100755
index 0000000..8298cfd
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/MediaVisionError.cs
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.IO;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Multimedia
+{
+ internal static class MediaVisionLog
+ {
+ internal const string Tag = "Tizen.Multimedia.MediaVision";
+ }
+
+ /// <summary>
+ /// Enumeration for media vision's error codes.
+ /// </summary>
+ internal enum MediaVisionError
+ {
+ MediaVisionErrorCode = -0x019D0000,
+ /// <summary>
+ /// Successful
+ /// </summary>
+ None = ErrorCode.None,
+ /// <summary>
+ /// Not supported
+ /// </summary>
+ NotSupported = ErrorCode.NotSupported,
+ /// <summary>
+ /// Message too long
+ /// </summary>
+ MsgTooLong = ErrorCode.MsgTooLong,
+ /// <summary>
+ /// No data
+ /// </summary>
+ NoData = ErrorCode.NoData,
+ /// <summary>
+ /// Key not available
+ /// </summary>
+ KeyNotAvailable = ErrorCode.KeyNotAvailable,
+ /// <summary>
+ /// Out of memory
+ /// </summary>
+ OutOfMemory = ErrorCode.OutOfMemory,
+ /// <summary>
+ /// Invalid parameter
+ /// </summary>
+ InvalidParameter = ErrorCode.InvalidParameter,
+ /// <summary>
+ /// Invalid operation
+ /// </summary>
+ InvalidOperation = ErrorCode.InvalidOperation,
+ /// <summary>
+ /// Permission denied
+ /// </summary>
+ PermissionDenied = ErrorCode.NotPermitted,
+ /// <summary>
+ /// Not supported format
+ /// </summary>
+ NotSupportedFormat = MediaVisionErrorCode | 0x01,
+ /// <summary>
+ /// Internal error
+ /// </summary>
+ Internal = MediaVisionErrorCode | 0x02,
+ /// <summary>
+ /// Invalid data
+ /// </summary>
+ InvalidData = MediaVisionErrorCode | 0x03,
+ /// <summary>
+ /// Invalid path (Since 3.0)
+ /// </summary>
+ InvalidPath = MediaVisionErrorCode | 0x04
+ }
+
+ internal static class MediaVisionErrorExtensions
+ {
+ public static void Validate(this MediaVisionError error, string msg)
+ {
+ if (error == MediaVisionError.None)
+ {
+ return;
+ }
+
+ switch (error)
+ {
+ case MediaVisionError.NotSupported:
+ throw new NotSupportedException(msg);
+ case MediaVisionError.MsgTooLong:
+ throw new ArgumentException($"{msg} : Message too long.");
+ case MediaVisionError.NoData:
+ throw new InvalidOperationException($"{msg} : No Data.");
+ case MediaVisionError.KeyNotAvailable:
+ throw new ArgumentException($"{msg} : Key Not Available.");
+ case MediaVisionError.OutOfMemory:
+ throw new OutOfMemoryException($"{msg} : Out of Memory.");
+ case MediaVisionError.InvalidParameter:
+ throw new ArgumentException($"{msg} : Invalid argument.");
+ case MediaVisionError.InvalidOperation:
+ throw new InvalidOperationException($"{msg} : Invalid Operation.");
+ case MediaVisionError.PermissionDenied:
+ throw new UnauthorizedAccessException($"{msg} : Permission Denied.");
+ case MediaVisionError.NotSupportedFormat:
+ throw new NotSupportedException($"{msg} : Not Supported Format.");
+ case MediaVisionError.Internal:
+ throw new InvalidOperationException($"{msg} : Internal Error.");
+ case MediaVisionError.InvalidData:
+ throw new ArgumentException($"{msg} : Invalid Data.");
+ case MediaVisionError.InvalidPath:
+ throw new FileNotFoundException($"{msg} : Invalid Path.");
+ default:
+ throw new InvalidOperationException($"{msg} : Unknown Error.");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/MediaVisionSource.cs b/src/Tizen.Multimedia.Vision/MediaVision/MediaVisionSource.cs
new file mode 100755
index 0000000..3bb4c2f
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/MediaVisionSource.cs
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Diagnostics;
+using InteropSource = Interop.MediaVision.MediaSource;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents the media vision source to keep information on image or video frame data as raw buffer.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public class MediaVisionSource : IBufferOwner, IDisposable
+ {
+ private IntPtr _handle = IntPtr.Zero;
+ private bool _disposed = false;
+
+ internal MediaVisionSource()
+ {
+ InteropSource.Create(out _handle).Validate("Failed to create media vision source");
+ }
+
+ private MediaVisionSource(Action<IntPtr> fillAction)
+ : this()
+ {
+ try
+ {
+ fillAction(_handle);
+ }
+ catch(Exception)
+ {
+ InteropSource.Destroy(_handle);
+ _disposed = true;
+ throw;
+ }
+ }
+
+ private static void FillMediaPacket(IntPtr handle, MediaPacket mediaPacket)
+ {
+ Debug.Assert(handle != IntPtr.Zero);
+
+ if (mediaPacket == null)
+ {
+ throw new ArgumentNullException(nameof(mediaPacket));
+ }
+
+ InteropSource.FillMediaPacket(handle, mediaPacket.GetHandle()).
+ Validate("Failed to fill media packet");
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MediaVisionSource"/> class based on the <see cref="MediaPacket"/>.
+ /// </summary>
+ /// <param name="mediaPacket">The <see cref="MediaPacket"/> from which the source will be filled.</param>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="mediaPacket"/> is null.</exception>
+ /// <exception cref="ObjectDisposedException"><paramref name="mediaPacket"/> has already been disposed of.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public MediaVisionSource(MediaPacket mediaPacket)
+ : this(handle => FillMediaPacket(handle, mediaPacket))
+ {
+ }
+
+ private static void FillBuffer(IntPtr handle, byte[] buffer, uint width, uint height, Colorspace colorspace)
+ {
+ Debug.Assert(handle != IntPtr.Zero);
+
+ if (buffer == null)
+ {
+ throw new ArgumentNullException(nameof(buffer));
+ }
+
+ if (buffer.Length == 0)
+ {
+ throw new ArgumentException("Buffer.Length is zero.", nameof(buffer));
+ }
+
+ if (colorspace == Colorspace.Invalid)
+ {
+ throw new ArgumentException($"color space must not be {Colorspace.Invalid}.", nameof(colorspace));
+ }
+
+ ValidationUtil.ValidateEnum(typeof(Colorspace), colorspace, nameof(colorspace));
+
+ InteropSource.FillBuffer(handle, buffer, buffer.Length, width, height, colorspace).
+ Validate("Failed to fill buffer");
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MediaVisionSource"/> class based on the buffer and <see cref="Colorspace"/>.
+ /// </summary>
+ /// <param name="buffer">The buffer of image data.</param>
+ /// <param name="width">The width of image.</param>
+ /// <param name="height">The height of image.</param>
+ /// <param name="colorspace">The image <see cref="Colorspace"/>.</param>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="buffer"/> has no element.(The length is zero.)\n
+ /// -or-\n
+ /// <paramref name="colorspace"/> is invalid.
+ /// </exception>
+ /// <since_tizen> 3</since_tizen>
+ public MediaVisionSource(byte[] buffer, uint width, uint height, Colorspace colorspace)
+ : this(handle => FillBuffer(handle, buffer, width, height, colorspace))
+ {
+ }
+
+ ~MediaVisionSource()
+ {
+ Dispose(false);
+ }
+
+ private IMediaBuffer _buffer;
+
+ /// <summary>
+ /// Gets the buffer of the media source.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">The <see cref="MediaVisionSource"/> has already been disposed of.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public IMediaBuffer Buffer
+ {
+ get
+ {
+ if (_buffer == null)
+ {
+ IntPtr bufferHandle = IntPtr.Zero;
+ int bufferSize = 0;
+
+ InteropSource.GetBuffer(Handle, out bufferHandle, out bufferSize).
+ Validate("Failed to get buffer");
+
+ _buffer = new DependentMediaBuffer(this, bufferHandle, bufferSize);
+ }
+ return _buffer;
+ }
+ }
+
+ /// <summary>
+ /// Gets height of the media source.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">The <see cref="MediaVisionSource"/> has already been disposed of.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public uint Height
+ {
+ get
+ {
+ uint height = 0;
+ var ret = InteropSource.GetHeight(Handle, out height);
+ MultimediaDebug.AssertNoError(ret);
+ return height;
+ }
+ }
+
+ /// <summary>
+ /// Gets width of the media source.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">The <see cref="MediaVisionSource"/> has already been disposed of.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public uint Width
+ {
+ get
+ {
+ uint width = 0;
+ var ret = InteropSource.GetWidth(Handle, out width);
+ MultimediaDebug.AssertNoError(ret);
+ return width;
+ }
+ }
+
+ /// <summary>
+ /// Gets <see cref="Colorspace"/> of the media source.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">The <see cref="MediaVisionSource"/> has already been disposed of.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public Colorspace Colorspace
+ {
+ get
+ {
+ Colorspace colorspace = Colorspace.Invalid;
+ var ret = InteropSource.GetColorspace(Handle, out colorspace);
+ MultimediaDebug.AssertNoError(ret);
+ return colorspace;
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_disposed)
+ {
+ return;
+ }
+ InteropSource.Destroy(_handle);
+ _disposed = true;
+ }
+
+ internal IntPtr Handle
+ {
+ get
+ {
+ if (_disposed)
+ {
+ throw new ObjectDisposedException(nameof(MediaVisionSource));
+ }
+ return _handle;
+ }
+ }
+
+ bool IBufferOwner.IsBufferAccessible(object buffer, MediaBufferAccessMode accessMode)
+ {
+ return true;
+ }
+
+ bool IBufferOwner.IsDisposed
+ {
+ get { return _disposed; }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/MovementDetectedEventArgs.cs b/src/Tizen.Multimedia.Vision/MediaVision/MovementDetectedEventArgs.cs
new file mode 100755
index 0000000..3456c5d
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/MovementDetectedEventArgs.cs
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides data for the <see cref="MovementDetector.Detected"/> event.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public class MovementDetectedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MovementDetectedEventArgs"/> class.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public MovementDetectedEventArgs(IEnumerable<Rectangle> areas)
+ {
+ Areas = areas;
+ }
+
+ /// <summary>
+ /// Gets a set of rectangular regions where movement was detected.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public IEnumerable<Rectangle> Areas { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/MovementDetectionConfiguration.cs b/src/Tizen.Multimedia.Vision/MediaVision/MovementDetectionConfiguration.cs
new file mode 100755
index 0000000..a9aebe8
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/MovementDetectionConfiguration.cs
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents a configuration of <see cref="MovementDetector"/>.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public class MovementDetectionConfiguration : SurveillanceEngineConfiguration
+ {
+ private const string KeyThreshold = "MV_SURVEILLANCE_MOVEMENT_DETECTION_THRESHOLD";
+
+ /// <summary>
+ /// A read-only field that represents the default value of <see cref="Threshold"/>.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public static readonly int DefaultThreshold = 10;
+
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MovementDetectionConfiguration"/> class.
+ /// </summary>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public MovementDetectionConfiguration()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets movement detection threshold.\n
+ /// This value might be set before subscription on <see cref="MovementDetector.Detected"/> event
+ /// to specify the sensitivity of the movement detector.
+ /// </summary>
+ /// <value>
+ /// The value indicating the sensitivity of the <see cref="MovementDetector"/> from 0 to 255 inclusive
+ /// where 255 means that no movements will be detected and 0 means that all frame changes
+ /// will be interpreted as movements.\n
+ /// The default is 10.
+ /// </value>
+ /// <exception cref="ObjectDisposedException">The <see cref="MovementDetectionConfiguration"/> already has been disposed of.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="value"/> is less than zero.\n
+ /// -or-\n
+ /// <paramref name="value"/> is greater than 255.
+ /// </exception>
+ /// <since_tizen> 3</since_tizen>
+ public int Threshold
+ {
+ get
+ {
+ return GetInt(KeyThreshold);
+ }
+ set
+ {
+ if (value < 0 || value > 255)
+ {
+ throw new ArgumentOutOfRangeException(nameof(Threshold), value,
+ $"Valid {nameof(Threshold)} range is 0 to 255 inclusive");
+ }
+
+ Set(KeyThreshold, value);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/MovementDetector.cs b/src/Tizen.Multimedia.Vision/MediaVision/MovementDetector.cs
new file mode 100755
index 0000000..d5861d0
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/MovementDetector.cs
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using static Interop.MediaVision.Surveillance;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides the ability to detect movement on image sources.
+ /// </summary>
+ /// <seealso cref="MovementDetectionConfiguration"/>
+ /// <since_tizen> 3</since_tizen>
+ public class MovementDetector : SurveillanceEngine
+ {
+ private const string KeyNumberOfRegions = "NUMBER_OF_MOVEMENT_REGIONS";
+ private const string KeyRegions = "MOVEMENT_REGIONS";
+
+ private const string MovementDetectedEventType = "MV_SURVEILLANCE_EVENT_MOVEMENT_DETECTED";
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MovementDetector"/> class.
+ /// </summary>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public MovementDetector() : base(MovementDetectedEventType)
+ {
+ }
+
+ /// <summary>
+ /// Occurs when the movement detected.
+ /// </summary>
+ /// <remarks>The event handler will be executed on an internal thread.</remarks>
+ /// <since_tizen> 3</since_tizen>
+ public event EventHandler<MovementDetectedEventArgs> Detected;
+
+ internal override void OnEventDetected(IntPtr trigger, IntPtr source, int streamId,
+ IntPtr result, IntPtr _)
+ {
+ try
+ {
+ Detected?.Invoke(this, CreateMovementDetectedEventArgs(result));
+ }
+ catch (Exception e)
+ {
+ MultimediaLog.Error(MediaVisionLog.Tag, "Failed to invoke Recognized event.", e);
+ }
+ }
+
+ private static Rectangle[] RetrieveAreas(IntPtr result)
+ {
+ int count = 0;
+ GetResultValue(result, KeyNumberOfRegions, out count).Validate("Failed to get result count");
+
+ if (count == 0)
+ {
+ return new Rectangle[0];
+ }
+
+ var rects = new global::Interop.MediaVision.Rectangle[count];
+
+ GetResultValue(result, KeyRegions, rects).Validate("Failed to get regions");
+
+ return global::Interop.ToApiStruct(rects);
+ }
+
+ private static MovementDetectedEventArgs CreateMovementDetectedEventArgs(IntPtr result)
+ {
+ return new MovementDetectedEventArgs(RetrieveAreas(result));
+ }
+
+
+ /// <summary>
+ /// Adds <see cref="SurveillanceSource"/>.
+ /// </summary>
+ /// <param name="source">The source used for recognition.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ObjectDisposedException">The <see cref="MovementDetector"/> has already been disposed of.</exception>
+ /// <see cref="SurveillanceSource.Push(MediaVisionSource)"/>
+ /// <since_tizen> 3</since_tizen>
+ public void AddSource(SurveillanceSource source)
+ {
+ AddSource(source, null);
+ }
+
+ /// <summary>
+ /// Adds <see cref="SurveillanceSource"/> with the provided <see cref="MovementDetectionConfiguration"/>.
+ /// </summary>
+ /// <param name="source">The source used for recognition.</param>
+ /// <param name="config">The config for the <paramref name="source"/>. This value can be null.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="MovementDetector"/> has already been disposed of.\n
+ /// -or-\n
+ /// <paramref name="config"/> has already been disposed of.
+ /// </exception>
+ /// <see cref="SurveillanceSource.Push(MediaVisionSource)"/>
+ /// <since_tizen> 3</since_tizen>
+ public void AddSource(SurveillanceSource source, MovementDetectionConfiguration config)
+ {
+ InvokeAddSource(source, config);
+ }
+
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/PersonAppearanceDetectedEventArgs.cs b/src/Tizen.Multimedia.Vision/MediaVision/PersonAppearanceDetectedEventArgs.cs
new file mode 100755
index 0000000..7c9576a
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/PersonAppearanceDetectedEventArgs.cs
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides data for the <see cref="PersonAppearanceDetector.Detected"/> event.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public class PersonAppearanceDetectedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PersonAppearanceDetectedEventArgs"/> class.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public PersonAppearanceDetectedEventArgs(IEnumerable<Rectangle> appeared,
+ IEnumerable<Rectangle> disappeared, IEnumerable<Rectangle> tracked)
+ {
+ AppearanceAreas = appeared;
+ DisappearanceAreas = disappeared;
+ TrackedAreas = tracked;
+ }
+
+ /// <summary>
+ /// Gets a set of rectangular regions where appearances of the persons were detected.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public IEnumerable<Rectangle> AppearanceAreas { get; }
+
+ /// <summary>
+ /// Gets a set of rectangular regions where disappearances of the persons were detected.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public IEnumerable<Rectangle> DisappearanceAreas { get; }
+
+ /// <summary>
+ /// Gets a set of rectangular regions where persons were tracked.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public IEnumerable<Rectangle> TrackedAreas { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/PersonAppearanceDetectionConfiguration.cs b/src/Tizen.Multimedia.Vision/MediaVision/PersonAppearanceDetectionConfiguration.cs
new file mode 100755
index 0000000..b4ef07b
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/PersonAppearanceDetectionConfiguration.cs
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents a configuration of <see cref="PersonAppearanceDetector"/> instances.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public class PersonAppearanceDetectionConfiguration : SurveillanceEngineConfiguration
+ {
+ private const string KeySkipFramesCount = "MV_SURVEILLANCE_SKIP_FRAMES_COUNT";
+
+ /// <summary>
+ /// A read-only field that represents the default value of <see cref="SkipFramesCount"/>.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public static readonly int DefaultSkipFramesCount = 0;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PersonAppearanceDetectionConfiguration"/> class.
+ /// </summary>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public PersonAppearanceDetectionConfiguration()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets how many frames will be skipped during push source.\n
+ /// </summary>
+ /// <value>
+ /// The value to specify the number of <see cref="MediaVisionSource"/> calls will be ignored by subscription
+ /// of the event trigger.\n
+ ///
+ /// The default is 0. It means that no frames will be skipped and all <see cref="MediaVisionSource"/> will
+ /// be processed.
+ /// </value>
+ /// <exception cref="ObjectDisposedException">The <see cref="PersonAppearanceDetectionConfiguration"/> already has been disposed of.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="value"/> is less than zero.</exception>
+ /// <seealso cref="SurveillanceSource.Push(MediaVisionSource)"/>
+ /// <since_tizen> 3</since_tizen>
+ public int SkipFramesCount
+ {
+ get
+ {
+ return GetInt(KeySkipFramesCount);
+ }
+ set
+ {
+ if (value < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(SkipFramesCount), value,
+ $"{nameof(SkipFramesCount)} can't be less than zero.");
+ }
+ Set(KeySkipFramesCount, value);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/PersonAppearanceDetector.cs b/src/Tizen.Multimedia.Vision/MediaVision/PersonAppearanceDetector.cs
new file mode 100755
index 0000000..ef6d305
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/PersonAppearanceDetector.cs
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using static Interop.MediaVision.Surveillance;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides the ability to detect person appearance changes on image sources.
+ /// </summary>
+ /// <seealso cref="PersonAppearanceDetectionConfiguration"/>
+ /// <since_tizen> 3</since_tizen>
+ public class PersonAppearanceDetector : SurveillanceEngine
+ {
+ private const string KeyAppearedNumber = "NUMBER_OF_APPEARED_PERSONS";
+ private const string KeyDisappearedNumber = "NUMBER_OF_DISAPPEARED_PERSONS";
+ private const string KeyTrackedNumber = "NUMBER_OF_TRACKED_PERSONS";
+ private const string KeyAppearedLocations = "APPEARED_PERSONS_LOCATIONS";
+ private const string KeyDisappearedLocations = "DISAPPEARED_PERSONS_LOCATIONS";
+ private const string KeyTrackedLocations = "TRACKED_PERSONS_LOCATIONS";
+
+ private const string PersonAppearanceEventType = "MV_SURVEILLANCE_EVENT_PERSON_APPEARED_DISAPEARED";
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PersonAppearanceDetector"/> class.
+ /// </summary>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public PersonAppearanceDetector() : base(PersonAppearanceEventType)
+ {
+ }
+
+ /// <summary>
+ /// Occurs when the any appearance changes detected.
+ /// </summary>
+ /// <remarks>The event handler will be executed on an internal thread.</remarks>
+ /// <since_tizen> 3</since_tizen>
+ public event EventHandler<PersonAppearanceDetectedEventArgs> Detected;
+
+ internal override void OnEventDetected(IntPtr trigger, IntPtr source, int streamId,
+ IntPtr result, IntPtr _)
+ {
+ try
+ {
+ Detected?.Invoke(this, CreatePersonAppearanceChangedEventArgs(result));
+ }
+ catch (Exception e)
+ {
+ MultimediaLog.Error(MediaVisionLog.Tag, "Failed to invoke Recognized event.", e);
+ }
+ }
+
+
+ private PersonAppearanceDetectedEventArgs CreatePersonAppearanceChangedEventArgs(IntPtr result)
+ {
+ return new PersonAppearanceDetectedEventArgs(
+ GetResultAreas(result, KeyAppearedNumber, KeyAppearedLocations),
+ GetResultAreas(result, KeyDisappearedNumber, KeyDisappearedLocations),
+ GetResultAreas(result, KeyTrackedNumber, KeyTrackedLocations)
+ );
+ }
+
+ private static Rectangle[] GetResultAreas(IntPtr result, string countKey, string regionsKey)
+ {
+ int count = 0;
+ GetResultValue(result, countKey, out count).Validate("Failed to get result");
+
+ var rects = new global::Interop.MediaVision.Rectangle[count];
+ if (count > 0)
+ {
+ GetResultValue(result, regionsKey, rects).Validate("Failed to get result");
+ }
+
+ return global::Interop.ToApiStruct(rects);
+ }
+
+ /// <summary>
+ /// Adds <see cref="SurveillanceSource"/>.
+ /// </summary>
+ /// <param name="source">The source used for recognition.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ObjectDisposedException">The <see cref="PersonAppearanceDetector"/> has already been disposed of.</exception>
+ /// <see cref="SurveillanceSource.Push(MediaVisionSource)"/>
+ /// <since_tizen> 3</since_tizen>
+ public void AddSource(SurveillanceSource source)
+ {
+ AddSource(source, null);
+ }
+
+ /// <summary>
+ /// Adds <see cref="SurveillanceSource"/> with the provided <see cref="PersonAppearanceDetectionConfiguration"/>.
+ /// </summary>
+ /// <param name="source">The source used for recognition.</param>
+ /// <param name="config">The config for the <paramref name="source"/>. This value can be null.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="PersonAppearanceDetector"/> has already been disposed of.\n
+ /// -or-\n
+ /// <paramref name="config"/> has already been disposed of.
+ /// </exception>
+ /// <see cref="SurveillanceSource.Push(MediaVisionSource)"/>
+ /// <since_tizen> 3</since_tizen>
+ public void AddSource(SurveillanceSource source, PersonAppearanceDetectionConfiguration config)
+ {
+ InvokeAddSource(source, config);
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/PersonRecognitionConfiguration.cs b/src/Tizen.Multimedia.Vision/MediaVision/PersonRecognitionConfiguration.cs
new file mode 100755
index 0000000..867de87
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/PersonRecognitionConfiguration.cs
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents a configuration of <see cref="PersonRecognizer"/> instances.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public class PersonRecognitionConfiguration : SurveillanceEngineConfiguration
+ {
+ private const string KeyFaceRecognitionModelFilePath = "MV_SURVEILLANCE_FACE_RECOGNITION_MODEL_FILE_PATH";
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PersonRecognitionConfiguration"/> class.
+ /// </summary>
+ /// <param name="modelPath">Path to the face recognition model.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="modelPath"/> is null.</exception>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public PersonRecognitionConfiguration(string modelPath)
+ {
+ FaceRecognitionModelPath = modelPath;
+ }
+
+ /// <summary>
+ /// Gets or sets face recognition model file path.
+ /// </summary>
+ /// <exception cref="ArgumentNullException"><paramref name="modelPath"/> is null.</exception>
+ /// <exception cref="ObjectDisposedException">The <see cref="PersonRecognitionConfiguration"/> already has been disposed of.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public string FaceRecognitionModelPath
+ {
+ get
+ {
+ return GetString(KeyFaceRecognitionModelFilePath);
+ }
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(FaceRecognitionModelPath));
+ }
+ Set(KeyFaceRecognitionModelFilePath, value);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/PersonRecognitionInfo.cs b/src/Tizen.Multimedia.Vision/MediaVision/PersonRecognitionInfo.cs
new file mode 100755
index 0000000..a7589c8
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/PersonRecognitionInfo.cs
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents a result of <see cref="PersonRecognizer"/> instances.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public class PersonRecognitionInfo
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PersonRecognitionInfo"/> class.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public PersonRecognitionInfo(Rectangle area, int label, double confidence)
+ {
+ Area = area;
+ Label = label;
+ Confidence = confidence;
+ }
+
+ /// <summary>
+ /// Gets the rectangular location where person face was recognized.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public Rectangle Area { get; }
+
+ /// <summary>
+ /// Gets the label that correspond to the recognized person.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public int Label { get; }
+
+ /// <summary>
+ /// Gets the confidence value that correspond to the recognized person.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public double Confidence { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/PersonRecognizedEventArgs.cs b/src/Tizen.Multimedia.Vision/MediaVision/PersonRecognizedEventArgs.cs
new file mode 100755
index 0000000..bbe65a9
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/PersonRecognizedEventArgs.cs
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides data for the <see cref="PersonRecognizer.Recognized"/> event.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public class PersonRecognizedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PersonRecognizedEventArgs"/> class.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public PersonRecognizedEventArgs(IEnumerable<PersonRecognitionInfo> recognitionInfo)
+ {
+ Recognitions = recognitionInfo;
+ }
+
+ /// <summary>
+ /// Gets a set of information that correspond to the recognized persons.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public IEnumerable<PersonRecognitionInfo> Recognitions { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/PersonRecognizer.cs b/src/Tizen.Multimedia.Vision/MediaVision/PersonRecognizer.cs
new file mode 100755
index 0000000..e14e38c
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/PersonRecognizer.cs
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using static Interop.MediaVision.Surveillance;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides the ability to recognize person on image sources.
+ /// </summary>
+ /// <seealso cref="PersonRecognitionConfiguration"/>
+ /// <since_tizen> 3</since_tizen>
+ public class PersonRecognizer : SurveillanceEngine
+ {
+ private const string KeyCount = "NUMBER_OF_PERSONS";
+ private const string KeyLocations = "PERSONS_LOCATIONS";
+ private const string KeyLabels = "PERSONS_LABELS";
+ private const string KeyConfidences = "PERSONS_CONFIDENCES";
+
+ private const string PersonRecognizedEventType = "MV_SURVEILLANCE_EVENT_PERSON_RECOGNIZED";
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PersonRecognizer"/> class.
+ /// </summary>
+ /// <exception cref="NotSupportedException">The feature is not supported.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public PersonRecognizer() : base(PersonRecognizedEventType)
+ {
+ }
+
+ /// <summary>
+ /// Occurs when a person recognized.
+ /// </summary>
+ /// <remarks>The event handler will be executed on an internal thread.</remarks>
+ /// <seealso cref="PersonRecognitionConfiguration.FaceRecognitionModelPath"/>
+ /// <since_tizen> 3</since_tizen>
+ public event EventHandler<PersonRecognizedEventArgs> Recognized;
+
+ internal override void OnEventDetected(IntPtr trigger, IntPtr source, int streamId,
+ IntPtr result, IntPtr _)
+ {
+ try
+ {
+ Recognized?.Invoke(this, CreatePersonRecognizedEventArgs(result));
+ }
+ catch (Exception e)
+ {
+ MultimediaLog.Error(MediaVisionLog.Tag, "Failed to invoke Recognized event.", e);
+ }
+ }
+
+ private PersonRecognizedEventArgs CreatePersonRecognizedEventArgs(IntPtr result)
+ {
+ int count;
+
+ GetResultValue(result, KeyCount, out count).Validate("Failed to get result count");
+
+ var recognitionInfo = new PersonRecognitionInfo[count];
+
+ if (count > 0)
+ {
+ var rects = new global::Interop.MediaVision.Rectangle[count];
+ GetResultValue(result, KeyLocations, rects).Validate("Failed to get location");
+
+ var labels = new int[count];
+ GetResultValue(result, KeyLabels, labels).Validate("Failed to get label");
+
+ var confidences = new double[count];
+ GetResultValue(result, KeyConfidences, confidences).Validate("Failed to get confidence");
+
+ for (int i = 0; i < count; i++)
+ {
+ recognitionInfo[i] = new PersonRecognitionInfo(rects[i].ToApiStruct(),
+ labels[i], confidences[i]);
+ }
+ }
+
+ return new PersonRecognizedEventArgs(recognitionInfo);
+ }
+
+ /// <summary>
+ /// Adds <see cref="SurveillanceSource"/> with the provided <see cref="PersonRecognitionConfiguration"/>.
+ /// </summary>
+ /// <param name="source">The source used for recognition.</param>
+ /// <param name="config">The config for the <paramref name="source"/>.</param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="source"/> is null.\n
+ /// -or-\n
+ /// <paramref name="config"/> is null.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="PersonRecognizer"/> has already been disposed of.\n
+ /// -or-\n
+ /// <paramref name="config"/> has already been disposed of.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <see cref="PersonRecognitionConfiguration.FaceRecognitionModelPath"/> of <paramref name="config"/> does not exists.
+ /// </exception>
+ /// <exception cref="UnauthorizedAccessException">
+ /// No permission to access to the <see cref="PersonRecognitionConfiguration.FaceRecognitionModelPath"/>.
+ /// </exception>
+ /// <exception cref="NotSupportedException">The model file is not supported format or file.</exception>
+ /// <see cref="SurveillanceSource.Push(MediaVisionSource)"/>
+ /// <since_tizen> 3</since_tizen>
+ public void AddSource(SurveillanceSource source, PersonRecognitionConfiguration config)
+ {
+ if (config == null)
+ {
+ throw new ArgumentNullException(nameof(config));
+ }
+ InvokeAddSource(source, config);
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/QrConfiguration.cs b/src/Tizen.Multimedia.Vision/MediaVision/QrConfiguration.cs
new file mode 100755
index 0000000..b090a38
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/QrConfiguration.cs
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents a QR configuration of <see cref="BarcodeGenerator"/>.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public class QrConfiguration
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="QrConfiguration"/> class.
+ /// </summary>
+ /// <param name="qrMode">Encoding mode for the message.</param>
+ /// <param name="ecc">Error correction level.</param>
+ /// <param name="version">QR code version. From 1 to 40 inclusive.</param>
+ /// <code>
+ /// var obj = new QrConfiguration(QrMode.Numeric, ErrorCorrectionLevel.Medium, 30);
+ /// </code>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="version"/> is less than 1.\n
+ /// -or-\n
+ /// <paramref name="version"/> is greater than 40.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="qrMode"/> is invalid.\n
+ /// -or-
+ /// <paramref name="ecc"/> is invalid.
+ /// </exception>
+ /// <since_tizen> 3</since_tizen>
+ public QrConfiguration(QrMode qrMode, ErrorCorrectionLevel ecc, int version)
+ {
+ if (version < 1 || version > 40)
+ {
+ throw new ArgumentOutOfRangeException(nameof(version), version,
+ "Valid version range is 1 to 40 inclusive.");
+ }
+ ValidationUtil.ValidateEnum(typeof(QrMode), qrMode, nameof(qrMode));
+ ValidationUtil.ValidateEnum(typeof(ErrorCorrectionLevel), ecc, nameof(ecc));
+
+ Mode = qrMode;
+ ErrorCorrectionLevel = ecc;
+ Version = version;
+ }
+
+ /// <summary>
+ /// Gets the encoding mode for the message.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public QrMode Mode { get; }
+
+ /// <summary>
+ /// Gets the error correction level.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public ErrorCorrectionLevel ErrorCorrectionLevel { get; }
+
+ /// <summary>
+ /// Gets the QR code version.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public int Version { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/QrMode.cs b/src/Tizen.Multimedia.Vision/MediaVision/QrMode.cs
new file mode 100755
index 0000000..489a066
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/QrMode.cs
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Specifies the supported QR code encoding mode.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public enum QrMode
+ {
+ /// <summary>
+ /// Numeric digits.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Numeric,
+ /// <summary>
+ /// Alphanumeric characters, '$', '%', '*', '+', '-', '.', '/' and ':'.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ AlphaNumeric,
+ /// <summary>
+ /// Raw 8-bit bytes.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Byte,
+ /// <summary>
+ /// UTF-8 character encoding.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ Utf8
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/Quadrangle.cs b/src/Tizen.Multimedia.Vision/MediaVision/Quadrangle.cs
new file mode 100755
index 0000000..cc394c9
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/Quadrangle.cs
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents a region with 4 <see cref="Point"/>s.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public class Quadrangle
+ {
+
+ /// <summary>
+ /// Initialize a new instance of the <see cref="Quadrangle"/> class with an array of <see cref="Point"/>.
+ /// </summary>
+ /// <remarks><paramref name="points"/> must have 4 elements.</remarks>
+ /// <param name="points">four points that define object bounding quadrangle.</param>
+ /// <exception cref="ArgumentException">The Length of <paramref name="points"/> is not 4.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public Quadrangle(Point[] points)
+ {
+ if (points.Length != 4)
+ {
+ throw new ArgumentException($"{points} must have 4 elements.");
+ }
+
+ Points = points;
+ }
+
+ /// <summary>
+ /// Gets four points that define the object bounding quadrangle.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public Point[] Points { get; }
+
+ public override string ToString() =>
+ $"[{{{Points[0].ToString()}}}, {{{Points[1].ToString()}}}, {{{Points[2].ToString()}}}, {{{Points[3].ToString()}}}]";
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/SurveillanceConfiguration.cs b/src/Tizen.Multimedia.Vision/MediaVision/SurveillanceConfiguration.cs
new file mode 100755
index 0000000..a80ccc0
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/SurveillanceConfiguration.cs
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// SurveillanceEngineConfiguration is a base class for surveillance configurations.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public class SurveillanceEngineConfiguration : EngineConfiguration
+ {
+ internal SurveillanceEngineConfiguration() : base("face_recognition", "image_recognition")
+ {
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/SurveillanceEngine.cs b/src/Tizen.Multimedia.Vision/MediaVision/SurveillanceEngine.cs
new file mode 100755
index 0000000..b06c503
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/SurveillanceEngine.cs
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using static Interop.MediaVision.Surveillance;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// SurveillanceEngine is a base class for surveillance event triggers.
+ /// Media Vision Surveillance provides functionality can be utilized for creation of video surveillance systems.
+ /// </summary>
+ /// <seealso cref="MovementDetector"/>
+ /// <seealso cref="PersonAppearanceDetector"/>
+ /// <seealso cref="PersonRecognizer"/>
+ /// <since_tizen> 3</since_tizen>
+ public abstract class SurveillanceEngine : IDisposable
+ {
+ private IntPtr _handle = IntPtr.Zero;
+ private bool _disposed = false;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="SurveillanceEngine"/> class.
+ /// </summary>
+ /// <param name="eventType">The type of the event trigger</param>
+ internal SurveillanceEngine(string eventType)
+ {
+ EventTriggerCreate(eventType, out _handle).Validate("Failed to create surveillance event trigger.");
+ }
+
+ ~SurveillanceEngine()
+ {
+ Dispose(false);
+ }
+
+ internal IntPtr Handle
+ {
+ get
+ {
+ if (_disposed)
+ {
+ throw new ObjectDisposedException(GetType().Name);
+ }
+ return _handle;
+ }
+ }
+
+ /// <summary>
+ /// Sets and gets ROI (Region Of Interest).
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">The <see cref="SurveillanceEngine"/> has already been disposed of.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public Point[] Roi
+ {
+ get
+ {
+ IntPtr roiPtr = IntPtr.Zero;
+ try
+ {
+ int count = 0;
+ GetEventTriggerRoi(Handle, out count, out roiPtr).Validate("Failed to get roi");
+
+ Point[] points = new Point[count];
+ IntPtr iterPtr = roiPtr;
+
+ for (int i = 0; i < count; i++)
+ {
+ points[i] = Marshal.PtrToStructure<global::Interop.MediaVision.Point>(iterPtr).ToApiStruct();
+ iterPtr = IntPtr.Add(iterPtr, Marshal.SizeOf<global::Interop.MediaVision.Point>());
+ }
+
+ return points;
+ }
+ finally
+ {
+ LibcSupport.Free(roiPtr);
+ }
+ }
+ set
+ {
+ int length = value == null ? 0 : value.Length;
+
+ var points = value == null ? null : global::Interop.ToMarshalable(value);
+
+ SetEventTriggerRoi(Handle, length, points).Validate("Failed to set roi");
+ }
+ }
+
+ internal abstract void OnEventDetected(IntPtr trigger, IntPtr source,
+ int streamId, IntPtr eventResult, IntPtr userData);
+
+ internal void InvokeAddSource(SurveillanceSource source, SurveillanceEngineConfiguration config)
+ {
+ if (source == null)
+ {
+ throw new ArgumentNullException(nameof(source));
+ }
+ SubscribeEventTrigger(Handle, source.StreamId, EngineConfiguration.GetHandle(config),
+ OnEventDetected).Validate("Failed to subscribe trigger");
+ }
+
+ /// <summary>
+ /// Removes the source from <see cref="SurveillanceEngine"/>.
+ /// </summary>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ObjectDisposedException">The <see cref="SurveillanceEngine"/> has already been disposed of.</exception>
+ /// <exception cref="ArgumentException"><paramref name="source"/> has not been added.</exception>
+ /// <since_tizen> 3</since_tizen>
+ public void RemoveSource(SurveillanceSource source)
+ {
+ if (source == null)
+ {
+ throw new ArgumentNullException(nameof(source));
+ }
+ UnsubscribeEventTrigger(Handle, source.StreamId).Validate("Failed to unsubscribe event trigger");
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_disposed)
+ {
+ return;
+ }
+
+ EventTriggerDestroy(_handle);
+ _disposed = true;
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/MediaVision/SurveillanceSource.cs b/src/Tizen.Multimedia.Vision/MediaVision/SurveillanceSource.cs
new file mode 100755
index 0000000..792243c
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/MediaVision/SurveillanceSource.cs
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using static Interop.MediaVision.Surveillance;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides the ability to push source to surveillance engines.
+ /// </summary>
+ /// <seealso cref="MovementDetector"/>
+ /// <seealso cref="PersonAppearanceDetector"/>
+ /// <seealso cref="PersonRecognizer"/>
+ /// <since_tizen> 3</since_tizen>
+ public class SurveillanceSource
+ {
+ private static int _nextStreamId = int.MinValue;
+
+ private static int GetNextStreamId()
+ {
+ if (_nextStreamId == int.MaxValue)
+ {
+ return _nextStreamId = int.MinValue;
+ }
+ return _nextStreamId++;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="SurveillanceSource"/> class.
+ /// </summary>
+ /// <since_tizen> 3</since_tizen>
+ public SurveillanceSource()
+ {
+ StreamId = GetNextStreamId();
+ }
+
+ /// <summary>
+ /// Pushes source to the surveillance system to detect events.
+ /// </summary>
+ /// <param name="source">The media source used for surveillance.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ObjectDisposedException"><paramref name="source"/> has already been disposed of.</exception>
+ /// <exception cref="InvalidOperationException">This <see cref="SurveillanceSource"/> has not been added yet.</exception>
+ /// <seealso cref="MovementDetector.AddSource(SurveillanceSource)"/>
+ /// <seealso cref="MovementDetector.AddSource(SurveillanceSource, MovementDetectionConfiguration)"/>
+ /// <seealso cref="PersonAppearanceDetector.AddSource(SurveillanceSource)"/>
+ /// <seealso cref="PersonAppearanceDetector.AddSource(SurveillanceSource, PersonAppearanceDetectionConfiguration)"/>
+ /// <seealso cref="PersonRecognizer.AddSource(SurveillanceSource, PersonRecognitionConfiguration)"/>
+ /// <since_tizen> 3</since_tizen>
+ public void Push(MediaVisionSource source)
+ {
+ if (source == null)
+ {
+ throw new ArgumentNullException(nameof(source));
+ }
+
+ PushSource(source.Handle, StreamId).Validate("Failed to push source");
+ }
+
+ internal int StreamId { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia.Vision/Tizen.Multimedia.Vision.csproj b/src/Tizen.Multimedia.Vision/Tizen.Multimedia.Vision.csproj
new file mode 100644
index 0000000..0e5378c
--- /dev/null
+++ b/src/Tizen.Multimedia.Vision/Tizen.Multimedia.Vision.csproj
@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen.Multimedia\Tizen.Multimedia.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Multimedia/AssemblyAttrs.cs b/src/Tizen.Multimedia/AssemblyAttrs.cs
new file mode 100644
index 0000000..c9f90b1
--- /dev/null
+++ b/src/Tizen.Multimedia/AssemblyAttrs.cs
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ // This file specifies any assembly atrributes.
+ // Note that InternalsVisibleToAttribute can be removed or added and needs to be only Multimedia packages only.
+
+using System.Runtime.CompilerServices;
+
+[assembly: InternalsVisibleTo("Tizen.Multimedia.Camera, " +
+ "PublicKey=0024000004800000940000000602000000240000525341310004000001000100d115b100424841" +
+ "6b12d21b626cfb17149c9303fe394693fd3b32d7872e89559a4fa96c98110c2e62eea48aca693b" +
+ "ddbe17094ca8ea2e2cd79970ca590fb672b9b371b5d7002076817321f62d6483ea50c56dbd1f37" +
+ "b185a4c24c47718876e6ae6d266508c551170d4cbdda3f82edaff9405ee3d7857282d8269e8e518d2f0fb2")]
+
+[assembly: InternalsVisibleTo("Tizen.Multimedia.MediaCodec, " +
+ "PublicKey=0024000004800000940000000602000000240000525341310004000001000100d115b100424841" +
+ "6b12d21b626cfb17149c9303fe394693fd3b32d7872e89559a4fa96c98110c2e62eea48aca693b" +
+ "ddbe17094ca8ea2e2cd79970ca590fb672b9b371b5d7002076817321f62d6483ea50c56dbd1f37" +
+ "b185a4c24c47718876e6ae6d266508c551170d4cbdda3f82edaff9405ee3d7857282d8269e8e518d2f0fb2")]
+
+[assembly: InternalsVisibleTo("Tizen.Multimedia.MediaPlayer, " +
+ "PublicKey=0024000004800000940000000602000000240000525341310004000001000100d115b100424841" +
+ "6b12d21b626cfb17149c9303fe394693fd3b32d7872e89559a4fa96c98110c2e62eea48aca693b" +
+ "ddbe17094ca8ea2e2cd79970ca590fb672b9b371b5d7002076817321f62d6483ea50c56dbd1f37" +
+ "b185a4c24c47718876e6ae6d266508c551170d4cbdda3f82edaff9405ee3d7857282d8269e8e518d2f0fb2")]
+
+[assembly: InternalsVisibleTo("Tizen.Multimedia.Recorder, " +
+ "PublicKey=0024000004800000940000000602000000240000525341310004000001000100d115b100424841" +
+ "6b12d21b626cfb17149c9303fe394693fd3b32d7872e89559a4fa96c98110c2e62eea48aca693b" +
+ "ddbe17094ca8ea2e2cd79970ca590fb672b9b371b5d7002076817321f62d6483ea50c56dbd1f37" +
+ "b185a4c24c47718876e6ae6d266508c551170d4cbdda3f82edaff9405ee3d7857282d8269e8e518d2f0fb2")]
+
+[assembly: InternalsVisibleTo("Tizen.Multimedia.StreamRecorder, " +
+ "PublicKey=0024000004800000940000000602000000240000525341310004000001000100d115b100424841" +
+ "6b12d21b626cfb17149c9303fe394693fd3b32d7872e89559a4fa96c98110c2e62eea48aca693b" +
+ "ddbe17094ca8ea2e2cd79970ca590fb672b9b371b5d7002076817321f62d6483ea50c56dbd1f37" +
+ "b185a4c24c47718876e6ae6d266508c551170d4cbdda3f82edaff9405ee3d7857282d8269e8e518d2f0fb2")]
+
+[assembly: InternalsVisibleTo("Tizen.Multimedia.Remoting, " +
+ "PublicKey=0024000004800000940000000602000000240000525341310004000001000100d115b100424841" +
+ "6b12d21b626cfb17149c9303fe394693fd3b32d7872e89559a4fa96c98110c2e62eea48aca693b" +
+ "ddbe17094ca8ea2e2cd79970ca590fb672b9b371b5d7002076817321f62d6483ea50c56dbd1f37" +
+ "b185a4c24c47718876e6ae6d266508c551170d4cbdda3f82edaff9405ee3d7857282d8269e8e518d2f0fb2")]
+
+[assembly: InternalsVisibleTo("Tizen.Multimedia.Util, " +
+ "PublicKey=0024000004800000940000000602000000240000525341310004000001000100d115b100424841" +
+ "6b12d21b626cfb17149c9303fe394693fd3b32d7872e89559a4fa96c98110c2e62eea48aca693b" +
+ "ddbe17094ca8ea2e2cd79970ca590fb672b9b371b5d7002076817321f62d6483ea50c56dbd1f37" +
+ "b185a4c24c47718876e6ae6d266508c551170d4cbdda3f82edaff9405ee3d7857282d8269e8e518d2f0fb2")]
+
+[assembly: InternalsVisibleTo("Tizen.Multimedia.Vision, " +
+ "PublicKey=0024000004800000940000000602000000240000525341310004000001000100d115b100424841" +
+ "6b12d21b626cfb17149c9303fe394693fd3b32d7872e89559a4fa96c98110c2e62eea48aca693b" +
+ "ddbe17094ca8ea2e2cd79970ca590fb672b9b371b5d7002076817321f62d6483ea50c56dbd1f37" +
+ "b185a4c24c47718876e6ae6d266508c551170d4cbdda3f82edaff9405ee3d7857282d8269e8e518d2f0fb2")] \ No newline at end of file
diff --git a/src/Tizen.Multimedia/AudioManager/AudioDevice.cs b/src/Tizen.Multimedia/AudioManager/AudioDevice.cs
new file mode 100755
index 0000000..e085d9c
--- /dev/null
+++ b/src/Tizen.Multimedia/AudioManager/AudioDevice.cs
@@ -0,0 +1,110 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Multimedia
+{
+ internal static class AudioDeviceLog
+ {
+ internal const string Tag = "Tizen.Multimedia.AudioDevice";
+ }
+
+ /// <summary>
+ /// The Device API provides functions to query the information of sound devices.
+ /// </summary>
+ public class AudioDevice
+ {
+ private readonly int _id;
+ private readonly string _name;
+ private readonly AudioDeviceType _type;
+ private readonly AudioDeviceIoDirection _ioDirection;
+ private readonly AudioDeviceState _state;
+ private readonly IntPtr _handle;
+
+ internal AudioDevice(IntPtr deviceHandle)
+ {
+ _handle = deviceHandle;
+ int ret;
+
+ ret = Interop.AudioDevice.GetDeviceId(_handle, out _id);
+ if (ret != 0)
+ {
+ Tizen.Log.Error(AudioDeviceLog.Tag, "Unable to get device Id: " + (AudioManagerError)ret);
+ }
+ AudioManagerErrorFactory.CheckAndThrowException(ret, _handle, "Unable to get device Id");
+
+ IntPtr name;
+ ret = Interop.AudioDevice.GetDeviceName(_handle, out name);
+ if (ret != 0)
+ {
+ Tizen.Log.Error(AudioDeviceLog.Tag, "Unable to get device name" + (AudioManagerError)ret);
+ }
+ AudioManagerErrorFactory.CheckAndThrowException(ret, _handle, "Unable to get device name");
+
+ _name = Marshal.PtrToStringAnsi(name);
+
+ ret = Interop.AudioDevice.GetDeviceType(_handle, out _type);
+ if (ret != 0)
+ {
+ Tizen.Log.Error(AudioDeviceLog.Tag, "Unable to get device type" + (AudioManagerError)ret);
+ }
+ AudioManagerErrorFactory.CheckAndThrowException(ret, _handle, "Unable to get device type");
+
+ ret = Interop.AudioDevice.GetDeviceIoDirection(_handle, out _ioDirection);
+ if (ret != 0)
+ {
+ Tizen.Log.Error(AudioDeviceLog.Tag, "Unable to get device IoDirection" + (AudioManagerError)ret);
+ }
+ AudioManagerErrorFactory.CheckAndThrowException(ret, _handle, "Unable to get device IO Direction");
+
+ ret = Interop.AudioDevice.GetDeviceState(_handle, out _state);
+ if (ret != 0)
+ {
+ Tizen.Log.Error(AudioDeviceLog.Tag, "Unable to get device state" + (AudioManagerError)ret);
+ }
+ AudioManagerErrorFactory.CheckAndThrowException(ret, _handle, "Unable to get device state");
+ }
+
+ /// <summary>
+ /// The id of the device.
+ /// </summary>
+ public int Id => _id;
+
+ /// <summary>
+ /// The name of the device.
+ /// </summary>
+ public string Name => _name;
+
+ /// <summary>
+ /// The type of the device.
+ /// </summary>
+ public AudioDeviceType Type => _type;
+
+ /// <summary>
+ /// The io direction of the device.
+ /// </summary>
+ public AudioDeviceIoDirection IoDirection => _ioDirection;
+
+ /// <summary>
+ /// The state of the device.
+ /// </summary>
+ public AudioDeviceState State => _state;
+
+ internal IntPtr Handle => _handle;
+ }
+}
diff --git a/src/Tizen.Multimedia/AudioManager/AudioDeviceConnectionChangedEventArgs.cs b/src/Tizen.Multimedia/AudioManager/AudioDeviceConnectionChangedEventArgs.cs
new file mode 100644
index 0000000..9369a99
--- /dev/null
+++ b/src/Tizen.Multimedia/AudioManager/AudioDeviceConnectionChangedEventArgs.cs
@@ -0,0 +1,42 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Class extending EventArgs which contains parameters to be passed to event handler of DeviceConnected event
+ /// </summary>
+ public class AudioDeviceConnectionChangedEventArgs : EventArgs
+ {
+ internal AudioDeviceConnectionChangedEventArgs(AudioDevice device, bool isConnected)
+ {
+ Device = device;
+ IsConnected = isConnected;
+ }
+
+ /// <summary>
+ /// The object of sound device
+ /// </summary>
+ public AudioDevice Device { get; }
+
+ /// <summary>
+ /// The state of device connection: (true = connected, false = disconnected)
+ /// </summary>
+ public bool IsConnected { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia/AudioManager/AudioDeviceStateChangedEventArgs.cs b/src/Tizen.Multimedia/AudioManager/AudioDeviceStateChangedEventArgs.cs
new file mode 100644
index 0000000..41a5564
--- /dev/null
+++ b/src/Tizen.Multimedia/AudioManager/AudioDeviceStateChangedEventArgs.cs
@@ -0,0 +1,42 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Class extending EventArgs which contains parameters to be passed to event handler of DeviceInformationChanged event
+ /// </summary>
+ public class AudioDeviceStateChangedEventArgs : EventArgs
+ {
+ internal AudioDeviceStateChangedEventArgs(AudioDevice device, AudioDeviceState changedState)
+ {
+ Device = device;
+ ChangedState = changedState;
+ }
+
+ /// <summary>
+ /// The object of sound device
+ /// </summary>
+ public AudioDevice Device { get; }
+
+ /// <summary>
+ /// The entry of sound device state
+ /// </summary>
+ public AudioDeviceState ChangedState { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia/AudioManager/AudioManager.cs b/src/Tizen.Multimedia/AudioManager/AudioManager.cs
new file mode 100755
index 0000000..1469637
--- /dev/null
+++ b/src/Tizen.Multimedia/AudioManager/AudioManager.cs
@@ -0,0 +1,198 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Multimedia
+{
+ internal static class AudioManagerLog
+ {
+ internal const string Tag = "Tizen.Multimedia.AudioManager";
+ }
+
+ /// <summary>
+ /// The Audio Manager class provides functions to get and set sound parameters like volume and devices.
+ /// </summary>
+ public static class AudioManager
+ {
+ private static int _deviceConnectionChangedCallbackId = -1;
+ private static int _deviceStateChangedCallbackId = -1;
+
+ private static Interop.SoundDeviceConnectionChangedCallback _audioDeviceConnectionChangedCallback;
+ private static Interop.SoundDeviceStateChangedCallback _audioDeviceStateChangedCallback;
+
+ private static EventHandler<AudioDeviceConnectionChangedEventArgs> _audioDeviceConnectionChanged;
+ private static EventHandler<AudioDeviceStateChangedEventArgs> _audioDeviceStateChanged;
+
+ /// <summary>
+ /// Constructor for AudioManager. Initializes the VolumeController property etc.
+ /// </summary>
+ static AudioManager()
+ {
+ VolumeController = new AudioVolume();
+ }
+
+ /// <summary>
+ /// Registers/Unregisters a function to be invoked when the state of connection of an Audio device was changed.
+ /// </summary>
+ public static event EventHandler<AudioDeviceConnectionChangedEventArgs> DeviceConnectionChanged
+ {
+ add
+ {
+ if (_audioDeviceConnectionChanged == null)
+ {
+ RegisterAudioDeviceEvent();
+ Tizen.Log.Info(AudioManagerLog.Tag, "DeviceConnectionChanged event registered");
+ }
+ _audioDeviceConnectionChanged += value;
+ Tizen.Log.Info(AudioManagerLog.Tag, "DeviceConnectionChanged event added");
+ }
+ remove
+ {
+ if (_audioDeviceConnectionChanged?.GetInvocationList()?.GetLength(0) == 1)
+ {
+ UnregisterDeviceConnectionChangedEvent();
+ }
+ _audioDeviceConnectionChanged -= value;
+ Tizen.Log.Info(AudioManagerLog.Tag, "DeviceConnectionChanged event removed");
+ }
+ }
+
+ /// <summary>
+ /// Registers/Unregisters a callback function to be invoked when the state of an Audio sound device was changed.
+ /// </summary>
+ public static event EventHandler<AudioDeviceStateChangedEventArgs> DeviceStateChanged
+ {
+ add
+ {
+ if (_audioDeviceStateChanged == null)
+ {
+ RegisterDeviceStateChangedEvent();
+ }
+ _audioDeviceStateChanged += value;
+ Tizen.Log.Info(AudioManagerLog.Tag, "DeviceStateChanged event added");
+ }
+ remove
+ {
+ if (_audioDeviceStateChanged?.GetInvocationList()?.GetLength(0) == 1)
+ {
+ UnregisterDeviceStateChangedEvent();
+ }
+ _audioDeviceStateChanged -= value;
+ Tizen.Log.Info(AudioManagerLog.Tag, "DeviceStateChanged event removed");
+ }
+ }
+
+ /// <summary>
+ /// The VolumeController object (singleton) is-a part of SoundManager and its properties and methods are used via AudioManager
+ /// </summary>
+ public static AudioVolume VolumeController { get; }
+
+ /// <summary>
+ /// Gets the list consisting of all devices currently connected.
+ /// </summary>
+ /// <param name="options">The audio device options</param>
+ /// <returns>The list of connected devices: IEnumerable of Device objects</returns>
+ public static IEnumerable<AudioDevice> GetCurrentDevices(AudioDeviceOptions options)
+ {
+ List<AudioDevice> audioDeviceList = new List<AudioDevice>();
+ IntPtr deviceListHandle;
+ IntPtr handlePosition;
+ AudioDeviceIoDirection ioDirection;
+
+ int ret = Interop.AudioDevice.GetCurrentDeviceList(options, out deviceListHandle);
+ if (ret != (int)AudioManagerError.NoData)
+ {
+ AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to get next device");
+ }
+ while (ret == (int)AudioManagerError.None)
+ {
+ ret = Interop.AudioDevice.GetNextDevice(deviceListHandle, out handlePosition);
+ if (ret == (int)AudioManagerError.NoData)
+ {
+ break;
+ }
+ else if (ret != (int)AudioManagerError.None)
+ {
+ AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to get next device");
+ }
+
+ if (options == AudioDeviceOptions.Input || (options == AudioDeviceOptions.Output))
+ {
+ ret = Interop.AudioDevice.GetDeviceIoDirection(handlePosition, out ioDirection);
+ if (ret != 0)
+ {
+ Tizen.Log.Error(AudioManagerLog.Tag, "Unable to get device IoDirection" + (AudioManagerError)ret);
+ AudioManagerErrorFactory.CheckAndThrowException(ret, handlePosition, "Unable to get device IO Direction");
+ }
+ else if (ioDirection == AudioDeviceIoDirection.InputAndOutput)
+ {
+ continue;
+ }
+ }
+ audioDeviceList.Add(new AudioDevice(handlePosition));
+ }
+ return audioDeviceList;
+ }
+
+ private static void RegisterAudioDeviceEvent()
+ {
+ _audioDeviceConnectionChangedCallback = (IntPtr device, bool isConnected, IntPtr userData) =>
+ {
+ AudioDeviceConnectionChangedEventArgs eventArgs = new AudioDeviceConnectionChangedEventArgs(new AudioDevice(device), isConnected);
+ _audioDeviceConnectionChanged?.Invoke(null, eventArgs);
+ };
+ int ret = Interop.AudioDevice.AddDeviceConnectionChangedCallback(AudioDeviceOptions.All, _audioDeviceConnectionChangedCallback, IntPtr.Zero, out _deviceConnectionChangedCallbackId);
+ AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to add device connection changed callback");
+ Tizen.Log.Info(AudioManagerLog.Tag, "AudioDeviceConnectionChanged Event registered");
+ }
+
+ private static void RegisterDeviceStateChangedEvent()
+ {
+ _audioDeviceStateChangedCallback = (IntPtr device, AudioDeviceState changedState, IntPtr userData) =>
+ {
+ AudioDeviceStateChangedEventArgs eventArgs = new AudioDeviceStateChangedEventArgs(new AudioDevice(device), changedState);
+ _audioDeviceStateChanged?.Invoke(null, eventArgs);
+ };
+ int ret = Interop.AudioDevice.AddDeviceStateChangedCallback(AudioDeviceOptions.All, _audioDeviceStateChangedCallback, IntPtr.Zero, out _deviceStateChangedCallbackId);
+ AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to add device state changed callback");
+ Tizen.Log.Info(AudioManagerLog.Tag, "AudioDeviceStateChangedEvent callback registered");
+ }
+
+ private static void UnregisterDeviceConnectionChangedEvent()
+ {
+ if (_deviceConnectionChangedCallbackId > 0)
+ {
+ int ret = Interop.AudioDevice.RemoveDeviceConnectionChangedCallback(_deviceConnectionChangedCallbackId);
+ AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to remove device connection changed callback");
+ Tizen.Log.Info(AudioManagerLog.Tag, "AudioDeviceConnectionChangedEvent callback unregistered");
+ _deviceConnectionChangedCallbackId = -1;
+ }
+ }
+
+ private static void UnregisterDeviceStateChangedEvent()
+ {
+ if (_deviceStateChangedCallbackId > 0)
+ {
+ int ret = Interop.AudioDevice.RemoveDeviceStateChangedCallback(_deviceStateChangedCallbackId);
+ AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to remove device state changed callback");
+ Tizen.Log.Info(AudioManagerLog.Tag, "AudioDeviceStateChanged callback unregistered");
+ _deviceStateChangedCallbackId = -1;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia/AudioManager/AudioManagerEnumerations.cs b/src/Tizen.Multimedia/AudioManager/AudioManagerEnumerations.cs
new file mode 100755
index 0000000..6b50ee2
--- /dev/null
+++ b/src/Tizen.Multimedia/AudioManager/AudioManagerEnumerations.cs
@@ -0,0 +1,326 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Enumeration for audio device options.
+ /// </summary>
+ public enum AudioDeviceOptions
+ {
+ /// <summary>
+ /// Mask for input devices
+ /// </summary>
+ Input = 0x0001,
+ /// <summary>
+ /// Mask for output devices
+ /// </summary>
+ Output = 0x0002,
+ /// <summary>
+ /// Mask for input/output devices (both directions are available)
+ /// </summary>
+ InputAndOutput = 0x0004,
+ /// <summary>
+ /// Mask for built-in devices
+ /// </summary>
+ Internal = 0x00010,
+ /// <summary>
+ /// Mask for external devices
+ /// </summary>
+ External = 0x0020,
+ /// <summary>
+ /// Mask for deactivated devices
+ /// </summary>
+ Deactivated = 0x1000,
+ /// <summary>
+ /// Mask for activated devices
+ /// </summary>
+ Activated = 0x2000,
+ /// <summary>
+ /// Mask for all devices
+ /// </summary>
+ All = 0xFFFF
+ }
+
+ /// <summary>
+ /// Enumeration for audio device type.
+ /// </summary>
+ public enum AudioDeviceType
+ {
+ /// <summary>
+ /// Built-in speaker
+ /// </summary>
+ BuiltinSpeaker,
+ /// <summary>
+ /// Built-in receiver
+ /// </summary>
+ BuiltinReceiver,
+ /// <summary>
+ /// Built-in mic
+ /// </summary>
+ BuiltinMic,
+ /// <summary>
+ /// Audio jack that can be connected to wired accessory such as headphones and headsets
+ /// </summary>
+ AudioJack,
+ /// <summary>
+ /// Bluetooth Media (A2DP)
+ /// </summary>
+ BluetoothMedia,
+ /// <summary>
+ /// HDMI
+ /// </summary>
+ Hdmi,
+ /// <summary>
+ /// Device for forwarding
+ /// </summary>
+ Forwarding,
+ /// <summary>
+ /// USB Audio
+ /// </summary>
+ UsbAudio,
+ /// <summary>
+ /// Bluetooth Voice (SCO)
+ /// </summary>
+ BluetoothVoice
+ }
+
+ /// <summary>
+ /// Enumeration for audio device direction.
+ /// </summary>
+ public enum AudioDeviceIoDirection
+ {
+ /// <summary>
+ /// Input device
+ /// </summary>
+ Input,
+ /// <summary>
+ /// Output device
+ /// </summary>
+ Output,
+ /// <summary>
+ /// Input/output device (both directions are available)
+ /// </summary>
+ InputAndOutput
+ }
+
+ /// <summary>
+ /// Enumeration for audio device state.
+ /// </summary>
+ public enum AudioDeviceState
+ {
+ /// <summary>
+ /// Deactivated state
+ /// </summary>
+ Deactivated,
+ /// <summary>
+ /// Activated state
+ /// </summary>
+ Activated
+ }
+
+ /// <summary>
+ /// Enumeration for audio volume type.
+ /// </summary>
+ public enum AudioVolumeType
+ {
+ /// <summary>
+ /// Volume type for system
+ /// </summary>
+ System,
+ /// <summary>
+ /// Volume type for notification
+ /// </summary>
+ Notification,
+ /// <summary>
+ /// Volume type for alarm
+ /// </summary>
+ Alarm,
+ /// <summary>
+ /// Volume type for ringtone
+ /// </summary>
+ Ringtone,
+ /// <summary>
+ /// Volume type for media
+ /// </summary>
+ Media,
+ /// <summary>
+ /// Volume type for call
+ /// </summary>
+ Call,
+ /// <summary>
+ /// Volume type for voip
+ /// </summary>
+ Voip,
+ /// <summary>
+ /// Volume type for voice
+ /// </summary>
+ Voice,
+ /// <summary>
+ /// Volume type None
+ /// </summary>
+ None
+ }
+
+ /// <summary>
+ /// Enumeration for audio stream type.
+ /// </summary>
+ public enum AudioStreamType
+ {
+ /// <summary>
+ /// Audio stream type for media
+ /// </summary>
+ Media,
+ /// <summary>
+ /// Audio stream type for system
+ /// </summary>
+ System,
+ /// <summary>
+ /// Audio stream type for alarm
+ /// </summary>
+ Alarm,
+ /// <summary>
+ /// Audio stream type for notification
+ /// </summary>
+ Notification,
+ /// <summary>
+ /// Audio stream type for emergency
+ /// </summary>
+ Emergency,
+ /// <summary>
+ /// Audio stream type for voice information
+ /// </summary>
+ VoiceInformation,
+ /// <summary>
+ /// Audio stream type for voice recognition
+ /// </summary>
+ VoiceRecognition,
+ /// <summary>
+ /// Audio stream type for ringtone for VoIP
+ /// </summary>
+ RingtoneVoip,
+ /// <summary>
+ /// Audio stream type for VoIP
+ /// </summary>
+ Voip,
+ /// <summary>
+ /// Audio stream type for media only for external devices
+ /// </summary>
+ MediaExternalOnly
+ }
+
+ /// <summary>
+ /// Enumeration for change reason of audio stream focus state.
+ /// </summary>
+ public enum AudioStreamFocusChangedReason
+ {
+ /// <summary>
+ /// Changed by the stream type for media
+ /// </summary>
+ Media,
+ /// <summary>
+ /// Changed by the stream type for system
+ /// </summary>
+ System,
+ /// <summary>
+ /// Changed by the stream type for alarm
+ /// </summary>
+ Alarm,
+ /// <summary>
+ /// Changed by the stream type for notification
+ /// </summary>
+ Notification,
+ /// <summary>
+ /// Changed by the stream type for emergency
+ /// </summary>
+ Emergency,
+ /// <summary>
+ /// Changed by the stream type for voice information
+ /// </summary>
+ VoiceInformation,
+ /// <summary>
+ /// Changed by the stream type for voice recognition
+ /// </summary>
+ VoiceRecognition,
+ /// <summary>
+ /// Changed by the stream type for ringtone
+ /// </summary>
+ RingtoneVoip,
+ /// <summary>
+ /// Changed by the stream type for VoIP
+ /// </summary>
+ Voip,
+ /// <summary>
+ /// Changed by the stream type for voice-call or video-call
+ /// </summary>
+ Call,
+ /// <summary>
+ /// Changed by the stream type for media only for external devices
+ /// </summary>
+ MediaExternalOnly
+ }
+
+ /// <summary>
+ /// Enumeration for audio stream focus options.
+ /// </summary>
+ public enum AudioStreamFocusOptions
+ {
+ /// <summary>
+ /// Mask for playback focus
+ /// </summary>
+ Playback = 0x0001,
+ /// <summary>
+ /// Mask for recording focus
+ /// </summary>
+ Recording = 0x0002
+ }
+
+ /// <summary>
+ /// Enumeration for audio stream focus state.
+ /// </summary>
+ public enum AudioStreamFocusState
+ {
+ /// <summary>
+ /// Focus state for release
+ /// </summary>
+ Released,
+ /// <summary>
+ ///Focus state for acquisition
+ /// </summary>
+ Acquired
+ }
+
+ /// <summary>
+ /// Enumeration for audio stream behavior
+ /// </summary>
+ [Flags]
+ public enum AudioStreamBehavior
+ {
+ /// <summary>
+ /// Audio Stream Behavior NONE
+ /// </summary>
+ None = 0x0000,
+ /// <summary>
+ /// Audio Stream Behavior No Resume
+ /// </summary>
+ NoResume = 0x0001,
+ /// <summary>
+ /// Audio Stream Behavior Fading
+ /// </summary>
+ Fading = 0x0002
+ }
+}
diff --git a/src/Tizen.Multimedia/AudioManager/AudioManagerErrorFactory.cs b/src/Tizen.Multimedia/AudioManager/AudioManagerErrorFactory.cs
new file mode 100644
index 0000000..22fba2f
--- /dev/null
+++ b/src/Tizen.Multimedia/AudioManager/AudioManagerErrorFactory.cs
@@ -0,0 +1,120 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Enumeration for sound manager's error codes.
+ /// </summary>
+ internal enum AudioManagerError{
+
+ SoundManagerError = -0x01960000,
+ /// <summary>
+ /// Successful
+ /// </summary>
+ None = ErrorCode.None,
+ /// <summary>
+ /// Out of memory
+ /// </summary>
+ OutOfMemory = ErrorCode.OutOfMemory,
+ /// <summary>
+ /// Invalid parameter
+ /// </summary>
+ InvalidParameter = ErrorCode.InvalidParameter,
+ /// <summary>
+ /// Invalid operation
+ /// </summary>
+ InvalidOperation = ErrorCode.InvalidOperation,
+ /// <summary>
+ /// Permission denied
+ /// </summary>
+ PermissionDenied = ErrorCode.PermissionDenied,
+ /// <summary>
+ /// Not supported
+ /// </summary>
+ NotSupported = ErrorCode.NotSupported,
+ /// <summary>
+ /// No data
+ /// </summary>
+ NoData = ErrorCode.NoData,
+ /// <summary>
+ /// Internal error inside the sound system
+ /// </summary>
+ Internal = SoundManagerError | 01,
+ /// <summary>
+ /// Noncompliance with the sound system policy
+ /// </summary>
+ Policy = SoundManagerError | 02,
+ /// <summary>
+ /// No playing sound
+ /// </summary>
+ NoPlayingSound = SoundManagerError | 03,
+ /// <summary>
+ /// Invalid state (Since 3.0)
+ /// </summary>
+ InvalidState = SoundManagerError | 04
+ }
+
+ internal static class AudioManagerErrorFactory
+ {
+ static internal void CheckAndThrowException(int error, string msg)
+ {
+ AudioManagerError e = (AudioManagerError) error;
+ switch (e)
+ {
+ case AudioManagerError.None:
+ return;
+ case AudioManagerError.OutOfMemory:
+ throw new InvalidOperationException("Out of Memory: " + msg);
+ case AudioManagerError.InvalidParameter:
+ throw new ArgumentException("Invalid Parameter: " + msg);
+ case AudioManagerError.InvalidOperation:
+ throw new InvalidOperationException("Invalid Opertation: " + msg);
+ case AudioManagerError.PermissionDenied:
+ throw new InvalidOperationException("Permission Denied: " + msg);
+ case AudioManagerError.NotSupported:
+ throw new InvalidOperationException("Not Supported: " + msg);
+ case AudioManagerError.NoData:
+ throw new InvalidOperationException("No Data: " + msg);
+ case AudioManagerError.Internal:
+ throw new InvalidOperationException("Internal Error: " + msg);
+ case AudioManagerError.Policy:
+ throw new InvalidOperationException("Noncomplaince with System Sound Policy error: " + msg);
+ case AudioManagerError.NoPlayingSound:
+ throw new InvalidOperationException("No playing sound: " + msg);
+ case AudioManagerError.InvalidState:
+ throw new InvalidOperationException("Invalid State: " + msg);
+ default:
+ throw new InvalidOperationException("Unknown Error Code: " + msg);
+ }
+ }
+
+ static internal void CheckAndThrowException(int error, IntPtr handle, string msg)
+ {
+ if (handle == IntPtr.Zero)
+ {
+ throw new InvalidOperationException("Invalid instance (object may have been disposed or released)");
+ }
+ else
+ {
+ CheckAndThrowException(error, msg);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia/AudioManager/AudioStreamPolicy.cs b/src/Tizen.Multimedia/AudioManager/AudioStreamPolicy.cs
new file mode 100755
index 0000000..b914c9c
--- /dev/null
+++ b/src/Tizen.Multimedia/AudioManager/AudioStreamPolicy.cs
@@ -0,0 +1,334 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ internal static class AudioStreamPolicyLog
+ {
+ internal const string Tag = "Tizen.Multimedia.AudioStreamPolicy";
+ }
+
+ /// <summary>
+ /// The Stream Policy API provides functions to control a sound stream.
+ /// </summary>
+ public class AudioStreamPolicy : IDisposable
+ {
+ private static int _focusStateWatchCounter = 0;
+ private static EventHandler<FocusStateChangedEventArgs> _focusStateWatchForPlayback;
+ private static EventHandler<FocusStateChangedEventArgs> _focusStateWatchForRecording;
+ private static Interop.SoundStreamFocusStateWatchCallback _focusStateWatchCallback;
+ private static int _focusWatchCbId;
+
+ private IntPtr _streamInfo;
+ private AudioStreamType _streamType;
+ private bool _disposed = false;
+ private EventHandler<StreamFocusStateChangedEventArgs> _focusStateChanged;
+ private Interop.SoundStreamFocusStateChangedCallback _focusStateChangedCallback;
+
+ /// <summary>
+ /// Creates and returns an AudioStreamPolicy object
+ /// </summary>
+ /// <remarks>
+ /// To apply the stream policy according to this stream information, this object should be passed to other APIs
+ /// related to playback or recording. (e.g., player, wav-player, audio-io, etc.)
+ /// </remarks>
+ /// <param name="streamType">Type of sound stream for which policy needs to be created</param>
+ /// <returns>StreamPolicy object</returns>
+ public AudioStreamPolicy(AudioStreamType streamType)
+ {
+ _streamType = streamType;
+
+ _focusStateChangedCallback = (IntPtr streamInfo, AudioStreamFocusOptions focusMask, AudioStreamFocusState focusState, int reason, int audioStreamBehavior, string extraInfo, IntPtr userData) => {
+ StreamFocusStateChangedEventArgs eventArgs = new StreamFocusStateChangedEventArgs((AudioStreamFocusChangedReason)reason, extraInfo);
+ _focusStateChanged?.Invoke(this, eventArgs);
+ };
+ int ret = Interop.AudioStreamPolicy.CreateStreamInformation((int)streamType, _focusStateChangedCallback, IntPtr.Zero, out _streamInfo);
+ AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to create stream information");
+ }
+
+ ~AudioStreamPolicy()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Registers the watch function to be invoked when the focus state for each sound stream type is changed regardless of the process.
+ /// <remarks>
+ /// Remarks: You can set this only once per process.
+ /// </remarks>
+ /// </summary>
+ public static event EventHandler<FocusStateChangedEventArgs> PlaybackFocusStateWatch {
+ add {
+ Tizen.Log.Info(AudioStreamPolicyLog.Tag, "############# _focusStateWatchCounter" + _focusStateWatchCounter);
+ if(_focusStateWatchCounter == 0) {
+ RegisterFocusStateWatchEvent();
+ }
+ _focusStateWatchCounter++;
+ _focusStateWatchForPlayback += value;
+ }
+ remove {
+ Tizen.Log.Info(AudioStreamPolicyLog.Tag, "############# _focusStateWatchCounter" + _focusStateWatchCounter);
+ _focusStateWatchForPlayback -= value;
+ _focusStateWatchCounter--;
+ if(_focusStateWatchCounter == 0) {
+ UnregisterFocusStateWatch();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Registers the watch function to be invoked when the focus state for each sound stream type is changed regardless of the process.
+ /// <remarks>
+ /// Remarks: You can set this only once per process.
+ /// </remarks>
+ /// </summary>
+ public static event EventHandler<FocusStateChangedEventArgs> RecordingFocusStateWatch {
+ add {
+ if(_focusStateWatchCounter == 0) {
+ RegisterFocusStateWatchEvent();
+ }
+ _focusStateWatchCounter++;
+ _focusStateWatchForRecording += value;
+ }
+ remove {
+ _focusStateWatchForRecording -= value;
+ _focusStateWatchCounter--;
+ if(_focusStateWatchCounter == 0) {
+ UnregisterFocusStateWatch();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Registers function to be called when the state of focus that belongs to the current
+ /// streamInfo is changed.
+ /// </summary>
+ /// <remarks>
+ /// Remarks: This function is issued in the internal thread of the sound manager. Therefore it is recommended not to call UI update function in this function.
+ /// Postcondition : Check PlaybackFocusState and RecordingFocusState in the registered event handler to figure out how the focus state of the StreamInfo has been changed.
+ /// </remarks>
+ public event EventHandler<StreamFocusStateChangedEventArgs> StreamFocusStateChanged {
+ add {
+ _focusStateChanged += value;
+ }
+ remove {
+ _focusStateChanged -= value;
+ }
+ }
+
+ /// <summary>
+ /// The sound type of the stream information.
+ /// </summary>
+ public AudioVolumeType VolumeType {
+ get {
+ AudioVolumeType soundType;
+ int ret = Interop.AudioStreamPolicy.GetSoundType(_streamInfo, out soundType);
+ if(ret != 0) {
+ Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Unable to get sound type:" + (AudioManagerError)ret);
+ return AudioVolumeType.None;
+ }
+ return soundType;
+ }
+ }
+
+ /// <summary>
+ /// The state of focus for playback.
+ /// </summary>
+ public AudioStreamFocusState PlaybackFocusState {
+ get {
+ AudioStreamFocusState stateForPlayback;
+ AudioStreamFocusState stateForRecording;
+ int ret = Interop.AudioStreamPolicy.GetFocusState(_streamInfo, out stateForPlayback, out stateForRecording);
+ if(ret != 0) {
+ Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Unable to get focus state" + (AudioManagerError)ret);
+ return AudioStreamFocusState.Released;
+ }
+ return stateForPlayback;
+ }
+ }
+
+ /// <summary>
+ /// The state of focus for recording.
+ /// </summary>
+ public AudioStreamFocusState RecordingFocusState {
+ get {
+ AudioStreamFocusState stateForPlayback;
+ AudioStreamFocusState stateForRecording;
+ int ret = Interop.AudioStreamPolicy.GetFocusState(_streamInfo, out stateForPlayback, out stateForRecording);
+ if(ret != 0) {
+ Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Unable to get focus state" + (AudioManagerError)ret);
+ return AudioStreamFocusState.Released;
+ }
+ return stateForRecording;
+ }
+ }
+
+ /// <summary>
+ /// Auto focus reacquisition property
+ /// </summary>
+ /// <remarks>
+ /// The focus reacquistion is set as default. If you don't want to reacquire the focus you've lost automatically, disable the focus reacqusition setting by using this API and vice versa.
+ /// </remarks>
+ public bool FocusReacquisitionEnabled {
+ get {
+ bool enabled;
+ int ret = Interop.AudioStreamPolicy.GetFocusReacquisition(_streamInfo, out enabled);
+ if(ret != 0) {
+ Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Unable to get focus reacquisition" + (AudioManagerError)ret);
+ return true;
+ }
+ return enabled;
+ }
+ set {
+ int ret = Interop.AudioStreamPolicy.SetFocusReacquisition(_streamInfo, value);
+ AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to set focus reacquisition");
+ }
+ }
+
+ public IntPtr Handle {
+ get {
+ return _streamInfo;
+ }
+ }
+
+ /// <summary>
+ /// Acquires the stream focus.
+ /// </summary>
+ /// <param name="options">The focus mask that user wants to acquire</param>
+ /// <param name="audioStreamBehavior">The required action for releaser</param>
+ /// <param name="extraInformation">The Extra information for this request (optional, this can be null)</param>
+ /// <remarks>
+ /// Do not call this API within event handlers of FocuStateChanged and StreamFocusStateWatch else it will throw and exception
+ /// </remarks>
+ public void AcquireFocus(AudioStreamFocusOptions options, AudioStreamBehavior audioStreamBehavior, string extraInformation)
+ {
+ int ret = Interop.AudioStreamPolicy.AcquireFocus(_streamInfo, options, (int)audioStreamBehavior, extraInformation);
+ Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Acquire focus return: " + ret);
+ AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to acquire focus");
+ }
+
+ /// <summary>
+ /// Releases the acquired focus.
+ /// </summary>
+ /// <param name="options">The focus mask that user wants to release</param>
+ /// <param name="audioStreamBehavior">The required action for acquirer</param>
+ /// <param name="extraInformation">he Extra information for this request (optional, this can be null)</param>
+ /// <remarks>
+ /// Do not call this API within event handlers of FocuStateChanged and StreamFocusStateWatch else it will throw and exception
+ /// </remarks>
+ public void ReleaseFocus(AudioStreamFocusOptions options, AudioStreamBehavior audioStreamBehavior, string extraInformation)
+ {
+ int ret = Interop.AudioStreamPolicy.ReleaseFocus(_streamInfo, options, (int)audioStreamBehavior, extraInformation);
+ Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Release focus return: " + ret);
+ AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to release focus");
+ }
+
+ /// <summary>
+ /// Applies the stream routing.
+ /// </summary>
+ /// <remarks>
+ /// If the stream has not been made yet, this setting will be applied when the stream starts to play.
+ /// Precondition: Call AddDeviceForStreamRouting() before calling this function.
+ /// </remarks>
+ public void ApplyStreamRouting()
+ {
+ int ret = Interop.AudioStreamPolicy.ApplyStreamRouting(_streamInfo);
+ Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Apply Routing: " + (AudioManagerError)ret);
+ AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to apply stream routing");
+ }
+
+ /// <summary>
+ /// Adds the device to the stream information for the stream routing.
+ /// </summary>
+ /// <remarks>
+ /// Remarks: Use SoundManager.GetCurrentDeviceList() to get the device.
+ /// The available types of the StreamInfo for this API are SoundStreamTypeVoip and SoundStreamTypeMediaExternalOnly.
+ /// Postcondition: You can apply this setting by calling ApplyStreamRouting().
+ /// </remarks>
+ /// <param name="soundDevice">The device item from the current sound devices list.</param>
+ public void AddDeviceForStreamRouting(AudioDevice soundDevice)
+ {
+ int ret = Interop.AudioStreamPolicy.AddDeviceForStreamRouting(_streamInfo, soundDevice.Handle);
+ Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Add stream routing: " + (AudioManagerError)ret);
+
+ AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to add device for stream routing");
+ }
+
+ /// <summary>
+ /// Removes the device to the stream information for the stream routing.
+ /// </summary>
+ /// <remarks>
+ /// Remarks: Use SoundManager.GetCurrentDeviceList() to get the device.
+ /// The available types of the StreamInfo for this API are SoundStreamTypeVoip and SoundStreamTypeMediaExternalOnly.
+ /// Postcondition: You can apply this setting by calling ApplyStreamRouting().
+ /// </remarks>
+ /// <param name="soundDevice">The device item from the current sound devices list.</param>
+ public void RemoveDeviceForStreamRouting(AudioDevice soundDevice)
+ {
+ int ret = Interop.AudioStreamPolicy.RemoveDeviceForStreamRouting(_streamInfo, soundDevice.Handle);
+ Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Remove stream routing: " + (AudioManagerError)ret);
+ AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to remove device for stream routing");
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if(!_disposed) {
+ if(disposing) {
+ // to be used if there are any other disposable objects
+ }
+ if(_streamInfo != IntPtr.Zero) {
+ Interop.AudioStreamPolicy.DestroyStreamInformation(_streamInfo); // Destroy the handle
+ _streamInfo = IntPtr.Zero;
+ }
+ _disposed = true;
+ }
+ }
+
+ private static void RegisterFocusStateWatchEvent()
+ {
+ _focusStateWatchCallback = (int id, AudioStreamFocusOptions options, AudioStreamFocusState focusState, AudioStreamFocusChangedReason reason, string extraInfo, IntPtr userData) => {
+ Tizen.Log.Info(AudioStreamPolicyLog.Tag, "############# _Inside _focusStateWatchCallback : id = " + id + "options = " + options);
+ FocusStateChangedEventArgs eventArgs = new FocusStateChangedEventArgs(focusState, reason, extraInfo);
+ if(options == AudioStreamFocusOptions.Playback) {
+ Tizen.Log.Info(AudioStreamPolicyLog.Tag, "############# _eventArgs = " + eventArgs);
+ _focusStateWatchForPlayback?.Invoke(null, eventArgs);
+ } else if(options == AudioStreamFocusOptions.Recording) {
+ _focusStateWatchForRecording?.Invoke(null, eventArgs);
+ } else if(options == (AudioStreamFocusOptions.Playback | AudioStreamFocusOptions.Recording)) {
+ _focusStateWatchForPlayback?.Invoke(null, eventArgs);
+ _focusStateWatchForRecording?.Invoke(null, eventArgs);
+ }
+ };
+ int ret = Interop.AudioStreamPolicy.AddFocusStateWatchCallback(AudioStreamFocusOptions.Playback | AudioStreamFocusOptions.Recording, _focusStateWatchCallback, IntPtr.Zero, out _focusWatchCbId);
+ Tizen.Log.Info(AudioStreamPolicyLog.Tag, "############# _AddFocusStateWatchCallback : ret = " + ret + " ID = " + _focusWatchCbId);
+ AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to set focus state watch callback");
+ }
+
+ private static void UnregisterFocusStateWatch()
+ {
+ int ret = Interop.AudioStreamPolicy.RemoveFocusStateWatchCallback(_focusWatchCbId);
+ AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to unset focus state watch callback");
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia/AudioManager/AudioVolume.cs b/src/Tizen.Multimedia/AudioManager/AudioVolume.cs
new file mode 100755
index 0000000..d87eab2
--- /dev/null
+++ b/src/Tizen.Multimedia/AudioManager/AudioVolume.cs
@@ -0,0 +1,107 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ internal static class AudioVolumeLog
+ {
+ internal const string Tag = "Tizen.Multimedia.AudioVolume";
+ }
+
+ /// <summary>
+ /// The AudioVolume API provides functions to check and control volumes.
+ /// </summary>
+ public class AudioVolume
+ {
+ private static int _volumeChangedCallbackId = -1;
+ private EventHandler<VolumeChangedEventArgs> _volumeChanged;
+ private Interop.SoundManagerVolumeChangedCallback _volumeChangedCallback;
+
+ internal AudioVolume()
+ {
+ Level = new VolumeLevel();
+ MaxLevel = new MaxVolumeLevel();
+ }
+
+ /// <summary>
+ /// Registers a function to be invoked when the volume level is changed.
+ /// </summary>
+ public event EventHandler<VolumeChangedEventArgs> Changed {
+ add {
+ Tizen.Log.Info(AudioVolumeLog.Tag, "VolumeController Changed Event added....");
+ if(_volumeChanged == null) {
+ RegisterVolumeChangedEvent();
+ }
+ _volumeChanged += value;
+ }
+ remove {
+ Tizen.Log.Info(AudioVolumeLog.Tag, "VolumeController Changed Event removed....");
+ if(_volumeChanged?.GetInvocationList()?.GetLength(0) == 1) {
+ UnregisterVolumeChangedEvent();
+ }
+ _volumeChanged -= value;
+ }
+ }
+
+ /// <summary>
+ /// The Audio Manager has predefined volume types.(system, notification, alarm, ringtone, media, call, voip, voice).
+ /// The volume type of the sound being currently played.
+ /// </summary>
+ public AudioVolumeType CurrentPlaybackType {
+ get {
+ AudioVolumeType currentType;
+ int ret = Interop.AudioVolume.GetCurrentSoundType(out currentType);
+ if(ret != 0) {
+ Tizen.Log.Info(AudioVolumeLog.Tag, "Unable to get current playback sound type" + (AudioManagerError)ret);
+ return AudioVolumeType.None;
+ }
+ return currentType;
+ }
+ }
+
+ /// <summary>
+ /// The indexer class which is used to get/set volume level specified for a particular sound type.
+ /// </summary>
+ public VolumeLevel Level;
+
+ /// <summary>
+ /// The indexer class which is used to get maximum volume level supported for a particular sound type.
+ /// </summary>
+ public MaxVolumeLevel MaxLevel;
+
+ private void RegisterVolumeChangedEvent()
+ {
+ _volumeChangedCallback = (AudioVolumeType type, uint volume, IntPtr userData) => {
+ VolumeChangedEventArgs eventArgs = new VolumeChangedEventArgs(type, volume);
+ _volumeChanged.Invoke(this, eventArgs);
+ };
+ int error = Interop.AudioVolume.AddVolumeChangedCallback(_volumeChangedCallback, IntPtr.Zero, out _volumeChangedCallbackId);
+ Tizen.Log.Info(AudioVolumeLog.Tag, "VolumeController Add Changed Event return id:" + _volumeChangedCallbackId + "error:" + error);
+ AudioManagerErrorFactory.CheckAndThrowException(error, "unable to add level changed callback");
+ }
+
+ private void UnregisterVolumeChangedEvent()
+ {
+ if (_volumeChangedCallbackId > 0) {
+ int error = Interop.AudioVolume.RemoveVolumeChangedCallback(_volumeChangedCallbackId);
+ Tizen.Log.Info(AudioVolumeLog.Tag, "VolumeController Remove Changed Event(id:" + _volumeChangedCallbackId + ") return error: " + error);
+ AudioManagerErrorFactory.CheckAndThrowException(error, "unable to remove level changed callback");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia/AudioManager/FocusStateChangedEventArgs.cs b/src/Tizen.Multimedia/AudioManager/FocusStateChangedEventArgs.cs
new file mode 100644
index 0000000..cf17aae
--- /dev/null
+++ b/src/Tizen.Multimedia/AudioManager/FocusStateChangedEventArgs.cs
@@ -0,0 +1,48 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Class extending EventArgs and contains the necessary parameters to passed to FocusStateWatch event handler
+ /// </summary>
+ public class FocusStateChangedEventArgs : EventArgs
+ {
+ internal FocusStateChangedEventArgs(AudioStreamFocusState focusState, AudioStreamFocusChangedReason reason, string extraInformation)
+ {
+ FocusState = focusState;
+ FocusChangedReason = reason;
+ ExtraInformation = extraInformation;
+ }
+
+ /// <summary>
+ /// The changed focus state
+ /// </summary>
+ public AudioStreamFocusState FocusState { get; }
+
+ /// <summary>
+ /// The reason for state change of the focus
+ /// </summary>
+ public AudioStreamFocusChangedReason FocusChangedReason { get; }
+
+ /// <summary>
+ /// The extra information
+ /// </summary>
+ public string ExtraInformation { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia/AudioManager/MaxVolumeLevel.cs b/src/Tizen.Multimedia/AudioManager/MaxVolumeLevel.cs
new file mode 100644
index 0000000..5e1ed72
--- /dev/null
+++ b/src/Tizen.Multimedia/AudioManager/MaxVolumeLevel.cs
@@ -0,0 +1,46 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ internal static class MaxVolumeLog
+ {
+ internal const string Tag = "Tizen.Multimedia.MaxVolume";
+ }
+
+ /// <summary>
+ /// This is a indexer class which is used to get the maximum volume level
+ /// supported for a particular sound type.
+ /// </summary>
+ public class MaxVolumeLevel
+ {
+ public int this [AudioVolumeType type] {
+ get {
+ if(type == AudioVolumeType.None)
+ throw new ArgumentException("Wrong Audio volume type. Cannot get max volume level for AudioVolumeType.None");
+ int maxVolume;
+ int ret = Interop.AudioVolume.GetMaxVolume(type, out maxVolume);
+ if(ret != 0) {
+ Tizen.Log.Info(MaxVolumeLog.Tag, "Max Level Error: " + (AudioManagerError)ret);
+ return -1;
+ }
+ return maxVolume;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Multimedia/AudioManager/StreamFocusStateChangedEventArgs.cs b/src/Tizen.Multimedia/AudioManager/StreamFocusStateChangedEventArgs.cs
new file mode 100755
index 0000000..225cbe4
--- /dev/null
+++ b/src/Tizen.Multimedia/AudioManager/StreamFocusStateChangedEventArgs.cs
@@ -0,0 +1,43 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Class extending EventArgs and contains the necessary parameters to passed to FocusStateChanged event handler
+ /// </summary>
+ public class StreamFocusStateChangedEventArgs : EventArgs
+ {
+ /* FIXME */
+ internal StreamFocusStateChangedEventArgs(AudioStreamFocusChangedReason reason, string extraInformation)
+ {
+ FocusChangedReason = reason;
+ ExtraInformation = extraInformation;
+ }
+
+ /// <summary>
+ /// The reason for state change of the focus
+ /// </summary>
+ public AudioStreamFocusChangedReason FocusChangedReason { get; }
+
+ /// <summary>
+ /// The extra information
+ /// </summary>
+ public string ExtraInformation { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia/AudioManager/VolumeChangedEventArgs.cs b/src/Tizen.Multimedia/AudioManager/VolumeChangedEventArgs.cs
new file mode 100755
index 0000000..1643976
--- /dev/null
+++ b/src/Tizen.Multimedia/AudioManager/VolumeChangedEventArgs.cs
@@ -0,0 +1,42 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Extnded EventArgs which contains the parameteres to be passed to the AudioVolume Changed event
+ /// </summary>
+ public class VolumeChangedEventArgs : EventArgs
+ {
+ internal VolumeChangedEventArgs(AudioVolumeType type, uint level)
+ {
+ Type = type;
+ Level = level;
+ }
+
+ /// <summary>
+ /// The sound type of the changed volume
+ /// </summary>
+ public AudioVolumeType Type { get; }
+
+ /// <summary>
+ /// The new volume value
+ /// </summary>
+ public uint Level { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia/AudioManager/VolumeLevel.cs b/src/Tizen.Multimedia/AudioManager/VolumeLevel.cs
new file mode 100644
index 0000000..a4aeaed
--- /dev/null
+++ b/src/Tizen.Multimedia/AudioManager/VolumeLevel.cs
@@ -0,0 +1,55 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ internal static class VolumeLevelLog
+ {
+ internal const string Tag = "Tizen.Multimedia.VolumeLevel";
+ }
+
+ /// <summary>
+ /// This is a indexer class which is used to get/set the volume level
+ /// specified for a particular sound type.
+ /// </summary>
+ public class VolumeLevel
+ {
+ public int this [AudioVolumeType type] {
+ get {
+ if(type == AudioVolumeType.None)
+ throw new ArgumentException("Wrong Audio volume type. Cannot get volume level for AudioVolumeType.None");
+ int volume;
+ int ret = Interop.AudioVolume.GetVolume(type, out volume);
+ if(ret != 0) {
+ Tizen.Log.Info(VolumeLevelLog.Tag, "Get Level Error: " + (AudioManagerError)ret);
+ return -1;
+ }
+ return volume;
+ }
+ set {
+ if(type == AudioVolumeType.None)
+ throw new ArgumentException("Wrong Audio volume type. Cannot set volume level for AudioVolumeType.None");
+ int ret = Interop.AudioVolume.SetVolume(type, value);
+ if(ret != 0) {
+ Tizen.Log.Info(VolumeLevelLog.Tag, "Set Level Error: " + (AudioManagerError)ret);
+ AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to set level");
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Multimedia/Common.Internal/Features.cs b/src/Tizen.Multimedia/Common.Internal/Features.cs
new file mode 100644
index 0000000..50c8508
--- /dev/null
+++ b/src/Tizen.Multimedia/Common.Internal/Features.cs
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using Tizen.System;
+
+namespace Tizen.Multimedia
+{
+ internal static class Features
+ {
+ internal const string AudioEffect = "http://tizen.org/feature/multimedia.custom_audio_effect";
+ internal const string RawVideo = "http://tizen.org/feature/multimedia.raw_video";
+
+ internal static bool IsSupported(string featureKey)
+ {
+ bool supported = false;
+ SystemInfo.TryGetValue(featureKey, out supported);
+ return supported;
+ }
+
+ }
+}
diff --git a/src/Tizen.Multimedia/Common.Internal/FileUtil.cs b/src/Tizen.Multimedia/Common.Internal/FileUtil.cs
new file mode 100644
index 0000000..2b3e6f5
--- /dev/null
+++ b/src/Tizen.Multimedia/Common.Internal/FileUtil.cs
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.IO;
+
+namespace Tizen.Multimedia
+{
+ internal static class FileUtil
+ {
+ public static bool HasReadPermission(string path)
+ {
+ return Access(path, Interop.Libc.AccessMode.R_OK);
+ }
+
+ public static bool HasWritePermission(string path)
+ {
+
+ return Access(Path.GetDirectoryName(path), Interop.Libc.AccessMode.W_OK);
+ }
+
+ private static bool Access(string path, int mode)
+ {
+ if (path == null)
+ {
+ throw new ArgumentNullException(nameof(path));
+ }
+ return Interop.Libc.Access(path, mode) == 0;
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia/Common.Internal/IBufferOwner.cs b/src/Tizen.Multimedia/Common.Internal/IBufferOwner.cs
new file mode 100644
index 0000000..f779510
--- /dev/null
+++ b/src/Tizen.Multimedia/Common.Internal/IBufferOwner.cs
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ internal enum MediaBufferAccessMode
+ {
+ Read,
+ Write
+ }
+
+ internal interface IBufferOwner
+ {
+ bool IsBufferAccessible(object buffer, MediaBufferAccessMode accessMode);
+
+ bool IsDisposed { get; }
+ }
+
+
+ internal static class BufferOwnerExtensions
+ {
+ internal static void ValidateBufferReadable(this IBufferOwner bufferOwner, IReadOnlyBuffer buffer)
+ {
+ if (bufferOwner.IsDisposed)
+ {
+ throw new ObjectDisposedException(bufferOwner.GetType().Name);
+ }
+
+ if (!bufferOwner.IsBufferAccessible(buffer, MediaBufferAccessMode.Read))
+ {
+ throw new InvalidOperationException("The buffer is not in the readable state.");
+ }
+ }
+
+ internal static void ValidateBufferWritable(this IBufferOwner bufferOwner, IMediaBuffer buffer)
+ {
+ if (bufferOwner.IsDisposed)
+ {
+ throw new ObjectDisposedException(bufferOwner.GetType().Name);
+ }
+
+ if (!bufferOwner.IsBufferAccessible(buffer, MediaBufferAccessMode.Write))
+ {
+ throw new InvalidOperationException("The buffer is not in writable state.");
+ }
+ }
+ }
+
+}
diff --git a/src/Tizen.Multimedia/Common.Internal/LibcSupport.cs b/src/Tizen.Multimedia/Common.Internal/LibcSupport.cs
new file mode 100644
index 0000000..0f11db1
--- /dev/null
+++ b/src/Tizen.Multimedia/Common.Internal/LibcSupport.cs
@@ -0,0 +1,13 @@
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ internal static class LibcSupport
+ {
+ internal static void Free(IntPtr ptr)
+ {
+ Interop.Libc.Free(ptr);
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia/Common.Internal/MultimediaDebug.cs b/src/Tizen.Multimedia/Common.Internal/MultimediaDebug.cs
new file mode 100644
index 0000000..3e00569
--- /dev/null
+++ b/src/Tizen.Multimedia/Common.Internal/MultimediaDebug.cs
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System.Diagnostics;
+
+namespace Tizen.Multimedia
+{
+ internal class MultimediaDebug
+ {
+ [Conditional("DEBUG")]
+ internal static void AssertNoError(int errorCode)
+ {
+ Debug.Assert(errorCode == (int)Internals.Errors.ErrorCode.None,
+ $"The API is supposed not to return an error! But it returns error({ errorCode }).",
+ "Implementation of core may have been changed, modify the call to throw if the return code is not ok.");
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia/Common.Internal/MultimediaLog.cs b/src/Tizen.Multimedia/Common.Internal/MultimediaLog.cs
new file mode 100644
index 0000000..e844bdd
--- /dev/null
+++ b/src/Tizen.Multimedia/Common.Internal/MultimediaLog.cs
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Text;
+
+namespace Tizen.Multimedia
+{
+ internal static class MultimediaLog
+ {
+ [Conditional("DEBUG")]
+ public static void Debug(string tag, string message, Exception e = null, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ Log.Debug(tag, BuildMessage(message, e), file, func, line);
+ }
+
+ public static void Error(string tag, string message, Exception e = null, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ Log.Error(tag, BuildMessage(message, e), file, func, line);
+ }
+
+ public static void Fatal(string tag, string message, Exception e = null, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ Log.Fatal(tag, BuildMessage(message, e), file, func, line);
+ }
+
+ public static void Info(string tag, string message, Exception e = null, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ Log.Info(tag, BuildMessage(message, e), file, func, line);
+ }
+
+ public static void Verbose(string tag, string message, Exception e = null, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ Log.Verbose(tag, BuildMessage(message, e), file, func, line);
+ }
+
+ public static void Warn(string tag, string message, Exception e = null, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ Log.Warn(tag, BuildMessage(message, e), file, func, line);
+ }
+
+ private static string BuildMessage(string message, Exception exception)
+ {
+ if (exception == null)
+ {
+ return message;
+ }
+
+ StringBuilder sb = new StringBuilder();
+
+ Exception e = exception;
+ while (e != null)
+ {
+ message += e.Message + Environment.NewLine + e.StackTrace;
+ e = e.InnerException;
+ }
+
+ return sb.ToString();
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia/Common.Internal/ObjectKeeper.cs b/src/Tizen.Multimedia/Common.Internal/ObjectKeeper.cs
new file mode 100644
index 0000000..6f4de80
--- /dev/null
+++ b/src/Tizen.Multimedia/Common.Internal/ObjectKeeper.cs
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Multimedia
+{
+ internal abstract class ObjectKeeper : IDisposable
+ {
+ private ObjectKeeper()
+ {
+ }
+
+ public abstract void Dispose();
+
+ public static ObjectKeeperImpl<T> Get<T>(T target)
+ {
+ return new ObjectKeeperImpl<T>(target);
+ }
+
+ internal class ObjectKeeperImpl<T> : ObjectKeeper
+ {
+ private readonly GCHandle _handle;
+
+ internal ObjectKeeperImpl(T obj)
+ {
+ Target = obj;
+ _handle = GCHandle.Alloc(obj);
+ }
+
+ ~ObjectKeeperImpl()
+ {
+ Dispose(false);
+ }
+
+ private bool disposedValue = false;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ _handle.Free();
+ }
+
+ disposedValue = true;
+ }
+ }
+
+ public override void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ public T Target
+ {
+ get;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia/Common.Internal/ValdiationUtil.cs b/src/Tizen.Multimedia/Common.Internal/ValdiationUtil.cs
new file mode 100644
index 0000000..3e71d0b
--- /dev/null
+++ b/src/Tizen.Multimedia/Common.Internal/ValdiationUtil.cs
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ internal static class ValidationUtil
+ {
+ internal static void ValidateEnum(Type enumType, object value)
+ {
+ if (!Enum.IsDefined(enumType, value))
+ {
+ throw new ArgumentException($"Invalid { enumType.Name } value : { value }");
+ }
+ }
+
+ internal static void ValidateEnum(Type enumType, object value, string paramName)
+ {
+ if (!Enum.IsDefined(enumType, value))
+ {
+ throw new ArgumentException($"Invalid { enumType.Name } value : { value }", paramName);
+ }
+ }
+
+ internal static void ValidateFeatureSupported(string featureKey)
+ {
+ if (Features.IsSupported(featureKey) == false)
+ {
+ throw new NotSupportedException($"The feature({featureKey}) is not supported.");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia/Common/CodecNotSupportedException.cs b/src/Tizen.Multimedia/Common/CodecNotSupportedException.cs
new file mode 100644
index 0000000..ed8dec6
--- /dev/null
+++ b/src/Tizen.Multimedia/Common/CodecNotSupportedException.cs
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Specifies whether a codec is audio codec or video codec.
+ /// </summary>
+ public enum CodecKind
+ {
+ /// <summary>
+ /// Audio codec
+ /// </summary>
+ Audio,
+
+ /// <summary>
+ /// Video codec
+ /// </summary>
+ Video
+ }
+
+ /// <summary>
+ /// The exception that is thrown when the codec for an input file or a data stream is not supported
+ /// or the input is malformed.
+ /// </summary>
+ public class CodecNotSupportedException : InvalidOperationException
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CodecNotSupportedException"/> class
+ /// with <see cref="CodecKind"/> indicating which codec is not supported.
+ /// </summary>
+ public CodecNotSupportedException(CodecKind kind)
+ {
+ CodecKind = kind;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CodecNotSupportedException"/> class with
+ /// <see cref="CodecKind"/> indicating which codec is not supported and a specified error message.
+ /// </summary>
+ public CodecNotSupportedException(CodecKind kind, string message) : base(message)
+ {
+ CodecKind = kind;
+ }
+
+ /// <summary>
+ /// Gets the <see cref="CodecKind"/> of the exception.
+ /// </summary>
+ public CodecKind CodecKind { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia/Common/ColorSpace.cs b/src/Tizen.Multimedia/Common/ColorSpace.cs
new file mode 100644
index 0000000..edbb001
--- /dev/null
+++ b/src/Tizen.Multimedia/Common/ColorSpace.cs
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Specifies color spaces for Tizen.Multimedia.
+ /// </summary>
+ public enum ColorSpace
+ {
+ /// <summary>
+ /// Y800
+ /// </summary>
+ Y800,
+
+ /// <summary>
+ /// I420
+ /// </summary>
+ I420,
+
+ /// <summary>
+ /// NV12
+ /// </summary>
+ NV12,
+
+ /// <summary>
+ /// NV16
+ /// </summary>
+ NV16,
+
+ /// <summary>
+ /// NV21
+ /// </summary>
+ NV21,
+
+ /// <summary>
+ /// NV61
+ /// </summary>
+ NV61,
+
+ /// <summary>
+ /// YV12
+ /// </summary>
+ ///
+ YV12,
+
+ /// <summary>
+ /// YUYV
+ /// </summary>
+ Yuyv,
+
+ /// <summary>
+ /// YUV422
+ /// </summary>
+ Yuv422,
+
+ /// <summary>
+ /// UYVY
+ /// </summary>
+ Uyvy,
+
+ /// <summary>
+ /// YUV422P
+ /// </summary>
+ ///
+ Yuv422P,
+
+ /// <summary>
+ /// RGB565
+ /// </summary>
+ Rgb565,
+
+ /// <summary>
+ /// RGB888
+ /// </summary>
+ Rgb888,
+
+ /// <summary>
+ /// RGBA8888
+ /// </summary>
+ Rgba8888,
+
+ /// <summary>
+ /// ARGB8888
+ /// </summary>
+ Argb8888,
+
+ /// <summary>
+ /// BGRA8888
+ /// </summary>
+ Bgra8888,
+
+ /// <summary>
+ /// BGRX8888
+ /// </summary>
+ Bgrx8888
+
+ }
+}
diff --git a/src/Tizen.Multimedia/Common/Display.cs b/src/Tizen.Multimedia/Common/Display.cs
new file mode 100644
index 0000000..5fc22c3
--- /dev/null
+++ b/src/Tizen.Multimedia/Common/Display.cs
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using ElmSharp;
+
+namespace Tizen.Multimedia
+{
+ internal enum DisplayType
+ {
+ /// <summary>
+ /// Overlay surface display
+ /// </summary>
+ Overlay,
+
+ /// <summary>
+ /// Evas image object surface display
+ /// </summary>
+ Surface,
+
+ /// <summary>
+ /// This disposes off buffers
+ /// </summary>
+ None,
+ }
+
+ internal interface IDisplayable<ErrorType>
+ {
+ ErrorType ApplyEvasDisplay(DisplayType type, EvasObject evasObject);
+ }
+
+ /// <summary>
+ /// Provides a means to wrap various display types.
+ /// </summary>
+ /// <seealso cref="Player"/>
+ /// <seealso cref="Camera"/>
+ /// <seealso cref="ScreenMirroring"/>
+ public class Display
+ {
+ private Display(DisplayType type, EvasObject target)
+ {
+ if (target == null)
+ {
+ throw new ArgumentNullException(nameof(target));
+ }
+
+ if (target == IntPtr.Zero)
+ {
+ throw new ArgumentException("The evas object is not realized.");
+ }
+
+ Type = type;
+ EvasObject = target;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Display"/> class with a <see cref="MediaView"/> class.
+ /// </summary>
+ /// <feature>http://tizen.org/feature/multimedia.raw_video</feature>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ public Display(MediaView mediaView) : this(DisplayType.Surface, mediaView)
+ {
+ ValidationUtil.ValidateFeatureSupported(Features.RawVideo);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Display"/> class with a <see cref="Window"/> class.
+ /// </summary>
+ public Display(Window window) : this(DisplayType.Overlay, window)
+ {
+ }
+
+ private EvasObject EvasObject { get; }
+
+ private DisplayType Type { get; }
+
+ internal object Owner
+ {
+ get;
+ set;
+ }
+
+ internal ErrorType ApplyTo<ErrorType>(IDisplayable<ErrorType> target)
+ {
+ return target.ApplyEvasDisplay(Type, EvasObject);
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia/Common/FileFormatException.cs b/src/Tizen.Multimedia/Common/FileFormatException.cs
new file mode 100644
index 0000000..e7d7d9a
--- /dev/null
+++ b/src/Tizen.Multimedia/Common/FileFormatException.cs
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// The exception that is thrown when an input file or a data stream that is supposed to conform
+ /// to a certain file format specification is malformed.
+ /// </summary>
+ public class FileFormatException : FormatException
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="FileFormatException"/> class.
+ /// </summary>
+ public FileFormatException()
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="FileFormatException"/> class with a specified error message.
+ /// </summary>
+ public FileFormatException(string message) : base(message)
+ {
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia/Common/IMediaBuffer.cs b/src/Tizen.Multimedia/Common/IMediaBuffer.cs
new file mode 100644
index 0000000..f1f3f72
--- /dev/null
+++ b/src/Tizen.Multimedia/Common/IMediaBuffer.cs
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides functionality to read a media buffer.
+ /// </summary>
+ public interface IReadOnlyBuffer
+ {
+ /// <summary>
+ /// Gets or sets a value at the specified index.
+ /// </summary>
+ /// <param name="index">The index of the value to get or set.</param>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// index is less than zero.\n
+ /// -or-\n
+ /// index is equal to or greater than <see cref="Length"/>.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">The object that owns the current buffer already has been disposed of.</exception>
+ /// <exception cref="InvalidOperationException">The buffer is not available. i.e. not writable state.</exception>
+ byte this[int index]
+ {
+ get;
+ set;
+ }
+ /// <summary>
+ /// Gets the size of the buffer, in bytes.
+ /// </summary>
+ int Length
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Copies data from a byte array to the buffer.
+ /// </summary>
+ /// <param name="dest">The array to copy to.</param>
+ /// <param name="startIndex">The zero-based index in the source array where copying should start.</param>
+ /// <param name="length">The number of array elements to copy.</param>
+ /// <exception cref="ArgumentOutOfRangeException">startIndex or length is not valid.</exception>
+ /// <exception cref="ObjectDisposedException">The object that owns the current buffer already has been disposed of.</exception>
+ void CopyTo(byte[] dest, int startIndex, int length);
+
+ /// <summary>
+ /// Copies data from a byte array to the buffer.
+ /// </summary>
+ /// <param name="dest">The array to copy to.</param>
+ /// <param name="startIndex">The zero-based index in the source array where copying should start.</param>
+ /// <param name="length">The number of array elements to copy.</param>
+ /// <param name="offset">The zero-based index in the buffer where copying should start.</param>
+ /// <exception cref="ArgumentOutOfRangeException">startIndex, offset or length is not valid.</exception>
+ /// <exception cref="ObjectDisposedException">The object that owns the current buffer already has been disposed of.</exception>
+ void CopyTo(byte[] dest, int startIndex, int length, int offset);
+ }
+
+ /// <summary>
+ /// Provides functionality to read and write a media buffer.
+ /// </summary>
+ public interface IMediaBuffer : IReadOnlyBuffer
+ {
+ /// <summary>
+ /// Copies data from the buffer to a byte array.
+ /// </summary>
+ /// <param name="source">The array to copy from.</param>
+ /// <param name="startIndex">The zero-based index in the dest array where copying should start.</param>
+ /// <param name="length">The number of elements to copy.</param>
+ /// <exception cref="ArgumentOutOfRangeException">startIndex or length is not valid.</exception>
+ /// <exception cref="ObjectDisposedException">The object that owns the current buffer already has been disposed of.</exception>
+ /// <exception cref="InvalidOperationException">The buffer is not available. i.e. not writable state.</exception>
+
+ void CopyFrom(byte[] source, int startIndex, int length);
+
+ /// <summary>
+ /// Copies data from the buffer to a byte array.
+ /// </summary>
+ /// <param name="source">The array to copy from.</param>
+ /// <param name="startIndex">The zero-based index in the dest array where copying should start.</param>
+ /// <param name="length">The number of elements to copy.</param>
+ /// <param name="offset">The zero-based index in the buffer where copying should start.</param>
+ /// <exception cref="ArgumentOutOfRangeException">startIndex, offset or length is not valid.</exception>
+ /// <exception cref="ObjectDisposedException">The object that owns the current buffer already has been disposed of.</exception>
+ /// <exception cref="InvalidOperationException">The buffer is not available. i.e. not writable state.</exception>
+ void CopyFrom(byte[] source, int startIndex, int length, int offset);
+ }
+
+ /// <summary>
+ /// Represents a buffer for a <see cref="MediaPacket"/>.
+ /// </summary>
+ internal class DependentMediaBuffer : IMediaBuffer
+ {
+ private readonly IBufferOwner _owner;
+ private readonly IntPtr _dataHandle;
+
+ internal DependentMediaBuffer(IBufferOwner owner, IntPtr dataHandle, int size)
+ {
+ Debug.Assert(owner != null, "Owner is null!");
+ Debug.Assert(!owner.IsDisposed, "Owner has been already disposed!");
+ Debug.Assert(dataHandle != IntPtr.Zero, "dataHandle is null!");
+ Debug.Assert(size >= 0, "size must not be negative!");
+
+ _owner = owner;
+ _dataHandle = dataHandle;
+ Length = size;
+ }
+
+ public byte this[int index]
+ {
+ get
+ {
+ _owner.ValidateBufferReadable(this);
+
+ if (index < 0 || index >= Length)
+ {
+ throw new ArgumentOutOfRangeException($"Valid index range is [0, { nameof(Length) }).");
+ }
+
+ return Marshal.ReadByte(_dataHandle, index);
+ }
+ set
+ {
+ _owner.ValidateBufferWritable(this);
+
+ Marshal.WriteByte(_dataHandle, index, value);
+ }
+ }
+
+ /// <summary>
+ /// Validates the range
+ /// </summary>
+ /// <param name="offset"></param>
+ /// <param name="length"></param>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// offset + length is greater than <see cref="Length"/>.\n
+ /// -or-\n
+ /// offset or length is less than zero.
+ /// </exception>
+ private void ValidateRange(int offset, int length)
+ {
+ if (offset + length > Length)
+ {
+ throw new ArgumentOutOfRangeException("offset + length can't be greater than length of the buffer.");
+ }
+ if (length < 0)
+ {
+ throw new ArgumentOutOfRangeException($"Length can't be less than zero : { length }.");
+ }
+ if (offset < 0)
+ {
+ throw new ArgumentOutOfRangeException($"Offset can't be less than zero : { offset }.");
+ }
+ }
+
+ public void CopyFrom(byte[] source, int startIndex, int length, int offset)
+ {
+ _owner.ValidateBufferReadable(this);
+
+ if (startIndex < 0)
+ {
+ throw new ArgumentOutOfRangeException("startIndex can't be less than zero.");
+ }
+ if (startIndex + length > source.Length)
+ {
+ throw new ArgumentOutOfRangeException("startIndex + length can't be greater than source.Length.");
+ }
+
+ ValidateRange(offset, length);
+
+ Marshal.Copy(source, startIndex, IntPtr.Add(_dataHandle, offset), length);
+ }
+
+ public void CopyFrom(byte[] source, int startIndex, int length)
+ {
+ CopyFrom(source, startIndex, length, 0);
+ }
+
+ public void CopyTo(byte[] dest, int startIndex, int length, int offset)
+ {
+ _owner.ValidateBufferWritable(this);
+
+ if (startIndex < 0)
+ {
+ throw new ArgumentOutOfRangeException("Start index can't be less than zero.");
+ }
+ if (startIndex + length > dest.Length)
+ {
+ throw new ArgumentOutOfRangeException("startIndex + length can't be greater than dest.Length.");
+ }
+
+ ValidateRange(offset, length);
+
+ Marshal.Copy(IntPtr.Add(_dataHandle, offset), dest, startIndex, length);
+ }
+
+ public void CopyTo(byte[] dest, int startIndex, int length)
+ {
+ CopyTo(dest, startIndex, length, 0);
+ }
+
+ public int Length { get; }
+ }
+}
diff --git a/src/Tizen.Multimedia/Common/Point.cs b/src/Tizen.Multimedia/Common/Point.cs
new file mode 100644
index 0000000..9ac20fe
--- /dev/null
+++ b/src/Tizen.Multimedia/Common/Point.cs
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents a point in 2D space.
+ /// </summary>
+ public struct Point
+ {
+
+ /// <summary>
+ /// Initializes a new instance of the Point with the specified coordinates.
+ /// </summary>
+ /// <param name="x">X-axis coordinate of the point in 2D space.</param>
+ /// <param name="y">Y-axis coordinate of the point in 2D space.</param>
+ public Point(int x, int y)
+ {
+ X = x;
+ Y = y;
+ }
+
+ /// <summary>
+ /// Gets or sets X-axis coordinate of the point in 2D space.
+ /// </summary>
+ public int X
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// Gets or sets Y-axis coordinate of the point in 2D space.
+ /// </summary>
+ public int Y
+ {
+ get;
+ set;
+ }
+
+ public override string ToString() => $"X={X.ToString()}, Y={Y.ToString()}";
+
+ public override int GetHashCode()
+ {
+ return new { X, Y }.GetHashCode();
+ }
+
+ public override bool Equals(object obj)
+ {
+ return obj is Point && this == (Point)obj;
+ }
+
+ public static bool operator ==(Point lhs, Point rhs)
+ {
+ return lhs.X == rhs.X && lhs.Y == rhs.Y;
+ }
+
+ public static bool operator !=(Point lhs, Point rhs)
+ {
+ return !(lhs == rhs);
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia/Common/Range.cs b/src/Tizen.Multimedia/Common/Range.cs
new file mode 100644
index 0000000..cc82a74
--- /dev/null
+++ b/src/Tizen.Multimedia/Common/Range.cs
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents a range(min, max) value.
+ /// </summary>
+ public struct Range
+ {
+ /// <summary>
+ /// Initializes a new instance of the Range with the specified values.
+ /// </summary>
+ /// <param name="min">Minimum value of the range.</param>
+ /// <param name="max">Maximum value of the range.</param>
+ /// <exception cref="ArgumentException"><paramref name="max"/> is less than <paramref name="min"/>.</exception>
+ public Range(int min, int max)
+ {
+ if (min > max)
+ {
+ throw new ArgumentException($"min can't be greater than max.");
+ }
+ Min = min;
+ Max = max;
+ }
+
+ /// <summary>
+ /// Gets or sets minimum value of the range.
+ /// </summary>
+ public int Min
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// Gets or sets maximum value of the range.
+ /// </summary>
+ public int Max
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// Gets length of the range.
+ /// </summary>
+ public int Length => Max - Min;
+
+ /// <summary>
+ /// Determines if the specified value is inside of the range.
+ /// </summary>
+ /// <param name="value">A value to check.</param>
+ /// <returns>true if the value is inside of the range; otherwise false.</returns>
+ public bool IsInside(int value)
+ {
+ return Min <= value && value <= Max;
+ }
+
+ public override string ToString() => $"Min={Min.ToString()}, Max={Max.ToString()}";
+
+ public override int GetHashCode()
+ {
+ return new { Min, Max }.GetHashCode();
+ }
+
+ public override bool Equals(object obj)
+ {
+ return obj is Range && this == (Range)obj;
+ }
+
+ public static bool operator ==(Range lhs, Range rhs)
+ {
+ return lhs.Min == rhs.Min && lhs.Max == rhs.Max;
+ }
+
+ public static bool operator !=(Range lhs, Range rhs)
+ {
+ return !(lhs == rhs);
+ }
+ }
+}
+
diff --git a/src/Tizen.Multimedia/Common/Rectangle.cs b/src/Tizen.Multimedia/Common/Rectangle.cs
new file mode 100644
index 0000000..28d1485
--- /dev/null
+++ b/src/Tizen.Multimedia/Common/Rectangle.cs
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// This class represents location of the object bounded by rectangle defined by
+ /// coordinates of top left corner, width and height.
+ /// </summary>
+ public struct Rectangle
+ {
+ private Point _location;
+ private Size _size;
+
+ /// <summary>
+ /// Initializes a new instance of the Rectangle with the specified values.
+ /// </summary>
+ /// <param name="x">The x-coordinate of the upper-left corner of the rectangle.</param>
+ /// <param name="y">The y-coordinate of the upper-left corner of the rectangle.</param>
+ /// <param name="width">The Width of the rectangle.</param>
+ /// <param name="height">The Height of the rectangle.</param>
+ public Rectangle(int x, int y, int width, int height) : this(new Point(x, y),
+ new Size(width, height))
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the Rectangle with the specified values.
+ /// </summary>
+ /// <param name="location">A <see cref="Location"/> that represents the upper-left corner of the rectangular region.</param>
+ /// <param name="size">A <see cref="Size"/> that represents the width and height of the rectangular region.</param>
+ public Rectangle(Point location, Size size)
+ {
+ _location = location;
+ _size = size;
+ }
+
+ /// <summary>
+ /// Gets or sets the coordinates of the upper-left corner of the rectangle.
+ /// </summary>
+ public Point Location
+ {
+ get { return _location; }
+ set { _location = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets the x-coordinate of the upper-left corner of the rectangle.
+ /// </summary>
+ public int X
+ {
+ get { return _location.X; }
+ set { _location.X = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets the y-coordinate of the upper-left corner of the rectangle.
+ /// </summary>
+ public int Y
+ {
+ get { return _location.Y; }
+ set { _location.Y = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets the width of the rectangle.
+ /// </summary>
+ public int Width
+ {
+ get { return _size.Width; }
+ set { _size.Width = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets the height of the rectangle.
+ /// </summary>
+ public int Height
+ {
+ get { return _size.Height; }
+ set { _size.Height = value; }
+ }
+
+ /// <summary>
+ /// Gets the x-coordinate of the left edge of the rectangle.
+ /// </summary>
+ public int Left => X;
+
+ /// <summary>
+ /// Gets the y-coordinate of the top edge of the rectangle.
+ /// </summary>
+ public int Top => Y;
+
+ /// <summary>
+ /// Gets the x-coordinate of the right edge of the rectangle.
+ /// </summary>
+ public int Right => X + Width;
+
+ /// <summary>
+ /// Gets the y-coordinate of the bottom edge of the rectangle.
+ /// </summary>
+ public int Bottom => Y + Height;
+
+ /// <summary>
+ /// Gets or sets the size of the rectangle.
+ /// </summary>
+ public Size Size
+ {
+ get { return _size; }
+ set { _size = value; }
+ }
+
+ public override string ToString() => $"{_location.ToString()}, {_size.ToString()}";
+
+ public override int GetHashCode()
+ {
+ return new { Location, Size }.GetHashCode();
+ }
+
+ public override bool Equals(object obj)
+ {
+ return obj is Rectangle && this == (Rectangle)obj;
+ }
+
+ public static bool operator ==(Rectangle lhs, Rectangle rhs)
+ {
+ return lhs.Location == rhs.Location && lhs.Size == rhs.Size;
+ }
+
+ public static bool operator !=(Rectangle lhs, Rectangle rhs)
+ {
+ return !(lhs == rhs);
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia/Common/Size.cs b/src/Tizen.Multimedia/Common/Size.cs
new file mode 100644
index 0000000..b7bbb5a
--- /dev/null
+++ b/src/Tizen.Multimedia/Common/Size.cs
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ public struct Size
+ {
+ /// <summary>
+ /// Initializes a new instance of the Size with the specified values.
+ /// </summary>
+ /// <param name="width">Width of the size.</param>
+ /// <param name="height">Height of the size.</param>
+ public Size(int width, int height)
+ {
+ Width = width;
+ Height = height;
+ }
+
+ /// <summary>
+ /// Gets or sets the width of the Size.
+ /// </summary>
+ public int Width
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// Gets or sets the height of the Size.
+ /// </summary>
+ public int Height
+ {
+ get;
+ set;
+ }
+
+ public override string ToString() => $"Width={ Width.ToString() }, Height={ Height.ToString() }";
+
+ public override int GetHashCode()
+ {
+ return new { Width, Height }.GetHashCode();
+ }
+
+ public override bool Equals(object obj)
+ {
+ return obj is Size && this == (Size)obj;
+ }
+
+ public static bool operator ==(Size lhs, Size rhs)
+ {
+ return lhs.Width == rhs.Width && lhs.Height == rhs.Height;
+ }
+
+ public static bool operator !=(Size lhs, Size rhs)
+ {
+ return !(lhs == rhs);
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia/Common/Visibility.cs b/src/Tizen.Multimedia/Common/Visibility.cs
new file mode 100644
index 0000000..97e6d07
--- /dev/null
+++ b/src/Tizen.Multimedia/Common/Visibility.cs
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Specifies visibilities.
+ /// </summary>
+ public enum Visibility
+ {
+ /// <summary>
+ /// Invisible.
+ /// </summary>
+ Invisible,
+ /// <summary>
+ /// Visible.
+ /// </summary>
+ Visible
+ }
+}
diff --git a/src/Tizen.Multimedia/Interop/Interop.Device.cs b/src/Tizen.Multimedia/Interop/Interop.Device.cs
new file mode 100644
index 0000000..c8ae644
--- /dev/null
+++ b/src/Tizen.Multimedia/Interop/Interop.Device.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Multimedia
+{
+ internal static partial class Interop
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void SoundDeviceConnectionChangedCallback(IntPtr device, bool isConnected, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void SoundDeviceStateChangedCallback(IntPtr device, AudioDeviceState changedState, IntPtr userData);
+
+ internal static partial class AudioDevice
+ {
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_get_device_list")]
+ internal static extern int GetCurrentDeviceList(AudioDeviceOptions deviceMask, out IntPtr deviceList);
+
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_free_device_list")]
+ internal static extern int FreeDeviceList(IntPtr deviceList);
+
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_get_next_device")]
+ internal static extern int GetNextDevice(IntPtr deviceList, out IntPtr device);
+
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_get_device_type")]
+ internal static extern int GetDeviceType(IntPtr device, out AudioDeviceType type);
+
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_get_device_io_direction")]
+ internal static extern int GetDeviceIoDirection(IntPtr device, out AudioDeviceIoDirection ioDirection);
+
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_get_device_id")]
+ internal static extern int GetDeviceId(IntPtr device, out int id);
+
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_get_device_name")]
+ internal static extern int GetDeviceName(IntPtr device, out IntPtr name);
+
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_get_device_state")]
+ internal static extern int GetDeviceState(IntPtr device, out AudioDeviceState state);
+
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_add_device_connection_changed_cb")]
+ internal static extern int AddDeviceConnectionChangedCallback(AudioDeviceOptions deviceMask, SoundDeviceConnectionChangedCallback callback, IntPtr userData, out int id);
+
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_remove_device_connection_changed_cb")]
+ internal static extern int RemoveDeviceConnectionChangedCallback(int id);
+
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_add_device_state_changed_cb")]
+ internal static extern int AddDeviceStateChangedCallback(AudioDeviceOptions deviceMask, SoundDeviceStateChangedCallback callback, IntPtr userData, out int id);
+
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_remove_device_state_changed_cb")]
+ internal static extern int RemoveDeviceStateChangedCallback(int id);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Multimedia/Interop/Interop.EvasObject.cs b/src/Tizen.Multimedia/Interop/Interop.EvasObject.cs
new file mode 100644
index 0000000..4a06dd0
--- /dev/null
+++ b/src/Tizen.Multimedia/Interop/Interop.EvasObject.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Multimedia
+{
+ internal static partial class Interop
+ {
+ internal static partial class EvasObject
+ {
+ [DllImport("libevas.so.1")]
+ internal static extern IntPtr evas_object_image_add(IntPtr parent);
+ [DllImport("libevas.so.1")]
+ internal static extern IntPtr evas_object_evas_get(IntPtr obj);
+ [DllImport("libevas.so.1")]
+ internal static extern void evas_object_show(IntPtr obj);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Multimedia/Interop/Interop.Libc.cs b/src/Tizen.Multimedia/Interop/Interop.Libc.cs
new file mode 100644
index 0000000..7e9cb41
--- /dev/null
+++ b/src/Tizen.Multimedia/Interop/Interop.Libc.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Multimedia
+{
+ internal static partial class Interop
+ {
+ internal static partial class Libc
+ {
+ internal static class AccessMode
+ {
+ internal const int W_OK = 0x02;
+ internal const int R_OK = 0x04;
+ }
+
+ [DllImport(Libraries.Libc, EntryPoint = "free")]
+ public static extern void Free(IntPtr ptr);
+
+
+
+ [DllImport(Libraries.Libc, EntryPoint = "access")]
+ public static extern int Access(string path, int mode);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Multimedia/Interop/Interop.Libraries.cs b/src/Tizen.Multimedia/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..f0ce791
--- /dev/null
+++ b/src/Tizen.Multimedia/Interop/Interop.Libraries.cs
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ internal static partial class Interop
+ {
+ internal static partial class Libraries
+ {
+ public const string SoundManager = "libcapi-media-sound-manager.so.0";
+ public const string MediaTool = "libcapi-media-tool.so.0";
+ public const string Libc = "libc.so.6";
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia/Interop/Interop.MediaTool.cs b/src/Tizen.Multimedia/Interop/Interop.MediaTool.cs
new file mode 100644
index 0000000..e72f8c2
--- /dev/null
+++ b/src/Tizen.Multimedia/Interop/Interop.MediaTool.cs
@@ -0,0 +1,157 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Multimedia
+{
+ internal static partial class Interop
+ {
+ internal static class MediaPacket
+ {
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_packet_create")]
+ internal static extern int Create(IntPtr format, IntPtr finalizeCb, IntPtr cbData, out IntPtr handle);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_packet_alloc")]
+ internal static extern int Alloc(IntPtr handle);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_packet_destroy")]
+ internal static extern int Destroy(IntPtr handle);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_packet_get_format")]
+ internal static extern int GetFormat(IntPtr handle, out IntPtr format);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_packet_get_buffer_data_ptr")]
+ internal static extern int GetBufferData(IntPtr handle, out IntPtr dataHandle);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_packet_get_buffer_size")]
+ internal static extern int GetBufferSize(IntPtr handle, out ulong size);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_packet_set_buffer_size")]
+ internal static extern int SetBufferSize(IntPtr handle, ulong size);
+
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_packet_get_allocated_buffer_size")]
+ internal static extern int GetAllocatedBufferSize(IntPtr handle, out int size);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_packet_get_number_of_video_planes")]
+ internal static extern int GetNumberOfVideoPlanes(IntPtr handle, out uint num);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_packet_get_video_stride_width")]
+ internal static extern int GetVideoStrideWidth(IntPtr handle, int planeIndex, out int value);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_packet_get_video_stride_height")]
+ internal static extern int GetVideoStrideHeight(IntPtr handle, int planeIndex, out int value);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_packet_get_video_plane_data_ptr")]
+ internal static extern int GetVideoPlaneData(IntPtr handle, int planeIndex, out IntPtr dataHandle);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_packet_is_encoded")]
+ internal static extern int IsEncoded(IntPtr handle, out bool value);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_packet_get_flags")]
+ internal static extern int GetBufferFlags(IntPtr handle, out int value);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_packet_set_flags")]
+ internal static extern int SetBufferFlags(IntPtr handle, int value);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_packet_reset_flags")]
+ internal static extern int ResetBufferFlags(IntPtr handle);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_packet_get_pts")]
+ internal static extern int GetPts(IntPtr handle, out ulong value);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_packet_get_dts")]
+ internal static extern int GetDts(IntPtr handle, out ulong value);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_packet_set_pts")]
+ internal static extern int SetPts(IntPtr handle, ulong value);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_packet_set_dts")]
+ internal static extern int SetDts(IntPtr handle, ulong value);
+
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_packet_set_extra")]
+ internal static extern int SetExtra(IntPtr handle, IntPtr value);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_packet_get_extra")]
+ internal static extern int GetExtra(IntPtr handle, out IntPtr value);
+ }
+
+ internal static class MediaFormat
+ {
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_format_create")]
+ internal static extern int Create(out IntPtr handle);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_format_unref")]
+ internal static extern int Unref(IntPtr handle);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_format_get_type")]
+ internal static extern int GetType(IntPtr handle, out int type);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_format_get_container_mime")]
+ internal static extern int GetContainerMimeType(IntPtr handle, out int mimeType);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_format_set_container_mime")]
+ internal static extern int SetContainerMimeType(IntPtr handle, int mimeType);
+
+ #region Video apis
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_format_get_video_info")]
+ internal static extern int GetVideoInfo(IntPtr handle, out int mimeType,
+ out int width, out int height, out int averageBps, out int maxBps);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_format_get_video_frame_rate")]
+ internal static extern int GetVideoFrameRate(IntPtr handle, out int frameRate);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_format_set_video_mime")]
+ internal static extern int SetVideoMimeType(IntPtr handle, int value);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_format_set_video_width")]
+ internal static extern int SetVideoWidth(IntPtr handle, int value);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_format_set_video_height")]
+ internal static extern int SetVideoHeight(IntPtr handle, int value);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_format_set_video_avg_bps")]
+ internal static extern int SetVideoAverageBps(IntPtr handle, int value);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_format_set_video_frame_rate")]
+ internal static extern int SetVideoFrameRate(IntPtr handle, int value);
+ #endregion
+
+ #region Audio apis
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_format_get_audio_info")]
+ internal static extern int GetAudioInfo(IntPtr handle, out int mimeType,
+ out int channel, out int sampleRate, out int bit, out int averageBps);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_format_get_audio_aac_header_type")]
+ internal static extern int GetAudioAacType(IntPtr handle, out int aacType);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_format_set_audio_mime")]
+ internal static extern int SetAudioMimeType(IntPtr handle, int value);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_format_set_audio_channel")]
+ internal static extern int SetAudioChannel(IntPtr handle, int value);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_format_set_audio_samplerate")]
+ internal static extern int SetAudioSampleRate(IntPtr handle, int value);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_format_set_audio_bit")]
+ internal static extern int SetAudioBit(IntPtr handle, int value);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_format_set_audio_avg_bps")]
+ internal static extern int SetAudioAverageBps(IntPtr handle, int value);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_format_set_audio_aac_header_type")]
+ internal static extern int SetAudioAacType(IntPtr handle, int value);
+ #endregion
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_format_get_text_info")]
+ internal static extern int GetTextInfo(IntPtr handle, out int mimeType, out int textType);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_format_set_text_mime")]
+ internal static extern int SetTextMimeType(IntPtr handle, int value);
+
+ [DllImport(Libraries.MediaTool, EntryPoint = "media_format_set_text_type")]
+ internal static extern int SetTextType(IntPtr handle, int value);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Multimedia/Interop/Interop.StreamPolicy.cs b/src/Tizen.Multimedia/Interop/Interop.StreamPolicy.cs
new file mode 100644
index 0000000..9a7c59c
--- /dev/null
+++ b/src/Tizen.Multimedia/Interop/Interop.StreamPolicy.cs
@@ -0,0 +1,56 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Multimedia
+{
+ internal static partial class Interop
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void SoundStreamFocusStateChangedCallback(IntPtr streamInfo, AudioStreamFocusOptions focusMask, AudioStreamFocusState focusState, int reason, int audioStreamBehavior, string extraInfo, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void SoundStreamFocusStateWatchCallback(int id, AudioStreamFocusOptions focusMask, AudioStreamFocusState focusState, AudioStreamFocusChangedReason reason, string extraInfo, IntPtr userData);
+
+ internal static partial class AudioStreamPolicy
+ {
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_create_stream_information")]
+ internal static extern int CreateStreamInformation(int streamType, SoundStreamFocusStateChangedCallback callback, IntPtr userData, out IntPtr streamInfo);
+
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_destroy_stream_information")]
+ internal static extern int DestroyStreamInformation(IntPtr streamInfo);
+
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_add_device_for_stream_routing")]
+ internal static extern int AddDeviceForStreamRouting(IntPtr streamInfo, IntPtr device);
+
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_remove_device_for_stream_routing")]
+ internal static extern int RemoveDeviceForStreamRouting(IntPtr streamInfo, IntPtr device);
+
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_apply_stream_routing")]
+ internal static extern int ApplyStreamRouting(IntPtr streamInfo);
+
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_acquire_focus")]
+ internal static extern int AcquireFocus(IntPtr streamInfo, AudioStreamFocusOptions focusMask, int audioStreamBehavior, string extraInfo);
+
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_release_focus")]
+ internal static extern int ReleaseFocus(IntPtr streamInfo, AudioStreamFocusOptions focusMask, int audioStreamBehavior, string extraInfo);
+
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_get_focus_state")]
+ internal static extern int GetFocusState(IntPtr streaInfo, out AudioStreamFocusState stateForPlayback, out AudioStreamFocusState stateForRecording);
+
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_set_focus_reacquisition")]
+ internal static extern int SetFocusReacquisition(IntPtr streamInfo, bool enable);
+
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_get_focus_reacquisition")]
+ internal static extern int GetFocusReacquisition(IntPtr streamInfo, out bool enabled);
+
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_get_sound_type")]
+ internal static extern int GetSoundType(IntPtr streamInfo, out AudioVolumeType soundType);
+
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_add_focus_state_watch_cb")]
+ internal static extern int AddFocusStateWatchCallback(AudioStreamFocusOptions focusMask, SoundStreamFocusStateWatchCallback callback, IntPtr userData, out int id);
+
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_remove_focus_state_watch_cb")]
+ internal static extern int RemoveFocusStateWatchCallback(int id);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Multimedia/Interop/Interop.Volume.cs b/src/Tizen.Multimedia/Interop/Interop.Volume.cs
new file mode 100644
index 0000000..1b3f205
--- /dev/null
+++ b/src/Tizen.Multimedia/Interop/Interop.Volume.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Multimedia
+{
+ internal static partial class Interop
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void SoundManagerVolumeChangedCallback(AudioVolumeType type, uint volume, IntPtr userData);
+
+ internal static partial class AudioVolume
+ {
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_get_max_volume")]
+ internal static extern int GetMaxVolume(AudioVolumeType type, out int max);
+
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_set_volume")]
+ internal static extern int SetVolume(AudioVolumeType type, int volume);
+
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_get_volume")]
+ internal static extern int GetVolume(AudioVolumeType type, out int volume);
+
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_get_current_sound_type")]
+ internal static extern int GetCurrentSoundType(out AudioVolumeType type);
+
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_add_volume_changed_cb")]
+ internal static extern int AddVolumeChangedCallback(SoundManagerVolumeChangedCallback callback, IntPtr userData, out int id);
+
+ [DllImportAttribute(Libraries.SoundManager, EntryPoint = "sound_manager_remove_volume_changed_cb")]
+ internal static extern int RemoveVolumeChangedCallback(int id);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Multimedia/MediaTool/MediaFormat.cs b/src/Tizen.Multimedia/MediaTool/MediaFormat.cs
new file mode 100755
index 0000000..5a2092b
--- /dev/null
+++ b/src/Tizen.Multimedia/MediaTool/MediaFormat.cs
@@ -0,0 +1,808 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.Diagnostics;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// MediaFormat is a base class for media formats.
+ /// </summary>
+ public abstract class MediaFormat
+ {
+ /// <summary>
+ /// Initializes a new instance of the ContainerMediaFormat class with a type.
+ /// </summary>
+ /// <param name="type">A type for the format.</param>
+ internal MediaFormat(MediaFormatType type)
+ {
+ Type = type;
+ }
+
+ /// <summary>
+ /// Gets the type of the current format.
+ /// </summary>
+ public MediaFormatType Type
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Creates a media format from a native handle.
+ /// </summary>
+ /// <param name="handle">A native handle.</param>
+ /// <returns>An object of one of subclasses of <see cref="MediaFormat"/>.</returns>
+ internal static MediaFormat FromHandle(IntPtr handle)
+ {
+ if (handle == IntPtr.Zero)
+ {
+ throw new ArgumentException("The handle value is invalid.");
+ }
+
+ int type = 0;
+ int ret = Interop.MediaFormat.GetType(handle, out type);
+
+ if (ret != (int)ErrorCode.InvalidOperation)
+ {
+ MultimediaDebug.AssertNoError(ret);
+
+ switch ((MediaFormatType)type)
+ {
+ case MediaFormatType.Container:
+ return new ContainerMediaFormat(handle);
+
+ case MediaFormatType.Video:
+ return new VideoMediaFormat(handle);
+
+ case MediaFormatType.Audio:
+ return new AudioMediaFormat(handle);
+
+ case MediaFormatType.Text:
+ return new TextMediaFormat(handle);
+ }
+ }
+
+ throw new ArgumentException("looks like handle is corrupted.");
+ }
+
+ /// <summary>
+ /// Create a native media format from this object.
+ /// </summary>
+ /// <returns>A converted native handle.</returns>
+ /// <remarks>The returned handle must be destroyed using <see cref="Interop.MediaFormat.Unref(IntPtr)"/>.</remarks>
+ internal IntPtr AsNativeHandle()
+ {
+ IntPtr handle;
+ int ret = Interop.MediaFormat.Create(out handle);
+
+ MultimediaDebug.AssertNoError(ret);
+
+ AsNativeHandle(handle);
+
+ return handle;
+ }
+
+ internal static void ReleaseNativeHandle(IntPtr handle)
+ {
+ Interop.MediaFormat.Unref(handle);
+ }
+
+ /// <summary>
+ /// Fill out properties of a native media format with the current media format object.
+ /// </summary>
+ /// <param name="handle">A native handle to be written.</param>
+ internal abstract void AsNativeHandle(IntPtr handle);
+ }
+
+ /// <summary>
+ /// Represents a container media format. This class cannot be inherited.
+ /// </summary>
+ public sealed class ContainerMediaFormat : MediaFormat
+ {
+ /// <summary>
+ /// Initializes a new instance of the ContainerMediaFormat class.
+ /// </summary>
+ /// <param name="mimeType">The mime type of the container format.</param>
+ /// <exception cref="ArgumentException">mimeType is invalid(i.e. undefined value).</exception>
+ public ContainerMediaFormat(MediaFormatContainerMimeType mimeType)
+ : base(MediaFormatType.Container)
+ {
+ if (!Enum.IsDefined(typeof(MediaFormatContainerMimeType), mimeType))
+ {
+ throw new ArgumentException($"Invalid mime type value : { (int)mimeType }");
+ }
+ MimeType = mimeType;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the ContainerMediaFormat class from a native handle.
+ /// </summary>
+ /// <param name="handle">A native media format handle.</param>
+ internal ContainerMediaFormat(IntPtr handle)
+ : base(MediaFormatType.Container)
+ {
+ Debug.Assert(handle != IntPtr.Zero, "The handle is invalid!");
+
+ int mimeType = 0;
+
+ int ret = Interop.MediaFormat.GetContainerMimeType(handle, out mimeType);
+
+ MultimediaDebug.AssertNoError(ret);
+
+ Debug.Assert(Enum.IsDefined(typeof(MediaFormatContainerMimeType), mimeType),
+ "Invalid container mime type!");
+
+ MimeType = (MediaFormatContainerMimeType)mimeType;
+ }
+
+ /// <summary>
+ /// Gets the mime type of the current format.
+ /// </summary>
+ public MediaFormatContainerMimeType MimeType
+ {
+ get;
+ }
+
+ internal override void AsNativeHandle(IntPtr handle)
+ {
+ Debug.Assert(Type == MediaFormatType.Container);
+
+ int ret = Interop.MediaFormat.SetContainerMimeType(handle, (int)MimeType);
+
+ MultimediaDebug.AssertNoError(ret);
+ }
+
+ public override string ToString()
+ {
+ return $"MimeType={ MimeType.ToString() }";
+ }
+
+ public override bool Equals(object obj)
+ {
+ var rhs = obj as ContainerMediaFormat;
+ if (rhs == null)
+ {
+ return false;
+ }
+
+ return MimeType == rhs.MimeType;
+ }
+
+ public override int GetHashCode()
+ {
+ return (int)MimeType;
+ }
+ }
+
+ /// <summary>
+ /// Represents a video media format. This class cannot be inherited.
+ /// </summary>
+ public sealed class VideoMediaFormat : MediaFormat
+ {
+ private const int DefaultFrameRate = 0;
+ private const int DefaultBitRate = 0;
+
+ /// <summary>
+ /// Initializes a new instance of the VideoMediaFormat class with the specified mime type, width and height.
+ /// </summary>
+ /// <param name="mimeType">The mime type of the format.</param>
+ /// <param name="width">The width value of the format.</param>
+ /// <param name="height">The height value of the format</param>
+ /// <exception cref="ArgumentException">mimeType is invalid(i.e. undefined value).</exception>
+ /// <exception cref="ArgumentOutOfRangeException">width, or height is less than zero.</exception>
+ public VideoMediaFormat(MediaFormatVideoMimeType mimeType, int width, int height)
+ : this(mimeType, width, height, DefaultFrameRate)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the VideoMediaFormat class with the specified mime type and size.
+ /// </summary>
+ /// <param name="mimeType">The mime type of the format.</param>
+ /// <param name="size">The size of the format.</param>
+ /// <exception cref="ArgumentException">mimeType is invalid(i.e. undefined value).</exception>
+ /// <exception cref="ArgumentOutOfRangeException">width, or height is less than zero.</exception>
+ public VideoMediaFormat(MediaFormatVideoMimeType mimeType, Size size)
+ : this(mimeType, size, DefaultFrameRate)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the VideoMediaFormat class with the specified mime type,
+ /// width, height and frame rate.
+ /// </summary>
+ /// <param name="mimeType">The mime type of the format.</param>
+ /// <param name="width">The width value of the format.</param>
+ /// <param name="height">The height value of the format</param>
+ /// <param name="frameRate">The frame rate of the format.</param>
+ /// <exception cref="ArgumentException">mimeType is invalid(i.e. undefined value).</exception>
+ /// <exception cref="ArgumentOutOfRangeException">width, height or frameRate is less than zero.</exception>
+ public VideoMediaFormat(MediaFormatVideoMimeType mimeType, int width, int height,
+ int frameRate)
+ : this(mimeType, width, height, frameRate, DefaultBitRate)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the VideoMediaFormat class with the specified mime type,
+ /// width, height and frame rate.
+ /// </summary>
+ /// <param name="mimeType">The mime type of the format.</param>
+ /// <param name="size">The video size of the format.</param>
+ /// <param name="frameRate">The frame rate of the format.</param>
+ /// <exception cref="ArgumentException">mimeType is invalid(i.e. undefined value).</exception>
+ /// <exception cref="ArgumentOutOfRangeException">width, height or frameRate is less than zero.</exception>
+ public VideoMediaFormat(MediaFormatVideoMimeType mimeType, Size size,
+ int frameRate)
+ : this(mimeType, size, frameRate, DefaultBitRate)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the VideoMediaFormat class with the specified mime type,
+ /// width, height, frame rate and bit rate.
+ /// </summary>
+ /// <param name="mimeType">The mime type of the format.</param>
+ /// <param name="width">The width value of the format.</param>
+ /// <param name="height">The height value of the format</param>
+ /// <param name="frameRate">The frame rate of the format.</param>
+ /// <param name="bitRate">The bit rate of the format.</param>
+ /// <exception cref="ArgumentException">mimeType is invalid(i.e. undefined value).</exception>
+ /// <exception cref="ArgumentOutOfRangeException">width, height, frameRate or bitRate is less than zero.</exception>
+ public VideoMediaFormat(MediaFormatVideoMimeType mimeType, int width, int height,
+ int frameRate, int bitRate)
+ : this(mimeType, new Size(width, height), frameRate, bitRate)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the VideoMediaFormat class with the specified mime type,
+ /// size, frame rate and bit rate.
+ /// </summary>
+ /// <param name="mimeType">The mime type of the format.</param>
+ /// <param name="size">The size of the format.</param>
+ /// <param name="frameRate">The frame rate of the format.</param>
+ /// <param name="bitRate">The bit rate of the format.</param>
+ /// <exception cref="ArgumentException">mimeType is invalid(i.e. undefined value).</exception>
+ /// <exception cref="ArgumentOutOfRangeException">width, height, frameRate or bitRate is less than zero.</exception>
+ public VideoMediaFormat(MediaFormatVideoMimeType mimeType, Size size,
+ int frameRate, int bitRate)
+ : base(MediaFormatType.Video)
+ {
+ if (!Enum.IsDefined(typeof(MediaFormatVideoMimeType), mimeType))
+ {
+ throw new ArgumentException($"Invalid mime type value : { (int)mimeType }");
+ }
+ if (size.Width < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(size), size.Width, "Size.Width value can't be less than zero.");
+ }
+ if (size.Height < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(size), size.Height, "Size.Height value can't be less than zero.");
+ }
+ if (frameRate < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(frameRate), frameRate, "Frame rate can't be less than zero.");
+ }
+ if (bitRate < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(bitRate), bitRate, "Bit rate value can't be less than zero.");
+ }
+
+ MimeType = mimeType;
+ Size = size;
+ FrameRate = frameRate;
+ BitRate = bitRate;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the VideoMediaForma class from a native handle.
+ /// </summary>
+ /// <param name="handle">A native handle.</param>
+ internal VideoMediaFormat(IntPtr handle)
+ : base(MediaFormatType.Video)
+ {
+ Debug.Assert(handle != IntPtr.Zero, "The handle is invalid!");
+
+ int width = 0;
+ int height = 0;
+ int bitRate = 0;
+ int frameRate = 0;
+ MediaFormatVideoMimeType mimeType;
+ GetInfo(handle, out width, out height, out bitRate, out mimeType);
+
+ GetFrameRate(handle, out frameRate);
+
+ MimeType = mimeType;
+ Size = new Size(width, height);
+ FrameRate = frameRate;
+ BitRate = bitRate;
+ }
+
+ /// <summary>
+ /// Retrieves video properties of media format from a native handle.
+ /// </summary>
+ /// <param name="handle">A native handle that properties are retrieved from.</param>
+ /// <param name="width">An out parameter for width.</param>
+ /// <param name="height">An out parameter for height.</param>
+ /// <param name="bitRate">An out parameter for bit rate.</param>
+ /// <param name="mimeType">An out parameter for mime type.</param>
+ private static void GetInfo(IntPtr handle, out int width, out int height, out int bitRate,
+ out MediaFormatVideoMimeType mimeType)
+ {
+ Debug.Assert(handle != IntPtr.Zero, "The handle is invalid!");
+
+ int mimeTypeValue = 0;
+ int maxBps = 0;
+
+ int ret = Interop.MediaFormat.GetVideoInfo(handle,
+ out mimeTypeValue, out width, out height, out bitRate, out maxBps);
+
+ MultimediaDebug.AssertNoError(ret);
+
+ mimeType = (MediaFormatVideoMimeType)mimeTypeValue;
+
+ Debug.Assert(Enum.IsDefined(typeof(MediaFormatVideoMimeType), mimeType),
+ "Invalid video mime type!");
+ }
+
+ /// <summary>
+ /// Retrieves frame rate from a native handle.
+ /// </summary>
+ /// <param name="handle">A native handle that properties are retrieved from.</param>
+ /// <param name="frameRate">An out parameter for frame rate.</param>
+ private static void GetFrameRate(IntPtr handle, out int frameRate)
+ {
+ Debug.Assert(handle != IntPtr.Zero, "The handle is invalid!");
+
+ int ret = Interop.MediaFormat.GetVideoFrameRate(handle, out frameRate);
+
+ MultimediaDebug.AssertNoError(ret);
+ }
+
+ internal override void AsNativeHandle(IntPtr handle)
+ {
+ Debug.Assert(Type == MediaFormatType.Video);
+
+ int ret = Interop.MediaFormat.SetVideoMimeType(handle, (int)MimeType);
+ MultimediaDebug.AssertNoError(ret);
+
+ ret = Interop.MediaFormat.SetVideoWidth(handle, Size.Width);
+ MultimediaDebug.AssertNoError(ret);
+
+ ret = Interop.MediaFormat.SetVideoHeight(handle, Size.Height);
+ MultimediaDebug.AssertNoError(ret);
+
+ ret = Interop.MediaFormat.SetVideoAverageBps(handle, BitRate);
+ MultimediaDebug.AssertNoError(ret);
+
+ ret = Interop.MediaFormat.SetVideoFrameRate(handle, FrameRate);
+ MultimediaDebug.AssertNoError(ret);
+ }
+
+ /// <summary>
+ /// Gets the mime type of the current format.
+ /// </summary>
+ public MediaFormatVideoMimeType MimeType { get; }
+
+ /// <summary>
+ /// Gets the size of the current format.
+ /// </summary>
+ public Size Size { get; }
+
+ /// <summary>
+ /// Gets the frame rate value of the current format.
+ /// </summary>
+ public int FrameRate { get; }
+
+ /// <summary>
+ /// Gets the bit rate value of the current format.
+ /// </summary>
+ public int BitRate { get; }
+
+ public override string ToString()
+ {
+ return $@"MimeType={ MimeType.ToString() }, Size=({ Size.ToString() }), FrameRate=
+ { FrameRate.ToString() }, BitRate={ BitRate.ToString() }";
+ }
+
+ public override bool Equals(object obj)
+ {
+ var rhs = obj as VideoMediaFormat;
+ if (rhs == null)
+ {
+ return false;
+ }
+
+ return MimeType == rhs.MimeType && Size == rhs.Size &&
+ FrameRate == rhs.FrameRate && BitRate == rhs.BitRate;
+ }
+
+ public override int GetHashCode()
+ {
+ return new { MimeType, Size, FrameRate, BitRate }.GetHashCode();
+ }
+ }
+
+ /// <summary>
+ /// Represents an audio media format. This class cannot be inherited.
+ /// </summary>
+ public sealed class AudioMediaFormat : MediaFormat
+ {
+
+ /// <summary>
+ /// Initializes a new instance of the AudioMediaFormat class with the specified mime type,
+ /// channel, sample rate, bit and bit rate.
+ /// </summary>
+ /// <param name="mimeType">The mime type of the format.</param>
+ /// <param name="channel">The channel value of the format.</param>
+ /// <param name="sampleRate">The sample rate value of the format.</param>
+ /// <param name="bit">The bit value of the format.</param>
+ /// <param name="bitRate">The bit rate value of the format.</param>
+ /// <exception cref="ArgumentException"><paramref name="mimeType"/> is invalid(i.e. undefined value).</exception>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="channel"/>, <paramref name="sampleRate"/>, <paramref name="bit"/> or <paramref name="bitRate"/> is less than zero.
+ /// </exception>
+ public AudioMediaFormat(MediaFormatAudioMimeType mimeType,
+ int channel, int sampleRate, int bit, int bitRate)
+ : this(mimeType, channel, sampleRate, bit, bitRate, MediaFormatAacType.None)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the AudioMediaFormat class with the specified mime type,
+ /// channel, sample rate, bit, bit rate and aac type.
+ /// </summary>
+ /// <param name="mimeType">The mime type of the format.</param>
+ /// <param name="channel">The channel value of the format.</param>
+ /// <param name="sampleRate">The sample rate value of the format.</param>
+ /// <param name="bit">The bit value of the format.</param>
+ /// <param name="bitRate">The bit rate value of the format.</param>
+ /// <param name="aacType">The AAC bitstream format(ADIF or ADTS).</param>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="mimeType"/> or <paramref name="aacType"/> is invalid(i.e. undefined value).\n
+ /// -or-\n
+ /// <paramref name="aacType"/> is not <see cref="MediaFormatAacType.None"/>, but <paramref name="mimeType"/> is one of aac types.
+ /// </exception>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="channel"/>, <paramref name="sampleRate"/>, <paramref name="bit"/> or <paramref name="bitRate"/> is less than zero.
+ /// </exception>
+ public AudioMediaFormat(MediaFormatAudioMimeType mimeType,
+ int channel, int sampleRate, int bit, int bitRate, MediaFormatAacType aacType)
+ : base(MediaFormatType.Audio)
+ {
+ if (!Enum.IsDefined(typeof(MediaFormatAudioMimeType), mimeType))
+ {
+ throw new ArgumentException($"Invalid mime type value : { (int)mimeType }");
+ }
+ if (channel < 0)
+ {
+ throw new ArgumentOutOfRangeException("Channel value can't be negative.");
+ }
+ if (sampleRate < 0)
+ {
+ throw new ArgumentOutOfRangeException("Sample rate value can't be negative.");
+ }
+ if (bit < 0)
+ {
+ throw new ArgumentOutOfRangeException("Bit value can't be negative.");
+ }
+ if (bitRate < 0)
+ {
+ throw new ArgumentOutOfRangeException("Bit rate value can't be negative.");
+ }
+ if (!Enum.IsDefined(typeof(MediaFormatAacType), aacType))
+ {
+ throw new ArgumentException($"Invalid aac type value : { (int)aacType }");
+ }
+ if (!IsAacSupportedMimeType(mimeType) && aacType != MediaFormatAacType.None)
+ {
+ throw new ArgumentException("Aac is supported only with aac mime types.");
+ }
+
+ MimeType = mimeType;
+ Channel = channel;
+ SampleRate = sampleRate;
+ Bit = bit;
+ BitRate = bitRate;
+ AacType = aacType;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the AudioMediaFormat class from a native handle.
+ /// </summary>
+ /// <param name="handle">A native handle.</param>
+ internal AudioMediaFormat(IntPtr handle)
+ : base(MediaFormatType.Audio)
+ {
+ Debug.Assert(handle != IntPtr.Zero, "The handle is invalid!");
+
+ MediaFormatAudioMimeType mimeType;
+ int channel = 0;
+ int sampleRate = 0;
+ int bit = 0;
+ int bitRate = 0;
+ MediaFormatAacType aacType;
+ GetInfo(handle, out mimeType, out channel, out sampleRate, out bit, out bitRate);
+
+ if (IsAacSupportedMimeType(mimeType))
+ {
+ GetAacType(handle, out aacType);
+ }
+ else
+ {
+ aacType = MediaFormatAacType.None;
+ }
+
+ MimeType = mimeType;
+ Channel = channel;
+ SampleRate = sampleRate;
+ Bit = bit;
+ BitRate = bitRate;
+ AacType = aacType;
+ }
+
+ /// <summary>
+ /// Returns an indication whether a specified mime type is a aac type.
+ /// </summary>
+ /// <param name="mimeType">A mime type.</param>
+ private static bool IsAacSupportedMimeType(MediaFormatAudioMimeType mimeType)
+ {
+ return mimeType == MediaFormatAudioMimeType.AacLC ||
+ mimeType == MediaFormatAudioMimeType.AacHE ||
+ mimeType == MediaFormatAudioMimeType.AacHEPS;
+ }
+
+ /// <summary>
+ /// Retrieves audio properties of media format from a native handle.
+ /// </summary>
+ /// <param name="handle">A native handle that properties are retrieved from.</param>
+ /// <param name="mimeType">An out parameter for mime type.</param>
+ /// <param name="channel">An out parameter for channel.</param>
+ /// <param name="sampleRate">An out parameter for sample rate.</param>
+ /// <param name="bit">An out parameter for bit.</param>
+ /// <param name="bitRate">An out parameter for bit rate.</param>
+ private static void GetInfo(IntPtr handle, out MediaFormatAudioMimeType mimeType,
+ out int channel, out int sampleRate, out int bit, out int bitRate)
+ {
+ Debug.Assert(handle != IntPtr.Zero, "The handle is invalid!");
+
+ int mimeTypeValue = 0;
+
+ int ret = Interop.MediaFormat.GetAudioInfo(handle,
+ out mimeTypeValue, out channel, out sampleRate, out bit, out bitRate);
+
+ mimeType = (MediaFormatAudioMimeType)mimeTypeValue;
+
+ MultimediaDebug.AssertNoError(ret);
+
+ Debug.Assert(Enum.IsDefined(typeof(MediaFormatAudioMimeType), mimeType),
+ "Invalid audio mime type!");
+ }
+
+ /// <summary>
+ /// Retrieves aac type value from a native handle.
+ /// </summary>
+ /// <param name="handle">A native handle that properties are retrieved from.</param>
+ /// <param name="aacType">An out parameter for aac type.</param>
+ private static void GetAacType(IntPtr handle, out MediaFormatAacType aacType)
+ {
+ Debug.Assert(handle != IntPtr.Zero, "The handle is invalid!");
+
+ int aacTypeValue = 0;
+
+ int ret = Interop.MediaFormat.GetAudioAacType(handle, out aacTypeValue);
+
+ MultimediaDebug.AssertNoError(ret);
+
+ aacType = (MediaFormatAacType)aacTypeValue;
+
+ Debug.Assert(Enum.IsDefined(typeof(MediaFormatAacType), aacType), "Invalid aac type!");
+ }
+
+ internal override void AsNativeHandle(IntPtr handle)
+ {
+ Debug.Assert(Type == MediaFormatType.Audio);
+
+ int ret = Interop.MediaFormat.SetAudioMimeType(handle, (int)MimeType);
+ MultimediaDebug.AssertNoError(ret);
+
+ ret = Interop.MediaFormat.SetAudioChannel(handle, Channel);
+ MultimediaDebug.AssertNoError(ret);
+
+ ret = Interop.MediaFormat.SetAudioSampleRate(handle, SampleRate);
+ MultimediaDebug.AssertNoError(ret);
+
+ ret = Interop.MediaFormat.SetAudioBit(handle, Bit);
+ MultimediaDebug.AssertNoError(ret);
+
+ ret = Interop.MediaFormat.SetAudioAverageBps(handle, BitRate);
+ MultimediaDebug.AssertNoError(ret);
+
+ ret = Interop.MediaFormat.SetAudioAacType(handle, (int)AacType);
+ MultimediaDebug.AssertNoError(ret);
+ }
+
+ /// <summary>
+ /// Gets the mime type of the current format.
+ /// </summary>
+ public MediaFormatAudioMimeType MimeType { get; }
+
+ /// <summary>
+ /// Gets the channel value of the current format.
+ /// </summary>
+ public int Channel { get; }
+
+ /// <summary>
+ /// Gets the sample rate value of the current format.
+ /// </summary>
+ public int SampleRate { get; }
+
+ /// <summary>
+ /// Gets the bit value of the current format.
+ /// </summary>
+ public int Bit { get; }
+
+ /// <summary>
+ /// Gets the bit rate value of the current format.
+ /// </summary>
+ public int BitRate { get; }
+
+ /// <summary>
+ /// Gets the aac type of the current format.
+ /// </summary>
+ public MediaFormatAacType AacType { get; }
+
+ public override string ToString()
+ {
+ return $@"MimeTyp={ MimeType.ToString() }, Channel={ Channel.ToString() }, SampleRate=
+ { SampleRate }, Bit={ Bit.ToString() }, BitRate={ BitRate.ToString() }, AacType={ AacType.ToString() }";
+ }
+
+ public override bool Equals(object obj)
+ {
+ var rhs = obj as AudioMediaFormat;
+ if (rhs == null)
+ {
+ return false;
+ }
+
+ return MimeType == rhs.MimeType && Channel == rhs.Channel && SampleRate == rhs.SampleRate &&
+ Bit == rhs.Bit && BitRate == rhs.BitRate;
+ }
+
+ public override int GetHashCode()
+ {
+ return new { MimeType, Channel, SampleRate, Bit, BitRate }.GetHashCode();
+ }
+ }
+
+ /// <summary>
+ /// Represents a text media format. This class cannot be inherited.
+ /// </summary>
+ public sealed class TextMediaFormat : MediaFormat
+ {
+ /// <summary>
+ /// Initializes a new instance of the TextMediaFormat class with the specified mime type
+ /// and text type.
+ /// </summary>
+ /// <param name="mimeType">The mime type of the format.</param>
+ /// <param name="textType">The text type of the format.</param>
+ /// <exception cref="ArgumentException">
+ /// mimeType or textType is invalid(i.e. undefined value).</exception>
+ public TextMediaFormat(MediaFormatTextMimeType mimeType, MediaFormatTextType textType)
+ : base(MediaFormatType.Text)
+ {
+ if (!Enum.IsDefined(typeof(MediaFormatTextMimeType), mimeType))
+ {
+ throw new ArgumentException($"Invalid mime type value : { (int)mimeType }");
+ }
+ if (!Enum.IsDefined(typeof(MediaFormatTextType), textType))
+ {
+ throw new ArgumentException($"Invalid text type value : { (int)textType }");
+ }
+ MimeType = mimeType;
+ TextType = textType;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the TextMediaFormat class from a native handle.
+ /// </summary>
+ /// <param name="handle">A native handle.</param>
+ internal TextMediaFormat(IntPtr handle)
+ : base(MediaFormatType.Text)
+ {
+ Debug.Assert(handle != IntPtr.Zero, "The handle is invalid!");
+
+ MediaFormatTextMimeType mimeType;
+ MediaFormatTextType textType;
+
+ GetInfo(handle, out mimeType, out textType);
+
+ MimeType = mimeType;
+ TextType = textType;
+ }
+
+ /// <summary>
+ /// Retrieves text properties of media format from a native handle.
+ /// </summary>
+ /// <param name="handle">A native handle that properties are retrieved from.</param>
+ /// <param name="mimeType">An out parameter for mime type.</param>
+ /// <param name="textType">An out parameter for text type.</param>
+ private static void GetInfo(IntPtr handle, out MediaFormatTextMimeType mimeType,
+ out MediaFormatTextType textType)
+ {
+ int mimeTypeValue = 0;
+ int textTypeValue = 0;
+
+ int ret = Interop.MediaFormat.GetTextInfo(handle, out mimeTypeValue, out textTypeValue);
+
+ MultimediaDebug.AssertNoError(ret);
+
+ mimeType = (MediaFormatTextMimeType)mimeTypeValue;
+ textType = (MediaFormatTextType)textTypeValue;
+
+ Debug.Assert(Enum.IsDefined(typeof(MediaFormatTextMimeType), mimeType),
+ "Invalid text mime type!");
+ Debug.Assert(Enum.IsDefined(typeof(MediaFormatTextType), textType),
+ "Invalid text type!");
+ }
+
+ internal override void AsNativeHandle(IntPtr handle)
+ {
+ Debug.Assert(Type == MediaFormatType.Text);
+
+ int ret = Interop.MediaFormat.SetTextMimeType(handle, (int)MimeType);
+ MultimediaDebug.AssertNoError(ret);
+
+ ret = Interop.MediaFormat.SetTextType(handle, (int)TextType);
+ MultimediaDebug.AssertNoError(ret);
+ }
+
+ /// <summary>
+ /// Gets the mime type of the current format.
+ /// </summary>
+ public MediaFormatTextMimeType MimeType { get; }
+
+ /// <summary>
+ /// Gets the text type of the current format.
+ /// </summary>
+ public MediaFormatTextType TextType { get; }
+
+ public override string ToString()
+ {
+ return $"MimeType={ MimeType.ToString() }, TextType={ TextType.ToString() }";
+ }
+
+ public override bool Equals(object obj)
+ {
+ var rhs = obj as TextMediaFormat;
+ if (rhs == null)
+ {
+ return false;
+ }
+
+ return MimeType == rhs.MimeType && TextType == rhs.TextType;
+ }
+
+ public override int GetHashCode()
+ {
+ return new { MimeType, TextType }.GetHashCode();
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia/MediaTool/MediaFormatAacType.cs b/src/Tizen.Multimedia/MediaTool/MediaFormatAacType.cs
new file mode 100644
index 0000000..6839c9f
--- /dev/null
+++ b/src/Tizen.Multimedia/MediaTool/MediaFormatAacType.cs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Specifies aac types for <see cref="AudioMediaFormat"/>.
+ /// </summary>
+ public enum MediaFormatAacType
+ {
+ /// <summary>
+ /// Raw, no header
+ /// </summary>
+ None,
+ /// <summary>
+ /// ADTS header
+ /// </summary>
+ Adts,
+ /// <summary>
+ /// ADIF header
+ /// </summary>
+ Adif
+ }
+}
diff --git a/src/Tizen.Multimedia/MediaTool/MediaFormatMimeType.cs b/src/Tizen.Multimedia/MediaTool/MediaFormatMimeType.cs
new file mode 100755
index 0000000..55196a4
--- /dev/null
+++ b/src/Tizen.Multimedia/MediaTool/MediaFormatMimeType.cs
@@ -0,0 +1,372 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Specifies the media format types.
+ /// </summary>
+ /// <seealso cref="MediaFormat"/>
+ public enum MediaFormatType
+ {
+ /// <summary>
+ /// Audio media format.
+ /// </summary>
+ Audio = 0x01000000,
+
+ /// <summary>
+ /// Video media format.
+ /// </summary>
+ Video = 0x02000000,
+
+ /// <summary>
+ /// Container media format.
+ /// </summary>
+ Container = 0x04000000,
+
+ /// <summary>
+ /// Text media format.
+ /// </summary>
+ Text = 0x03000000,
+ }
+
+ /// <summary>
+ /// Enumeration for media format data type
+ /// </summary>
+ internal enum MediaFormatDataType
+ {
+ /// <summary>
+ /// Encoded type
+ /// </summary>
+ Encoded = 0x10000000,
+
+ /// <summary>
+ /// Raw type
+ /// </summary>
+ Raw = 0x20000000,
+ }
+
+ /// <summary>
+ /// Specifies the mime types for audio media formats.
+ /// </summary>
+ public enum MediaFormatAudioMimeType
+ {
+ /// <summary>
+ /// AMR, Alias for <see cref="AmrNB"/>.
+ /// </summary>
+ Amr = (MediaFormatType.Audio | MediaFormatDataType.Encoded | 0x1040),
+
+ /// <summary>
+ /// AMR-NB.
+ /// </summary>
+ AmrNB = (MediaFormatType.Audio | MediaFormatDataType.Encoded | 0x1040),
+
+ /// <summary>
+ /// AMR-WB.
+ /// </summary>
+ AmrWB = (MediaFormatType.Audio | MediaFormatDataType.Encoded | 0x1041),
+
+ /// <summary>
+ /// G729.
+ /// </summary>
+ //G729 = (MediaFormatType.Audio | MediaFormatDataType.Encoded | 0x1050),
+
+ /// <summary>
+ /// AAC, Alias for <see cref="AacLC"/>.
+ /// </summary>
+ Aac = (MediaFormatType.Audio | MediaFormatDataType.Encoded | 0x1060),
+
+ /// <summary>
+ /// AAC-LC (Advanced Audio Coding Low-Complexity profile).
+ /// </summary>
+ AacLC = (MediaFormatType.Audio | MediaFormatDataType.Encoded | 0x1060),
+
+ /// <summary>
+ /// HE-AAC (High-Efficiency Advanced Audio Coding).
+ /// </summary>
+ AacHE = (MediaFormatType.Audio | MediaFormatDataType.Encoded | 0x1061),
+
+ /// <summary>
+ /// HE-AAC-PS (High-Efficiency Advanced Audio Coding with Parametric Stereo).
+ /// </summary>
+ AacHEPS = (MediaFormatType.Audio | MediaFormatDataType.Encoded | 0x1062),
+
+ /// <summary>
+ /// MP3.
+ /// </summary>
+ MP3 = (MediaFormatType.Audio | MediaFormatDataType.Encoded | 0x1070),
+
+ /// <summary>
+ /// VORBIS.
+ /// </summary>
+ Vorbis = (MediaFormatType.Audio | MediaFormatDataType.Encoded | 0x1080),
+
+ /// <summary>
+ /// FLAC.
+ /// </summary>
+ Flac = (MediaFormatType.Audio | MediaFormatDataType.Encoded | 0x1090),
+
+ /// <summary>
+ /// Windows Media Audio 1.
+ /// </summary>
+ Wma1 = (MediaFormatType.Audio | MediaFormatDataType.Encoded | 0x10A0),
+
+ /// <summary>
+ /// Windows Media Audio 2.
+ /// </summary>
+ Wma2 = (MediaFormatType.Audio | MediaFormatDataType.Encoded | 0x10A1),
+
+ /// <summary>
+ /// Windows Media Audio Professional.
+ /// </summary>
+ WmaPro = (MediaFormatType.Audio | MediaFormatDataType.Encoded | 0x10A2),
+
+ /// <summary>
+ /// Windows Media Audio Lossless.
+ /// </summary>
+ WmaLossless = (MediaFormatType.Audio | MediaFormatDataType.Encoded | 0x10A3),
+
+ /// <summary>
+ /// PCM.
+ /// </summary>
+ Pcm = (MediaFormatType.Audio | MediaFormatDataType.Raw | 0x1510),
+ }
+
+ /// <summary>
+ /// Specifies the mime types for video media formats.
+ /// </summary>
+ public enum MediaFormatVideoMimeType
+ {
+ /// <summary>
+ /// H261.
+ /// </summary>
+ H261 = (MediaFormatType.Video | MediaFormatDataType.Encoded | 0x2010),
+
+ /// <summary>
+ /// H263.
+ /// </summary>
+ H263 = (MediaFormatType.Video | MediaFormatDataType.Encoded | 0x2020),
+
+ /// <summary>
+ /// H263P.
+ /// </summary>
+ H263P = (MediaFormatType.Video | MediaFormatDataType.Encoded | 0x2021),
+
+ /// <summary>
+ /// H264_SP
+ /// </summary>
+ H264SP = (MediaFormatType.Video | MediaFormatDataType.Encoded | 0x2030),
+
+ /// <summary>
+ /// H264_MP.
+ /// </summary>
+ H264MP = (MediaFormatType.Video | MediaFormatDataType.Encoded | 0x2031),
+
+ /// <summary>
+ /// H264_HP.
+ /// </summary>
+ H264HP = (MediaFormatType.Video | MediaFormatDataType.Encoded | 0x2032),
+
+ /// <summary>
+ /// MJPEG
+ /// </summary>
+ MJpeg = (MediaFormatType.Video | MediaFormatDataType.Encoded | 0x2040),
+
+ /// <summary>
+ /// MPEG1.
+ /// </summary>
+ Mpeg1 = (MediaFormatType.Video | MediaFormatDataType.Encoded | 0x2050),
+
+ /// <summary>
+ /// MPEG2_SP.
+ /// </summary>
+ Mpeg2SP = (MediaFormatType.Video | MediaFormatDataType.Encoded | 0x2060),
+
+ /// <summary>
+ /// MPEG2_MP.
+ /// </summary>
+ Mpeg2MP = (MediaFormatType.Video | MediaFormatDataType.Encoded | 0x2061),
+
+ /// <summary>
+ /// MPEG2_HP.
+ /// </summary>
+ Mpeg2HP = (MediaFormatType.Video | MediaFormatDataType.Encoded | 0x2062),
+
+ /// <summary>
+ /// MPEG4_SP.
+ /// </summary>
+ Mpeg4SP = (MediaFormatType.Video | MediaFormatDataType.Encoded | 0x2070),
+
+ /// <summary>
+ /// MPEG4_ASP.
+ /// </summary>
+ Mpeg4Asp = (MediaFormatType.Video | MediaFormatDataType.Encoded | 0x2071),
+
+ /// <summary>
+ /// I420
+ /// </summary>
+ I420 = (MediaFormatType.Video | MediaFormatDataType.Raw | 0x2510),
+
+ /// <summary>
+ /// NV12.
+ /// </summary>
+ NV12 = (MediaFormatType.Video | MediaFormatDataType.Raw | 0x2520),
+
+ /// <summary>
+ /// NV12T.
+ /// </summary>
+ NV12T = (MediaFormatType.Video | MediaFormatDataType.Raw | 0x2530),
+
+ /// <summary>
+ /// YV12.
+ /// </summary>
+ YV12 = (MediaFormatType.Video | MediaFormatDataType.Raw | 0x2540),
+
+ /// <summary>
+ /// NV21.
+ /// </summary>
+ NV21 = (MediaFormatType.Video | MediaFormatDataType.Raw | 0x2550),
+
+ /// <summary>
+ /// NV16.
+ /// </summary>
+ NV16 = (MediaFormatType.Video | MediaFormatDataType.Raw | 0x2560),
+
+ /// <summary>
+ /// YUYV.
+ /// </summary>
+ Yuyv = (MediaFormatType.Video | MediaFormatDataType.Raw | 0x2570),
+
+ /// <summary>
+ /// UYVY.
+ /// </summary>
+ Uyvy = (MediaFormatType.Video | MediaFormatDataType.Raw | 0x2580),
+
+ /// <summary>
+ /// 422P.
+ /// </summary>
+ Yuv422P = (MediaFormatType.Video | MediaFormatDataType.Raw | 0x2590),
+
+ /// <summary>
+ /// RGB565.
+ /// </summary>
+ Rgb565 = (MediaFormatType.Video | MediaFormatDataType.Raw | 0x25a0),
+
+ /// <summary>
+ /// RGB888.
+ /// </summary>
+ Rgb888 = (MediaFormatType.Video | MediaFormatDataType.Raw | 0x25b0),
+
+ /// <summary>
+ /// RGBA.
+ /// </summary>
+ Rgba = (MediaFormatType.Video | MediaFormatDataType.Raw | 0x25c0),
+
+ /// <summary>
+ /// ARGB.
+ /// </summary>
+ Argb = (MediaFormatType.Video | MediaFormatDataType.Raw | 0x25d0),
+
+ /// <summary>
+ /// BGRA.
+ /// </summary>
+ Bgra = (MediaFormatType.Video | MediaFormatDataType.Raw | 0x25e0),
+
+ /// <summary>
+ /// HW dependent
+ /// </summary>
+ //NativeVideo = (MediaFormatType.Video | MediaFormatDataType.Raw | 0x7000),
+ }
+
+ /// <summary>
+ /// Specifies the mime types for container media formats.
+ /// </summary>
+ public enum MediaFormatContainerMimeType
+ {
+ /// <summary>
+ /// MP4 container, Video.
+ /// </summary>
+ MP4 = (MediaFormatType.Container | 0x3010),
+
+ /// <summary>
+ /// AVI container, Video.
+ /// </summary>
+ Avi = (MediaFormatType.Container | 0x3020),
+
+ /// <summary>
+ /// MPEG2TS container, Video.
+ /// </summary>
+ Mpeg2TS = (MediaFormatType.Container | 0x3030),
+
+ /// <summary>
+ /// MPEG2PS container, Video.
+ /// </summary>
+ Mpeg2PS = (MediaFormatType.Container | 0x3040),
+
+ /// <summary>
+ /// MATROSKA container, Video.
+ /// </summary>
+ Matroska = (MediaFormatType.Container | 0x3050),
+
+ /// <summary>
+ /// WEBM container, Video.
+ /// </summary>
+ Webm = (MediaFormatType.Container | 0x3060),
+
+ /// <summary>
+ /// 3GP container, Video.
+ /// </summary>
+ ThreeGP = (MediaFormatType.Container | 0x3070),
+
+ /// <summary>
+ /// WAV container, Audio.
+ /// </summary>
+ Wav = (MediaFormatType.Container | 0x4010),
+
+ /// <summary>
+ /// OGG container, Audio
+ /// </summary>
+ Ogg = (MediaFormatType.Container | 0x4020),
+
+ /// <summary>
+ /// AAC_ADTS container, Audio
+ /// </summary>
+ AacAdts = (MediaFormatType.Container | 0x4030),
+
+ /// <summary>
+ /// AAC_ADIF container, Audio
+ /// </summary>
+ AacAdif = (MediaFormatType.Container | 0x4031),
+ }
+
+ /// <summary>
+ /// Enumeration for text mime type
+ /// </summary>
+ public enum MediaFormatTextMimeType
+ {
+ /// <summary>
+ /// MP4.
+ /// </summary>
+ MP4 = (MediaFormatType.Text | MediaFormatDataType.Encoded | 0x8010),
+
+ /// <summary>
+ /// 3GP.
+ /// </summary>
+ ThreeGP = (MediaFormatType.Text | MediaFormatDataType.Encoded | 0x8020),
+ }
+
+}
+
diff --git a/src/Tizen.Multimedia/MediaTool/MediaFormatTextType.cs b/src/Tizen.Multimedia/MediaTool/MediaFormatTextType.cs
new file mode 100755
index 0000000..38d3a5a
--- /dev/null
+++ b/src/Tizen.Multimedia/MediaTool/MediaFormatTextType.cs
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Specifies text types.
+ /// </summary>
+ public enum MediaFormatTextType
+ {
+ /// <summary>
+ /// This indicates no type specified.
+ /// </summary>
+ None,
+
+ /// <summary>
+ /// The mp4 type.
+ /// </summary>
+ MP4,
+
+ /// <summary>
+ /// The 3gpp type.
+ /// </summary>
+ ThreeGpp
+ }
+}
diff --git a/src/Tizen.Multimedia/MediaTool/MediaPacket.cs b/src/Tizen.Multimedia/MediaTool/MediaPacket.cs
new file mode 100644
index 0000000..14eadbf
--- /dev/null
+++ b/src/Tizen.Multimedia/MediaTool/MediaPacket.cs
@@ -0,0 +1,744 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using System.Threading;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents a packet for multimedia.
+ /// </summary>
+ public abstract class MediaPacket : IDisposable
+ {
+ private IntPtr _handle = IntPtr.Zero;
+
+ /// <summary>
+ /// Initializes a new instance of the MediaPacket class with the specified media format.
+ /// </summary>
+ /// <param name="format">The media format containing properties for the packet.</param>
+ /// <exception cref="System.ArgumentNullException">format is null.</exception>
+ /// <exception cref="System.ArgumentException">
+ /// <see cref="MediaFormatType"/> of the specified format is <see cref="MediaFormatType.Container"/>.</exception>
+ /// <exception cref="System.InvalidOperationException">Operation failed.</exception>
+ internal MediaPacket(MediaFormat format)
+ {
+ if (format == null)
+ {
+ throw new ArgumentNullException(nameof(format));
+ }
+
+ if (format.Type == MediaFormatType.Container)
+ {
+ throw new ArgumentException("Container format can't be used to create a new packet.");
+ }
+
+ Initialize(format);
+ _format = format;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the MediaPacket class from a native handle.
+ /// </summary>
+ /// <param name="handle">The native handle to be used.</param>
+ internal MediaPacket(IntPtr handle)
+ {
+ _handle = handle;
+
+ IntPtr formatHandle;
+ int ret = Interop.MediaPacket.GetFormat(handle, out formatHandle);
+
+ MultimediaDebug.AssertNoError(ret);
+
+ try
+ {
+ if (formatHandle != IntPtr.Zero)
+ {
+ _format = MediaFormat.FromHandle(formatHandle);
+ }
+ }
+ finally
+ {
+ Interop.MediaFormat.Unref(formatHandle);
+ }
+ }
+
+ ~MediaPacket()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Creates and initializes a native handle for the current object.
+ /// </summary>
+ /// <param name="format">The format to be set to the media format.</param>
+ /// <exception cref="System.InvalidOperationException">Operation failed.</exception>
+ private void Initialize(MediaFormat format)
+ {
+ if (format.Type == MediaFormatType.Container)
+ {
+ throw new ArgumentException("Creating a packet for container is not supported.");
+ }
+
+ IntPtr formatHandle = IntPtr.Zero;
+
+ try
+ {
+ formatHandle = format.AsNativeHandle();
+
+ int ret = Interop.MediaPacket.Create(formatHandle, IntPtr.Zero, IntPtr.Zero, out _handle);
+ MultimediaDebug.AssertNoError(ret);
+
+ Debug.Assert(_handle != IntPtr.Zero, "Created handle must not be null");
+
+ Alloc();
+ }
+ catch (Exception)
+ {
+ if (_handle != IntPtr.Zero)
+ {
+ Interop.MediaPacket.Destroy(_handle);
+ _handle = IntPtr.Zero;
+ }
+
+ throw;
+ }
+ finally
+ {
+ if (formatHandle != IntPtr.Zero)
+ {
+ Interop.MediaFormat.Unref(formatHandle);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Allocates internal buffer.
+ /// </summary>
+ /// <exception cref="System.InvalidOperationException">Operation failed.</exception>
+ private void Alloc()
+ {
+ ErrorCode ret = (ErrorCode)Interop.MediaPacket.Alloc(_handle);
+ if (ret == ErrorCode.None)
+ {
+ return;
+ }
+
+ switch (ret)
+ {
+ case ErrorCode.OutOfMemory:
+ throw new OutOfMemoryException("Failed to allocate buffer for the packet.");
+
+ default:
+ throw new InvalidOperationException("Failed to create a packet.");
+ }
+
+ }
+
+ private readonly MediaFormat _format;
+
+ /// <summary>
+ /// Gets the media format of the current packet.
+ /// </summary>
+ public MediaFormat Format
+ {
+ get
+ {
+ ValidateNotDisposed();
+ return _format;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the PTS(Presentation Time Stamp) value of the current packet.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed.</exception>
+ /// <exception cref="InvalidOperationException">
+ /// The MediaPacket is not writable state which means it being used by another module.</exception>
+ public ulong Pts
+ {
+ get
+ {
+ ValidateNotDisposed();
+
+ ulong value = 0;
+ int ret = Interop.MediaPacket.GetPts(_handle, out value);
+
+ MultimediaDebug.AssertNoError(ret);
+
+ return value;
+ }
+ set
+ {
+ ValidateNotDisposed();
+ ValidateNotLocked();
+
+ int ret = Interop.MediaPacket.SetPts(_handle, value);
+
+ MultimediaDebug.AssertNoError(ret);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the DTS(Decoding Time Stamp) value of the current packet.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed.</exception>
+ /// <exception cref="InvalidOperationException">
+ /// The MediaPacket is not in writable state which means it being used by another module.</exception>
+ public ulong Dts
+ {
+ get
+ {
+ ValidateNotDisposed();
+
+ ulong value = 0;
+ int ret = Interop.MediaPacket.GetDts(_handle, out value);
+
+ MultimediaDebug.AssertNoError(ret);
+
+ return value;
+ }
+ set
+ {
+ ValidateNotDisposed();
+ ValidateNotLocked();
+
+ int ret = Interop.MediaPacket.SetDts(_handle, value);
+
+ MultimediaDebug.AssertNoError(ret);
+ }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether the packet is encoded type.
+ /// </summary>
+ /// <value>true if the packet is encoded type; otherwise, false.</value>
+ /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed.</exception>
+ public bool IsEncoded
+ {
+ get
+ {
+ ValidateNotDisposed();
+
+ bool value = false;
+ int ret = Interop.MediaPacket.IsEncoded(_handle, out value);
+
+ MultimediaDebug.AssertNoError(ret);
+
+ return value;
+ }
+ }
+
+ private MediaPacketBuffer _buffer;
+
+ /// <summary>
+ /// Gets the buffer of the packet.
+ /// </summary>
+ /// <value>The <see cref="MediaPacketBuffer"/> allocated to the packet.
+ /// This property will return null if the packet is raw video format.</value>
+ /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed.</exception>
+ /// <seealso cref="IsEncoded"/>
+ /// <seealso cref="VideoPlanes"/>
+ public MediaPacketBuffer Buffer
+ {
+ get
+ {
+ ValidateNotDisposed();
+
+ if (IsVideoPlaneSupported)
+ {
+ return null;
+ }
+
+ if (_buffer == null)
+ {
+ _buffer = GetBuffer();
+ }
+
+ return _buffer;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a length of data written in the <see cref="Buffer"/>.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// The value specified for this property is less than zero or greater than <see cref="MediaPacketBuffer.Length"/>.</exception>
+ /// <exception cref="InvalidOperationException">
+ /// The MediaPacket has <see cref="VideoPlanes"/> instead of <see cref="Buffer"/>.\n
+ /// -or-\n
+ /// The MediaPacket is not in writable state which means it being used by another module.
+ /// </exception>
+ public int BufferWrittenLength
+ {
+ get
+ {
+ ValidateNotDisposed();
+
+ ulong value = 0;
+ int ret = Interop.MediaPacket.GetBufferSize(_handle, out value);
+ MultimediaDebug.AssertNoError(ret);
+
+ Debug.Assert(value < int.MaxValue);
+
+ return (int)value;
+ }
+ set
+ {
+ ValidateNotDisposed();
+ ValidateNotLocked();
+
+ if (IsVideoPlaneSupported)
+ {
+ throw new InvalidOperationException(
+ "This packet uses VideoPlanes instead of Buffer.");
+ }
+
+ Debug.Assert(Buffer != null);
+
+ if (value < 0 || value >= Buffer.Length)
+ {
+ throw new ArgumentOutOfRangeException("value must be less than Buffer.Size.");
+ }
+
+ int ret = Interop.MediaPacket.SetBufferSize(_handle, (ulong)value);
+ MultimediaDebug.AssertNoError(ret);
+ }
+ }
+
+ private MediaPacketVideoPlane[] _videoPlanes;
+
+ /// <summary>
+ /// Gets the video planes of the packet.
+ /// </summary>
+ /// <value>The <see cref="MediaPacketVideoPlane"/>s allocated to the packet.
+ /// This property will return null if the packet is not raw video format.</value>
+ /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed.</exception>
+ /// <seealso cref="IsEncoded"/>
+ /// <seealso cref="Buffer"/>
+ public MediaPacketVideoPlane[] VideoPlanes
+ {
+ get
+ {
+ ValidateNotDisposed();
+
+ if (!IsVideoPlaneSupported)
+ {
+ return null;
+ }
+
+ if (_videoPlanes == null)
+ {
+ _videoPlanes = GetVideoPlanes();
+ }
+
+ return _videoPlanes;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the buffer flags of the packet.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed.</exception>
+ /// <exception cref="InvalidOperationException">
+ /// The MediaPacket is not in writable state which means it being used by another module.
+ /// </exception>
+ public MediaPacketBufferFlags BufferFlags
+ {
+ get
+ {
+ ValidateNotDisposed();
+
+ int value = 0;
+
+ int ret = Interop.MediaPacket.GetBufferFlags(_handle, out value);
+
+ MultimediaDebug.AssertNoError(ret);
+
+ return (MediaPacketBufferFlags)value;
+ }
+
+ set
+ {
+ ValidateNotDisposed();
+ ValidateNotLocked();
+
+ int ret = Interop.MediaPacket.ResetBufferFlags(_handle);
+
+ MultimediaDebug.AssertNoError(ret);
+
+ ret = Interop.MediaPacket.SetBufferFlags(_handle, (int)value);
+
+ MultimediaDebug.AssertNoError(ret);
+ }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether the packet has been disposed of.
+ /// </summary>
+ /// <value>true if the packet has been disposed of; otherwise, false.</value>
+ public bool IsDisposed
+ {
+ get
+ {
+ return _isDisposed;
+ }
+ }
+
+ private bool _isDisposed = false;
+
+ /// <summary>
+ /// Releases all resources.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">
+ /// The MediaPacket can not be disposed which means it being used by another module.
+ /// </exception>
+ public void Dispose()
+ {
+ if (_isDisposed)
+ {
+ return;
+ }
+ ValidateNotLocked();
+
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_isDisposed)
+ {
+ return;
+ }
+
+ if (_handle != IntPtr.Zero)
+ {
+ Interop.MediaPacket.Destroy(_handle);
+ _handle = IntPtr.Zero;
+ }
+
+ _isDisposed = true;
+ }
+
+ internal IntPtr GetHandle()
+ {
+ ValidateNotDisposed();
+
+ Debug.Assert(_handle != IntPtr.Zero, "The handle is invalid!");
+
+ return _handle;
+ }
+
+ /// <summary>
+ /// Validate the current object has not been disposed of.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed of.</exception>
+ private void ValidateNotDisposed()
+ {
+ if (_isDisposed)
+ {
+ throw new ObjectDisposedException("This packet has already been disposed of.");
+ }
+ }
+
+ /// <summary>
+ /// Validate the current object is not locked.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed of.</exception>
+ /// <exception cref="InvalidOperationException">The MediaPacket is in use by another module.</exception>
+ private void ValidateNotLocked()
+ {
+ ValidateNotDisposed();
+
+ if (_lock.IsLocked)
+ {
+ throw new InvalidOperationException("Can't perform any writing operation." +
+ "The packet is in use, internally.");
+ }
+ }
+ /// <summary>
+ /// Ensures whether the packet is writable.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">The MediaPacket already has been disposed of.</exception>
+ /// <exception cref="InvalidOperationException">The MediaPacket is being used by another module.</exception>
+ internal void EnsureWritableState()
+ {
+ ValidateNotDisposed();
+ ValidateNotLocked();
+ }
+
+ /// <summary>
+ /// Ensures whether the packet is readable.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">The MediaPacket already has been disposed of.</exception>
+ internal void EnsureReadableState()
+ {
+ ValidateNotDisposed();
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether the packet is raw video format.
+ /// </summary>
+ /// <value>true if the packet is raw video format; otherwise, false.</value>
+ private bool IsVideoPlaneSupported
+ {
+ get
+ {
+ return !IsEncoded && Format.Type == MediaFormatType.Video;
+ }
+ }
+
+ /// <summary>
+ /// Retrieves video planes of the current packet.
+ /// </summary>
+ /// <returns>The <see cref="MediaPacketVideoPlane"/>s allocated to the current MediaPacket.</returns>
+ private MediaPacketVideoPlane[] GetVideoPlanes()
+ {
+ Debug.Assert(_handle != IntPtr.Zero, "The handle is invalid!");
+
+ uint numberOfPlanes = 0;
+ int ret = Interop.MediaPacket.GetNumberOfVideoPlanes(_handle, out numberOfPlanes);
+
+ MultimediaDebug.AssertNoError(ret);
+
+ MediaPacketVideoPlane[] planes = new MediaPacketVideoPlane[numberOfPlanes];
+
+ for (int i = 0; i < numberOfPlanes; ++i)
+ {
+ planes[i] = new MediaPacketVideoPlane(this, i);
+ }
+
+ return planes;
+ }
+
+ /// <summary>
+ /// Retrieves the buffer of the current packet.
+ /// </summary>
+ /// <returns>The <see cref="MediaPacketBuffer"/> allocated to the current MediaPacket.</returns>
+ private MediaPacketBuffer GetBuffer()
+ {
+ Debug.Assert(_handle != IntPtr.Zero, "The handle is invalid!");
+
+ IntPtr dataHandle;
+
+ int ret = Interop.MediaPacket.GetBufferData(_handle, out dataHandle);
+ MultimediaDebug.AssertNoError(ret);
+
+ Debug.Assert(dataHandle != IntPtr.Zero, "Data handle is invalid!");
+
+ int size = 0;
+ ret = Interop.MediaPacket.GetAllocatedBufferSize(_handle, out size);
+ MultimediaDebug.AssertNoError(ret);
+
+ return new MediaPacketBuffer(this, dataHandle, size);
+ }
+
+ #region Lock operations
+ private readonly LockState _lock = new LockState();
+
+ /// <summary>
+ /// Provides a thread-safe lock state controller.
+ /// </summary>
+ private sealed class LockState
+ {
+ const int LOCKED = 1;
+ const int UNLOCKED = 0;
+
+ private int _locked = UNLOCKED;
+
+ internal void SetLock()
+ {
+ if (Interlocked.CompareExchange(ref _locked, LOCKED, UNLOCKED) == LOCKED)
+ {
+ throw new InvalidOperationException("The packet is already locked.");
+ }
+ }
+
+ internal void SetUnlock()
+ {
+ if (Interlocked.CompareExchange(ref _locked, UNLOCKED, LOCKED) == UNLOCKED)
+ {
+ Debug.Fail("The packet to unlock is not locked. " +
+ "There must be an error somewhere that a lock isn't disposed correctly.");
+ }
+ }
+
+ internal bool IsLocked
+ {
+ get
+ {
+ return Interlocked.CompareExchange(ref _locked, 0, 0) == LOCKED;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Provides a thread-safe lock controller.
+ /// </summary>
+ /// <example>
+ /// using (var lock = BaseMediaPacket.Lock(mediaPacket))
+ /// {
+ /// ....
+ /// }
+ /// </example>
+ internal sealed class Lock : IDisposable
+ {
+ private readonly MediaPacket _packet;
+ private readonly GCHandle _gcHandle;
+ private int _lockCount;
+
+ internal static Lock Get(MediaPacket packet)
+ {
+ Debug.Assert(packet != null);
+
+ lock (packet)
+ {
+ Lock lck = FromHandle(packet._handle);
+
+ if (lck == null)
+ {
+ lck = new Lock(packet);
+ }
+
+ lck._lockCount++;
+
+ return lck;
+ }
+ }
+
+ private Lock(MediaPacket packet)
+ {
+ Debug.Assert(packet != null, "The packet is null!");
+
+ packet.ValidateNotDisposed();
+
+ _packet = packet;
+
+ _packet._lock.SetLock();
+
+ _gcHandle = GCHandle.Alloc(this);
+
+ SetExtra(GCHandle.ToIntPtr(_gcHandle));
+ }
+
+ internal static Lock FromHandle(IntPtr handle)
+ {
+ Debug.Assert(handle != IntPtr.Zero);
+
+ IntPtr extra = GetExtra(handle);
+
+ if (extra == IntPtr.Zero)
+ {
+ return null;
+ }
+
+ return (Lock)GCHandle.FromIntPtr(extra).Target;
+ }
+
+ private void SetExtra(IntPtr ptr)
+ {
+ int ret = Interop.MediaPacket.SetExtra(_packet._handle, ptr);
+
+ MultimediaDebug.AssertNoError(ret);
+ }
+
+ private static IntPtr GetExtra(IntPtr handle)
+ {
+ IntPtr value;
+
+ int ret = Interop.MediaPacket.GetExtra(handle, out value);
+
+ MultimediaDebug.AssertNoError(ret);
+
+ return value;
+ }
+
+ internal IntPtr GetHandle()
+ {
+ return _packet.GetHandle();
+ }
+
+ internal MediaPacket MediaPacket
+ {
+ get
+ {
+ return _packet;
+ }
+ }
+
+ private bool _isDisposed = false;
+
+ public void Dispose()
+ {
+ if (!_isDisposed)
+ {
+ lock (_packet)
+ {
+ _lockCount--;
+
+ if (_lockCount == 0)
+ {
+ // TODO rollback after the corresponding native api is fixed.
+ //SetExtra(IntPtr.Zero);
+
+ if (_gcHandle.IsAllocated)
+ {
+ _gcHandle.Free();
+ }
+
+ //We can assure that at this point '_packet' is always locked by this lock.
+ _packet._lock.SetUnlock();
+ }
+ }
+
+ _isDisposed = true;
+ }
+ }
+ }
+ #endregion
+
+ /// <summary>
+ /// Creates an object of the MediaPacket with the specified <see cref="MediaFormat"/>.
+ /// </summary>
+ /// <param name="format">The media format for the new packet.</param>
+ /// <returns>A new MediaPacket object.</returns>
+ public static MediaPacket Create(MediaFormat format)
+ {
+ return new SimpleMediaPacket(format);
+ }
+
+ internal static MediaPacket From(IntPtr handle)
+ {
+ return new SimpleMediaPacket(handle);
+ }
+ }
+
+ internal class SimpleMediaPacket : MediaPacket
+ {
+ internal SimpleMediaPacket(MediaFormat format) : base(format)
+ {
+ }
+
+ internal SimpleMediaPacket(IntPtr handle) : base(handle)
+ {
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia/MediaTool/MediaPacketBuffer.cs b/src/Tizen.Multimedia/MediaTool/MediaPacketBuffer.cs
new file mode 100644
index 0000000..49b9caf
--- /dev/null
+++ b/src/Tizen.Multimedia/MediaTool/MediaPacketBuffer.cs
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents a buffer for a <see cref="MediaPacket"/>.
+ /// </summary>
+ public class MediaPacketBuffer
+ {
+ private readonly MediaPacket _packet;
+ private readonly IntPtr _dataHandle;
+
+ internal MediaPacketBuffer(MediaPacket packet, IntPtr dataHandle, int size)
+ {
+ Debug.Assert(packet != null, "Packet is null!");
+ Debug.Assert(!packet.IsDisposed, "Packet is already disposed!");
+ Debug.Assert(dataHandle != IntPtr.Zero, "dataHandle is null!");
+ Debug.Assert(size >= 0, "size must not be negative!");
+
+ _packet = packet;
+ _dataHandle = dataHandle;
+ _length = size;
+ }
+
+ /// <summary>
+ /// Gets or sets a value at the specified index.
+ /// </summary>
+ /// <param name="index">The index of the value to get or set.</param>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// index is less than zero.\n
+ /// -or-\n
+ /// index is equal to or greater than <see cref="Length"/>.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">The MediaPacket that owns the current buffer already has been disposed of.</exception>
+ /// <exception cref="InvalidOperationException">The MediaPacket that owns the current buffer is being used by another module.</exception>
+ public byte this[int index]
+ {
+ get
+ {
+ _packet.EnsureReadableState();
+
+ if (index < 0 || index >= Length)
+ {
+ throw new ArgumentOutOfRangeException($"Valid index range is [0, { nameof(Length) }).");
+ }
+
+ return Marshal.ReadByte(_dataHandle, index);
+ }
+ set
+ {
+ _packet.EnsureWritableState();
+
+ Marshal.WriteByte(_dataHandle, index, value);
+ }
+ }
+
+ /// <summary>
+ /// Validates the range
+ /// </summary>
+ /// <param name="offset"></param>
+ /// <param name="length"></param>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// offset + length is greater than <see cref="Length"/>.\n
+ /// -or-\n
+ /// offset or length is less than zero.
+ /// </exception>
+ private void ValidateRange(int offset, int length)
+ {
+ if (offset + length > _length)
+ {
+ throw new ArgumentOutOfRangeException("offset + length can't be greater than length of the buffer.");
+ }
+ if (length < 0)
+ {
+ throw new ArgumentOutOfRangeException($"Length can't be less than zero : { length }.");
+ }
+ if (offset < 0)
+ {
+ throw new ArgumentOutOfRangeException($"Offset can't be less than zero : { offset }.");
+ }
+ }
+
+ /// <summary>
+ /// Copies data from a byte array to the buffer.
+ /// </summary>
+ /// <param name="source">The array to copy from.</param>
+ /// <param name="startIndex">The zero-based index in the source array where copying should start.</param>
+ /// <param name="length">The number of array elements to copy.</param>
+ /// <param name="offset">The zero-based index in the buffer where copying should start.</param>
+ /// <exception cref="ArgumentOutOfRangeException">startIndex, offset or length is not valid.</exception>
+ /// <exception cref="ObjectDisposedException">The MediaPacket that owns the current buffer already has been disposed of.</exception>
+ public void CopyFrom(byte[] source, int startIndex, int length, int offset = 0)
+ {
+ _packet.EnsureReadableState();
+
+ if (startIndex < 0)
+ {
+ throw new ArgumentOutOfRangeException("startIndex can't be less than zero.");
+ }
+ if (startIndex + length > source.Length)
+ {
+ throw new ArgumentOutOfRangeException("startIndex + length can't be greater than source.Length.");
+ }
+
+ ValidateRange(offset, length);
+
+ Marshal.Copy(source, startIndex, IntPtr.Add(_dataHandle, offset), length);
+ }
+
+ /// <summary>
+ /// Copies data from the buffer to a byte array.
+ /// </summary>
+ /// <param name="dest">The array to copy to.</param>
+ /// <param name="startIndex">The zero-based index in the dest array where copying should start.</param>
+ /// <param name="length">The number of elements to copy.</param>
+ /// <param name="offset">The zero-based index in the buffer where copying should start.</param>
+ /// <exception cref="ArgumentOutOfRangeException">startIndex, offset or length is not valid.</exception>
+ /// <exception cref="ObjectDisposedException">The MediaPacket that owns the current buffer already has been disposed of.</exception>
+ /// <exception cref="InvalidOperationException">The MediaPacket that owns the current buffer is being used by another module.</exception>
+ public void CopyTo(byte[] dest, int startIndex, int length, int offset = 0)
+ {
+ _packet.EnsureWritableState();
+
+ if (startIndex < 0)
+ {
+ throw new ArgumentOutOfRangeException("Start index can't be less than zero.");
+ }
+ if (startIndex + length > dest.Length)
+ {
+ throw new ArgumentOutOfRangeException("startIndex + length can't be greater than dest.Length.");
+ }
+
+ ValidateRange(offset, length);
+
+ Marshal.Copy(IntPtr.Add(_dataHandle, offset), dest, startIndex, length);
+ }
+
+ private readonly int _length;
+
+ /// <summary>
+ /// Gets the size of the buffer, in bytes.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">The MediaPacket that owns the current buffer already has been disposed of.</exception>
+ public int Length
+ {
+ get
+ {
+ _packet.EnsureReadableState();
+
+ return _length;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia/MediaTool/MediaPacketBufferFlags.cs b/src/Tizen.Multimedia/MediaTool/MediaPacketBufferFlags.cs
new file mode 100644
index 0000000..7c1bf05
--- /dev/null
+++ b/src/Tizen.Multimedia/MediaTool/MediaPacketBufferFlags.cs
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Specifies the flag for a buffer.
+ /// <para>
+ /// This enumeration has a <see cref="FlagsAttribute"/> attribute that allows a bitwise combination of its member values.
+ /// </para>
+ /// </summary>
+ [Flags]
+ public enum MediaPacketBufferFlags
+ {
+ /// <summary>
+ /// The buffer contains codec initialization or codec specific data instead of media data.
+ /// </summary>
+ CodecConfig = 0x1,
+
+ /// <summary>
+ /// The buffer indicates the end of stream.
+ /// </summary>
+ EndOfStream = 0x2,
+
+ /// <summary>
+ /// The buffer contains a sync frame.
+ /// </summary>
+ SyncFrame = 0x4,
+ }
+}
diff --git a/src/Tizen.Multimedia/MediaTool/MediaPacketVideoPlane.cs b/src/Tizen.Multimedia/MediaTool/MediaPacketVideoPlane.cs
new file mode 100644
index 0000000..3291221
--- /dev/null
+++ b/src/Tizen.Multimedia/MediaTool/MediaPacketVideoPlane.cs
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Diagnostics;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Represents a video plane for <see cref="MediaPacket"/>.
+ /// This class is used if and only if the format of the packet is raw video.
+ /// </summary>
+ public class MediaPacketVideoPlane
+ {
+ private readonly MediaPacket _packet;
+ private readonly int _strideWidth;
+ private readonly int _strideHeight;
+ private readonly MediaPacketBuffer _buffer;
+
+ internal MediaPacketVideoPlane(MediaPacket packet, int index)
+ {
+ Debug.Assert(packet != null, "The packet is null!");
+ Debug.Assert(!packet.IsDisposed, "Packet is already disposed!");
+ Debug.Assert(index >= 0, "Video plane index must not be negative!");
+
+ _packet = packet;
+
+ int ret = Interop.MediaPacket.GetVideoStrideWidth(packet.GetHandle(), index, out _strideWidth);
+ MultimediaDebug.AssertNoError(ret);
+
+ ret = Interop.MediaPacket.GetVideoStrideWidth(packet.GetHandle(), index, out _strideHeight);
+ MultimediaDebug.AssertNoError(ret);
+
+ IntPtr dataHandle;
+ ret = Interop.MediaPacket.GetVideoPlaneData(packet.GetHandle(), index, out dataHandle);
+ MultimediaDebug.AssertNoError(ret);
+
+ _buffer = new MediaPacketBuffer(packet, dataHandle, _strideWidth * _strideHeight);
+ }
+
+ /// <summary>
+ /// Gets the buffer of the current video plane.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">The MediaPacket that owns the current buffer already has been disposed of.</exception>
+ public MediaPacketBuffer Buffer
+ {
+ get
+ {
+ _packet.EnsureReadableState();
+ return _buffer;
+ }
+ }
+
+ /// <summary>
+ /// Gets the stride width of the current video plane.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">The MediaPacket that owns the current buffer already has been disposed of.</exception>
+ public int StrideWidth
+ {
+ get
+ {
+ _packet.EnsureReadableState();
+ return _strideWidth;
+ }
+ }
+
+ /// <summary>
+ /// Gets the stride height of the current video plane.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">The MediaPacket that owns the current buffer already has been disposed of.</exception>
+ public int StrideHeight
+ {
+ get
+ {
+ _packet.EnsureReadableState();
+ return _strideHeight;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Multimedia/MediaView/MediaView.cs b/src/Tizen.Multimedia/MediaView/MediaView.cs
new file mode 100755
index 0000000..0e3d4a8
--- /dev/null
+++ b/src/Tizen.Multimedia/MediaView/MediaView.cs
@@ -0,0 +1,22 @@
+using System;
+using ElmSharp;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// The MediaView class allows application developers to display the video output on screen.
+ /// </summary>
+ public class MediaView : EvasObject
+ {
+ public MediaView(EvasObject parent) : base(parent)
+ {
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ IntPtr evas = Interop.EvasObject.evas_object_evas_get(parent);
+ return Interop.EvasObject.evas_object_image_add(evas);
+ }
+ }
+}
+
diff --git a/src/Tizen.Multimedia/Tizen.Multimedia.csproj b/src/Tizen.Multimedia/Tizen.Multimedia.csproj
new file mode 100644
index 0000000..73a3b0a
--- /dev/null
+++ b/src/Tizen.Multimedia/Tizen.Multimedia.csproj
@@ -0,0 +1,15 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\ElmSharp\ElmSharp.csproj" />
+ <ProjectReference Include="..\Tizen.Applications.Common\Tizen.Applications.Common.csproj" />
+ <ProjectReference Include="..\Tizen.System.Information\Tizen.System.Information.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Network.Bluetooth/Interop/Interop.Bluetooth.cs b/src/Tizen.Network.Bluetooth/Interop/Interop.Bluetooth.cs
new file mode 100755
index 0000000..87accbb
--- /dev/null
+++ b/src/Tizen.Network.Bluetooth/Interop/Interop.Bluetooth.cs
@@ -0,0 +1,597 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Tizen.Network.Bluetooth;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Bluetooth
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void StateChangedCallback(int result, int state, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void NameChangedCallback(string deviceName, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void VisibilityModeChangedCallback(int result, int visibility, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void VisibilityDurationChangedCallback(int duration, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void DiscoveryStateChangedCallback(int result, BluetoothDeviceDiscoveryState state, IntPtr deviceInfo, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool BondedDeviceCallback([MarshalAs(UnmanagedType.Struct)]ref BluetoothDeviceStruct device, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void BondCreatedCallback(int result, [MarshalAs(UnmanagedType.Struct)]ref BluetoothDeviceStruct device, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void BondDestroyedCallback(int result, string deviceAddress, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void AuthorizationChangedCallback(int authorization, string deviceAddress, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ServiceSearchedCallback(int result, [MarshalAs(UnmanagedType.Struct)]ref BluetoothDeviceSdpStruct sdp, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void DeviceConnectionStateChangedCallback(bool connected, [MarshalAs(UnmanagedType.Struct)]ref BluetoothDeviceConnectionStruct device, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool ConnectedProfileCallback(int profile, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void DataReceivedCallback([MarshalAs(UnmanagedType.Struct)]ref SocketDataStruct socketData, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void SocketConnectionStateChangedCallback(int result, BluetoothSocketState connectionState, [MarshalAs(UnmanagedType.Struct)]ref SocketConnectionStruct socketConnection, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void AudioConnectionStateChangedCallback(int result, bool connected, string deviceAddress, int profileType, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void HidConnectionStateChangedCallback(int result, bool connected, string deviceAddress, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void TargetConnectionStateChangedCallback(bool connected, string deviceAddress, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void EqualizerStateChangedCallback(int equalizer, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void RepeatModeChangedCallback(int repeat, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ShuffleModeChangedCallback(int shuffle, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ScanModeChangedCallback(int scan, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ConnectionChangedCallback(int result, bool connected, string deviceAddress, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ClientCharacteristicValueChangedCallback(IntPtr characteristicHandle, string value, int len, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void GattClientRequestedCallback(int result, IntPtr handle, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool GattForEachCallback(int total, int index, IntPtr handle, IntPtr userData);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_initialize")]
+ internal static extern int Initialize();
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_deinitialize")]
+ internal static extern int Deinitialize();
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_get_name")]
+ internal static extern int GetName(out string name);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_set_name")]
+ internal static extern int SetName(string name);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_get_state")]
+ internal static extern int GetState(out BluetoothState isActivated);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_get_address")]
+ internal static extern int GetAddress(out string address);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_get_visibility")]
+ internal static extern int GetVisibility(out int visibility, out int duration);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_is_discovering")]
+ internal static extern int IsDiscovering(out bool isDiscovering);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_start_device_discovery")]
+ internal static extern int StartDiscovery();
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_stop_device_discovery")]
+ internal static extern int StopDiscovery();
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_foreach_bonded_device")]
+ internal static extern int GetBondedDevices(BondedDeviceCallback bondedDeviceCb, IntPtr userData);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_get_bonded_device_info")]
+ internal static extern int GetBondedDeviceByAddress(string deviceAddress, out IntPtr deviceInfo);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_free_device_info")]
+ internal static extern int FreeDeviceInfo(BluetoothDeviceStruct deviceInfo);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_is_service_used")]
+ internal static extern int IsServiceUsed(string serviceUuid, out bool used);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_get_local_oob_data")]
+ internal static extern int GetOobData(out IntPtr hash, out IntPtr randomizer, out int hashLen, out int randomizerLen);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_set_remote_oob_data")]
+ internal static extern int SetOobData(string deviceAddress, IntPtr hash, IntPtr randomizer, int hashLen, int randomizerLen);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_remove_remote_oob_data")]
+ internal static extern int RemoveOobData(string deviceAddress);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_set_state_changed_cb")]
+ internal static extern int SetStateChangedCallback(StateChangedCallback stateChangedCb, IntPtr userData);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_unset_state_changed_cb")]
+ internal static extern int UnsetStateChangedCallback();
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_set_name_changed_cb")]
+ internal static extern int SetNameChangedCallback(NameChangedCallback nameChangedCb, IntPtr userData);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_unset_name_changed_cb")]
+ internal static extern int UnsetNameChangedCallback();
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_set_visibility_mode_changed_cb")]
+ internal static extern int SetVisibilityModeChangedCallback(VisibilityModeChangedCallback visibilityChangedCb, IntPtr userData);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_unset_visibility_mode_changed_cb")]
+ internal static extern int UnsetVisibilityModeChangedCallback();
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_set_visibility_duration_changed_cb")]
+ internal static extern int SetVisibilityDurationChangedCallback(VisibilityDurationChangedCallback durationChangedCb, IntPtr userData);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_unset_visibility_duration_changed_cb")]
+ internal static extern int UnsetVisibilityDurationChangedCallback();
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_set_device_discovery_state_changed_cb")]
+ internal static extern int SetDiscoveryStateChangedCallback(DiscoveryStateChangedCallback discoveryChangedCb, IntPtr userData);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_unset_device_discovery_state_changed_cb")]
+ internal static extern int UnsetDiscoveryStateChangedCallback();
+
+ //Bluetooth Device
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_create_bond")]
+ internal static extern int CreateBond(string deviceAddress);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_destroy_bond")]
+ internal static extern int DestroyBond(string deviceAddress);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_cancel_bonding")]
+ internal static extern int CancelBonding();
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_set_alias")]
+ internal static extern int SetAlias(string deviceAddress, string alias);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_set_authorization")]
+ internal static extern int SetAuthorization(string deviceAddress, int state);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_get_service_mask_from_uuid_list")]
+ internal static extern int GetMaskFromUuid([MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr, SizeParamIndex = 1)] string[] uuids, int count, out BluetoothServiceClassType serviceMask);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_start_service_search")]
+ internal static extern int StartServiceSearch(string deviceAddress);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_foreach_connected_profiles")]
+ internal static extern int GetConnectedProfiles(string deviceAddress, ConnectedProfileCallback connectedProfileCb, IntPtr userData);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_is_profile_connected")]
+ internal static extern int IsProfileConnected(string deviceAddress, int profile, out bool connectionStatus);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_set_bond_created_cb")]
+ internal static extern int SetBondCreatedCallback(BondCreatedCallback bondCreatedCb, IntPtr userData);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_unset_bond_created_cb")]
+ internal static extern int UnsetBondCreatedCallback();
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_set_bond_destroyed_cb")]
+ internal static extern int SetBondDestroyedCallback(BondDestroyedCallback bondDestroyedCb, IntPtr userData);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_unset_bond_destroyed_cb")]
+ internal static extern int UnsetBondDestroyedCallback();
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_set_authorization_changed_cb")]
+ internal static extern int SetAuthorizationChangedCallback(AuthorizationChangedCallback authorizationChangedCb, IntPtr userData);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_unset_authorization_changed_cb")]
+ internal static extern int UnsetAuthorizationChangedCallback();
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_set_service_searched_cb")]
+ internal static extern int SetServiceSearchedCallback(ServiceSearchedCallback serviceSearchedCb, IntPtr userData);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_unset_service_searched_cb")]
+ internal static extern int UnsetServiceSearchedCallback();
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_set_connection_state_changed_cb")]
+ internal static extern int SetConnectionStateChangedCallback(DeviceConnectionStateChangedCallback connectionChangedCb, IntPtr userData);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_unset_connection_state_changed_cb")]
+ internal static extern int UnsetConnectionStateChangedCallback();
+
+ // Bluetooth LE Adapter
+
+ //Callback for event
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void AdapterLeScanResultChangedCallBack(int result,
+ [MarshalAs(UnmanagedType.Struct)]ref BluetoothLeScanDataStruct scanData, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate void AdvertisingStateChangedCallBack(int result, IntPtr advertiserHandle,
+ BluetoothLeAdvertisingState advertisingState, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate void GattConnectionStateChangedCallBack(int result, bool connected,
+ string remoteAddress, IntPtr userData);
+
+ //Bluetooth Le Adapter Apis
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_start_scan")]
+ public static extern int StartScan(AdapterLeScanResultChangedCallBack callback, IntPtr userData);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_stop_scan")]
+ public static extern int StopScan();
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_get_scan_result_service_uuids")]
+ public static extern int GetScanResultServiceUuid(ref BluetoothLeScanDataStruct scanData,
+ BluetoothLePacketType packetType, ref IntPtr uuids, ref int count);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_get_scan_result_device_name")]
+ public static extern int GetLeScanResultDeviceName(ref BluetoothLeScanDataStruct scanData,
+ BluetoothLePacketType packetType, out string deviceName);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_get_scan_result_tx_power_level")]
+ public static extern int GetScanResultTxPowerLevel(ref BluetoothLeScanDataStruct scanData,
+ BluetoothLePacketType packetType, out int txPowerLevel);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_get_scan_result_service_solicitation_uuids")]
+ public static extern int GetScaResultSvcSolicitationUuids(ref BluetoothLeScanDataStruct scanData,
+ BluetoothLePacketType packetType, out IntPtr uuids, out int count);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_get_scan_result_service_data_list")]
+ public static extern int GetScanResultServiceDataList(ref BluetoothLeScanDataStruct scanData,
+ BluetoothLePacketType PacketType, out IntPtr serviceDataArray, out int count);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_free_service_data_list")]
+ public static extern int FreeServiceDataList(IntPtr serviceData, int count);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_get_scan_result_appearance")]
+ public static extern int GetScanResultAppearance(ref BluetoothLeScanDataStruct scanData,
+ BluetoothLePacketType packetType, out int appearance);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_get_scan_result_manufacturer_data")]
+ public static extern int GetScanResultManufacturerData(ref BluetoothLeScanDataStruct scanData,
+ BluetoothLePacketType packetType, out int manufId, out IntPtr manufData,
+ out int manufDataLength);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_connect")]
+ internal static extern int GattConnect(string deviceAddress, bool autoConnect);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_disconnect")]
+ internal static extern int GattDisconnect(string deviceAddress);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_set_connection_state_changed_cb")]
+ internal static extern int SetGattConnectionStateChangedCallback(
+ GattConnectionStateChangedCallBack gattConnectionChangedCb, IntPtr userData);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_unset_connection_state_changed_cb")]
+ internal static extern int UnsetGattConnectionStateChangedCallback();
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_create_advertiser")]
+ public static extern int CreateAdvertiser(out IntPtr advertiserHandle);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_destroy_advertiser")]
+ public static extern int DestroyAdvertiser(IntPtr advertiserHandle);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_add_advertising_service_uuid")]
+ public static extern int AddAdvertisingServiceUuid(IntPtr advertiserHandle,
+ BluetoothLePacketType PacketType, string uuid);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_add_advertising_service_solicitation_uuid")]
+ public static extern int AddAdvertisingServiceSolicitationUuid(IntPtr advertiserHandle,
+ BluetoothLePacketType PacketType, string uuid);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_add_advertising_service_data")]
+ public static extern int AddAdvertisingServiceData(IntPtr advertiserHandle,
+ BluetoothLePacketType PacketType, string uuid, IntPtr serviceData, int serviceDatalength);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_set_advertising_appearance")]
+ public static extern int SetAdvertisingAppearance(IntPtr advertiserHandle,
+ BluetoothLePacketType packetType, int appearance);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_add_advertising_manufacturer_data")]
+ public static extern int AddAdvertisingManufData(IntPtr advertiserHandle, BluetoothLePacketType packetType,
+ int manufId, IntPtr manufData, int manufacturerDataLength);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_set_advertising_device_name")]
+ public static extern int SetAdvertisingDeviceName(IntPtr advertiserHandle, BluetoothLePacketType packetType,
+ bool includeName);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_set_advertising_tx_power_level")]
+ public static extern int SetAdvertisingTxPowerLevel(IntPtr advertiserHandle, BluetoothLePacketType packetType,
+ bool includePowerLevel);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_clear_advertising_data")]
+ public static extern int ClearAdvertisingData(IntPtr advertiserHandle, BluetoothLePacketType packetType);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_start_advertising_new")]
+ public static extern int BluetoothLeStartAdvertising(IntPtr advertiserHandle,
+ AdvertisingStateChangedCallBack callback, IntPtr userData);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_stop_advertising")]
+ public static extern int BluetoothLeStopAdvertising(IntPtr advertiserHandle);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_set_advertising_mode")]
+ public static extern int SetAdvertisingMode(IntPtr advertiserHandle,
+ BluetoothLeAdvertisingMode advertisingMode);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_set_advertising_connectable")]
+ public static extern int SetAdvertisingConnectable(IntPtr advertiserHandle,
+ bool connectable);
+
+ //Bluetooth Socket
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_create_rfcomm")]
+ internal static extern int CreateServerSocket(string serviceUuid, out int socketFd);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_destroy_rfcomm")]
+ internal static extern int DestroyServerSocket(int socketFd);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_listen_and_accept_rfcomm")]
+ internal static extern int Listen(int socketFd, int pendingConnections);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_connect_rfcomm")]
+ internal static extern int ConnectSocket(string address, string serviceUuid);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_disconnect_rfcomm")]
+ internal static extern int DisconnectSocket(int socketFd);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_send_data")]
+ internal static extern int SendData(int socketFd, string data, int dataLength);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_set_data_received_cb")]
+ internal static extern int SetDataReceivedCallback(DataReceivedCallback callback, IntPtr userData);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_unset_data_received_cb")]
+ internal static extern int UnsetDataReceivedCallback();
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_set_connection_state_changed_cb")]
+ internal static extern int SetConnectionStateChangedCallback(SocketConnectionStateChangedCallback callback, IntPtr userData);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_unset_connection_state_changed_cb")]
+ internal static extern int UnsetSocketConnectionStateChangedCallback();
+
+ // Bluetooth Audio
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_audio_initialize")]
+ internal static extern int InitializeAudio();
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_audio_deinitialize")]
+ internal static extern int DeinitializeAudio();
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_audio_connect")]
+ internal static extern int Connect(string deviceAddress, int profileType);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_audio_disconnect")]
+ internal static extern int Disconnect(string deviceAddress, int profileType);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_audio_set_connection_state_changed_cb")]
+ internal static extern int SetAudioConnectionStateChangedCallback(AudioConnectionStateChangedCallback audioStateChangedCb, IntPtr userData);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_audio_unset_connection_state_changed_cb")]
+ internal static extern int UnsetAudioConnectionStateChangedCallback();
+
+ //Bluetooth Hid
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_hid_host_initialize")]
+ internal static extern int InitializeHid(HidConnectionStateChangedCallback hidConnectionChangedCb, IntPtr userData);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_hid_host_deinitialize")]
+ internal static extern int DeinitializeHid();
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_hid_host_connect")]
+ internal static extern int Connect(string deviceAddress);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_hid_host_disconnect")]
+ internal static extern int Disconnect(string deviceAddress);
+
+ //Bluetooth Avrcp
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_target_initialize")]
+ internal static extern int InitializeAvrcp(TargetConnectionStateChangedCallback targetStateChangedCb, IntPtr userData);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_target_deinitialize")]
+ internal static extern int DeinitializeAvrcp();
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_target_notify_equalizer_state")]
+ internal static extern int NotifyEqualizerState(int state);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_target_notify_repeat_mode")]
+ internal static extern int NotifyRepeatMode(int repeat);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_target_notify_shuffle_mode")]
+ internal static extern int NotifyShuffleMode(int shuffle);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_target_notify_scan_mode")]
+ internal static extern int NotifyScanMode(int scan);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_target_notify_player_state")]
+ internal static extern int NotifyPlayerState(int state);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_target_notify_position")]
+ internal static extern int NotifyCurrentPosition(uint position);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_target_notify_track")]
+ internal static extern int NotifyTrack(string title, string artist, string album, string genre, uint trackNum, uint totaltracks, uint duration);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_set_equalizer_state_changed_cb")]
+ internal static extern int SetEqualizerStateChangedCallback(EqualizerStateChangedCallback equalizerStateChangedCb, IntPtr userData);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_unset_equalizer_state_changed_cb")]
+ internal static extern int UnsetEqualizerStateChangedCallback();
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_set_repeat_mode_changed_cb")]
+ internal static extern int SetRepeatModeChangedCallback(RepeatModeChangedCallback repeatModeChangedCb, IntPtr userData);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_unset_repeat_mode_changed_cb")]
+ internal static extern int UnsetRepeatModeChangedCallback();
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_set_shuffle_mode_changed_cb")]
+ internal static extern int SetShuffleModeChangedCallback(ShuffleModeChangedCallback shuffleModeChangedCb, IntPtr userData);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_unset_shuffle_mode_changed_cb")]
+ internal static extern int UnsetShuffleModeChangedCallback();
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_set_scan_mode_changed_cb")]
+ internal static extern int SetScanModeChangedCallback(ScanModeChangedCallback scanModeChangedCb, IntPtr userData);
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_unset_scan_mode_changed_cb")]
+ internal static extern int UnsetScanModeChangedCallback();
+
+ // Bluetooth GATT
+
+ [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+ internal delegate bool BtGattForeachCallback(int total, int index, IntPtr gattHandle, IntPtr userData);
+
+ [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+ internal delegate void BtGattServerReadValueRequestedCallback(string clientAddress, int requestId, IntPtr serverHandle, IntPtr gattHandle, int offset, IntPtr userData);
+
+ [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+ internal delegate void BtGattServerWriteValueRequestedCallback(string clientAddress, int requestId, IntPtr serverHandle, IntPtr gattHandle, int offset, bool response_needed, byte[] value, int len, IntPtr userData);
+
+ [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+ internal delegate void BtClientCharacteristicValueChangedCallback(IntPtr characteristicHandle, byte[] value, int len, IntPtr userData);
+
+ [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+ internal delegate void BtGattServerNotificationStateChangeCallback(bool notify, IntPtr serverHandle, IntPtr characteristicHandle, IntPtr userData);
+
+ [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+ internal delegate void BtGattServerNotificationSentCallback(int result, string clientAddress, IntPtr serverHandle, IntPtr characteristicHandle, bool completed, IntPtr userData);
+
+ [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+ internal delegate void BtGattClientRequestCompletedCallback(int result, IntPtr requestHandle, IntPtr userData);
+
+ // Gatt Attribute
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_destroy")]
+ internal static extern int BtGattDestroy(IntPtr gattHandle);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_get_uuid")]
+ internal static extern int BtGattGetUuid(BluetoothGattAttributeHandle gattHandle, out string uuid);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_get_value")]
+ internal static extern int BtGattGetValue(BluetoothGattAttributeHandle gattHandle, out IntPtr nativeValue, out int valueLength);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_set_value")]
+ internal static extern int BtGattSetValue(BluetoothGattAttributeHandle gattHandle, byte[] value, int valueLength);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_get_int_value")]
+ internal static extern int BtGattGetIntValue(BluetoothGattAttributeHandle gattHandle, int type, int offset, out int value);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_set_int_value")]
+ internal static extern int BtGattSetIntValue(BluetoothGattAttributeHandle gattHandle, int type, int value, int offset);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_get_float_value")]
+ internal static extern int BtGattGetFloatValue(BluetoothGattAttributeHandle gattHandle, int type, int offset, out float value);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_set_float_value")]
+ internal static extern int BtGattSetFloatValue(BluetoothGattAttributeHandle gattHandle, int type, int mantissa, int exponent, int offset);
+
+ // GATT Descriptor
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_descriptor_create")]
+ internal static extern int BtGattDescriptorCreate(string uuid, int permissions, byte[] value, int valueLength, out BluetoothGattAttributeHandle descriptorHandle);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_descriptor_get_permissions")]
+ internal static extern int BtGattDescriptorGetPermissions(BluetoothGattAttributeHandle descriptorHandle, out int permissions);
+
+ // GATT Characteristic
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_characteristic_create")]
+ internal static extern int BtGattCharacteristicCreate(string uuid, int permissions, int properties, byte[] value, int valueLength, out BluetoothGattAttributeHandle characteristicHandle);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_characteristic_get_permissions")]
+ internal static extern int BtGattCharacteristicGetPermissions(BluetoothGattAttributeHandle characteristicHandle, out int permissions);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_characteristic_get_properties")]
+ internal static extern int BtGattCharacteristicGetProperties(BluetoothGattAttributeHandle characteristicHandle, out int properties);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_characteristic_set_properties")]
+ internal static extern int BtGattCharacteristicSetProperties(BluetoothGattAttributeHandle characteristicHandle, int properties);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_characteristic_get_write_type")]
+ internal static extern int BtGattCharacteristicGetWriteType(BluetoothGattAttributeHandle characteristicHandle, out int writeType);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_characteristic_set_write_type")]
+ internal static extern int BtGattCharacteristicSetWriteType(BluetoothGattAttributeHandle characteristicHandle, int writeType);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_characteristic_add_descriptor")]
+ internal static extern int BtGattCharacteristicAddDescriptor(BluetoothGattAttributeHandle characteristicHandle, BluetoothGattAttributeHandle descriptorHandle);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_characteristic_get_descriptor")]
+ internal static extern int BtGattCharacteristicGetDescriptor(BluetoothGattAttributeHandle characteristicHandle, string uuid, out BluetoothGattAttributeHandle descriptorHandle);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_characteristic_foreach_descriptors")]
+ internal static extern int BtGattCharacteristicForeachDescriptors(BluetoothGattAttributeHandle characteristicHandle, BtGattForeachCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_client_set_characteristic_value_changed_cb")]
+ internal static extern int BtGattClientSetCharacteristicValueChangedCallback(BluetoothGattAttributeHandle characteristicHandle, BtClientCharacteristicValueChangedCallback cb, IntPtr userData);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_client_unset_characteristic_value_changed_cb")]
+ internal static extern int BtGattClientUnsetCharacteristicValueChangedCallback(BluetoothGattAttributeHandle characteristicHandle);
+
+ // GATT Service
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_service_create")]
+ internal static extern int BtGattServiceCreate(string uuid, int type, out BluetoothGattAttributeHandle serviceHandle);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_service_add_characteristic")]
+ internal static extern int BtGattServiceAddCharacteristic(BluetoothGattAttributeHandle serviceHandle, BluetoothGattAttributeHandle characteristicHandle);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_service_get_characteristic")]
+ internal static extern int BtGattServiceGetCharacteristic(BluetoothGattAttributeHandle serviceHandle, string uuid, out BluetoothGattAttributeHandle characteristicHandle);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_service_foreach_characteristics")]
+ internal static extern int BtGattServiceForeachCharacteristics(BluetoothGattAttributeHandle serviceHandle, BtGattForeachCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_service_add_included_service")]
+ internal static extern int BtGattServiceAddIncludedService(BluetoothGattAttributeHandle serviceHandle, BluetoothGattAttributeHandle includedServiceHandle);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_service_get_included_service")]
+ internal static extern int BtGattServiceGetIncludedService(BluetoothGattAttributeHandle serviceHandle, string uuid, out BluetoothGattAttributeHandle includedServiceHandle);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_service_foreach_included_services")]
+ internal static extern int BtGattServiceForeachIncludedServices(BluetoothGattAttributeHandle serviceHandle, BtGattForeachCallback callback, IntPtr userData);
+
+ // GATT Client
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_client_destroy")]
+ internal static extern int BtGattClientDestroy(IntPtr clientHandle);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_client_create")]
+ internal static extern int BtGattClientCreate(string remoteAddress, out BluetoothGattClientHandle clientHandle);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_client_get_remote_address")]
+ internal static extern int BtGattClientGetRemoteAddress(BluetoothGattClientHandle clientHandle, out string remoteAddress);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_client_get_service")]
+ internal static extern int BtGattClientGetService(BluetoothGattClientHandle clientHandle, string uuid, out BluetoothGattAttributeHandle serviceHandle);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_client_foreach_services")]
+ internal static extern int BtGattClientForeachServices(BluetoothGattClientHandle clientHandle, BtGattForeachCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_client_read_value")]
+ internal static extern int BtGattClientReadValue(BluetoothGattAttributeHandle gattHandle, BtGattClientRequestCompletedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_client_write_value")]
+ internal static extern int BtGattClientWriteValue(BluetoothGattAttributeHandle gattHandle, BtGattClientRequestCompletedCallback callback, IntPtr userData);
+
+ // GATT Server
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_destroy")]
+ internal static extern int BtGattServerDestroy(IntPtr serverHandle);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_create")]
+ internal static extern int BtGattServerCreate(out BluetoothGattServerHandle serverHandle);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_initialize")]
+ internal static extern int BtGattServerInitialize();
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_deinitialize")]
+ internal static extern int BtGattServerDeinitialize();
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_set_read_value_requested_cb")]
+ internal static extern int BtGattServerSetReadValueRequestedCallback(BluetoothGattAttributeHandle gattHandle, BtGattServerReadValueRequestedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_set_write_value_requested_cb")]
+ internal static extern int BtGattServerSetWriteValueRequestedCallback(BluetoothGattAttributeHandle gattHandle, BtGattServerWriteValueRequestedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_set_characteristic_notification_state_change_cb")]
+ internal static extern int BtGattServeSetNotificationStateChangeCallback(BluetoothGattAttributeHandle characteristicHandle, BtGattServerNotificationStateChangeCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_start")]
+ internal static extern int BtGattServerStart();
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_register_service")]
+ internal static extern int BtGattServerRegisterService(BluetoothGattServerHandle serverHandle, BluetoothGattAttributeHandle serviceHandle);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_unregister_service")]
+ internal static extern int BtGattServerUnregisterService(BluetoothGattServerHandle serverHandle, BluetoothGattAttributeHandle serviceHandle);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_unregister_all_services")]
+ internal static extern int BtGattServerUnregisterAllServices(BluetoothGattServerHandle serverHandle);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_get_service")]
+ internal static extern int BtGattServerGetService(BluetoothGattServerHandle serverHandle, string uuid, out BluetoothGattAttributeHandle serviceHandle);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_foreach_services")]
+ internal static extern int BtGattServerForeachServices(BluetoothGattServerHandle serverHandle, BtGattForeachCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_send_response")]
+ internal static extern int BtGattServerSendResponse(int requestId, int requestType, int offset, int status, byte[] value, int valueLen);
+
+ [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_notify_characteristic_changed_value")]
+ internal static extern int BtGattServerNotify(BluetoothGattAttributeHandle characteristicHandle, BtGattServerNotificationSentCallback callback, string clientAddress, IntPtr userData);
+ }
+}
+
+
diff --git a/src/Tizen.Network.Bluetooth/Interop/Interop.Glib.cs b/src/Tizen.Network.Bluetooth/Interop/Interop.Glib.cs
new file mode 100644
index 0000000..576a6e2
--- /dev/null
+++ b/src/Tizen.Network.Bluetooth/Interop/Interop.Glib.cs
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Glib
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool GSourceFunc(IntPtr userData);
+
+ [DllImport(Libraries.Glib, EntryPoint = "g_idle_add", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern uint IdleAdd(GSourceFunc d, IntPtr data);
+ }
+}
diff --git a/src/Tizen.Network.Bluetooth/Interop/Interop.Libc.cs b/src/Tizen.Network.Bluetooth/Interop/Interop.Libc.cs
new file mode 100644
index 0000000..825599e
--- /dev/null
+++ b/src/Tizen.Network.Bluetooth/Interop/Interop.Libc.cs
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Libc
+ {
+ [DllImport(Libraries.Libc, EntryPoint = "free", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int Free(IntPtr ptr);
+ }
+}
diff --git a/src/Tizen.Network.Bluetooth/Interop/Interop.Libraries.cs b/src/Tizen.Network.Bluetooth/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..4aa83d4
--- /dev/null
+++ b/src/Tizen.Network.Bluetooth/Interop/Interop.Libraries.cs
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string Bluetooth = "libcapi-network-bluetooth.so.0";
+ public const string Glib = "libglib-2.0.so.0";
+ public const string Libc = "libc.so.6";
+ }
+}
diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth.csproj b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth.csproj
new file mode 100644
index 0000000..e84e6f7
--- /dev/null
+++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth.csproj
@@ -0,0 +1,16 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ <ProjectReference Include="..\Tizen.System.Information\Tizen.System.Information.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
+
diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAdapter.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAdapter.cs
new file mode 100644
index 0000000..727bb46
--- /dev/null
+++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAdapter.cs
@@ -0,0 +1,459 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Network.Bluetooth
+{
+ /// <summary>
+ /// A class which is used to control a bluetooth adapter and get the list of bonded devices.<br>
+ /// The BluetoothAdapter class is used to discover neighbouring bluetooth devices.
+ /// </summary>
+ /// <privilege> http://tizen.org/privilege/bluetooth </privilege>
+ static public class BluetoothAdapter
+ {
+ /// <summary>
+ /// A property to check whether Bluetooth is enabled.
+ /// </summary>
+ static public bool IsBluetoothEnabled
+ {
+ get
+ {
+ return BluetoothAdapterImpl.Instance.IsBluetoothEnabled;
+ }
+ }
+
+ /// <summary>
+ /// The local adapter address.
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ static public string Address
+ {
+ get
+ {
+ if (IsBluetoothEnabled)
+ {
+ return BluetoothAdapterImpl.Instance.Address;
+ }
+ else
+ {
+ return null;
+ }
+ }
+ }
+
+ /// <summary>
+ /// The name of the local adapter.
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ static public string Name
+ {
+ get
+ {
+ if (IsBluetoothEnabled)
+ {
+ return BluetoothAdapterImpl.Instance.Name;
+ }
+ else
+ {
+ return null;
+ }
+ }
+ set
+ {
+ BluetoothAdapterImpl.Instance.Name = value;
+ }
+ }
+
+ /// <summary>
+ /// The visibility mode of the Bluetooth adapter.
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ static public VisibilityMode Visibility
+ {
+ get
+ {
+ if (IsBluetoothEnabled)
+ {
+ return BluetoothAdapterImpl.Instance.Visibility;
+ }
+ else
+ {
+ return VisibilityMode.NonDiscoverable;
+ }
+ }
+ }
+
+ /// <summary>
+ /// A property to check whether device discovery is in progress.
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ static public bool IsDiscoveryInProgress
+ {
+ get
+ {
+ if (IsBluetoothEnabled)
+ {
+ return BluetoothAdapterImpl.Instance.IsDiscoveryInProgress;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ /// <summary>
+ /// The remaining time, in seconds, until the visibility mode is changed from TimeLimitedDiscoverable to NonDiscoverable.
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ static public int RemainingTimeAsVisible
+ {
+ get
+ {
+ if (IsBluetoothEnabled)
+ {
+ return BluetoothAdapterImpl.Instance.RemainingTimeAsVisible;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ }
+
+ /// <summary>
+ /// (event) StateChanged is raised when bluetooth adapter state is changed.
+ /// </summary>
+ static public event EventHandler<StateChangedEventArgs> StateChanged
+ {
+ add
+ {
+ BluetoothAdapterImpl.Instance.StateChanged += value;
+ }
+ remove
+ {
+ BluetoothAdapterImpl.Instance.StateChanged -= value;
+ }
+ }
+
+ /// <summary>
+ /// (event) NameChanged is raised when bluetooth adapter name is changed.
+ /// </summary>
+ static public event EventHandler<NameChangedEventArgs> NameChanged
+ {
+ add
+ {
+ BluetoothAdapterImpl.Instance.NameChanged += value;
+ }
+ remove
+ {
+ BluetoothAdapterImpl.Instance.NameChanged -= value;
+ }
+ }
+
+ /// <summary>
+ /// (event) VisibilityModeChanged is raised when bluetooth adapter visibility mode is changed.
+ /// </summary>
+ static public event EventHandler<VisibilityModeChangedEventArgs> VisibilityModeChanged
+ {
+ add
+ {
+ BluetoothAdapterImpl.Instance.VisibilityModeChanged += value;
+ }
+ remove
+ {
+ BluetoothAdapterImpl.Instance.VisibilityModeChanged -= value;
+ }
+ }
+
+ /// <summary>
+ /// (event) VisibilityDurationChanged is raised very second until the visibility mode is changed to NonDiscoverable.
+ /// </summary>
+ static public event EventHandler<VisibilityDurationChangedEventArgs> VisibilityDurationChanged
+ {
+ add
+ {
+ BluetoothAdapterImpl.Instance.VisibilityDurationChanged += value;
+ }
+ remove
+ {
+ BluetoothAdapterImpl.Instance.VisibilityDurationChanged -= value;
+ }
+ }
+
+ /// <summary>
+ /// (event) DiscoveryStateChanged is raised when the device discovery state is changed.
+ /// </summary>
+ static public event EventHandler<DiscoveryStateChangedEventArgs> DiscoveryStateChanged
+ {
+ add
+ {
+ BluetoothAdapterImpl.Instance.DiscoveryStateChanged += value;
+ }
+ remove
+ {
+ BluetoothAdapterImpl.Instance.DiscoveryStateChanged -= value;
+ }
+ }
+
+ /// <summary>
+ /// Event that is called when the LE Scan result is obtained.
+ /// </summary>
+ static public event EventHandler<AdapterLeScanResultChangedEventArgs> ScanResultChanged
+ {
+ add
+ {
+ BluetoothLeImplAdapter.Instance.AdapterLeScanResultChanged += value;
+ }
+ remove {
+ BluetoothLeImplAdapter.Instance.AdapterLeScanResultChanged -= value;
+ }
+ }
+
+ /// <summary>
+ /// Starts the device discovery process.
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled and device discovery can be stopped by StopDiscovery().
+ /// If this succeeds, DiscoveryStateChanged event will be invoked.
+ /// </remarks>
+ static public void StartDiscovery()
+ {
+ if (IsBluetoothEnabled)
+ {
+ BluetoothAdapterImpl.Instance.StartDiscovery();
+ }
+ }
+
+ /// <summary>
+ /// Stops the device discovery process.
+ /// </summary>
+ /// <remarks>
+ /// The device discovery must be in progress with StartDiscovery().
+ /// If this succeeds, DiscoveryStateChanged event will be invoked.
+ /// </remarks>
+ static public void StopDiscovery()
+ {
+ if (IsDiscoveryInProgress)
+ {
+ BluetoothAdapterImpl.Instance.StopDiscovery();
+ }
+ }
+
+ /// <summary>
+ /// Retrieves the device information of all bonded devices.
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ /// <returns> List of Bonded BluetoothDeviceInfo objects.</returns>
+ static public IEnumerable<BluetoothDevice> GetBondedDevices()
+ {
+ if (IsBluetoothEnabled)
+ {
+ return BluetoothAdapterImpl.Instance.GetBondedDevices();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Gets the device information of a bonded device.
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ /// <returns> Information of bonded BluetoothDeviceInfo object.</returns>
+ static public BluetoothDevice GetBondedDevice(string address)
+ {
+ if (IsBluetoothEnabled)
+ {
+ return BluetoothAdapterImpl.Instance.GetBondedDevice(address);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Checks whether the UUID of service is used or not.
+ /// </summary>
+ /// <returns><c>true</c> if the specified serviceUuid is used; otherwise, <c>false</c>.</returns>
+ /// <param name="serviceUuid">The UUID of Service.</param>
+ static public bool IsServiceUsed(string serviceUuid)
+ {
+ return BluetoothAdapterImpl.Instance.IsServiceUsed(serviceUuid);
+ }
+
+ /// <summary>
+ /// Gets the hash and randomizer value of local oob data object.
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ /// <returns>The BluetoothOobData object.</returns>
+ static public BluetoothOobData GetLocalOobData()
+ {
+ if (IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ return BluetoothAdapterImpl.Instance.GetLocalOobData();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Sets the Hash and Randmoizer value of oob data into the remote device.
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ /// <param name="address">Remote Device address.</param>
+ /// <param name="oobData">BluetoothOobData object.</param>
+ static public void SetRemoteOobData(string address, BluetoothOobData oobData)
+ {
+ if (IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ BluetoothAdapterImpl.Instance.SetRemoteOobData(address, oobData);
+ }
+ }
+
+ /// <summary>
+ /// Removes the Hash and Randomizer value of oob data from the remote device.
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ /// <param name="address">Remote Device address.</param>
+ static public void RemoveRemoteOobData(string address)
+ {
+ if (IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ BluetoothAdapterImpl.Instance.RemoveRemoteOobData(address);
+ }
+ }
+
+ /// <summary>
+ /// Starts the Bluetooth Le scan operation to discover BLE devices
+ /// </summary>
+ /// <remarks>
+ /// Bluetooth must be enabled.
+ /// </remarks>the result of the operation StartLeScan
+ static public void StartLeScan()
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ int ret = BluetoothLeImplAdapter.Instance.StartScan ();
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to in start the le scan operation, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+ else
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
+ }
+ }
+
+ /// <summary>
+ /// Stops the Bluetooth Le scan operation.
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>the result of the operation stopLescan
+ static public void StopLeScan()
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ int ret = BluetoothLeImplAdapter.Instance.StopScan ();
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to stop the le scan operation, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+ else
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
+ }
+ }
+
+ /// <summary>
+ /// Returns BluetoothLeAdvertiser instance.
+ /// </summary>
+ /// <remarks>
+ /// The bluetooth must be enabled before calling this API.
+ /// </remarks>
+ /// <returns>The BluetoothLeAdvertiser instance.</returns>
+ static public BluetoothLeAdvertiser GetBluetoothLeAdvertiser()
+ {
+ return BluetoothLeAdvertiser.Instance;
+ }
+
+ /// <summary>
+ /// Registers a rfcomm server socket with a specific UUID.
+ /// </summary>
+ /// <remarks>
+ /// The bluetooth must be enabled before calling this API.
+ /// </remarks>
+ /// <returns>The BluetoothServerSocket instance.</returns>
+ /// <param name="serviceUuid">The UUID of service to provide.</param>
+ static public BluetoothServerSocket CreateServerSocket(string serviceUuid)
+ {
+ if (IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ return BluetoothAdapterImpl.Instance.CreateServerSocket (serviceUuid);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Removes the rfcomm server socket which was created using CreateServerSocket().
+ /// </summary>
+ /// <remarks>
+ /// The socket must be created with CreateServerSocket(). ConnectionStateChanged event is raised after this API is called.
+ /// </remarks>
+ /// <param name="socket">The server socket instance which is created using CreateServerSocket().</param>
+ static public void DestroyServerSocket(BluetoothServerSocket socket)
+ {
+ if (IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ BluetoothAdapterImpl.Instance.DestroyServerSocket(socket);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAdapterImpl.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAdapterImpl.cs
new file mode 100644
index 0000000..92c4b0a
--- /dev/null
+++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAdapterImpl.cs
@@ -0,0 +1,636 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Network.Bluetooth
+{
+ static internal class Globals
+ {
+ internal const string LogTag = "Tizen.Network.Bluetooth";
+ internal static bool IsInitialize = false;
+ internal static bool IsAudioInitialize = false;
+ internal static bool IsHidInitialize = false;
+ }
+
+ internal partial class BluetoothAdapterImpl : IDisposable
+ {
+ private event EventHandler<StateChangedEventArgs> _stateChanged;
+ private event EventHandler<NameChangedEventArgs> _nameChanged;
+ private event EventHandler<VisibilityModeChangedEventArgs> _visibilityModeChanged;
+ private event EventHandler<VisibilityDurationChangedEventArgs> _visibilityDurationChanged;
+ private event EventHandler<DiscoveryStateChangedEventArgs> _discoveryStateChanged;
+
+ private Interop.Bluetooth.StateChangedCallback _stateChangedCallback;
+ private Interop.Bluetooth.NameChangedCallback _nameChangedCallback;
+ private Interop.Bluetooth.VisibilityModeChangedCallback _visibilityChangedCallback;
+ private Interop.Bluetooth.VisibilityDurationChangedCallback _visibilitydurationChangedCallback;
+ private Interop.Bluetooth.DiscoveryStateChangedCallback _discoveryStateChangedCallback;
+
+ private static readonly BluetoothAdapterImpl _instance = new BluetoothAdapterImpl();
+ private bool disposed = false;
+
+ internal event EventHandler<StateChangedEventArgs> StateChanged
+ {
+ add
+ {
+ if (_stateChanged == null)
+ {
+ RegisterStateChangedEvent();
+ }
+ _stateChanged += value;
+ }
+ remove
+ {
+ _stateChanged -= value;
+ if (_stateChanged == null)
+ {
+ UnregisterStateChangedEvent();
+ }
+ }
+ }
+
+ internal event EventHandler<NameChangedEventArgs> NameChanged
+ {
+ add
+ {
+ if (_nameChanged == null)
+ {
+ RegisterNameChangedEvent();
+ }
+ _nameChanged += value;
+ }
+ remove
+ {
+ _nameChanged -= value;
+ if (_nameChanged == null)
+ {
+ UnregisterNameChangedEvent();
+ }
+ }
+ }
+
+ internal event EventHandler<VisibilityModeChangedEventArgs> VisibilityModeChanged
+ {
+ add
+ {
+ if (_visibilityModeChanged == null)
+ {
+ RegisterVisibilityChangedEvent();
+ }
+ _visibilityModeChanged += value;
+ }
+ remove
+ {
+ _visibilityModeChanged -= value;
+ if (_visibilityModeChanged == null)
+ {
+ UnregisterVisibilityChangedEvent();
+ }
+ }
+ }
+
+ internal event EventHandler<VisibilityDurationChangedEventArgs> VisibilityDurationChanged
+ {
+ add
+ {
+ if (_visibilityDurationChanged == null)
+ {
+ RegisterVisibilityDurationChangedEvent();
+ }
+ _visibilityDurationChanged += value;
+ }
+ remove
+ {
+ _visibilityDurationChanged -= value;
+ if (_visibilityDurationChanged == null)
+ {
+ UnregisterVisibilityDurationChangedEvent();
+ }
+ }
+ }
+
+ internal event EventHandler<DiscoveryStateChangedEventArgs> DiscoveryStateChanged
+ {
+ add
+ {
+ if (_discoveryStateChanged == null)
+ {
+ RegisterDiscoveryStateChangedEvent();
+ }
+ _discoveryStateChanged+= value;
+ }
+ remove
+ {
+ _discoveryStateChanged -= value;
+ if (_discoveryStateChanged == null)
+ {
+ UnregisterDiscoveryStateChangedEvent();
+ }
+ }
+ }
+
+ private void RegisterStateChangedEvent()
+ {
+ _stateChangedCallback = (int result, int state, IntPtr userData) =>
+ {
+ if (_stateChanged != null)
+ {
+ BluetoothState st = (BluetoothState)state;
+ BluetoothError res = (BluetoothError)result;
+ _stateChanged(null, new StateChangedEventArgs(res,st));
+ }
+ };
+ int ret = Interop.Bluetooth.SetStateChangedCallback(_stateChangedCallback, IntPtr.Zero);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set state changed callback, Error - " + (BluetoothError)ret);
+ }
+ }
+
+ private void UnregisterStateChangedEvent()
+ {
+ int ret = Interop.Bluetooth.UnsetStateChangedCallback();
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset state changed callback, Error - " + (BluetoothError)ret);
+ }
+ }
+
+ private void RegisterNameChangedEvent()
+ {
+ _nameChangedCallback = (string deviceName, IntPtr userData) =>
+ {
+ if (_nameChanged != null)
+ {
+ _nameChanged(null, new NameChangedEventArgs(deviceName));
+ }
+ };
+ int ret = Interop.Bluetooth.SetNameChangedCallback(_nameChangedCallback, IntPtr.Zero);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set name changed callback, Error - " + (BluetoothError)ret);
+ }
+ }
+
+ private void UnregisterNameChangedEvent()
+ {
+ int ret = Interop.Bluetooth.UnsetNameChangedCallback();
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset name changed callback, Error - " + (BluetoothError)ret);
+ }
+ }
+
+ private void RegisterVisibilityChangedEvent()
+ {
+ _visibilityChangedCallback = (int result, int mode, IntPtr userData) =>
+ {
+ if (_visibilityModeChanged != null)
+ {
+ VisibilityMode visibility = (VisibilityMode)mode;
+ BluetoothError res = (BluetoothError)result;
+ _visibilityModeChanged(null, new VisibilityModeChangedEventArgs(res,visibility));
+ }
+ };
+ int ret = Interop.Bluetooth.SetVisibilityModeChangedCallback(_visibilityChangedCallback, IntPtr.Zero);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set visibility mode changed callback, Error - " + (BluetoothError)ret);
+ }
+ }
+
+ private void UnregisterVisibilityChangedEvent()
+ {
+ int ret = Interop.Bluetooth.UnsetVisibilityModeChangedCallback();
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset visibility mode changed callback, Error - " + (BluetoothError)ret);
+ }
+ }
+
+ private void RegisterVisibilityDurationChangedEvent()
+ {
+ _visibilitydurationChangedCallback = (int duration, IntPtr userData) =>
+ {
+ if (_visibilityDurationChanged != null)
+ {
+ _visibilityDurationChanged(null, new VisibilityDurationChangedEventArgs(duration));
+ }
+ };
+ int ret = Interop.Bluetooth.SetVisibilityDurationChangedCallback(_visibilitydurationChangedCallback, IntPtr.Zero);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set visibility duration changed callback, Error - " + (BluetoothError)ret);
+ }
+ }
+
+ private void UnregisterVisibilityDurationChangedEvent()
+ {
+ int ret = Interop.Bluetooth.UnsetVisibilityDurationChangedCallback();
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset visiiblity duration changed callback, Error - " + (BluetoothError)ret);
+ }
+ }
+
+ private void RegisterDiscoveryStateChangedEvent()
+ {
+ _discoveryStateChangedCallback = (int result, BluetoothDeviceDiscoveryState state, IntPtr deviceInfo, IntPtr userData) =>
+ {
+ Log.Info(Globals.LogTag, "Discovery state changed callback is called");
+ if (_discoveryStateChanged != null)
+ {
+ BluetoothError res = (BluetoothError)result;
+ switch(state)
+ {
+ case BluetoothDeviceDiscoveryState.Started:
+ _discoveryStateChanged(null, new DiscoveryStateChangedEventArgs(res,state));
+ break;
+ case BluetoothDeviceDiscoveryState.Finished:
+ {
+ _discoveryStateChanged(null, new DiscoveryStateChangedEventArgs(res,state));
+ break;
+ }
+ case BluetoothDeviceDiscoveryState.Found:
+ {
+ BluetoothDiscoveredDeviceStruct info = (BluetoothDiscoveredDeviceStruct)Marshal.PtrToStructure(deviceInfo, typeof(BluetoothDiscoveredDeviceStruct));
+ _discoveryStateChanged(null, new DiscoveryStateChangedEventArgs(res,state,BluetoothUtils.ConvertStructToDiscoveredDevice(info)));
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ };
+ int ret = Interop.Bluetooth.SetDiscoveryStateChangedCallback(_discoveryStateChangedCallback, IntPtr.Zero);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set discovery state changed callback, Error - " + (BluetoothError)ret);
+ }
+ }
+
+ private void UnregisterDiscoveryStateChangedEvent()
+ {
+ int ret = Interop.Bluetooth.UnsetDiscoveryStateChangedCallback();
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset discovery state changed callback, Error - " + (BluetoothError)ret);
+ }
+ }
+
+ internal bool IsBluetoothEnabled
+ {
+ get
+ {
+ BluetoothState active;
+ int ret = Interop.Bluetooth.GetState(out active);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get state, Error - " + (BluetoothError)ret);
+ }
+ if (active == BluetoothState.Enabled)
+ return true;
+ else
+ return false;
+ }
+ }
+ internal string Address
+ {
+ get
+ {
+ string address;
+ int ret = Interop.Bluetooth.GetAddress(out address);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get address, Error - " + (BluetoothError)ret);
+ return "";
+ }
+ return address;
+ }
+ }
+
+ internal VisibilityMode Visibility
+ {
+ get
+ {
+ int visibilityMode;
+ int time;
+ int ret = Interop.Bluetooth.GetVisibility(out visibilityMode, out time);
+ if(ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get visibility mode, Error - " + (BluetoothError)ret);
+ return VisibilityMode.NonDiscoverable;
+ }
+ return (VisibilityMode)visibilityMode;
+ }
+ }
+
+ internal bool IsDiscoveryInProgress
+ {
+ get
+ {
+ bool isDiscovering;
+ int ret = Interop.Bluetooth.IsDiscovering(out isDiscovering);
+ if(ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get discovery progress state, Error - " + (BluetoothError)ret);
+ }
+ return isDiscovering;
+ }
+ }
+
+ internal int RemainingTimeAsVisible
+ {
+ get
+ {
+ int duration = 0;
+ int visibilityMode;
+ int ret = Interop.Bluetooth.GetVisibility(out visibilityMode, out duration);
+ if ((ret != (int)BluetoothError.None) || ((VisibilityMode)visibilityMode != VisibilityMode.TimeLimitedDiscoverable))
+ {
+ Log.Error(Globals.LogTag, "Failed to get remaining visible time, Error - " + (BluetoothError)ret);
+ }
+ return duration;
+ }
+ }
+
+ internal string Name
+ {
+ get
+ {
+ string name;
+ int ret = Interop.Bluetooth.GetName(out name);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get adapter name, Error - " + (BluetoothError)ret);
+ return "";
+ }
+ return name;
+ }
+ set
+ {
+ int ret = Interop.Bluetooth.SetName(value.ToString());
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set adapter name, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+ }
+
+ internal void StartDiscovery()
+ {
+ int ret = Interop.Bluetooth.StartDiscovery();
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to start discovery, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+
+ internal void StopDiscovery()
+ {
+ int ret = Interop.Bluetooth.StopDiscovery();
+ if(ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to stop discovery, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+
+ internal IEnumerable<BluetoothDevice> GetBondedDevices()
+ {
+ List<BluetoothDevice> deviceList = new List<BluetoothDevice>();
+ Interop.Bluetooth.BondedDeviceCallback callback = (ref BluetoothDeviceStruct deviceInfo, IntPtr userData) =>
+ {
+ Log.Info(Globals.LogTag, "Bonded devices cb is called");
+ if(!deviceInfo.Equals(null))
+ {
+ deviceList.Add(BluetoothUtils.ConvertStructToDeviceClass(deviceInfo));
+ }
+ return true;
+ };
+ int ret = Interop.Bluetooth.GetBondedDevices(callback, IntPtr.Zero);
+ if(ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get bonded devices, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ return deviceList;
+ }
+
+ internal BluetoothDevice GetBondedDevice(string address)
+ {
+ IntPtr deviceInfo;
+ int ret = Interop.Bluetooth.GetBondedDeviceByAddress(address, out deviceInfo);
+ if(ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get bonded device by address, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ BluetoothDeviceStruct device = (BluetoothDeviceStruct)Marshal.PtrToStructure(deviceInfo, typeof(BluetoothDeviceStruct));
+
+ return BluetoothUtils.ConvertStructToDeviceClass(device);
+ }
+
+ internal bool IsServiceUsed(string serviceUuid)
+ {
+ bool isUsed;
+ int ret = Interop.Bluetooth.IsServiceUsed(serviceUuid, out isUsed);
+ if(ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to check the usage of service, Error - " + (BluetoothError)ret);
+ }
+ return isUsed;
+ }
+
+ internal BluetoothOobData GetLocalOobData()
+ {
+ BluetoothOobData oobData = new BluetoothOobData();
+ IntPtr hash;
+ IntPtr randomizer;
+ int hashLength;
+ int randomizerLength;
+ int ret = Interop.Bluetooth.GetOobData(out hash, out randomizer, out hashLength, out randomizerLength);
+ if(ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get the local oob data, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+
+ byte[] hashArr = new byte[hashLength];
+ Marshal.Copy(hash, hashArr, 0, hashLength);
+ byte[] randomizerArr = new byte[randomizerLength];
+ Marshal.Copy(randomizer, randomizerArr, 0, randomizerLength);
+
+ oobData.HashValue = hashArr;
+ oobData.RandomizerValue = randomizerArr;
+ return oobData;
+ }
+
+ internal void SetRemoteOobData(string deviceAddress, BluetoothOobData oobData)
+ {
+ byte[] hash = oobData.HashValue;
+ byte[] randomizer = oobData.RandomizerValue;
+ int hashLength = hash.Length;
+ int randomizerLength = randomizer.Length;
+
+ IntPtr hashPtr = Marshal.AllocHGlobal(hashLength);
+ Marshal.Copy(hash, 0, hashPtr, hashLength);
+ IntPtr randomizerPtr = Marshal.AllocHGlobal(randomizerLength);
+ Marshal.Copy(randomizer, 0, randomizerPtr, randomizerLength);
+
+ int ret = Interop.Bluetooth.SetOobData(deviceAddress, hashPtr, randomizerPtr, hashLength, randomizerLength);
+ if(ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set the remote oob data, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+
+ internal void RemoveRemoteOobData(string deviceAddress)
+ {
+ int ret = Interop.Bluetooth.RemoveOobData(deviceAddress);
+ if(ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to remove the remote oob data, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+
+ internal BluetoothServerSocket CreateServerSocket(string serviceUuid)
+ {
+ int socketFd;
+ int ret = Interop.Bluetooth.CreateServerSocket(serviceUuid, out socketFd);
+ if(ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to create server socket, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ Log.Info (Globals.LogTag, "Created socketfd: "+ socketFd);
+ return new BluetoothServerSocket(socketFd);
+ }
+
+ internal void DestroyServerSocket(BluetoothServerSocket socket)
+ {
+ int ret = Interop.Bluetooth.DestroyServerSocket(socket.socketFd);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to destroy socket, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+
+ internal static BluetoothAdapterImpl Instance
+ {
+ get
+ {
+ return _instance;
+ }
+ }
+
+ private BluetoothAdapterImpl()
+ {
+ initialize();
+ }
+
+ ~BluetoothAdapterImpl()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects.
+ }
+ //Free unmanaged objects
+ RemoveAllRegisteredEvent();
+ deinitialize();
+ disposed = true;
+ }
+
+ private void initialize()
+ {
+ int ret = Interop.Bluetooth.Initialize();
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error (Globals.LogTag, "Failed to initialize bluetooth, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException (ret);
+ }
+ else
+ {
+ Globals.IsInitialize = true;
+ }
+ }
+
+ private void deinitialize()
+ {
+ int ret = Interop.Bluetooth.Deinitialize();
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error (Globals.LogTag, "Failed to deinitialize bluetooth, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException (ret);
+ }
+ else
+ {
+ Globals.IsInitialize = false;
+ }
+ }
+
+ private void RemoveAllRegisteredEvent()
+ {
+ //unregister all remaining events when this object is released.
+ if (_stateChanged != null)
+ {
+ UnregisterStateChangedEvent();
+ }
+
+ if (_nameChanged != null)
+ {
+ UnregisterNameChangedEvent();
+ }
+
+ if (_visibilityDurationChanged != null)
+ {
+ UnregisterVisibilityDurationChangedEvent();
+ }
+
+ if (_visibilityModeChanged != null)
+ {
+ UnregisterVisibilityChangedEvent();
+ }
+
+ if (_discoveryStateChanged != null)
+ {
+ UnregisterDiscoveryStateChangedEvent();
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAudio.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAudio.cs
new file mode 100644
index 0000000..d66a401
--- /dev/null
+++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAudio.cs
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Network.Bluetooth
+{
+ /// <summary>
+ /// A class which is used to handle the connection with other Bluetooth audio devices
+ /// like headset, hands-free and headphone.
+ /// </summary>
+ /// <privilege> http://tizen.org/privilege/bluetooth </privilege>
+ public class BluetoothAudio : BluetoothProfile
+ {
+ internal BluetoothAudio()
+ {
+ }
+
+ /// <summary>
+ /// (event) AudioConnectionStateChanged is called when audio connection state is changed.
+ /// </summary>
+ public event EventHandler<AudioConnectionStateChangedEventArgs> AudioConnectionStateChanged
+ {
+ add
+ {
+ BluetoothAudioImpl.Instance.AudioConnectionStateChanged += value;
+ }
+ remove
+ {
+ BluetoothAudioImpl.Instance.AudioConnectionStateChanged -= value;
+ }
+ }
+
+ /// <summary>
+ /// Connect the remote device with the given audio profile.
+ /// </summary>
+ /// <remarks>
+ /// The device must be bonded with remote device by CreateBond().If connection request succeeds, AudioConnectionStateChanged event will be invoked.
+ /// If audio profile type is All and this request succeeds, then AudioConnectionStateChanged event will be called twice when HspHfp <br>
+ /// and AdvancedAudioDistribution is connected.
+ /// </remarks>
+ /// <param name="profileType">Type of audio profile.</param>
+ public void Connect(BluetoothAudioProfileType profileType)
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ int ret = BluetoothAudioImpl.Instance.Connect(RemoteAddress, profileType);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to Connect - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+ else
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
+ }
+ }
+
+ /// <summary>
+ /// Disconnects the remote device with the given audio profile.
+ /// </summary>
+ /// <remarks>
+ /// The device must be connected by Connect().If the disconnection request succeeds, AudioConnectionStateChanged event will be invoked.
+ /// If audio profile type is All and this request succeeds, then AudioConnectionStateChanged event will be called twice when HspHfp <br>
+ /// and AdvancedAudioDistribution is disconnected.
+ /// </remarks>
+ /// <param name="type">Type of audio profile.</param>
+ public void Disconnect(BluetoothAudioProfileType type)
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ int ret = BluetoothAudioImpl.Instance.Disconnect(RemoteAddress, type);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to Disconnect - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+ else
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAudioImpl.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAudioImpl.cs
new file mode 100644
index 0000000..eeb1977
--- /dev/null
+++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAudioImpl.cs
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Network.Bluetooth
+{
+ internal class BluetoothAudioImpl : IDisposable
+ {
+ private event EventHandler<AudioConnectionStateChangedEventArgs> _audioConnectionChanged;
+ private Interop.Bluetooth.AudioConnectionStateChangedCallback _audioConnectionChangedCallback;
+
+ private static readonly BluetoothAudioImpl _instance = new BluetoothAudioImpl();
+ private bool disposed = false;
+
+ internal event EventHandler<AudioConnectionStateChangedEventArgs> AudioConnectionStateChanged
+ {
+ add
+ {
+ if (_audioConnectionChanged == null)
+ {
+ RegisterAudioConnectionChangedEvent();
+ }
+ _audioConnectionChanged += value;
+ }
+ remove
+ {
+ _audioConnectionChanged -= value;
+ if (_audioConnectionChanged == null)
+ {
+ UnregisterAudioConnectionChangedEvent();
+ }
+ }
+ }
+
+ private void RegisterAudioConnectionChangedEvent()
+ {
+ _audioConnectionChangedCallback = (int result, bool connected, string deviceAddress, int profileType, IntPtr userData) =>
+ {
+ if (_audioConnectionChanged != null)
+ {
+ _audioConnectionChanged(null, new AudioConnectionStateChangedEventArgs(result, connected, deviceAddress, (BluetoothAudioProfileType)profileType));
+ }
+ };
+ int ret = Interop.Bluetooth.SetAudioConnectionStateChangedCallback(_audioConnectionChangedCallback, IntPtr.Zero);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set audio connection changed callback, Error - " + (BluetoothError)ret);
+ }
+ }
+
+ private void UnregisterAudioConnectionChangedEvent()
+ {
+ int ret = Interop.Bluetooth.UnsetAudioConnectionStateChangedCallback();
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset audio connection changed callback, Error - " + (BluetoothError)ret);
+ }
+ }
+
+ internal int Connect(string deviceAddress, BluetoothAudioProfileType type)
+ {
+ int ret = Interop.Bluetooth.Connect(deviceAddress, (int)type);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to connect device with the given profile type, Error - " + (BluetoothError)ret);
+ }
+ return ret;
+ }
+
+ internal int Disconnect(string deviceAddress, BluetoothAudioProfileType type)
+ {
+ int ret = Interop.Bluetooth.Disconnect(deviceAddress, (int)type);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to disconnect device with the given profile type, Error - " + (BluetoothError)ret);
+ }
+ return ret;
+ }
+
+ internal static BluetoothAudioImpl Instance
+ {
+ get
+ {
+ return _instance;
+ }
+ }
+
+ private BluetoothAudioImpl ()
+ {
+ Log.Info(Globals.LogTag, "Initializing audio");
+ initialize();
+ }
+
+ ~BluetoothAudioImpl()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects.
+ }
+ //Free unmanaged objects
+ deinitialize();
+ RemoveAllRegisteredEvent();
+ disposed = true;
+ }
+
+ private void initialize()
+ {
+ if (Globals.IsInitialize)
+ {
+ int ret = Interop.Bluetooth.InitializeAudio ();
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to initialize bluetoothaudio, Error - " + (BluetoothError)ret);
+ Globals.IsAudioInitialize = false;
+ BluetoothErrorFactory.ThrowBluetoothException (ret);
+ }
+ else
+ {
+ Globals.IsAudioInitialize = true;
+ }
+ }
+ else
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotInitialized);
+ }
+ }
+
+ private void deinitialize()
+ {
+ if (Globals.IsAudioInitialize) {
+ int ret = Interop.Bluetooth.DeinitializeAudio ();
+ if (ret != (int)BluetoothError.None) {
+ Log.Error (Globals.LogTag, "Failed to deinitialize bluetoothaudio, Error - " + (BluetoothError)ret);
+ }
+ }
+ }
+
+ private void RemoveAllRegisteredEvent()
+ {
+ if (_audioConnectionChanged != null)
+ {
+ UnregisterAudioConnectionChangedEvent();
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAvrcp.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAvrcp.cs
new file mode 100644
index 0000000..f83ad82
--- /dev/null
+++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAvrcp.cs
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Network.Bluetooth
+{
+ /// <summary>
+ /// A class which is used to notify changes of the target device(e.g.media player) to the control device(e.g.headset).
+ /// </summary>
+ /// <privilege> http://tizen.org/privilege/bluetooth </privilege>
+ public class BluetoothAvrcp : BluetoothProfile
+ {
+ internal BluetoothAvrcp()
+ {
+ }
+
+ /// <summary>
+ /// (event) TargetConnectionStateChanged is invoked when the connection state is changed.
+ /// </summary>
+ public event EventHandler<TargetConnectionStateChangedEventArgs> TargetConnectionStateChanged
+ {
+ add
+ {
+ BluetoothAvrcpImpl.Instance.TargetConnectionStateChanged += value;
+ }
+ remove
+ {
+ BluetoothAvrcpImpl.Instance.TargetConnectionStateChanged -= value;
+ }
+ }
+
+ /// <summary>
+ /// (event) EqualizerStateChanged is invoked when the equalizer state is changed by the remote control device.
+ /// </summary>
+ public event EventHandler<EqualizerStateChangedEventArgs> EqualizerStateChanged
+ {
+ add
+ {
+ BluetoothAvrcpImpl.Instance.EqualizerStateChanged += value;
+ }
+ remove
+ {
+ BluetoothAvrcpImpl.Instance.EqualizerStateChanged -= value;
+ }
+ }
+
+ /// <summary>
+ /// (event) RepeatModeChanged is invoked when the repeat mode is changed by the remote control device.
+ /// </summary>
+ public event EventHandler<RepeatModeChangedEventArgs> RepeatModeChanged
+ {
+ add
+ {
+ BluetoothAvrcpImpl.Instance.RepeatModeChanged += value;
+ }
+ remove
+ {
+ BluetoothAvrcpImpl.Instance.RepeatModeChanged -= value;
+ }
+ }
+
+ /// <summary>
+ /// (event) ShuffleModeChanged is invoked when the shuffle mode is changed by the remote control device.
+ /// </summary>
+ public event EventHandler<ShuffleModeChangedeventArgs> ShuffleModeChanged
+ {
+ add
+ {
+ BluetoothAvrcpImpl.Instance.ShuffleModeChanged += value;
+ }
+ remove
+ {
+ BluetoothAvrcpImpl.Instance.ShuffleModeChanged -= value;
+ }
+ }
+
+ /// <summary>
+ /// (event) ScanModeChanged is invoked when the scan mode is changed by the remote control device.
+ /// </summary>
+ public event EventHandler<ScanModeChangedEventArgs> ScanModeChanged
+ {
+ add
+ {
+ BluetoothAvrcpImpl.Instance.ScanModeChanged += value;
+ }
+ remove
+ {
+ BluetoothAvrcpImpl.Instance.ScanModeChanged -= value;
+ }
+ }
+
+ /// <summary>
+ /// Notifies the equalize state to the remote device.
+ /// </summary>
+ /// <remarks>
+ /// The remote device must be connected.
+ /// </remarks>
+ /// <param name="state">Equalizer state.</param>
+ public void NotifyEqualizerState(EqualizerState state)
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ BluetoothAvrcpImpl.Instance.NotifyEqualizeState(state);
+ }
+ else
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
+ }
+ }
+
+ /// <summary>
+ /// Notifies the repeat mode to the remote device.
+ /// </summary>
+ /// <remarks>
+ /// The remote device must be connected.
+ /// </remarks>
+ /// <param name="mode">Repeat mode.</param>
+ public void NotifyRepeatMode(RepeatMode mode)
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ BluetoothAvrcpImpl.Instance.NotifyRepeatMode(mode);
+ }
+ else
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
+ }
+ }
+
+ /// <summary>
+ /// Notifies the shuffle mode to the remote device.
+ /// </summary>
+ /// <remarks>
+ /// The remote device must be connected.
+ /// </remarks>
+ /// <param name="mode">Shuffle mode.</param>
+ public void NotifyShuffleMode(ShuffleMode mode)
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ BluetoothAvrcpImpl.Instance.NotifyShuffleMode(mode);
+ }
+ else
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
+ }
+ }
+
+ /// <summary>
+ /// Notifies the scan mode to the remote device.
+ /// </summary>
+ /// <remarks>
+ /// The remote device must be connected.
+ /// </remarks>
+ /// <param name="mode">Scan mode.</param>
+ public void NotifyScanMode(ScanMode mode)
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ BluetoothAvrcpImpl.Instance.NotifyScanMode(mode);
+ }
+ else
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
+ }
+ }
+
+ /// <summary>
+ /// Notifies the player state to the remote device.
+ /// </summary>
+ /// <remarks>
+ /// The remote device must be connected.
+ /// </remarks>
+ /// <param name="state">Player state.</param>
+ public void NotifyPlayerState(PlayerState state)
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ BluetoothAvrcpImpl.Instance.NotifyPlayerState(state);
+ }
+ else
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
+ }
+ }
+
+ /// <summary>
+ /// Notifies the current position of song to the remote device.
+ /// </summary>
+ /// <remarks>
+ /// The remote device must be connected.
+ /// </remarks>
+ /// <param name="position">Current position in milliseconds.</param>
+ public void NotifyCurrentPosition(uint position)
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ BluetoothAvrcpImpl.Instance.NotifyCurrentPosition(position);
+ }
+ else
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
+ }
+ }
+
+ /// <summary>
+ /// Notifies the track to the remote device.
+ /// </summary>
+ /// <remarks>
+ /// The remote device must be connected.
+ /// </remarks>
+ /// <param name="trackData">Data of the track.</param>
+ public void NotifyTrack(Track trackData)
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ BluetoothAvrcpImpl.Instance.NotifyTrack(trackData);
+ }
+ else
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
+ }
+ }
+ }
+}
+
diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAvrcpImpl.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAvrcpImpl.cs
new file mode 100644
index 0000000..b9606bd
--- /dev/null
+++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAvrcpImpl.cs
@@ -0,0 +1,419 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Network.Bluetooth
+{
+ internal class BluetoothAvrcpImpl : IDisposable
+ {
+ private event EventHandler<TargetConnectionStateChangedEventArgs> _targetConnectionChanged;
+ private event EventHandler<EqualizerStateChangedEventArgs> _equalizerStateChanged;
+ private event EventHandler<RepeatModeChangedEventArgs> _repeatModeChanged;
+ private event EventHandler<ScanModeChangedEventArgs> _scanModeChanged;
+ private event EventHandler<ShuffleModeChangedeventArgs> _shuffleModeChanged;
+
+ private Interop.Bluetooth.TargetConnectionStateChangedCallback _targetConnectionChangedCallback;
+ private Interop.Bluetooth.EqualizerStateChangedCallback _equalizerStateChangedCallback;
+ private Interop.Bluetooth.RepeatModeChangedCallback _repeatModeChangedCallback;
+ private Interop.Bluetooth.ShuffleModeChangedCallback _shuffleModeChangedCallback;
+ private Interop.Bluetooth.ScanModeChangedCallback _scanModeChangedCallback;
+
+ private static BluetoothAvrcpImpl _instance = new BluetoothAvrcpImpl();
+ private bool disposed = false;
+
+ internal event EventHandler<TargetConnectionStateChangedEventArgs> TargetConnectionStateChanged
+ {
+ add
+ {
+ _targetConnectionChanged += value;
+ }
+ remove
+ {
+ _targetConnectionChanged -= value;
+ }
+ }
+
+ internal event EventHandler<EqualizerStateChangedEventArgs> EqualizerStateChanged
+ {
+ add
+ {
+ if (_equalizerStateChanged == null)
+ {
+ RegisterEqualizerStateChangedEvent();
+ }
+ _equalizerStateChanged += value;
+ }
+ remove
+ {
+ _equalizerStateChanged -= value;
+ if (_equalizerStateChanged == null)
+ {
+ UnregisterEqualizerStateChangedEvent();
+ }
+ }
+ }
+
+ internal event EventHandler<RepeatModeChangedEventArgs> RepeatModeChanged
+ {
+ add
+ {
+ if (_repeatModeChanged == null)
+ {
+ RegisterRepeatModeChangedEvent();
+ }
+ _repeatModeChanged += value;
+ }
+ remove
+ {
+ _repeatModeChanged -= value;
+ if (_repeatModeChanged == null)
+ {
+ UnregisterRepeatModeChangedEvent();
+ }
+ }
+ }
+
+ internal event EventHandler<ShuffleModeChangedeventArgs> ShuffleModeChanged
+ {
+ add
+ {
+ if (_shuffleModeChanged == null)
+ {
+ RegisterShuffleModeChangedEvent();
+ }
+ _shuffleModeChanged += value;
+ }
+ remove
+ {
+ _shuffleModeChanged -= value;
+ if (_shuffleModeChanged == null)
+ {
+ UnregisterShuffleModeChangedEvent();
+ }
+ }
+ }
+
+ internal event EventHandler<ScanModeChangedEventArgs> ScanModeChanged
+ {
+ add
+ {
+ if (_scanModeChanged == null)
+ {
+ RegisterScanModeChangedEvent();
+ }
+ _scanModeChanged += value;
+ }
+ remove
+ {
+ _scanModeChanged -= value;
+ if (_scanModeChanged == null)
+ {
+ UnregisterScanModeChangedEvent();
+ }
+ }
+ }
+
+ private void RegisterEqualizerStateChangedEvent()
+ {
+ _equalizerStateChangedCallback = (int equalizer, IntPtr userData) =>
+ {
+ if (_equalizerStateChanged != null)
+ {
+ EqualizerState state = (EqualizerState) equalizer;
+ _equalizerStateChanged(null, new EqualizerStateChangedEventArgs(state));
+ }
+ };
+ int ret = Interop.Bluetooth.SetEqualizerStateChangedCallback(_equalizerStateChangedCallback, IntPtr.Zero);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set equalizer state changed callback, Error - " + (BluetoothError)ret);
+ }
+ }
+ private void UnregisterEqualizerStateChangedEvent()
+ {
+ int ret = Interop.Bluetooth.UnsetEqualizerStateChangedCallback();
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset equalizer state changed callback, Error - " + (BluetoothError)ret);
+ }
+ }
+
+ private void RegisterRepeatModeChangedEvent()
+ {
+ _repeatModeChangedCallback = (int repeat, IntPtr userData) =>
+ {
+ if (_repeatModeChanged != null)
+ {
+ RepeatMode mode = (RepeatMode)repeat;
+ _repeatModeChanged(null, new RepeatModeChangedEventArgs(mode));
+ }
+ };
+ int ret = Interop.Bluetooth.SetRepeatModeChangedCallback(_repeatModeChangedCallback, IntPtr.Zero);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set repeat mode changed callback, Error - " + (BluetoothError)ret);
+ }
+ }
+ private void UnregisterRepeatModeChangedEvent()
+ {
+ int ret = Interop.Bluetooth.UnsetRepeatModeChangedCallback();
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset repeat mode changed callback, Error - " + (BluetoothError)ret);
+ }
+ }
+
+ private void RegisterShuffleModeChangedEvent()
+ {
+ Log.Debug (Globals.LogTag, "inside RegisterShuffleModeChangedEvent");
+ _shuffleModeChangedCallback = (int shuffle, IntPtr userData) =>
+ {
+ Log.Debug (Globals.LogTag, "inside RegisterShuffleModeChangedEvent callback");
+ if (_shuffleModeChanged != null)
+ {
+ ShuffleMode mode = (ShuffleMode) shuffle;
+ _shuffleModeChanged(null, new ShuffleModeChangedeventArgs(mode));
+ }
+ };
+ int ret = Interop.Bluetooth.SetShuffleModeChangedCallback(_shuffleModeChangedCallback, IntPtr.Zero);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Debug (Globals.LogTag, "failed inside RegisterShuffleModeChangedEvent");
+ Log.Error(Globals.LogTag, "Failed to set shuffle mode changed callback, Error - " + (BluetoothError)ret);
+ }
+ }
+ private void UnregisterShuffleModeChangedEvent()
+ {
+ int ret = Interop.Bluetooth.UnsetShuffleModeChangedCallback();
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset shuffle mode changed callback, Error - " + (BluetoothError)ret);
+ }
+ }
+
+ private void RegisterScanModeChangedEvent()
+ {
+ _scanModeChangedCallback = (int scan, IntPtr userData) =>
+ {
+ if (_scanModeChanged != null)
+ {
+ ScanMode mode = (ScanMode) scan;
+ _scanModeChanged(null, new ScanModeChangedEventArgs(mode));
+ }
+ };
+ int ret = Interop.Bluetooth.SetScanModeChangedCallback(_scanModeChangedCallback, IntPtr.Zero);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set scan mode changed callback, Error - " + (BluetoothError)ret);
+ }
+ }
+ private void UnregisterScanModeChangedEvent()
+ {
+ int ret = Interop.Bluetooth.UnsetScanModeChangedCallback();
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset scan mode changed callback, Error - " + (BluetoothError)ret);
+ }
+ }
+
+ private void targetInitialize()
+ {
+ if (Globals.IsInitialize)
+ {
+ _targetConnectionChangedCallback = (bool connected, string deviceAddress, IntPtr userData) =>
+ {
+ if (_targetConnectionChanged != null)
+ {
+ _targetConnectionChanged(null, new TargetConnectionStateChangedEventArgs(connected, deviceAddress));
+ }
+ };
+
+ int ret = Interop.Bluetooth.InitializeAvrcp(_targetConnectionChangedCallback, IntPtr.Zero);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error (Globals.LogTag, "Failed to initialize bluetooth avrcp, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ else
+ {
+ Globals.IsAudioInitialize = true;
+ }
+ }
+ else
+ {
+ Log.Error(Globals.LogTag, "Failed to initialize Avrcp, BT not initialized");
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotInitialized);
+ }
+ }
+
+ private void targetDeinitialize()
+ {
+ if (Globals.IsAudioInitialize)
+ {
+ int ret = Interop.Bluetooth.DeinitializeAvrcp();
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error (Globals.LogTag, "Failed to deinitialize bluetooth avrcp, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ else
+ {
+ Globals.IsAudioInitialize = false;
+ }
+ }
+ }
+
+ internal void NotifyEqualizeState(EqualizerState state)
+ {
+ int ret = Interop.Bluetooth.NotifyEqualizerState((int)state);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to notify equalizer state to remote device, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+
+ internal void NotifyRepeatMode(RepeatMode repeat)
+ {
+ int ret = Interop.Bluetooth.NotifyRepeatMode((int)repeat);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to notify repeat mode to remote device, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+
+ internal void NotifyShuffleMode(ShuffleMode shuffle)
+ {
+ int ret = Interop.Bluetooth.NotifyShuffleMode((int)shuffle);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to notify shuffle mode to remote device, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+
+ internal void NotifyScanMode(ScanMode scan)
+ {
+ int ret = Interop.Bluetooth.NotifyScanMode((int)scan);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to notify scan mode to remote device, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+
+ internal void NotifyPlayerState(PlayerState state)
+ {
+ int ret = Interop.Bluetooth.NotifyPlayerState((int)state);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to notify player state to remote device, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+
+ internal void NotifyCurrentPosition(uint position)
+ {
+ int ret = Interop.Bluetooth.NotifyCurrentPosition(position);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to notify position to remote device, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+
+ internal void NotifyTrack(Track trackData)
+ {
+ string title = trackData.Title;
+ string artist = trackData.Artist;
+ string album = trackData.Album;
+ string genre = trackData.Genre;
+ uint trackNum = trackData.TrackNum;
+ uint totalTracks = trackData.TotalTracks;
+ uint duration = trackData.Duration;
+
+ int ret = Interop.Bluetooth.NotifyTrack(title, artist, album, genre, trackNum, totalTracks, duration);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to notify track data to the remote device, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+
+ internal static BluetoothAvrcpImpl Instance
+ {
+ get
+ {
+ return _instance;
+ }
+ }
+
+ private BluetoothAvrcpImpl()
+ {
+ targetInitialize();
+ }
+
+ ~BluetoothAvrcpImpl()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects.
+ }
+ //Free unmanaged objects
+ targetDeinitialize();
+ RemoveAllRegisteredEvent();
+ disposed = true;
+ }
+
+ private void RemoveAllRegisteredEvent()
+ {
+ //unregister all remaining events when this object is released.
+ if (_equalizerStateChanged != null)
+ {
+ UnregisterEqualizerStateChangedEvent();
+ }
+ if (_repeatModeChanged != null)
+ {
+ UnregisterRepeatModeChangedEvent();
+ }
+ if (_scanModeChanged != null)
+ {
+ UnregisterScanModeChangedEvent();
+ }
+ if (_shuffleModeChanged != null)
+ {
+ UnregisterShuffleModeChangedEvent();
+ }
+ }
+ }
+}
+
diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothData.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothData.cs
new file mode 100755
index 0000000..3122e59
--- /dev/null
+++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothData.cs
@@ -0,0 +1,499 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+using System.Collections.Concurrent;
+using System.Collections.ObjectModel;
+using System.Collections.Specialized;
+
+namespace Tizen.Network.Bluetooth
+{
+ /// <summary>
+ /// A class to handle device class type and service.
+ /// </summary>
+ public class BluetoothClass
+ {
+ internal BluetoothMajorDeviceClassType MajorType;
+ internal BluetoothMinorDeviceClassType MinorType;
+ internal int Mask;
+
+ internal BluetoothClass()
+ {
+ }
+
+ /// <summary>
+ /// Type of the major device class.
+ /// </summary>
+ public BluetoothMajorDeviceClassType MajorDeviceClassType
+ {
+ get
+ {
+ return MajorType;
+ }
+ }
+ /// <summary>
+ /// Type of the minor device class.
+ /// </summary>
+ public BluetoothMinorDeviceClassType MinorDeviceClassType
+ {
+ get
+ {
+ return MinorType;
+ }
+ }
+ /// <summary>
+ /// Major service class mask.
+ /// </summary>
+ public int MajorServiceClassMask
+ {
+ get
+ {
+ return Mask;
+ }
+ }
+ }
+
+ /// <summary>
+ /// A class containing the information of Bluetooth oob data.
+ /// </summary>
+ public class BluetoothOobData
+ {
+ /// <summary>
+ /// Default Constructor.Initializes an object of BluetoothOobData
+ /// </summary>
+ public BluetoothOobData()
+ {
+ }
+
+ /// <summary>
+ /// Hash value.
+ /// </summary>
+ public byte[] HashValue
+ {
+ get;
+ set;
+ }
+ /// <summary>
+ /// Randomizer value.
+ /// </summary>
+ public byte[] RandomizerValue
+ {
+ get;
+ set;
+ }
+ }
+
+ /// <summary>
+ /// A class containing the information of Bluetooth device sdp data.
+ /// </summary>
+ public class BluetoothDeviceSdpData
+ {
+ internal string Address;
+ internal Collection<string> Uuid;
+
+ internal BluetoothDeviceSdpData()
+ {
+ }
+
+ /// <summary>
+ /// The device address.
+ /// </summary>
+ public string DeviceAddress
+ {
+ get
+ {
+ return Address;
+ }
+ }
+ /// <summary>
+ /// The service UUID.
+ /// </summary>
+ public IEnumerable<string> ServiceUuid
+ {
+ get
+ {
+ return Uuid;
+ }
+ }
+ }
+
+ /// <summary>
+ /// A class containing the information of Bluetooth device connection data.
+ /// </summary>
+ public class BluetoothDeviceConnectionData
+ {
+ internal string RemoteAddress;
+ internal BluetoothConnectionLinkType Link;
+ internal BluetoothDisconnectReason Reason;
+
+ internal BluetoothDeviceConnectionData()
+ {
+ }
+
+ /// <summary>
+ /// The device address.
+ /// </summary>
+ public string Address
+ {
+ get
+ {
+ return RemoteAddress;
+ }
+ }
+ /// <summary>
+ /// The type of the connection link.
+ /// </summary>
+ public BluetoothConnectionLinkType LinkType
+ {
+ get
+ {
+ return Link;
+ }
+ }
+ /// <summary>
+ /// The disconnect reason.
+ /// </summary>
+ public BluetoothDisconnectReason DisconnectReason
+ {
+ get
+ {
+ return Reason;
+ }
+ }
+ }
+
+ /// <summary>
+ /// A class containing the information of track data.
+ /// </summary>
+ public class Track
+ {
+ /// <summary>
+ /// Default Constructor.Initializes an object of Track
+ /// </summary>
+ public Track()
+ {
+ }
+
+ /// <summary>
+ /// Title of track.
+ /// </summary>
+ public string Title
+ {
+ get;
+ set;
+ }
+ /// <summary>
+ /// Artist of track.
+ /// </summary>
+ public string Artist
+ {
+ get;
+ set;
+ }
+ /// <summary>
+ /// Album of track.
+ /// </summary>
+ public string Album
+ {
+ get;
+ set;
+ }
+ /// <summary>
+ /// Genre of track.
+ /// </summary>
+ public string Genre
+ {
+ get;
+ set;
+ }
+ /// <summary>
+ /// Track number.
+ /// </summary>
+ public uint TrackNum
+ {
+ get;
+ set;
+ }
+ /// <summary>
+ /// Number of all tracks.
+ /// </summary>
+ public uint TotalTracks
+ {
+ get;
+ set;
+ }
+ /// <summary>
+ /// Duration of track in milliseconds.
+ /// </summary>
+ public uint Duration
+ {
+ get;
+ set;
+ }
+ }
+
+ /// <summary>
+ /// A class containing the information of Manufacturer data.
+ /// </summary>
+ public class ManufacturerData
+ {
+ /// <summary>
+ /// Default Constructor.Initializes an object of ManufacturerData
+ /// </summary>
+ public ManufacturerData()
+ {
+ }
+
+ /// <summary>
+ /// The manufacturer id.
+ /// </summary>
+ public int Id
+ {
+ get;
+ set;
+ }
+ /// <summary>
+ /// The length of the manufacturer data.
+ /// </summary>
+ public int DataLength
+ {
+ get;
+ set;
+ }
+ /// <summary>
+ /// The manufacturer data.
+ /// </summary>
+ public byte[] Data
+ {
+ get;
+ set;
+ }
+ }
+
+ internal class BluetoothLeScanData
+ {
+ internal string RemoteAddress
+ {
+ get;
+ set;
+ }
+ internal BluetoothLeDeviceAddressType AddressType
+ {
+ get;
+ set;
+ }
+ internal int Rssi
+ {
+ get;
+ set;
+ }
+ internal int AdvDataLength
+ {
+ get;
+ set;
+ }
+ internal byte[] AdvData
+ {
+ get;
+ set;
+ }
+ internal int ScanDataLength
+ {
+ get;
+ set;
+ }
+ internal byte[] ScanData
+ {
+ get;
+ set;
+ }
+ }
+
+ /// <summary>
+ /// A class containing the information of Bluetooth service data.
+ /// </summary>
+ public class BluetoothServiceData
+ {
+ /// <summary>
+ /// Default Constructor.Initializes an object of BluetoothServiceData
+ /// </summary>
+ public BluetoothServiceData()
+ {
+ }
+
+ /// <summary>
+ /// The Uuid of service.
+ /// </summary>
+ public string Uuid
+ {
+ get;
+ set;
+ }
+ /// <summary>
+ /// The data length of the service data.
+ /// </summary>
+ public int DataLength
+ {
+ get;
+ set;
+ }
+ /// <summary>
+ /// The service data.
+ /// </summary>
+ public byte[] Data
+ {
+ get;
+ set;
+ }
+ }
+
+ /// <summary>
+ /// A class containing the service data information.
+ /// </summary>
+ public class BluetoothLeServiceData
+ {
+ internal string Uuid;
+ internal byte[] Data;
+ internal int Length;
+
+ internal BluetoothLeServiceData()
+ {
+ }
+
+ /// <summary>
+ /// Bluetooth Le service uuid.
+ /// </summary>
+ public string ServiceUuid
+ {
+ get
+ {
+ return Uuid;
+ }
+ }
+ /// <summary>
+ /// Bluetooth Le service data
+ /// </summary>
+ public byte[] ServiceData
+ {
+ get
+ {
+ return Data;
+ }
+ }
+ /// <summary>
+ /// The length of the service data.
+ /// </summary>
+ public int ServiceDataLength
+ {
+ get
+ {
+ return Length;
+ }
+ }
+ }
+
+ /// <summary>
+ /// A class containing the information of Socket data.
+ /// </summary>
+ public class SocketData
+ {
+ internal string RecvData;
+ internal int Size;
+ internal int Fd;
+
+ internal SocketData()
+ {
+ }
+
+ /// <summary>
+ /// The socket fd.
+ /// </summary>
+ public int SocketFd
+ {
+ get
+ {
+ return Fd;
+ }
+ }
+ /// <summary>
+ /// The length of the received data.
+ /// </summary>
+ public int DataSize
+ {
+ get
+ {
+ return Size;
+ }
+ }
+ /// <summary>
+ /// The received data.
+ /// </summary>
+ public string Data
+ {
+ get
+ {
+ return RecvData;
+ }
+ }
+ }
+
+ /// <summary>
+ /// A class containing the information of Socket connection.
+ /// </summary>
+ public class SocketConnection
+ {
+ internal string Uuid;
+ internal string RemoteAddress;
+ internal int Fd;
+
+ internal SocketConnection()
+ {
+ }
+
+ /// <summary>
+ /// The connected socket fd.
+ /// </summary>
+ public int SocketFd
+ {
+ get
+ {
+ return Fd;
+ }
+ }
+ /// <summary>
+ /// The remote device address.
+ /// </summary>
+ public string Address
+ {
+ get
+ {
+ return RemoteAddress;
+ }
+ }
+ /// <summary>
+ /// The service Uuid.
+ /// </summary>
+ public string ServiceUuid
+ {
+ get
+ {
+ return Uuid;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothDevice.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothDevice.cs
new file mode 100644
index 0000000..503861e
--- /dev/null
+++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothDevice.cs
@@ -0,0 +1,677 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Collections.Concurrent;
+using System.Collections.ObjectModel;
+using System.Collections.Specialized;
+
+namespace Tizen.Network.Bluetooth
+{
+ /// <summary>
+ /// A class which is used to handle the connection with other devices and set authorization of other devices.<br>
+ /// The BluetoothDevice class is used to search for services available on remote devices.
+ /// </summary>
+ /// <privilege> http://tizen.org/privilege/bluetooth </privilege>
+ public class BluetoothDevice
+ {
+ private event EventHandler<BondCreatedEventArgs> _bondCreated;
+ private event EventHandler<BondDestroyedEventArgs> _bondDestroyed;
+ private event EventHandler<AuthorizationChangedEventArgs> _authorizationChanged;
+ private event EventHandler<ServiceSearchedEventArgs> _serviceSearched;
+ private event EventHandler<DeviceConnectionStateChangedEventArgs> _connectionChanged;
+
+ private Interop.Bluetooth.BondCreatedCallback _bondCreatedCallback;
+ private Interop.Bluetooth.BondDestroyedCallback _bondDestroyedCallback;
+ private Interop.Bluetooth.AuthorizationChangedCallback _authorizationChangedCallback;
+ private Interop.Bluetooth.ServiceSearchedCallback _serviceSearchedCallback;
+ private Interop.Bluetooth.DeviceConnectionStateChangedCallback _connectionChangedCallback;
+
+ internal string RemoteDeviceAddress;
+ internal string RemoteDeviceName;
+ internal int RemoteDeviceRssi;
+ internal BluetoothClass RemoteDeviceClass;
+ internal Collection<string> RemoteDeviceService;
+ internal int RemoteDeviceCount;
+ internal bool RemotePaired;
+ internal bool RemoteAuthorized;
+ internal bool RemoteConnected;
+ internal BluetoothAppearanceType RemoteAppearance;
+ internal int RemoteManufLength;
+ internal string RemoteManufData;
+
+ internal BluetoothDevice()
+ {
+ }
+
+ /// <summary>
+ /// Address of device.
+ /// </summary>
+ public string Address
+ {
+ get
+ {
+ return RemoteDeviceAddress;
+ }
+ }
+ /// <summary>
+ /// Name of device.
+ /// </summary>
+ public string Name
+ {
+ get
+ {
+ return RemoteDeviceName;
+ }
+ }
+ /// <summary>
+ /// Strength indicator of received signal of device.
+ /// </summary>
+ public int Rssi
+ {
+ get
+ {
+ return RemoteDeviceRssi;
+ }
+ }
+ /// <summary>
+ /// Class of device.
+ /// </summary>
+ public BluetoothClass Class
+ {
+ get
+ {
+ return RemoteDeviceClass;
+ }
+ }
+ /// <summary>
+ /// Service UUID list of device.
+ /// </summary>
+ public IEnumerable<string> ServiceUuidList
+ {
+ get
+ {
+ return RemoteDeviceService;
+ }
+ }
+ /// <summary>
+ /// The number of services.
+ /// </summary>
+ public int ServiceCount
+ {
+ get
+ {
+ return RemoteDeviceCount;
+ }
+ }
+ /// <summary>
+ /// The paired state of device.
+ /// </summary>
+ public bool IsPaired
+ {
+ get
+ {
+ return RemotePaired;
+ }
+ }
+ /// <summary>
+ /// The connection state of device.
+ /// </summary>
+ public bool IsConnected
+ {
+ get
+ {
+ return RemoteConnected;
+ }
+ }
+ /// <summary>
+ /// The authorization state of device.
+ /// </summary>
+ public bool IsAuthorized
+ {
+ get
+ {
+ return RemoteAuthorized;
+ }
+ }
+ /// <summary>
+ /// Bluetooth Appearance.
+ /// </summary>
+ public BluetoothAppearanceType AppearanceType
+ {
+ get
+ {
+ return RemoteAppearance;
+ }
+ }
+
+ /// <summary>
+ /// The length of manufacturer data.
+ /// </summary>
+ public int ManufacturerDataLength
+ {
+ get
+ {
+ return RemoteManufLength;
+ }
+ }
+ /// <summary>
+ /// The manufacturer data.
+ /// </summary>
+ public string ManufacturerData
+ {
+ get
+ {
+ return RemoteManufData;
+ }
+ }
+
+ /// <summary>
+ /// (event) BondCreated is raised when process of creating bond is finished.
+ /// </summary>
+ public event EventHandler<BondCreatedEventArgs> BondCreated
+ {
+ add
+ {
+ if (_bondCreated == null)
+ {
+ RegisterBondCreatedEvent();
+ }
+ _bondCreated += value;
+ }
+ remove
+ {
+ _bondCreated -= value;
+ if (_bondCreated == null)
+ {
+ UnregisterBondCreatedEvent();
+ }
+ }
+ }
+
+ /// <summary>
+ /// (event) BondDestroyed is raised when the bond is destroyed.
+ /// </summary>
+ public event EventHandler<BondDestroyedEventArgs> BondDestroyed
+ {
+ add
+ {
+ if (_bondDestroyed == null)
+ {
+ RegisterBondDestroyedEvent();
+ }
+ _bondDestroyed += value;
+ }
+ remove
+ {
+ _bondDestroyed -= value;
+ if (_bondDestroyed == null)
+ {
+ UnregisterBondDestroyedEvent();
+ }
+ }
+ }
+
+ /// <summary>
+ /// (event) AuthorizationChanged is raised when the authorization of device is changed.
+ /// </summary>
+ public event EventHandler<AuthorizationChangedEventArgs> AuthorizationChanged
+ {
+ add
+ {
+ if (_authorizationChanged == null)
+ {
+ RegisterAuthorizationChangedEvent();
+ }
+ _authorizationChanged += value;
+ }
+ remove
+ {
+ _authorizationChanged -= value;
+ if (_authorizationChanged == null)
+ {
+ UnregisterAuthorizationChangedEvent();
+ }
+ }
+ }
+
+ /// <summary>
+ /// (event) ServiceSearched is raised when the process of service searched is finished.
+ /// </summary>
+ public event EventHandler<ServiceSearchedEventArgs> ServiceSearched
+ {
+ add
+ {
+ if (_serviceSearched == null)
+ {
+ RegisterServiceSearchedEvent();
+ }
+ _serviceSearched += value;
+ }
+ remove
+ {
+ _serviceSearched -= value;
+ if (_serviceSearched == null)
+ {
+ UnregisterServiceSearchedEvent();
+ }
+ }
+ }
+
+ /// <summary>
+ /// (event) ConnectionStateChanged is raised when the connection state is changed.
+ /// </summary>
+ public event EventHandler<DeviceConnectionStateChangedEventArgs> ConnectionStateChanged
+ {
+ add
+ {
+ if (_connectionChanged == null)
+ {
+ RegisterConnectionChangedEvent();
+ }
+ _connectionChanged += value;
+ }
+ remove
+ {
+ _connectionChanged -= value;
+ if (_connectionChanged == null)
+ {
+ UnregisterConnectionChangedEvent();
+ }
+ }
+ }
+
+ private void RegisterBondCreatedEvent()
+ {
+ _bondCreatedCallback = (int result, ref BluetoothDeviceStruct device, IntPtr userData) =>
+ {
+ if (_bondCreated != null)
+ {
+ BluetoothError res = (BluetoothError)result;
+ _bondCreated(null, new BondCreatedEventArgs(res, BluetoothUtils.ConvertStructToDeviceClass(device)));
+ }
+ };
+ int ret = Interop.Bluetooth.SetBondCreatedCallback(_bondCreatedCallback, IntPtr.Zero);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set bond created callback, Error - " + (BluetoothError)ret);
+ }
+ }
+
+ private void UnregisterBondCreatedEvent()
+ {
+ int ret = Interop.Bluetooth.UnsetBondCreatedCallback();
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset bond created callback, Error - " + (BluetoothError)ret);
+ }
+ }
+
+ private void RegisterBondDestroyedEvent()
+ {
+ _bondDestroyedCallback = (int result, string deviceAddress, IntPtr userData) =>
+ {
+ if (_bondDestroyed != null)
+ {
+ BluetoothError res = (BluetoothError)result;
+ _bondDestroyed(null, new BondDestroyedEventArgs(res, deviceAddress));
+ }
+ };
+ int ret = Interop.Bluetooth.SetBondDestroyedCallback(_bondDestroyedCallback, IntPtr.Zero);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set bond destroyed callback, Error - " + (BluetoothError)ret);
+ }
+ }
+
+ private void UnregisterBondDestroyedEvent()
+ {
+ int ret = Interop.Bluetooth.UnsetBondDestroyedCallback();
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset bond destroyed callback, Error - " + (BluetoothError)ret);
+ }
+ }
+
+ private void RegisterServiceSearchedEvent()
+ {
+ _serviceSearchedCallback = (int result, ref BluetoothDeviceSdpStruct sdp, IntPtr userData) =>
+ {
+ Log.Info(Globals.LogTag, "Servicesearched cb is called");
+ if (_serviceSearched != null)
+ {
+ BluetoothError res = (BluetoothError)result;
+ _serviceSearched(null, new ServiceSearchedEventArgs(res, BluetoothUtils.ConvertStructToSdpData(sdp)));
+ }
+ };
+ int ret = Interop.Bluetooth.SetServiceSearchedCallback(_serviceSearchedCallback, IntPtr.Zero);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set service searched callback, Error - " + (BluetoothError)ret);
+ }
+ }
+
+ private void UnregisterServiceSearchedEvent()
+ {
+ int ret = Interop.Bluetooth.UnsetServiceSearchedCallback();
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset service searched callback, Error - " + (BluetoothError)ret);
+ }
+ }
+
+ private void RegisterAuthorizationChangedEvent()
+ {
+ _authorizationChangedCallback = (int authorization, string deviceAddress, IntPtr userData) =>
+ {
+ Log.Info(Globals.LogTag, "Authorization changed cb is called");
+ if (_authorizationChanged != null)
+ {
+ BluetoothAuthorizationType auth = (BluetoothAuthorizationType)authorization;
+ _authorizationChanged(null, new AuthorizationChangedEventArgs(auth, deviceAddress));
+ }
+ };
+ int ret = Interop.Bluetooth.SetAuthorizationChangedCallback(_authorizationChangedCallback, IntPtr.Zero);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set authroization changed callback, Error - " + (BluetoothError)ret);
+ }
+ }
+
+ private void UnregisterAuthorizationChangedEvent()
+ {
+ int ret = Interop.Bluetooth.UnsetAuthorizationChangedCallback();
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset authroization changed callback, Error - " + (BluetoothError)ret);
+ }
+ }
+
+ private void RegisterConnectionChangedEvent()
+ {
+ _connectionChangedCallback = (bool connected, ref BluetoothDeviceConnectionStruct device, IntPtr userData) =>
+ {
+ Log.Info(Globals.LogTag, "Connection state changed cb is called");
+ if (_connectionChanged != null)
+ {
+ _connectionChanged(null, new DeviceConnectionStateChangedEventArgs(connected, BluetoothUtils.ConvertStructToConnectionData(device)));
+ }
+ };
+
+ int ret = Interop.Bluetooth.SetConnectionStateChangedCallback(_connectionChangedCallback, IntPtr.Zero);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set connection state changed callback, Error - " + (BluetoothError)ret);
+ }
+ }
+
+ private void UnregisterConnectionChangedEvent()
+ {
+ int ret = Interop.Bluetooth.UnsetConnectionStateChangedCallback();
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset connection state changed callback, Error - " + (BluetoothError)ret);
+ }
+ }
+
+ /// <summary>
+ /// Creates a bond with remote Bluetooth device.
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled and remote device must be discoverable by StartDiscovery().The bond can be destroyed by DestroyBond().
+ /// The bonding request can be cancelled by CancelBonding().If this succeeds, BondCreated event will be invoked.
+ /// </remarks>
+ public void CreateBond()
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled)
+ {
+ int ret = Interop.Bluetooth.CreateBond(RemoteDeviceAddress);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to create bond, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Cancels the bonding process.
+ /// </summary>
+ /// <remarks>
+ /// Bonding must be in progress by CreateBond().
+ /// </remarks>
+ public void CancelBonding()
+ {
+ int ret = Interop.Bluetooth.CancelBonding();
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to cancel bonding process, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Destroys the bond.
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled and the bond must be created by CreateBond().
+ /// If this succeeds, BondDestroyed event will be invoked.
+ /// </remarks>
+ public void DestroyBond()
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled)
+ {
+ int ret = Interop.Bluetooth.DestroyBond(RemoteDeviceAddress);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to destroy bond, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Sets an alias for the bonded device.
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled and the bond must be created by CreateBond().
+ /// </remarks>
+ /// <param name="aliasName">Alias name of remote device.</param>
+ public void SetAlias(string aliasName)
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled)
+ {
+ int ret = Interop.Bluetooth.SetAlias(RemoteDeviceAddress, aliasName);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set alias name, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Sets the authorization of a bonded device.
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled and the bond must be created by CreateBond().
+ /// If this succeeds, AuthorizationChanged event will be invoked.
+ /// </remarks>
+ /// <param name="authorizationState">Authorization state.</param>
+ public void SetAuthorization(BluetoothAuthorizationType authorizationState)
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled)
+ {
+ int ret = Interop.Bluetooth.SetAuthorization(RemoteDeviceAddress, (int)authorizationState);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set authroization state, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the mask from UUID.
+ /// </summary>
+ /// <returns>The service mask list converted from the given UUID list.</returns>
+ /// <param name="uuids">Uuid list of the device.</param>
+ public BluetoothServiceClassType GetMaskFromUuid(string[] uuids)
+ {
+ BluetoothServiceClassType serviceMask;
+
+ int ret = Interop.Bluetooth.GetMaskFromUuid(uuids, uuids.Length, out serviceMask);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get service mask, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ return serviceMask;
+ }
+
+ /// <summary>
+ /// Starts the search for services supported by the specified device.
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled and remote device must be discoverable by StartDiscovery().The bond must be created by CreateBond().
+ /// If this succeeds, ServiceSearched will be invoked.
+ /// </remarks>
+ public void StartServiceSearch()
+ {
+ Log.Info(Globals.LogTag, "startservicesearch entry");
+ if (BluetoothAdapter.IsBluetoothEnabled)
+ {
+ int ret = Interop.Bluetooth.StartServiceSearch(RemoteDeviceAddress);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to start service search, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the connected profiles.
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ /// <returns>The connected Bluetooth profiles.</returns>
+ public IEnumerable<BluetoothProfileType> GetConnectedProfiles()
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled)
+ {
+ List<BluetoothProfileType> profileList = new List<BluetoothProfileType>();
+ Interop.Bluetooth.ConnectedProfileCallback callback = (int profile, IntPtr userData) =>
+ {
+ if (!profile.Equals(null))
+ {
+ profileList.Add((BluetoothProfileType)profile);
+ }
+ return true;
+ };
+ int ret = Interop.Bluetooth.GetConnectedProfiles(RemoteDeviceAddress, callback, IntPtr.Zero);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get connected profiles, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ return profileList;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Determines if profile is connected to the specified remote device.
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ /// <returns><c>true</c> if profile is connected; otherwise, <c>false</c>.</returns>
+ /// <param name="profileType">Bluetooth Profile type.</param>
+ public bool IsProfileConnected(BluetoothProfileType profileType)
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled)
+ {
+ bool isConnected;
+ int ret = Interop.Bluetooth.IsProfileConnected(RemoteDeviceAddress, (int)profileType, out isConnected);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get profile connected state, Error - " + (BluetoothError)ret);
+ }
+ return isConnected;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Returns the instance of Bluetooth profile type.
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ public T GetProfile<T>() where T : BluetoothProfile
+ {
+ /*
+ * FIXME: Find a proper way for dynamic allocation.
+ */
+ T profile = null;
+ String type = typeof(T).ToString();
+ if (type.Equals("Tizen.Network.Bluetooth.BluetoothAudio"))
+ {
+ BluetoothAudio audio = new BluetoothAudio();
+ profile = (audio as T);
+ }
+ else if (type.Equals("Tizen.Network.Bluetooth.BluetoothAvrcp"))
+ {
+ BluetoothAvrcp avrcp = new BluetoothAvrcp();
+ profile = (avrcp as T);
+ }
+ else if (type.Equals("Tizen.Network.Bluetooth.BluetoothHid"))
+ {
+ BluetoothHid hid = new BluetoothHid();
+ profile = (hid as T);
+ }
+
+ if (profile != null)
+ {
+ profile.RemoteAddress = RemoteDeviceAddress;
+ }
+ return profile;
+ }
+
+ /// <summary>
+ /// Creates the client socket.
+ /// </summary>
+ /// <returns>The IBluetoothClientSocket instance.</returns>
+ /// <param name="serviceUuid">The UUID of service.</param>
+ public IBluetoothClientSocket CreateSocket(string serviceUuid)
+ {
+ BluetoothSocket clientSocket = new BluetoothSocket();
+ clientSocket.remoteAddress = this.Address;
+ clientSocket.serviceUuid = serviceUuid;
+ return (IBluetoothClientSocket)clientSocket;
+ }
+ }
+}
diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothEnumerations.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothEnumerations.cs
new file mode 100755
index 0000000..b49775c
--- /dev/null
+++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothEnumerations.cs
@@ -0,0 +1,1202 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Network.Bluetooth
+{
+ /// <summary>
+ /// Enumeration for Bluetooth state.
+ /// </summary>
+ public enum BluetoothState
+ {
+ /// <summary>
+ /// Disabled state.
+ /// </summary>
+ Disabled = 0,
+ /// <summary>
+ /// Enabled state.
+ /// </summary>
+ Enabled
+ }
+
+ /// <summary>
+ /// Enumeration for Bluetooth errors.
+ /// </summary>
+ public enum BluetoothError
+ {
+ /// <summary>
+ /// Successful
+ /// </summary>
+ None = ErrorCode.None,
+ /// <summary>
+ /// Operation cancelled
+ /// </summary>
+ Cancelled = ErrorCode.Canceled,
+ /// <summary>
+ /// Invalid parameter
+ /// </summary>
+ InvalidParameter = ErrorCode.InvalidParameter,
+ /// <summary>
+ /// Out of memory
+ /// </summary>
+ OutOfMemory = ErrorCode.OutOfMemory,
+ /// <summary>
+ /// Device or resource busy
+ /// </summary>
+ ResourceBusy = ErrorCode.ResourceBusy,
+ /// <summary>
+ /// Timeout error
+ /// </summary>
+ TimedOut = ErrorCode.TimedOut,
+ /// <summary>
+ /// Operation now in progress
+ /// </summary>
+ NowInProgress = ErrorCode.NowInProgress,
+ /// <summary>
+ /// Bluetooth is Not Supported
+ /// </summary>
+ NotSupported = ErrorCode.NotSupported,
+ /// <summary>
+ /// Permission denied
+ /// </summary>
+ PermissionDenied = ErrorCode.PermissionDenied,
+ /// <summary>
+ /// Quota exceeded
+ /// </summary>
+ QuotaExceeded = ErrorCode.QuotaExceeded,
+ /// <summary>
+ /// No data available
+ /// </summary>
+ NoData = ErrorCode.NoData,
+ /// <summary>
+ /// Local adapter not initialized
+ /// </summary>
+ NotInitialized = -0x01C00000 | 0x0101,
+ /// <summary>
+ /// Local adapter not enabled
+ /// </summary>
+ NotEnabled = -0x01C00000 | 0x0102,
+ /// <summary>
+ /// Operation already done
+ /// </summary>
+ AlreadyDone = -0x01C00000 | 0x0103,
+ /// <summary>
+ /// Operation failed
+ /// </summary>
+ OperationFailed = -0x01C00000 | 0x0104,
+ /// <summary>
+ /// Operation not in progress
+ /// </summary>
+ NotInProgress = -0x01C00000 | 0x0105,
+ /// <summary>
+ /// Remote device not bonded
+ /// </summary>
+ RemoteDeviceNotBonded = -0x01C00000 | 0x0106,
+ /// <summary>
+ /// Authentication rejected
+ /// </summary>
+ AuthRejected = -0x01C00000 | 0x0107,
+ /// <summary>
+ /// Authentication failed
+ /// </summary>
+ AuthFailed = -0x01C00000 | 0x0108,
+ /// <summary>
+ /// Remote device not found
+ /// </summary>
+ RemoteDeviceNotFound = -0x01C00000 | 0x0109,
+ /// <summary>
+ /// Service search failed
+ /// </summary>
+ ServiceSearchFailed = -0x01C00000 | 0x010A,
+ /// <summary>
+ /// Remote device is not connected
+ /// </summary>
+ RemoteDeviceNotConnected = -0x01C00000 | 0x010B,
+ /// <summary>
+ /// Resource temporarily unavailable
+ /// </summary>
+ ResourceUnavailable = -0x01C00000 | 0x010C,
+ /// <summary>
+ /// Service Not Found
+ /// </summary>
+ ServiceNotFound = -0x01C00000 | 0x010D
+ }
+
+ /// <summary>
+ /// Enumeration for Bluetooth visibility mode.
+ /// </summary>
+ public enum VisibilityMode
+ {
+ /// <summary>
+ /// Non discoverable mode.
+ /// </summary>
+ NonDiscoverable = 0,
+ /// <summary>
+ /// Discoverable mode.
+ /// </summary>
+ Discoverable = 1,
+ /// <summary>
+ /// Discoverable mode with limited time.
+ /// </summary>
+ TimeLimitedDiscoverable = 2
+ }
+
+ /// <summary>
+ /// Enumeration for Bluetooth major device class type.
+ /// </summary>
+ public enum BluetoothMajorDeviceClassType
+ {
+ /// <summary>
+ /// Miscellaneous major class type.
+ /// </summary>
+ Misc = 0x00,
+ /// <summary>
+ /// Computer major class type.
+ /// </summary>
+ Computer = 0x01,
+ /// <summary>
+ /// Phone major class type.
+ /// </summary>
+ Phone = 0x02,
+ /// <summary>
+ /// LAN/Network access point major class type.
+ /// </summary>
+ LanNetworkAccessPoint = 0x03,
+ /// <summary>
+ /// Audio/Video major class type.
+ /// </summary>
+ AudioVideo = 0x04,
+ /// <summary>
+ /// Peripheral major class type.
+ /// </summary>
+ Peripheral = 0x05,
+ /// <summary>
+ /// Imaging major class type.
+ /// </summary>
+ Imaging = 0x06,
+ /// <summary>
+ /// Wearable major class type.
+ /// </summary>
+ Wearable = 0x07,
+ /// <summary>
+ /// Toy major class type.
+ /// </summary>
+ Toy = 0x08,
+ /// <summary>
+ /// Health major class type.
+ /// </summary>
+ Health = 0x09,
+ /// <summary>
+ /// Uncategorized major class type.
+ /// </summary>
+ Uncategorized = 0x1F
+ }
+
+ /// <summary>
+ /// Enumeration for Bluetooth minor device class type.
+ /// </summary>
+ public enum BluetoothMinorDeviceClassType
+ {
+ /// <summary>
+ /// Uncategorized computer minor class type.
+ /// </summary>
+ ComputerUncategorized = 0x00,
+ /// <summary>
+ /// Desktop workstation computer minor class type.
+ /// </summary>
+ ComputerDesktopWorkstation = 0x04,
+ /// <summary>
+ /// Server computer minor class type.
+ /// </summary>
+ ComputerServer = 0x08,
+ /// <summary>
+ /// Laptop computer minor class type.
+ /// </summary>
+ ComputerLaptop = 0x0C,
+ /// <summary>
+ /// Handheld PC/PDA computer minor class type.
+ /// </summary>
+ ComputerHandheldPcOrPda = 0x10,
+ /// <summary>
+ /// Palm sized PC/PDA computer minor class type.
+ /// </summary>
+ ComputerPalmSizedPcOrPda = 0x14,
+ /// <summary>
+ /// Wearable computer minor class type.
+ /// </summary>
+ ComputerWearableComputer = 0x18,
+
+ /// <summary>
+ /// Unclassified phone minor class type.
+ /// </summary>
+ PhoneUncategorized = 0x00,
+ /// <summary>
+ /// Cellular phone minor class type.
+ /// </summary>
+ PhoneCellular = 0x04,
+ /// <summary>
+ /// Cordless phone minor class type.
+ /// </summary>
+ PhoneCordless = 0x08,
+ /// <summary>
+ /// SmartPhone phone minor class type.
+ /// </summary>
+ PhoneSmartPhone = 0x0C,
+ /// <summary>
+ /// Wired modem or voice gateway phone minor class type.
+ /// </summary>
+ PhoneWiredModemOrVoiceGateway = 0x10,
+ /// <summary>
+ /// ISDN phone minor class type.
+ /// </summary>
+ PhoneCommonIsdnAccess = 0x14,
+
+ /// <summary>
+ /// Fully available LAN/Network access point minor class type.
+ /// </summary>
+ LanNetworkAccessPointFullyAvailable = 0x04,
+ /// <summary>
+ /// 1-17% utilized LAN/Network access point minor class type.
+ /// </summary>
+ LanNetworkAccessPoint1To17PercentUtilized = 0x20,
+ /// <summary>
+ /// 17-33% utilized LAN/Network access point minor class type.
+ /// </summary>
+ LanNetworkAccessPoint17To33PercentUtilized = 0x40,
+ /// <summary>
+ /// 33-50% utilized LAN/Network access point minor class type.
+ /// </summary>
+ LanNetworkAccessPoint33To50PercentUtilized = 0x60,
+ /// <summary>
+ /// 50-67% utilized LAN/Network access point minor class type.
+ /// </summary>
+ LanNetworkAccessPoint50To67PercentUtilized = 0x80,
+ /// <summary>
+ /// 67-83% utilized LAN/Network access point minor class type.
+ /// </summary>
+ LanNetworkAccessPoint67To83PercentUtilized = 0xA0,
+ /// <summary>
+ /// 83-99% utilized LAN/Network access point minor class type.
+ /// </summary>
+ LanNetworkAccessPoint83To99PercentUtilized = 0xC0,
+ /// <summary>
+ /// No service available LAN/Network access point minor class type.
+ /// </summary>
+ LanNetworkAccessPointNoServiceAvailable = 0xE0,
+
+ /// <summary>
+ /// Uncategorized audio/video minor class type.
+ /// </summary>
+ AudioVideoUncategorized = 0x00,
+ /// <summary>
+ /// Wearable headset audio/video minor class type.
+ /// </summary>
+ AudioVideoWearableHeadset = 0x04,
+ /// <summary>
+ /// Hands free audio/video minor class type.
+ /// </summary>
+ AudioVideoHandsFree = 0x08,
+ /// <summary>
+ /// Microphone audio/video minor class type.
+ /// </summary>
+ AudioVideoMicrophone = 0x10,
+ /// <summary>
+ /// Loudspeaker audio/video minor class type.
+ /// </summary>
+ AudioVideoLoudspeaker = 0x14,
+ /// <summary>
+ /// Headphones audio/video minor class type.
+ /// </summary>
+ AudioVideoHeadphones = 0x18,
+ /// <summary>
+ /// Portable audio audio/video minor class type.
+ /// </summary>
+ AudioVideoPortableAudio = 0x1C,
+ /// <summary>
+ /// Car audio audio/video minor class type.
+ /// </summary>
+ AudioVideoCarAudio = 0x20,
+ /// <summary>
+ /// SetTopbox audio/video minor class type.
+ /// </summary>
+ AudioVideoSetTopBox = 0x24,
+ /// <summary>
+ /// Hifi audio audio/video minor class type.
+ /// </summary>
+ AudioVideoHifiAudioDevice = 0x28,
+ /// <summary>
+ /// VCR audio/video minor class type.
+ /// </summary>
+ AudioVideoVcr = 0x2C,
+ /// <summary>
+ /// Video camera audio/video minor class type.
+ /// </summary>
+ AudioVideoVideoCamera = 0x30,
+ /// <summary>
+ /// Camcorder audio/video minor class type.
+ /// </summary>
+ AudioVideoCamcorder = 0x34,
+ /// <summary>
+ /// Video monitor audio/video minor class type.
+ /// </summary>
+ AudioVideoVideoMonitor = 0x38,
+ /// <summary>
+ /// Video display and loudspeaker audio/video minor class type.
+ /// </summary>
+ AudioVideoVideoDisplayLoudspeaker = 0x3C,
+ /// <summary>
+ /// Video conferencing audio/video minor class type.
+ /// </summary>
+ AudioVideoVideoConferencing = 0x40,
+ /// <summary>
+ /// Gaming/toy audio/video minor class type.
+ /// </summary>
+ AudioVideoGamingToy = 0x48,
+
+ /// <summary>
+ /// Uncategorized peripheral minor class type.
+ /// </summary>
+ PeripheralUncategorized = 0x00,
+ /// <summary>
+ /// Keyboard peripheral minor class type.
+ /// </summary>
+ PeripheralKeyBoard = 0x40,
+ /// <summary>
+ /// Pointing device peripheral minor class type.
+ /// </summary>
+ PeripheralPointingDevice = 0x80,
+ /// <summary>
+ /// Combo keyboard peripheral minor class type.
+ /// </summary>
+ PeripheralComboKeyboardPointingDevice = 0xC0,
+ /// <summary>
+ /// Joystick peripheral minor class type.
+ /// </summary>
+ PeripheralJoystick = 0x04,
+ /// <summary>
+ /// Game pad peripheral minor class type.
+ /// </summary>
+ PeripheralGamePad = 0x08,
+ /// <summary>
+ /// Remote control peripheral minor class type.
+ /// </summary>
+ PeripheralRemoteControl = 0x0C,
+ /// <summary>
+ /// Sensing device peripheral minor class type.
+ /// </summary>
+ PeripheralSensingDevice = 0x10,
+ /// <summary>
+ /// Digitizer peripheral minor class type.
+ /// </summary>
+ PeripheralDigitizerTablet = 0x14,
+ /// <summary>
+ /// Card reader peripheral minor class type.
+ /// </summary>
+ PeripheralCardReader = 0x18,
+ /// <summary>
+ /// Digital pen peripheral minor class type.
+ /// </summary>
+ PeripheralDigitalPen = 0x1C,
+ /// <summary>
+ /// Handheld scanner peripheral minor class type.
+ /// </summary>
+ PeripheralHandheldScanner = 0x20,
+ /// <summary>
+ /// Handheld gestural input computer minor class type.
+ /// </summary>
+ PeripheralHandheldGesturalInputDevice = 0x24,
+
+ /// <summary>
+ /// Display imaging minor class type.
+ /// </summary>
+ ImagingDisplay = 0x10,
+ /// <summary>
+ /// Camera imaging minor class type.
+ /// </summary>
+ ImagingCamera = 0x20,
+ /// <summary>
+ /// Scanner imaging minor class type.
+ /// </summary>
+ ImagingScanner = 0x40,
+ /// <summary>
+ /// Printer imaging minor class type.
+ /// </summary>
+ ImagingPrinter = 0x80,
+
+ /// <summary>
+ /// Wrist watch wearable minor class type.
+ /// </summary>
+ WearableWristWatch = 0x04,
+ /// <summary>
+ /// Pager wearable minor class type.
+ /// </summary>
+ WearablePager = 0x08,
+ /// <summary>
+ /// Jacket wearable minor class type.
+ /// </summary>
+ WearableJacket = 0x0C,
+ /// <summary>
+ /// Helmet wearable minor class type.
+ /// </summary>
+ WearableHelmet = 0x10,
+ /// <summary>
+ /// Glasses wearable minor class type.
+ /// </summary>
+ WearableGlasses = 0x14,
+
+ /// <summary>
+ /// Robot toy minor class type.
+ /// </summary>
+ ToyRobot = 0x04,
+ /// <summary>
+ /// Vehicle toy minor class type.
+ /// </summary>
+ ToyVehicle = 0x08,
+ /// <summary>
+ /// Doll toy minor class type.
+ /// </summary>
+ ToyDollAction = 0x0C,
+ /// <summary>
+ /// Controller toy minor class type.
+ /// </summary>
+ ToyController = 0x10,
+ /// <summary>
+ /// Game toy minor class type.
+ /// </summary>
+ ToyGame = 0x14,
+
+ /// <summary>
+ /// Uncategorized health minor class type.
+ /// </summary>
+ HealthUncategorized = 0x00,
+ /// <summary>
+ /// BP monitor health minor class type.
+ /// </summary>
+ HealthBloodPressureMonitor = 0x04,
+ /// <summary>
+ /// Thermometer health minor class type.
+ /// </summary>
+ HealthThermometer = 0x08,
+ /// <summary>
+ /// Scale health minor class type.
+ /// </summary>
+ HealthWeighingScale = 0x0C,
+ /// <summary>
+ /// Glucose meter health minor class type.
+ /// </summary>
+ HealthGlucoseMeter= 0x10,
+ /// <summary>
+ /// Pulse oximeter health minor class type.
+ /// </summary>
+ HealthPulseOximeter = 0x14,
+ /// <summary>
+ /// Heart/Pulse rate monitor health minor class type.
+ /// </summary>
+ HealthHeartPulseRateMonitor = 0x18,
+ /// <summary>
+ /// Display health minor class type.
+ /// </summary>
+ HealthDataDisplay = 0x1C,
+ /// <summary>
+ /// Step counter health minor class type.
+ /// </summary>
+ HealthStepCounter = 0x20,
+ /// <summary>
+ /// Body composition analyzer health minor class type.
+ /// </summary>
+ HealthBodyCompositionAnalyzer = 0x24,
+ /// <summary>
+ /// Peak flow monitor health minor class type.
+ /// </summary>
+ HealthPeakFlowMonitor = 0x28,
+ /// <summary>
+ /// Medication monitor health minor class type.
+ /// </summary>
+ HealthMedicationMonitor = 0x2C,
+ /// <summary>
+ /// Knee prosthesis health minor class type.
+ /// </summary>
+ HealthKneeProsthesis = 0x30,
+ /// <summary>
+ /// Ankle prosthesis health minor class type.
+ /// </summary>
+ HealthAnkleProsthesis = 0x34
+ }
+
+ /// <summary>
+ /// Enumeration for Bluetooth device discovery state.
+ /// </summary>
+ public enum BluetoothDeviceDiscoveryState
+ {
+ /// <summary>
+ /// Device discovery is started.
+ /// </summary>
+ Started = 0,
+ /// <summary>
+ /// Device discovery is finished.
+ /// </summary>
+ Finished,
+ /// <summary>
+ /// The remote device is found.
+ /// </summary>
+ Found
+ }
+
+ /// <summary>
+ /// Enumeration for Bluetooth appearance type.
+ /// </summary>
+ public enum BluetoothAppearanceType
+ {
+ /// <summary>
+ /// Unknown.
+ /// </summary>
+ Unknown = 0,
+ /// <summary>
+ /// Generic phone.
+ /// </summary>
+ GenericPhone = 1,
+ /// <summary>
+ /// Generic computer.
+ /// </summary>
+ GenericComputer = 2,
+ /// <summary>
+ /// Generic watch.
+ /// </summary>
+ GenericWatch = 3
+ }
+
+ /// <summary>
+ /// Enumeration for Bluetooth audio profile type.
+ /// </summary>
+ public enum BluetoothAudioProfileType
+ {
+ /// <summary>
+ /// All supported profiles of audio.
+ /// </summary>
+ All = 0,
+ /// <summary>
+ /// Headset and Hands-Free profile.
+ /// </summary>
+ HspHfp,
+ /// <summary>
+ /// Advanced audio distribution profile.
+ /// </summary>
+ AdvancedAudioDistribution,
+ /// <summary>
+ /// Audio Gateway profile.
+ /// </summary>
+ AudioGateway,
+ /// <summary>
+ /// Advanced Audio Distribution profile sink role.
+ /// </summary>
+ AdvancedAudioDistributionSink
+ }
+
+ /// <summary>
+ /// Enumeration for Bluetooth service class type.
+ /// </summary>
+ public enum BluetoothServiceClassType
+ {
+ /// <summary>
+ /// No service class.
+ /// </summary>
+ None = 0,
+ /// <summary>
+ /// Res service class.
+ /// </summary>
+ Res = 0x00000001,
+ /// <summary>
+ /// Spp service class.
+ /// </summary>
+ Spp = 0x00000002,
+ /// <summary>
+ /// Dun service class.
+ /// </summary>
+ Dun = 0x00000004,
+ /// <summary>
+ /// Fax service class.
+ /// </summary>
+ Fax = 0x00000008,
+ /// <summary>
+ /// Lap service class.
+ /// </summary>
+ Lap = 0x00000010,
+ /// <summary>
+ /// Hsp service class.
+ /// </summary>
+ Hsp = 0x00000020,
+ /// <summary>
+ /// Hfp service class.
+ /// </summary>
+ Hfp = 0x00000040,
+ /// <summary>
+ /// Opp service class.
+ /// </summary>
+ Opp = 0x00000080,
+ /// <summary>
+ /// Ftp service class.
+ /// </summary>
+ Ftp = 0x00000100,
+ /// <summary>
+ /// Ctp service class.
+ /// </summary>
+ Ctp = 0x00000200,
+ /// <summary>
+ /// Icp service class.
+ /// </summary>
+ Icp = 0x00000400,
+ /// <summary>
+ /// Sync service class.
+ /// </summary>
+ Sync = 0x00000800,
+ /// <summary>
+ /// Bpp service class.
+ /// </summary>
+ Bpp = 0x00001000,
+ /// <summary>
+ /// Bip service class.
+ /// </summary>
+ Bip = 0x00002000,
+ /// <summary>
+ /// Panu service class.
+ /// </summary>
+ Panu = 0x00004000,
+ /// <summary>
+ /// Nap service class.
+ /// </summary>
+ Nap = 0x00008000,
+ /// <summary>
+ /// Gn service class.
+ /// </summary>
+ Gn = 0x00010000,
+ /// <summary>
+ /// Sap service class.
+ /// </summary>
+ Sap = 0x00020000,
+ /// <summary>
+ /// A2dp service class.
+ /// </summary>
+ A2dp = 0x00040000,
+ /// <summary>
+ /// Avrcp service class.
+ /// </summary>
+ Avrcp = 0x00080000,
+ /// <summary>
+ /// Pbap service class.
+ /// </summary>
+ Pbap = 0x00100000,
+ /// <summary>
+ /// Hid service class.
+ /// </summary>
+ Hid = 0x00200000,
+ /// <summary>
+ /// A2dp Source service class.
+ /// </summary>
+ A2dpSource = 0x00400000,
+ /// <summary>
+ /// All service class.
+ /// </summary>
+ All = 0x00FFFFFF,
+ /// <summary>
+ /// Max service class.
+ /// </summary>
+ Max
+ }
+
+ /// <summary>
+ /// Enumeration for Bluetooth profile type.
+ /// </summary>
+ public enum BluetoothProfileType
+ {
+ /// <summary>
+ /// Rfcomm profile.
+ /// </summary>
+ Rfcomm = 0,
+ /// <summary>
+ /// Advanced Audio Distribution Profile Source role
+ /// </summary>
+ AdvancedAudioDistribution,
+ /// <summary>
+ /// Headset profile.
+ /// </summary>
+ Headset,
+ /// <summary>
+ /// Human Interface Device profile.
+ /// </summary>
+ HumanInterfaceDevice,
+ /// <summary>
+ /// Network Access Point profile.
+ /// </summary>
+ NetworkAccessPoint,
+ /// <summary>
+ /// Audio Gateway profile.
+ /// </summary>
+ AudioGateway,
+ /// <summary>
+ /// Generic Attribute profile.
+ /// </summary>
+ GenericAttribute,
+ /// <summary>
+ /// Nap Server profile.
+ /// </summary>
+ NapServer,
+ /// <summary>
+ /// Advanced Audio Distribution profile sink role.
+ /// </summary>
+ AdvancedAudioDistributionSink
+ }
+
+ /// <summary>
+ /// Enumeration for Bluetooth authorization type.
+ /// </summary>
+ public enum BluetoothAuthorizationType
+ {
+ /// <summary>
+ /// Authorized type.
+ /// </summary>
+ Authorized = 0,
+ /// <summary>
+ /// Unauthorized type.
+ /// </summary>
+ Unauthorized
+ }
+
+ /// <summary>
+ /// Enumeration for Bluetooth connection link type.
+ /// </summary>
+ public enum BluetoothConnectionLinkType
+ {
+ /// <summary>
+ /// BR/EDR link.
+ /// </summary>
+ BrEdr = 0,
+ /// <summary>
+ /// LE link.
+ /// </summary>
+ Le,
+ /// <summary>
+ /// The default connection type.
+ /// </summary>
+ Default
+ }
+
+ /// <summary>
+ /// Enumeration for Bluetooth disconnect reason.
+ /// </summary>
+ public enum BluetoothDisconnectReason
+ {
+ /// <summary>
+ /// Disconnected by unknown reason.
+ /// </summary>
+ Unknown = 0,
+ /// <summary>
+ /// Disconnected by timeout.
+ /// </summary>
+ Timeout,
+ /// <summary>
+ /// Disconnected by local host.
+ /// </summary>
+ LocalHost,
+ /// <summary>
+ /// Disconnected by remote.
+ /// </summary>
+ Remote
+ }
+
+ /// <summary>
+ /// Enumerations of connected Bluetooth device event role.
+ /// </summary>
+ public enum BluetoothSocketRole
+ {
+ /// <summary>
+ /// Unknown role.
+ /// </summary>
+ Unknown,
+ /// <summary>
+ /// Server role.
+ /// </summary>
+ Server,
+ /// <summary>
+ /// Client role.
+ /// </summary>
+ Client
+ }
+
+ /// <summary>
+ /// Enumerations of Bluetooth socket connection state.
+ /// </summary>
+ public enum BluetoothSocketState
+ {
+ /// <summary>
+ /// RFCOMM is connected.
+ /// </summary>
+ Connected,
+ /// <summary>
+ /// RFCOMM is disconnected.
+ /// </summary>
+ Disconnected
+ }
+
+ /// <summary>
+ /// Enumeration for equalizer state.
+ /// </summary>
+ public enum EqualizerState
+ {
+ /// <summary>
+ /// Equalizer Off.
+ /// </summary>
+ Off = 0,
+ /// <summary>
+ /// Equalizer On.
+ /// </summary>
+ On
+ }
+
+ /// <summary>
+ /// Enumeration for repeat mode.
+ /// </summary>
+ public enum RepeatMode
+ {
+ /// <summary>
+ /// Repeat off.
+ /// </summary>
+ Off = 0,
+ /// <summary>
+ /// Single track repeat.
+ /// </summary>
+ SingleTrack,
+ /// <summary>
+ /// All track repeat.
+ /// </summary>
+ AllTrack,
+ /// <summary>
+ /// Group repeat.
+ /// </summary>
+ Group
+ }
+
+ /// <summary>
+ /// Enumeration for shuffle mode.
+ /// </summary>
+ public enum ShuffleMode
+ {
+ /// <summary>
+ /// Shuffle off.
+ /// </summary>
+ Off = 0,
+ /// <summary>
+ /// All tracks shuffle.
+ /// </summary>
+ AllTrack,
+ /// <summary>
+ /// Group shuffle.
+ /// </summary>
+ Group
+ }
+
+ /// <summary>
+ /// Enumeration for scan mode.
+ /// </summary>
+ public enum ScanMode
+ {
+ /// <summary>
+ /// Scan off.
+ /// </summary>
+ Off = 0,
+ /// <summary>
+ /// All tracks scan.
+ /// </summary>
+ AllTrack,
+ /// <summary>
+ /// Group scan.
+ /// </summary>
+ Group
+ }
+
+ /// <summary>
+ /// Enumeration for player state.
+ /// </summary>
+ public enum PlayerState
+ {
+ /// <summary>
+ /// Stopped state.
+ /// </summary>
+ Stopped = 0,
+ /// <summary>
+ /// Playing state.
+ /// </summary>
+ Playing,
+ /// <summary>
+ /// Paused state.
+ /// </summary>
+ Paused,
+ /// <summary>
+ /// Seek forward state.
+ /// </summary>
+ SeekForward,
+ /// <summary>
+ /// Seek rewind state.
+ /// </summary>
+ SeekRewind
+ }
+
+ /// <summary>
+ /// Enumeration for Bluetooth Le device address type.
+ /// </summary>
+ public enum BluetoothLeDeviceAddressType
+ {
+ /// <summary>
+ /// The bluetooth le public address.
+ /// </summary>
+ BluetoothLePublicAddress,
+ /// <summary>
+ /// The bluetooth le private address.
+ /// </summary>
+ BluetoothLePrivateAddress
+ }
+
+ /// <summary>
+ /// Enumeration for Bluetooth LePacket type.
+ /// </summary>
+ public enum BluetoothLePacketType
+ {
+ /// <summary>
+ /// The bluetooth le advertising packet.
+ /// </summary>
+ BluetoothLeAdvertisingPacket,
+ /// <summary>
+ /// The bluetooth le scan response packet.
+ /// </summary>
+ BluetoothLeScanResponsePacket
+ }
+
+ /// <summary>
+ /// Enumeration for Bluetooth Le data type.
+ /// </summary>
+ public enum BluetoothLeDataType
+ {
+ /// <summary>
+ /// The bluetooth le packet data list 16 bit service uuid.
+ /// </summary>
+ BluetoothLePacketDataList16BitServiceUuid,
+ /// <summary>
+ /// The bluetooth le packet manufacturer data.
+ /// </summary>
+ BluetoothLePacketManufacturerData
+ }
+
+ /// <summary>
+ /// Enumeration for Bluetooth Le Advertising mode type.
+ /// </summary>
+ public enum BluetoothLeAdvertisingMode
+ {
+ /// <summary>
+ /// The bluetooth le advertising balanced mode.
+ /// </summary>
+ BluetoothLeAdvertisingBalancedMode,
+ /// <summary>
+ /// The bluetooth le advertising low latency mode.
+ /// </summary>
+ BluetoothLeAdvertisingLowLatencyMode,
+ /// <summary>
+ /// The bluetooth le advertising low energy mode.
+ /// </summary>
+ BluetoothLeAdvertisingLowEnergyMode
+ }
+
+ /// <summary>
+ /// Enumeration for Bluetooth Le Advertising mode type.
+ /// </summary>
+ public enum BluetoothLeAdvertisingState
+ {
+ /// <summary>
+ /// The bluetooth le advertising stopped.
+ /// </summary>
+ BluetoothLeAdvertisingStopped,
+ /// <summary>
+ /// The bluetooth le advertising started.
+ /// </summary>
+ BluetoothLeAdvertisingStarted
+ }
+
+ /// <summary>
+ /// Enumerations of the integer type for GATT handle's value.
+ /// </summary>
+ public enum IntDataType
+ {
+ /// <summary>
+ /// 8 bit signed int type.
+ /// </summary>
+ SignedInt8,
+ /// <summary>
+ /// 16 bit signed int type.
+ /// </summary>
+ SignedInt16,
+ /// <summary>
+ /// 32 bit signed int type.
+ /// </summary>
+ SignedInt32,
+ /// <summary>
+ /// 8 bit unsigned int type.
+ /// </summary>
+ UnsignedInt8,
+ /// <summary>
+ /// 16 bit unsigned int type.
+ /// </summary>
+ UnsignedInt16,
+ /// <summary>
+ /// 32 bit unsigned int type.
+ /// </summary>
+ UnsignedInt32
+ }
+
+ /// <summary>
+ /// Enumerations of the float type for GATT handle's value.
+ /// </summary>
+ public enum FloatDataType
+ {
+ /// <summary>
+ /// 32 bit float type.
+ /// </summary>
+ Float,
+ /// <summary>
+ /// 16 bit float type.
+ /// </summary>
+ SFloat,
+ }
+
+ /// <summary>
+ /// Enumerations of the GATT handle's type.
+ /// </summary>
+ public enum GattHandleType
+ {
+ /// <summary>
+ /// GATT service type.
+ /// </summary>
+ Service,
+ /// <summary>
+ /// GATT characteristic type.
+ /// </summary>
+ Characteristic,
+ /// <summary>
+ /// GATT descriptor type.
+ /// </summary>
+ Descriptor
+ }
+
+ /// <summary>
+ /// Enumerations of the service type.
+ /// </summary>
+ public enum BluetoothGattServiceType
+ {
+ /// <summary>
+ /// GATT primary service type.
+ /// </summary>
+ Primary,
+ /// <summary>
+ /// GATT secondary service type.
+ /// </summary>
+ Secondary
+ }
+
+ /// <summary>
+ /// Enumerations of the characteristic's property.
+ /// </summary>
+ [Flags]
+ public enum BluetoothGattProperty
+ {
+ /// <summary>
+ /// Broadcast property.
+ /// </summary>
+ Broadcast = 1,
+ /// <summary>
+ /// Read property.
+ /// </summary>
+ Read = 2,
+ /// <summary>
+ /// Write without response property.
+ /// </summary>
+ WriteWithoutResponse = 4,
+ /// <summary>
+ /// Write property.
+ /// </summary>
+ Write = 8,
+ /// <summary>
+ /// Notify property.
+ /// </summary>
+ Notify = 16,
+ /// <summary>
+ /// Indicate property.
+ /// </summary>
+ Indicate = 32,
+ /// <summary>
+ /// Authenticated signed writes property.
+ /// </summary>
+ AuthenticatedSignedWrites = 64,
+ /// <summary>
+ /// Extended properties.
+ /// </summary>
+ ExtendedProperties = 128,
+ }
+
+ /// <summary>
+ /// Enumerations of bluetooth gatt permission type.
+ /// </summary>
+ [Flags]
+ public enum BluetoothGattPermission
+ {
+ /// <summary>
+ /// Read permission.
+ /// </summary>
+ Read = 1,
+ /// <summary>
+ /// Write permission.
+ /// </summary>
+ Write = 2,
+ }
+
+ /// <summary>
+ /// Enumerations of the write type.
+ /// </summary>
+ public enum BluetoothGattWriteType
+ {
+ /// <summary>
+ /// Write without response.
+ /// </summary>
+ NoResponse,
+ /// <summary>
+ /// Write with response.
+ /// </summary>
+ WriteWithResponse
+ }
+
+ /// <summary>
+ /// Enumerations of the remote device request types for attributes
+ /// </summary>
+ public enum BluetoothGattRequestType
+ {
+ /// <summary>
+ /// Read Requested.
+ /// </summary>
+ Read = 0,
+ /// <summary>
+ /// Write Requested.
+ /// </summary>
+ Write = 1,
+ }
+}
diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothError.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothError.cs
new file mode 100644
index 0000000..76ab207
--- /dev/null
+++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothError.cs
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Network.Bluetooth
+{
+ static internal class BluetoothErrorFactory
+ {
+ static internal void ThrowBluetoothException(int exception)
+ {
+ BluetoothError error = (BluetoothError)exception;
+ switch (error)
+ {
+ case BluetoothError.InvalidParameter:
+ throw new InvalidOperationException("Invalid parameter");
+
+ case BluetoothError.Cancelled:
+ throw new InvalidOperationException("Operation cancelled");
+
+ case BluetoothError.AlreadyDone:
+ throw new InvalidOperationException("Operation already done");
+
+ case BluetoothError.TimedOut:
+ throw new InvalidOperationException("Timeout error");
+
+ case BluetoothError.AuthFailed:
+ throw new InvalidOperationException("Authentication failed");
+
+ case BluetoothError.AuthRejected:
+ throw new InvalidOperationException("Authentication rejected");
+
+ case BluetoothError.NoData:
+ throw new InvalidOperationException("No data available");
+
+ case BluetoothError.NotEnabled:
+ throw new InvalidOperationException("Local adapter not enabled");
+
+ case BluetoothError.NotInitialized:
+ throw new InvalidOperationException("Local adapter not initialized");
+
+ case BluetoothError.NowInProgress:
+ throw new InvalidOperationException("Operation now in progress");
+
+ case BluetoothError.NotInProgress:
+ throw new InvalidOperationException("Operation not in progress");
+
+ case BluetoothError.NotSupported:
+ throw new InvalidOperationException("Bluetooth is not supported");
+
+ case BluetoothError.OperationFailed:
+ throw new InvalidOperationException("Operation failed");
+
+ case BluetoothError.OutOfMemory:
+ throw new InvalidOperationException("Out of memory");
+
+ case BluetoothError.PermissionDenied:
+ throw new InvalidOperationException("Permission denied");
+
+ case BluetoothError.QuotaExceeded:
+ throw new InvalidOperationException("Quota exceeded");
+
+ case BluetoothError.RemoteDeviceNotBonded:
+ throw new InvalidOperationException("Remote device not bonded");
+
+ case BluetoothError.RemoteDeviceNotConnected:
+ throw new InvalidOperationException("Remote device not connected");
+
+ case BluetoothError.RemoteDeviceNotFound:
+ throw new InvalidOperationException("Remote device not found");
+
+ case BluetoothError.ResourceBusy:
+ throw new InvalidOperationException("Device or resource busy");
+
+ case BluetoothError.ResourceUnavailable:
+ throw new InvalidOperationException("Resource temporarily unavailable");
+
+ case BluetoothError.ServiceNotFound:
+ throw new InvalidOperationException("Service Not Found");
+
+ case BluetoothError.ServiceSearchFailed:
+ throw new InvalidOperationException("Service search failed");
+
+ default:
+ throw new InvalidOperationException("Unknown exception");
+ }
+ }
+ }
+}
+
diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothEventArgs.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothEventArgs.cs
new file mode 100755
index 0000000..563ba87
--- /dev/null
+++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothEventArgs.cs
@@ -0,0 +1,1044 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Network.Bluetooth
+{
+ /// <summary>
+ /// An extended EventArgs class which contains changed Bluetooth state.
+ /// </summary>
+ public class StateChangedEventArgs : EventArgs
+ {
+ private BluetoothState _type;
+ private BluetoothError _result;
+
+ internal StateChangedEventArgs(BluetoothError result, BluetoothState type)
+ {
+ _type = type;
+ _result = result;
+ }
+
+ /// <summary>
+ /// The state of Bluetooth.
+ /// </summary>
+ public BluetoothState BTState
+ {
+ get
+ {
+ return _type;
+ }
+ }
+
+ /// <summary>
+ /// The BluetoothError result.
+ /// </summary>
+ public BluetoothError Result
+ {
+ get
+ {
+ return _result;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains changed Bluetooth name.
+ /// </summary>
+ public class NameChangedEventArgs : EventArgs
+ {
+ private string _name;
+
+ internal NameChangedEventArgs(string name)
+ {
+ _name = name;
+ }
+
+ /// <summary>
+ /// The name of the device.
+ /// </summary>
+ public string DeviceName
+ {
+ get
+ {
+ return _name;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains changed Bluetooth visibility mode.
+ /// </summary>
+ public class VisibilityModeChangedEventArgs : EventArgs
+ {
+ private VisibilityMode _mode;
+ private BluetoothError _result;
+
+ internal VisibilityModeChangedEventArgs(BluetoothError result, VisibilityMode mode)
+ {
+ _result = result;
+ _mode = mode;
+ }
+
+ /// <summary>
+ /// The visibility mode.
+ /// </summary>
+ public VisibilityMode Visibility
+ {
+ get
+ {
+ return _mode;
+ }
+ }
+
+ /// <summary>
+ /// The BluetoothError result.
+ /// </summary>
+ public BluetoothError Result
+ {
+ get
+ {
+ return _result;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains the duration until the visibility mode is changed from TimeLimitedDiscoverable to NonDiscoverable.
+ /// </summary>
+ public class VisibilityDurationChangedEventArgs : EventArgs
+ {
+ private int _duration;
+
+ internal VisibilityDurationChangedEventArgs(int duration)
+ {
+ _duration = duration;
+ }
+
+ /// <summary>
+ /// The duration.
+ /// </summary>
+ public int Duration
+ {
+ get
+ {
+ return _duration;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains changed Bluetooth device discovery state and the discovered device information.
+ /// </summary>
+ public class DiscoveryStateChangedEventArgs : EventArgs
+ {
+ private BluetoothError _result;
+ private BluetoothDeviceDiscoveryState _state;
+ private BluetoothDevice _device;
+
+ internal DiscoveryStateChangedEventArgs(BluetoothError result, BluetoothDeviceDiscoveryState state)
+ {
+ _result = result;
+ _state = state;
+ }
+
+ internal DiscoveryStateChangedEventArgs(BluetoothError result, BluetoothDeviceDiscoveryState state, BluetoothDevice device)
+ {
+ _result = result;
+ _state = state;
+ _device = device;
+ }
+
+ /// <summary>
+ /// The BluetoothError result.
+ /// </summary>
+ public BluetoothError Result
+ {
+ get
+ {
+ return _result;
+ }
+ }
+
+ /// <summary>
+ /// The state of the discovery.
+ /// </summary>
+ public BluetoothDeviceDiscoveryState DiscoveryState
+ {
+ get
+ {
+ return _state;
+ }
+ }
+
+ /// <summary>
+ /// The remote device found.
+ /// </summary>
+ public BluetoothDevice DeviceFound
+ {
+ get
+ {
+ return _device;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains the bonded device information.
+ /// </summary>
+ public class BondCreatedEventArgs : EventArgs
+ {
+ private BluetoothError _result;
+ private BluetoothDevice _device;
+
+ internal BondCreatedEventArgs(BluetoothError result, BluetoothDevice device)
+ {
+ _result = result;
+ _device = device;
+ }
+
+ /// <summary>
+ /// The BluetoothError result.
+ /// </summary>
+ public BluetoothError Result
+ {
+ get
+ {
+ return _result;
+ }
+ }
+
+ /// <summary>
+ /// The remote device.
+ /// </summary>
+ public BluetoothDevice Device
+ {
+ get
+ {
+ return _device;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains the address of the remote Bluetooth device to destroy bond with.
+ /// </summary>
+ public class BondDestroyedEventArgs : EventArgs
+ {
+ private BluetoothError _result;
+ private string _address;
+
+ internal BondDestroyedEventArgs(BluetoothError result, string address)
+ {
+ _result = result;
+ _address = address;
+ }
+
+ /// <summary>
+ /// The BluetoothError result.
+ /// </summary>
+ public BluetoothError Result
+ {
+ get
+ {
+ return _result;
+ }
+ }
+
+ /// <summary>
+ /// The remote device address.
+ /// </summary>
+ /// <value>The device address.</value>
+ public string DeviceAddress
+ {
+ get
+ {
+ return _address;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains the authorization state and address of the remote Bluetooth device.
+ /// </summary>
+ public class AuthorizationChangedEventArgs : EventArgs
+ {
+ private BluetoothAuthorizationType _authType;
+ private string _address;
+
+ internal AuthorizationChangedEventArgs(BluetoothAuthorizationType authType, string address)
+ {
+ _authType = authType;
+ _address = address;
+ }
+
+ /// <summary>
+ /// The authorization.
+ /// </summary>
+ public BluetoothAuthorizationType Authorization
+ {
+ get
+ {
+ return _authType;
+ }
+ }
+
+ /// <summary>
+ /// The device address.
+ /// </summary>
+ public string DeviceAddress
+ {
+ get
+ {
+ return _address;
+ }
+ }
+
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains the service lists found on the remote Bluetooth device.
+ /// </summary>
+ public class ServiceSearchedEventArgs : EventArgs
+ {
+ private BluetoothDeviceSdpData _sdpData;
+ private BluetoothError _result;
+
+ internal ServiceSearchedEventArgs(BluetoothError result, BluetoothDeviceSdpData sdpData)
+ {
+ _result = result;
+ _sdpData = sdpData;
+ }
+
+ /// <summary>
+ /// The BluetoothError result.
+ /// </summary>
+ public BluetoothError Result
+ {
+ get
+ {
+ return _result;
+ }
+ }
+ /// <summary>
+ /// The sdp data.
+ /// </summary>
+ public BluetoothDeviceSdpData SdpData
+ {
+ get
+ {
+ return _sdpData;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains the connection state and connection information of the remote device.
+ /// </summary>
+ public class DeviceConnectionStateChangedEventArgs : EventArgs
+ {
+ private bool _isConnected;
+ private BluetoothDeviceConnectionData _connectionData;
+
+ internal DeviceConnectionStateChangedEventArgs(bool isConnected, BluetoothDeviceConnectionData connectionData)
+ {
+ _isConnected = isConnected;
+ _connectionData = connectionData;
+ }
+
+ /// <summary>
+ /// A value indicating whether the device is connected.
+ /// </summary>
+ public bool IsConnected
+ {
+ get
+ {
+ return _isConnected;
+ }
+ }
+
+ /// <summary>
+ /// The device connection data.
+ /// </summary>
+ public BluetoothDeviceConnectionData ConnectionData
+ {
+ get
+ {
+ return _connectionData;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains data received information.
+ /// </summary>
+ public class SocketDataReceivedEventArgs : EventArgs
+ {
+ private SocketData _data;
+
+ internal SocketDataReceivedEventArgs(SocketData data)
+ {
+ _data = data;
+ }
+
+ /// <summary>
+ /// The socket data.
+ /// </summary>
+ public SocketData Data
+ {
+ get
+ {
+ return _data;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains changed connection state.
+ /// </summary>
+ public class SocketConnectionStateChangedEventArgs : EventArgs
+ {
+ private BluetoothError _result;
+ private BluetoothSocketState _state;
+ private SocketConnection _connection;
+
+ internal SocketConnectionStateChangedEventArgs(BluetoothError result, BluetoothSocketState state, SocketConnection connection)
+ {
+ _result = result;
+ _state = state;
+ _connection = connection;
+ }
+
+ /// <summary>
+ /// The BluetoothError result.
+ /// </summary>
+ public BluetoothError Result
+ {
+ get
+ {
+ return _result;
+ }
+ }
+
+ /// <summary>
+ /// The socket state.
+ /// </summary>
+ public BluetoothSocketState State
+ {
+ get
+ {
+ return _state;
+ }
+ }
+
+ /// <summary>
+ /// The socket connection.
+ /// </summary>
+ public SocketConnection Connection
+ {
+ get
+ {
+ return _connection;
+ }
+ }
+ }
+
+ public class AcceptStateChangedEventArgs : EventArgs
+ {
+ private BluetoothError _result;
+ private BluetoothSocketState _state;
+ private SocketConnection _connection;
+ private IBluetoothServerSocket _server;
+
+ internal AcceptStateChangedEventArgs(BluetoothError result, BluetoothSocketState state, SocketConnection connection, BluetoothSocket server)
+ {
+ _result = result;
+ _state = state;
+ _connection = connection;
+ _server = (IBluetoothServerSocket)server;
+ }
+
+ /// <summary>
+ /// The BluetoothError result.
+ /// </summary>
+ public BluetoothError Result
+ {
+ get
+ {
+ return _result;
+ }
+ }
+
+ /// <summary>
+ /// The socket state.
+ /// </summary>
+ public BluetoothSocketState State
+ {
+ get
+ {
+ return _state;
+ }
+ }
+
+ /// <summary>
+ /// The socket connection.
+ /// </summary>
+ public SocketConnection Connection
+ {
+ get
+ {
+ return _connection;
+ }
+ }
+
+ /// <summary>
+ /// The server socket instance.
+ /// </summary>
+ public IBluetoothServerSocket Server
+ {
+ get
+ {
+ return _server;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains the connection state,remote address and the type of audio profile.
+ /// </summary>
+ public class AudioConnectionStateChangedEventArgs : EventArgs
+ {
+ private int _result;
+ private bool _isConnected;
+ private string _address;
+ private BluetoothAudioProfileType _type;
+
+ internal AudioConnectionStateChangedEventArgs(int result, bool isConnected, string address, BluetoothAudioProfileType type)
+ {
+ _result = result;
+ _type = type;
+ _isConnected = isConnected;
+ _address = address;
+ }
+
+ /// <summary>
+ /// The result.
+ /// </summary>
+ public int Result
+ {
+ get
+ {
+ return _result;
+ }
+ }
+
+ /// <summary>
+ /// A value indicating whether this instance is connected.
+ /// </summary>
+ public bool IsConnected
+ {
+ get
+ {
+ return _isConnected;
+ }
+ }
+
+ /// <summary>
+ /// The address.
+ /// </summary>
+ public string Address
+ {
+ get
+ {
+ return _address;
+ }
+ }
+
+ /// <summary>
+ /// The type of the audio profile.
+ /// </summary>
+ public BluetoothAudioProfileType ProfileType
+ {
+ get
+ {
+ return _type;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains the connection state and address of the remote Bluetooth device.
+ /// </summary>
+ public class HidConnectionStateChangedEventArgs : EventArgs
+ {
+ private int _result;
+ private bool _isConnected;
+ private string _address;
+
+ internal HidConnectionStateChangedEventArgs(int result, bool isConnected, string address)
+ {
+ _result = result;
+ _isConnected = isConnected;
+ _address = address;
+ }
+
+ /// <summary>
+ /// The result.
+ /// </summary>
+ public int Result
+ {
+ get
+ {
+ return _result;
+ }
+ }
+
+ /// <summary>
+ /// A value indicating whether this instance is connected.
+ /// </summary>
+ public bool IsConnected
+ {
+ get
+ {
+ return _isConnected;
+ }
+ }
+
+ /// <summary>
+ /// The address.
+ /// </summary>
+ public string Address
+ {
+ get
+ {
+ return _address;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains the changed equalizer state.
+ /// </summary>
+ public class EqualizerStateChangedEventArgs : EventArgs
+ {
+ private EqualizerState _state;
+
+ internal EqualizerStateChangedEventArgs(EqualizerState state)
+ {
+ _state = state;
+ }
+
+ /// <summary>
+ /// The state of equalizer.
+ /// </summary>
+ public EqualizerState State
+ {
+ get
+ {
+ return _state;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains the changed repeat mode.
+ /// </summary>
+ public class RepeatModeChangedEventArgs : EventArgs
+ {
+ private RepeatMode _mode;
+
+ internal RepeatModeChangedEventArgs(RepeatMode mode)
+ {
+ _mode = mode;
+ }
+
+ /// <summary>
+ /// The repeat mode.
+ /// </summary>
+ public RepeatMode Mode
+ {
+ get
+ {
+ return _mode;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains the changed shuffle mode.
+ /// </summary>
+ public class ShuffleModeChangedeventArgs : EventArgs
+ {
+ private ShuffleMode _mode;
+
+ internal ShuffleModeChangedeventArgs(ShuffleMode mode)
+ {
+ _mode = mode;
+ }
+
+ /// <summary>
+ /// The shuffle mode.
+ /// </summary>
+ public ShuffleMode Mode
+ {
+ get
+ {
+ return _mode;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains the changed scan mode.
+ /// </summary>
+ public class ScanModeChangedEventArgs : EventArgs
+ {
+ private ScanMode _mode;
+
+ internal ScanModeChangedEventArgs(ScanMode mode)
+ {
+ _mode = mode;
+ }
+
+ /// <summary>
+ /// The scan mode.
+ /// </summary>
+ public ScanMode Mode
+ {
+ get
+ {
+ return _mode;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains the connection state and the remote device address.
+ /// </summary>
+ public class TargetConnectionStateChangedEventArgs : EventArgs
+ {
+ private bool _isConnected;
+ private string _address;
+
+ internal TargetConnectionStateChangedEventArgs(bool isConnected, string address)
+ {
+ _isConnected = isConnected;
+ _address = address;
+ }
+
+ /// <summary>
+ /// A value indicating whether this instance is connected.
+ /// </summary>
+ public bool IsConnected
+ {
+ get
+ {
+ return _isConnected;
+ }
+ }
+
+ /// <summary>
+ /// The address.
+ /// </summary>
+ public string Address
+ {
+ get
+ {
+ return _address;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains changed Bluetooth LE advertising state changed information.
+ /// </summary>
+ public class AdvertisingStateChangedEventArgs : EventArgs
+ {
+ private BluetoothLeAdvertisingState _state;
+ private int _result;
+ private IntPtr _advertiserHandle;
+
+ //TODO : Add conversion code from IntPtr to BluetoothLeAdvertiser class later
+ internal AdvertisingStateChangedEventArgs(int result, IntPtr advertiserHandle,
+ BluetoothLeAdvertisingState state)
+ {
+ _result = result;
+ _advertiserHandle = advertiserHandle;
+ _state = state;
+ }
+
+ /// <summary>
+ /// The result.
+ /// </summary>
+ public int Result
+ {
+ get
+ {
+ return _result;
+ }
+ }
+
+ /// <summary>
+ /// The advertiser handle.
+ /// </summary>
+ public IntPtr AdvertiserHandle
+ {
+ get
+ {
+ return _advertiserHandle;
+ }
+ }
+
+ /// <summary>
+ /// The Le advertising state.
+ /// </summary>
+ public BluetoothLeAdvertisingState State
+ {
+ get
+ {
+ return _state;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains changed Bluetooth LE scan result information.
+ /// </summary>
+ public class AdapterLeScanResultChangedEventArgs : EventArgs
+ {
+ private BluetoothLeDevice _deviceData;
+ private BluetoothError _result;
+
+ internal AdapterLeScanResultChangedEventArgs(BluetoothError result, BluetoothLeDevice deviceData)
+ {
+ _deviceData = deviceData;
+ _result = result;
+ }
+
+ /// <summary>
+ /// The result.
+ /// </summary>
+ public BluetoothError Result
+ {
+ get
+ {
+ return _result;
+ }
+ }
+
+ /// <summary>
+ /// The Le device data.
+ /// </summary>
+ public BluetoothLeDevice DeviceData
+ {
+ get
+ {
+ return _deviceData;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains changed Bluetooth LE GATT connection state.
+ /// </summary>
+ public class GattConnectionStateChangedEventArgs : EventArgs
+ {
+ private bool _isConnected;
+ private int _result;
+ private string _remoteAddress;
+
+ internal GattConnectionStateChangedEventArgs(int result, bool connected, string remoteAddress)
+ {
+ _isConnected = connected;
+ _result = result;
+ _remoteAddress = remoteAddress;
+ }
+
+ /// <summary>
+ /// The result.
+ /// </summary>
+ public int Result
+ {
+ get
+ {
+ return _result;
+ }
+ }
+
+ /// <summary>
+ /// A value indicating whether this instance is connected.
+ /// </summary>
+ public bool IsConnected
+ {
+ get
+ {
+ return _isConnected;
+ }
+ }
+
+ /// <summary>
+ /// The remote address.
+ /// </summary>
+ public string RemoteAddress
+ {
+ get
+ {
+ return _remoteAddress;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains changed attribute value.
+ /// </summary>
+ public class ValueChangedEventArgs : EventArgs
+ {
+ internal ValueChangedEventArgs(byte[] value)
+ {
+ Value = value;
+ }
+
+ /// <summary>
+ /// The attribute value.
+ /// </summary>
+ public byte[] Value { get; }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains read value request data.
+ /// </summary>
+ public class ReadRequestedEventArgs : EventArgs
+ {
+ internal ReadRequestedEventArgs(BluetoothGattServer server, string clientAddress, int requestId, int offset)
+ {
+ Server = server;
+ ClientAddress = clientAddress;
+ RequestId = requestId;
+ Offset = offset;
+ }
+
+ /// <summary>
+ /// The gatt server instance.
+ /// </summary>
+ public BluetoothGattServer Server { get; }
+ /// <summary>
+ /// The client address.
+ /// </summary>
+ public string ClientAddress { get; }
+ /// <summary>
+ /// The request identifier.
+ /// </summary>
+ public int RequestId { get; }
+ /// <summary>
+ /// The offset.
+ /// </summary>
+ public int Offset { get; }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains read value request data.
+ /// </summary>
+ public class WriteRequestedEventArgs : EventArgs
+ {
+ internal WriteRequestedEventArgs(BluetoothGattServer server, string clientAddress, int requestId, byte[] value, int offset, bool response_needed)
+ {
+ Server = server;
+ ClientAddress = clientAddress;
+ RequestId = requestId;
+ Value = value;
+ Offset = offset;
+ Response_needed = response_needed;
+ }
+
+ /// <summary>
+ /// The gatt server instance.
+ /// </summary>
+ public BluetoothGattServer Server { get; }
+ /// <summary>
+ /// The client address.
+ /// </summary>
+ public string ClientAddress { get; }
+ /// <summary>
+ /// The request identifier.
+ /// </summary>
+ public int RequestId { get; }
+ /// <summary>
+ /// The read value.
+ /// </summary>
+ public byte[] Value { get; }
+ /// <summary>
+ /// The offset.
+ /// </summary>
+ public int Offset { get; }
+ /// <summary>
+ /// Indicates whether a response is required by the remote device.
+ /// </summary>
+ public bool Response_needed { get; }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains client preference to enables or disables the Notification/Indication.
+ /// </summary>
+ public class NotificationStateChangedEventArg : EventArgs
+ {
+ internal NotificationStateChangedEventArg(BluetoothGattServer server, bool value)
+ {
+ Server = server;
+ Value = value;
+ }
+
+ /// <summary>
+ /// The gatt server instance.
+ /// </summary>
+ public BluetoothGattServer Server { get; }
+ /// <summary>
+ /// A value indicating whether the notification is enabled
+ /// </summary>
+ public bool Value { get; }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains read value request data.
+ /// </summary>
+ public class NotificationSentEventArg : EventArgs
+ {
+ internal NotificationSentEventArg(BluetoothGattServer server, string clientAddress, int result, bool completed)
+ {
+ Result = result;
+ ClientAddress = clientAddress;
+ Server = server;
+ Completed = completed;
+ }
+
+ /// <summary>
+ /// The gatt server instance.
+ /// </summary>
+ public BluetoothGattServer Server { get; }
+ /// <summary>
+ /// The client address.
+ /// </summary>
+ public string ClientAddress { get; }
+ /// <summary>
+ /// The result.
+ /// </summary>
+ public int Result { get; }
+ /// <summary>
+ /// Gets a value indicating whether notification sent is completed.
+ /// </summary>
+ public bool Completed { get; }
+ }
+}
diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothGatt.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothGatt.cs
new file mode 100755
index 0000000..98c5218
--- /dev/null
+++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothGatt.cs
@@ -0,0 +1,928 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tizen.Network.Bluetooth
+{
+ /// <summary>
+ /// Bluetooth GATT server
+ /// </summary>
+ public class BluetoothGattServer
+ {
+ private static BluetoothGattServer _instance;
+ private BluetoothGattServerImpl _impl;
+ private BluetoothGattServer()
+ {
+ _impl = new BluetoothGattServerImpl();
+ }
+
+ /// <summary>
+ /// (event) called when indication acknowledgement received, once for each notified client
+ /// </summary>
+ public event EventHandler<NotificationSentEventArg> NotificationSent
+ {
+ add
+ {
+ _impl._notificationSent += value;
+ }
+ remove
+ {
+ _impl._notificationSent -= value;
+ }
+ }
+
+ /// <summary>
+ /// Creates bluetooth gatt server
+ /// </summary>
+ /// <returns></returns>
+ public static BluetoothGattServer CreateServer()
+ {
+ if (_instance == null)
+ {
+ BluetoothGattServer server = new BluetoothGattServer();
+ if (server.IsValid())
+ {
+ _instance = server;
+ }
+ }
+ return _instance;
+ }
+
+ /// <summary>
+ /// Registers the server along with the GATT services of the application it is hosting
+ /// </summary>
+ public void Start()
+ {
+ _impl.Start();
+ }
+
+ /// <summary>
+ /// Registers a specified service to this server
+ /// </summary>
+ /// <param name="service">service, which needs to be registered with this server</param>
+ public void RegisterGattService(BluetoothGattService service)
+ {
+ if (service.IsRegistered())
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.InvalidParameter);
+ }
+ _impl.RegisterGattService(this, service);
+ }
+
+ /// <summary>
+ /// Unregisters a specified service from this server
+ /// </summary>
+ /// <param name="service">service, which needs to be unregistered from this server</param>
+ /// <remarks>
+ /// Once unregistered, service object will become invalid and should not be used to access sevices's or any children attribute's methods/ members.
+ /// </remarks>
+ public void UnregisterGattService(BluetoothGattService service)
+ {
+ if (service.GetGattServer() != this)
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.InvalidParameter);
+ }
+
+ _impl.UnregisterGattService(service);
+ }
+
+ /// <summary>
+ /// Unregisters all services from this server
+ /// </summary>
+ /// <remarks>
+ /// Once unregistered, servicees will become invalid and should not be used to access sevices's or any children attribute's methods/ members.
+ /// </remarks>
+ public void UnregisterGattServices()
+ {
+ _impl.UnregisterAllGattServices(this);
+ }
+
+ /// <summary>
+ /// Gets service with given UUID that belongs to this server.
+ /// </summary>
+ /// <param name="uuid">UUID for the service to get</param>
+ /// <returns>service with given uuid if it exists, null otherwise</returns>
+ public BluetoothGattService GetService(string uuid)
+ {
+ return _impl.GetService(this, uuid);
+ }
+
+ /// <summary>
+ /// Gets list of services that belongs to this server.
+ /// </summary>
+ /// <returns>list of services that belongs to this server</returns>
+ public IEnumerable<BluetoothGattService> GetServices()
+ {
+ return _impl.GetServices(this);
+ }
+
+ /// <summary>
+ /// Send indication for value change of the characteristic to the remote devices
+ /// </summary>
+ /// <param name="characteristic">characteristic whose value is changes</param>
+ /// <param name="clientAddress">Remote device address to send notify or indicate and if set to NULL then notify/indicate all is enabled.</param>
+ public async Task<bool> SendIndicationAsync(BluetoothGattCharacteristic characteristic, string clientAddress)
+ {
+ return await _impl.SendIndicationAsync(this, characteristic, clientAddress);
+ }
+
+ /// <summary>
+ /// Send notification for value change of the characteristic to the remote devices
+ /// </summary>
+ /// <param name="characteristic">characteristic The characteristic which has a changed value</param>
+ /// <param name="clientAddress">Remote device address to send notify or indicate and if set to NULL then notify/indicate all is enabled.</param>
+ public void SendNotification(BluetoothGattCharacteristic characteristic, string clientAddress)
+ {
+ _impl.SendNotification(characteristic, clientAddress);
+ }
+
+ /// <summary>
+ /// Sends a response to the remote device as a result of a read/ write request
+ /// </summary>
+ /// <param name="requestId">The identification of a read/ write request</param>
+ /// <param name="type">The request type for read/write</param>
+ /// <param name="status">error value in case of failure, 0 for success</param>
+ /// <param name="value">Value to be sent</param>
+ /// <param name="offset">Fffset from where the value is read</param>
+ public void SendResponse(int requestId, BluetoothGattRequestType type, int status, byte[] value, int offset)
+ {
+ _impl.SendResponse(requestId, (int)type, status, value, offset);
+ }
+
+ internal bool IsValid()
+ {
+ return _impl.GetHandle().IsInvalid == false;
+ }
+ }
+
+ /// <summary>
+ /// Bluetooth GATT client
+ /// </summary>
+ public class BluetoothGattClient
+ {
+ private BluetoothGattClientImpl _impl;
+ private string _remoteAddress = string.Empty;
+
+ internal BluetoothGattClient(string remoteAddress)
+ {
+ _impl = new BluetoothGattClientImpl(remoteAddress);
+ _remoteAddress = remoteAddress;
+ }
+
+ internal static BluetoothGattClient CreateClient(string remoteAddress)
+ {
+ BluetoothGattClient client = new BluetoothGattClient(remoteAddress);
+ return client.Isvalid() ? client : null;
+ }
+
+ public void DestroyClient()
+ {
+ _impl.GetHandle().Dispose();
+ }
+
+ /// <summary>
+ /// Address of remote device.
+ /// </summary>
+ public string RemoteAddress
+ {
+ get
+ {
+ if (string.IsNullOrEmpty(_remoteAddress))
+ {
+ _remoteAddress = _impl.GetRemoteAddress();
+ }
+ return _remoteAddress;
+ }
+ }
+
+ /// <summary>
+ /// Gets service with given UUID that belongs to the remote device.
+ /// </summary>
+ /// <param name="uuid">UUID for the service to get</param>
+ /// <returns>service with given uuid if it exists, null otherwise</returns>
+ public BluetoothGattService GetService(string uuid)
+ {
+ return _impl.GetService(this, uuid);
+ }
+
+ /// <summary>
+ /// Gets list of services that belongs to the remote device.
+ /// </summary>
+ /// <returns>list of services that belongs to the remote device</returns>
+ public IEnumerable<BluetoothGattService> GetServices()
+ {
+ return _impl.GetServices(this);
+ }
+
+ /// <summary>
+ /// Reads the value of given characteristic from the remote device asynchronously.
+ /// </summary>
+ /// <param name="characteristic">characteristic to be read</param>
+ /// <returns>true on success, false otherwise</returns>
+ public async Task<bool> ReadValueAsync(BluetoothGattCharacteristic characteristic)
+ {
+ return await _impl.ReadValueAsyncTask(characteristic.GetHandle());
+ }
+
+ /// <summary>
+ /// Reads the value of given descriptor from the remote device asynchronously.
+ /// </summary>
+ /// <param name="descriptor">descriptor to be read</param>
+ /// <returns>true on success, false otherwise</returns>
+ public async Task<bool> ReadValueAsync(BluetoothGattDescriptor descriptor)
+ {
+ return await _impl.ReadValueAsyncTask(descriptor.GetHandle());
+ }
+
+ /// <summary>
+ /// Write value of given characteristic to remote device asynchronously.
+ /// </summary>
+ /// <param name="characteristic">characteristic to be written</param>
+ /// <returns>true on success, false otherwise</returns>
+ public async Task<bool> WriteValueAsync(BluetoothGattCharacteristic characteristic)
+ {
+ return await _impl.WriteValueAsyncTask(characteristic.GetHandle());
+ }
+
+ /// <summary>
+ /// Write value of given descriptor to remote device asynchronously.
+ /// </summary>
+ /// <param name="descriptor">descriptor to be written</param>
+ /// <returns>true on success, false otherwise</returns>
+ public async Task<bool> WriteValueAsync(BluetoothGattDescriptor descriptor)
+ {
+ return await _impl.WriteValueAsyncTask(descriptor.GetHandle());
+ }
+
+ internal bool Isvalid()
+ {
+ return _impl.GetHandle().IsInvalid == false;
+ }
+ }
+
+ /// <summary>
+ /// Bluetooth GATT service
+ /// </summary>
+ public class BluetoothGattService
+ {
+ private BluetoothGattServiceImpl _impl;
+ private BluetoothGattClient _parentClient = null;
+ private BluetoothGattServer _parentServer = null;
+ private BluetoothGattService _parentService = null;
+
+ /// <summary>
+ /// Constructor
+ /// </summary>
+ /// <param name="uuid">UUID of the service</param>
+ /// <param name="type">type of service</param>
+ public BluetoothGattService(string uuid, BluetoothGattServiceType type)
+ {
+ Uuid = uuid;
+ _impl = new BluetoothGattServiceImpl(uuid, type);
+ }
+
+ internal BluetoothGattService(BluetoothGattServiceImpl impl, string uuid)
+ {
+ Uuid = uuid;
+ _impl = impl;
+ }
+
+ /// <summary>
+ /// Specification name from the UUID
+ /// </summary>
+ public string Uuid { get; }
+
+ /// <summary>
+ /// Adds a characteristic to this service
+ /// </summary>
+ /// <param name="characteristic">characteristic to be added</param>
+ /// <returns>true on success, false otherwise</returns>
+ public void AddCharacteristic(BluetoothGattCharacteristic characteristic)
+ {
+ if (GetGattClient() != null)
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotSupported);
+ }
+
+ if (characteristic.GetService() != null)
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.InvalidParameter);
+ }
+
+ _impl.AddCharacteristic(characteristic);
+ characteristic.SetParent(this);
+ }
+
+ /// <summary>
+ /// Gets characteristic with given UUID that belongs to this service.
+ /// </summary>
+ /// <param name="uuid">UUID for the characteristic to get</param>
+ /// <returns>characteristic with given uuid if it exists, null otherwise</returns>
+ public BluetoothGattCharacteristic GetCharacteristic(string uuid)
+ {
+ return _impl.GetCharacteristic(this, uuid);
+ }
+
+ /// <summary>
+ /// Gets list of characteristic that belongs to this service.
+ /// </summary>
+ /// <returns>list of characteristic that belongs to this service</returns>
+ public IEnumerable<BluetoothGattCharacteristic> GetCharacteristics()
+ {
+ return _impl.GetCharacteristics(this);
+ }
+
+ /// <summary>
+ /// Includes a service to this service
+ /// </summary>
+ /// <param name="service">service to be included</param>
+ /// <returns>true on success, false otherwise</returns>
+ public void AddService(BluetoothGattService service)
+ {
+ if (GetGattClient() != null)
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotSupported);
+ }
+
+ if (service.IsRegistered())
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.InvalidParameter);
+ }
+
+ _impl.AddIncludeService(service);
+ service.SetParent(this);
+ }
+
+ /// <summary>
+ /// Gets included service
+ /// </summary>
+ /// <param name="uuid">UUID for the service to get</param>
+ /// <returns>service with given uuid if it exists, null otherwise</returns>
+ public BluetoothGattService GetIncludeService(string uuid)
+ {
+ return _impl.GetIncludeService(this, uuid);
+ }
+
+ /// <summary>
+ /// Gets included service list of this service.
+ /// </summary>
+ /// <returns>included service list of this service</returns>
+ public IEnumerable<BluetoothGattService> GetIncludeServices()
+ {
+ return _impl.GetIncludeServices(this);
+ }
+
+ /// <summary>
+ /// Gets the server instance which the specified service belongs to.
+ /// </summary>
+ /// <returns>server instance which the specified service belongs to</returns>
+ public BluetoothGattServer GetGattServer()
+ {
+ return _parentServer;
+ }
+
+ /// <summary>
+ /// Gets the client instance which the specified service belongs to.
+ /// </summary>
+ /// <returns>client instance which the specified service belongs to</returns>
+ public BluetoothGattClient GetGattClient()
+ {
+ return _parentClient;
+ }
+
+ internal BluetoothGattAttributeHandle GetHandle()
+ {
+ return _impl.GetHandle();
+ }
+
+ internal void SetParent(BluetoothGattService parent)
+ {
+ if (!IsRegistered())
+ {
+ _parentService = parent;
+ _impl.ReleaseHandleOwnership();
+ }
+ }
+
+ internal void SetParent(BluetoothGattClient parent)
+ {
+ if (!IsRegistered())
+ {
+ _parentClient = parent;
+ _impl.ReleaseHandleOwnership();
+ }
+ }
+
+ internal void SetParent(BluetoothGattServer parent)
+ {
+ if (!IsRegistered())
+ {
+ _parentServer = parent;
+ _impl.ReleaseHandleOwnership();
+ }
+ }
+
+ internal void UnregisterService()
+ {
+ _parentServer = null;
+ _parentClient = null;
+ _parentService = null;
+ }
+
+ internal bool IsRegistered()
+ {
+ return _parentClient != null || _parentServer != null || _parentService != null;
+ }
+ }
+
+ /// <summary>
+ /// Bluetooth GATT characteristic
+ /// </summary>
+ public class BluetoothGattCharacteristic : BluetoothGattAttribute
+ {
+ private BluetoothGattCharacteristicImpl _impl;
+ private BluetoothGattService _parent = null;
+
+ private Interop.Bluetooth.BtClientCharacteristicValueChangedCallback _characteristicValueChangedCallback;
+ private Interop.Bluetooth.BtGattServerNotificationStateChangeCallback _notificationStateChangedCallback;
+
+ private EventHandler<ValueChangedEventArgs> _characteristicValueChanged;
+ internal EventHandler<NotificationStateChangedEventArg> _notificationStateChanged;
+
+ /// <summary>
+ /// Constructor
+ /// </summary>
+ /// <param name="uuid">UUID of the characterstic</param>
+ /// <param name="permissions">Permissions for the characterstic</param>
+ /// <param name="properties">Properties set for the characterstic</param>
+ /// <param name="value">Value associated with the characterstic</param>
+ /// <remarks>throws in case of internal error</remarks>
+ public BluetoothGattCharacteristic(string uuid, BluetoothGattPermission permissions, BluetoothGattProperty properties, byte[] value) : base(uuid, permissions)
+ {
+ _impl = new BluetoothGattCharacteristicImpl(uuid, permissions, properties, value);
+ }
+
+ internal BluetoothGattCharacteristic(BluetoothGattCharacteristicImpl impl, string uuid, BluetoothGattPermission permission) : base(uuid, permission)
+ {
+ _impl = impl;
+ }
+
+ /// <summary>
+ /// (event) CharacteristicValueChanged is raised when server notifies for change in this characteristic value
+ /// </summary>
+ /// <remarks>
+ /// Adding event handle on charateristic on server side will not have any effect
+ /// </remarks>
+ public event EventHandler<ValueChangedEventArgs> ValueChanged
+ {
+ add
+ {
+ if (Client != null)
+ {
+ if (_characteristicValueChanged == null)
+ {
+ _characteristicValueChangedCallback = (gattHandle, characteristicValue, len, userData) =>
+ {
+ _characteristicValueChanged?.Invoke(this, new ValueChangedEventArgs(characteristicValue));
+ };
+
+ _impl.SetCharacteristicValueChangedEvent(_characteristicValueChangedCallback);
+ }
+ _characteristicValueChanged = value;
+ }
+ }
+ remove
+ {
+ if (Client != null)
+ {
+ _characteristicValueChanged = null;
+ if (_characteristicValueChanged == null)
+ {
+ _impl.UnsetCharacteristicValueChangedEvent();
+ }
+
+ }
+ }
+ }
+
+ /// <summary>
+ /// (event) NotificationStateChanged is called when client enables or disables the Notification/Indication for particular characteristics.
+ /// </summary>
+ /// <remarks>
+ /// Adding event handle on charateristic on client side will not have any effect
+ /// </remarks>
+ public event EventHandler<NotificationStateChangedEventArg> NotificationStateChanged
+ {
+ add
+ {
+ if (Server != null)
+ {
+ if (_notificationStateChangedCallback == null)
+ {
+ _notificationStateChangedCallback = (notify, serverHandle, characteristicHandle, userData) =>
+ {
+ _notificationStateChanged?.Invoke(this, new NotificationStateChangedEventArg(Server, notify));
+ };
+
+ _impl.SetNotificationStateChangedEvent(_notificationStateChangedCallback);
+ }
+
+ _notificationStateChanged = value;
+ }
+ }
+ remove
+ {
+ if (Server != null)
+ {
+ _notificationStateChanged = null;
+ // CAPI does not allow unsetting ReadValueRequestedEventCallback.
+ }
+ }
+ }
+
+ /// <summary>
+ /// Property for this characteristic
+ /// </summary>
+ public BluetoothGattProperty Properties
+ {
+ get
+ {
+ return _impl.GetProperties();
+ }
+ set
+ {
+ if (Server != null)
+ {
+ _impl.SetProperties(value);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Write type to be used for write operations
+ /// </summary>
+ public BluetoothGattWriteType WriteType
+ {
+ get
+ {
+ return _impl.GetWriteType();
+ }
+ set
+ {
+ _impl.SetWriteType(value);
+ }
+ }
+
+ internal override BluetoothGattClient Client
+ {
+ get
+ {
+ return _parent?.GetGattClient();
+ }
+ }
+
+ internal override BluetoothGattServer Server
+ {
+ get
+ {
+ return _parent?.GetGattServer();
+ }
+ }
+
+ internal override BluetoothGattAttributeImpl Impl
+ {
+ get
+ {
+ return _impl;
+ }
+ }
+
+ /// <summary>
+ /// Adds a descriptor to this characteristic
+ /// </summary>
+ /// <param name="descriptor">descriptor to be added</param>
+ /// <returns>true on success, false otherwise</returns>
+ public void AddDescriptor(BluetoothGattDescriptor descriptor)
+ {
+ if (Client != null)
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotSupported);
+ }
+
+ if (descriptor.GetCharacteristic() != null)
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.InvalidParameter);
+ }
+
+ _impl.AddDescriptor(descriptor);
+ descriptor.SetParent(this);
+ }
+
+ /// <summary>
+ /// Gets descriptor with given UUID that belongs to this characteristic.
+ /// </summary>
+ /// <param name="uuid">UUID for the descriptor to get</param>
+ /// <returns>descriptor with given uuid if it exists, null otherwise</returns>
+ public BluetoothGattDescriptor GetDescriptor(string uuid)
+ {
+ return _impl.GetDescriptor(this, uuid);
+ }
+
+ /// <summary>
+ /// Gets list of descriptors that belongs to this characteristic.
+ /// </summary>
+ /// <returns>list of descriptors that belongs to this characteristic</returns>
+ public IEnumerable<BluetoothGattDescriptor> GetDescriptors()
+ {
+ return _impl.GetDescriptors(this);
+ }
+
+ /// <summary>
+ /// Gets the service instance which the specified characterstic belongs to.
+ /// </summary>
+ /// <returns>characteristic instance, the specified characterstic belongs to.</returns>
+ public BluetoothGattService GetService()
+ {
+ return _parent;
+ }
+
+ internal void SetParent(BluetoothGattService parent)
+ {
+ if (_parent == null)
+ {
+ _parent = parent;
+ ReleaseHandleOwnership();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Bluetooth GATT descriptor
+ /// </summary>
+ public class BluetoothGattDescriptor : BluetoothGattAttribute
+ {
+ private BluetoothGattCharacteristic _parent = null;
+ private BluetoothGattDescriptorImpl _impl;
+
+ /// <summary>
+ /// Constructor
+ /// </summary>
+ /// <param name="uuid">UUID of the descriptor</param>
+ /// <param name="permisions">Permissions for the descriptor</param>
+ /// <param name="value">Value associated with the descriptor</param>
+ /// <remarks>throws in case of internal error</remarks>
+ public BluetoothGattDescriptor(string uuid, BluetoothGattPermission permisions, byte[] value) : base (uuid, permisions)
+ {
+ _impl = new BluetoothGattDescriptorImpl(uuid, permisions, value);
+ }
+
+ internal BluetoothGattDescriptor(BluetoothGattDescriptorImpl impl, string uuid, BluetoothGattPermission permission) : base(uuid, permission)
+ {
+ _impl = impl;
+ }
+
+ internal override BluetoothGattClient Client
+ {
+ get
+ {
+ return _parent?.Client;
+ }
+ }
+
+ internal override BluetoothGattServer Server
+ {
+ get
+ {
+ return _parent?.Server;
+ }
+ }
+
+ internal override BluetoothGattAttributeImpl Impl
+ {
+ get
+ {
+ return _impl;
+ }
+ }
+
+ /// <summary>
+ /// Gets the characteristic instance which the specified descriptor belongs to.
+ /// </summary>
+ /// <returns>characteristic instance, the specified descriptor belongs to.</returns>
+ public BluetoothGattCharacteristic GetCharacteristic()
+ {
+ return _parent;
+ }
+
+ internal void SetParent(BluetoothGattCharacteristic parent)
+ {
+ if (_parent == null)
+ {
+ _parent = parent;
+ ReleaseHandleOwnership();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Bluetooth GATT attribute
+ /// </summary>
+ public abstract class BluetoothGattAttribute
+ {
+ private Interop.Bluetooth.BtGattServerReadValueRequestedCallback _readValueRequestedCallback;
+ private Interop.Bluetooth.BtGattServerWriteValueRequestedCallback _writeValueRequestedCallback;
+
+ private EventHandler<ReadRequestedEventArgs> _readValueRequested;
+ private EventHandler<WriteRequestedEventArgs> _writeValueRequested;
+
+ public BluetoothGattAttribute(string uuid, BluetoothGattPermission permission)
+ {
+ Uuid = uuid;
+ Permissions = permission;
+ }
+
+ // Events
+
+ /// <summary>
+ /// Event called when client request to read value of a characteristic or descriptor
+ /// </summary>
+ public event EventHandler<ReadRequestedEventArgs> ReadRequested
+ {
+ add
+ {
+ if (Server == null) return;
+ if (_readValueRequestedCallback == null)
+ {
+ _readValueRequestedCallback = (clientAddress, requestId, serverHandle, gattHandle, offset, userData) =>
+ {
+ _readValueRequested?.Invoke(this, new ReadRequestedEventArgs(Server, clientAddress, requestId, offset));
+ };
+ Impl.SetReadValueRequestedEventCallback(_readValueRequestedCallback);
+ }
+ _readValueRequested = value;
+ }
+ remove
+ {
+ if (Server == null) return;
+ _readValueRequested = null;
+ // CAPI does not allow unsetting ReadValueRequestedEventCallback.
+ }
+ }
+
+ /// <summary>
+ /// Event called when a value of a characteristic or descriptor has been changed by a client
+ /// </summary>
+ public event EventHandler<WriteRequestedEventArgs> WriteRequested
+ {
+ add
+ {
+ if (Server == null) return;
+ if (_writeValueRequested == null)
+ {
+ _writeValueRequestedCallback = (clientAddress, requestId, serverHandle, gattHandle, offset, response_needed, valueToWrite, len, userData) =>
+ {
+ _writeValueRequested?.Invoke(this, new WriteRequestedEventArgs(Server, clientAddress, requestId, valueToWrite, offset, response_needed));
+ };
+ Impl.SetWriteValueRequestedEventCallback(_writeValueRequestedCallback);
+ }
+ _writeValueRequested = value;
+ }
+ remove
+ {
+ if (Server == null) return;
+ _writeValueRequested = null;
+ // CAPI does not allow unsetting ReadValueRequestedEventCallback.
+ }
+ }
+
+ /// <summary>
+ /// Attribute's UUID
+ /// </summary>
+ public string Uuid { get; }
+
+ /// <summary>
+ /// Permissions for this attribute
+ /// </summary>
+ public BluetoothGattPermission Permissions { get; }
+
+ /// <summary>
+ /// Value of this descriptor
+ /// </summary>
+ public byte[] Value
+ {
+ get
+ {
+ return Impl.GetValue();
+ }
+ set
+ {
+ Impl.SetValue(value);
+ }
+ }
+
+ internal abstract BluetoothGattClient Client { get; }
+ internal abstract BluetoothGattServer Server { get; }
+ internal abstract BluetoothGattAttributeImpl Impl { get; }
+
+ /// <summary>
+ /// Returns string value at specified offset
+ /// </summary>
+ /// <param name="offset"></param>
+ /// <returns>string value at specified offset</returns>
+ public string GetValue(int offset)
+ {
+ return Impl.GetValue(offset);
+ }
+
+ /// <summary>
+ /// Sets string value as specified offset
+ /// </summary>
+ /// <param name="value">value to set</param>
+ /// <exception cref="InvalidOperationException">Throws excetion if value is null</exception>
+ public void SetValue(string value)
+ {
+ if (string.IsNullOrEmpty(value))
+ GattUtil.ThrowForError((int)BluetoothError.InvalidParameter, "value should not be null");
+
+ byte[] val = Encoding.UTF8.GetBytes(value);
+ Impl.SetValue(val);
+ }
+
+ /// <summary>
+ /// Returns value at specified offset as int value of specified type
+ /// </summary>
+ /// <param name="type">type of int value</param>
+ /// <param name="offset">offset in the attribute value buffer</param>
+ /// <returns>int value at given offset</returns>
+ /// <exception cref="InvalidOperationException">Throws excetion if (offset + size of int value) is greater then length of value buffer</exception>
+ public int GetValue(IntDataType type, int offset)
+ {
+ return Impl.GetValue(type, offset);
+ }
+
+ /// <summary>
+ /// Update Value at specified offset by int value of specified type
+ /// </summary>
+ /// <param name="type">type of int value</param>
+ /// <param name="value">value to set</param>
+ /// <param name="offset">offset in the attribute value buffer</param>
+ /// <exception cref="InvalidOperationException">Throws excetion if (offset + size of int value) is greater then length of value buffer</exception>
+ public void SetValue(IntDataType type, int value, int offset)
+ {
+ Impl.SetValue(type, value, offset);
+ }
+
+ /// <summary>
+ /// Returns value at specified offset as float value of specified type
+ /// </summary>
+ /// <param name="type">type of float value</param>
+ /// <param name="offset">offset in the attribute value buffer</param>
+ /// <returns>float value at given offset</returns>
+ /// <exception cref="InvalidOperationException">Throws excetion if (offset + size of float value) is greater then length of value buffer</exception>
+ public float GetValue(FloatDataType type, int offset)
+ {
+ return Impl.GetValue(type, offset);
+ }
+
+ /// <summary>
+ /// Update Value at specified offset by float value of specified type
+ /// </summary>
+ /// <param name="type">type of float value</param>
+ /// <param name="mantissa">mantissa of float value</param>
+ /// <param name="exponent">exponent of float value</param>
+ /// <param name="offset">offset in the attribute value buffer</param>
+ /// <exception cref="InvalidOperationException">Throws excetion if (offset + size of float value) is greater then length of value buffer</exception>
+ public void SetValue(FloatDataType type, int mantissa, int exponent, int offset)
+ {
+ Impl.SetValue(type, mantissa, exponent, offset);
+ }
+
+ internal void ReleaseHandleOwnership()
+ {
+ Impl.ReleaseHandleOwnership();
+ }
+
+ internal BluetoothGattAttributeHandle GetHandle()
+ {
+ return Impl.GetHandle();
+ }
+ }
+}
diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothGattImpl.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothGattImpl.cs
new file mode 100755
index 0000000..e1a8508
--- /dev/null
+++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothGattImpl.cs
@@ -0,0 +1,707 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tizen.Network.Bluetooth
+{
+ internal class BluetoothGattServerImpl
+ {
+ private BluetoothGattServerHandle _handle;
+ internal event EventHandler<NotificationSentEventArg> _notificationSent;
+
+ internal BluetoothGattServerImpl()
+ {
+ int err = Interop.Bluetooth.BtGattServerInitialize();
+ GattUtil.ThrowForError(err, "Failed to initialize server");
+
+ err = Interop.Bluetooth.BtGattServerCreate(out _handle);
+ GattUtil.ThrowForError(err, "Failed to create server");
+ }
+
+ internal void Start()
+ {
+ int err = Interop.Bluetooth.BtGattServerStart();
+ GattUtil.ThrowForError(err, "Failed to start server");
+ }
+
+ internal void RegisterGattService(BluetoothGattServer server, BluetoothGattService service)
+ {
+ int err = Interop.Bluetooth.BtGattServerRegisterService(_handle, service.GetHandle());
+ GattUtil.ThrowForError(err, "Failed to Register service");
+
+ service.SetParent(server);
+ }
+
+ internal void UnregisterGattService(BluetoothGattService service)
+ {
+ int err = Interop.Bluetooth.BtGattServerUnregisterService(_handle, service.GetHandle());
+ GattUtil.ThrowForError(err, "Failed to Unregister service");
+
+ service.UnregisterService();
+ }
+
+ internal void UnregisterAllGattServices(BluetoothGattServer server)
+ {
+ int err = Interop.Bluetooth.BtGattServerUnregisterAllServices(_handle);
+ GattUtil.ThrowForError(err, "Failed to Unregister all services");
+ }
+
+ internal BluetoothGattService GetService(BluetoothGattServer server, string uuid)
+ {
+ BluetoothGattAttributeHandle serviceHandle;
+ int err = Interop.Bluetooth.BtGattServerGetService(_handle, uuid, out serviceHandle);
+ if (err.IsFailed())
+ {
+ GattUtil.Error(err, string.Format("Failed to get service with UUID ({0})", uuid));
+ return null;
+ }
+
+ BluetoothGattService service = new BluetoothGattService(new BluetoothGattServiceImpl(serviceHandle), uuid); ;
+ service.SetParent(server);
+ return service;
+ }
+
+ internal IEnumerable<BluetoothGattService> GetServices(BluetoothGattServer server)
+ {
+ List<BluetoothGattService> attribututeList = new List<BluetoothGattService>();
+ Interop.Bluetooth.BtGattForeachCallback cb = (total, index, attributeHandle, userData) =>
+ {
+ BluetoothGattAttributeHandle handle = new BluetoothGattAttributeHandle(attributeHandle, false);
+ BluetoothGattService service = BluetoothGattServiceImpl.CreateBluetoothGattService(handle, ""); ;
+ if (service != null)
+ {
+ service.SetParent(server);
+ attribututeList.Add(service);
+ }
+ return true;
+ };
+
+ int err = Interop.Bluetooth.BtGattServerForeachServices(_handle, cb, IntPtr.Zero);
+ GattUtil.Error(err, "Failed to get all services");
+
+ return attribututeList;
+ }
+
+ internal void SendResponse(int requestId, int request_type, int status, byte[] value, int offset)
+ {
+ int err = Interop.Bluetooth.BtGattServerSendResponse(requestId, request_type, offset, status, value, value.Length);
+ GattUtil.ThrowForError(err, string.Format("Failed to send response for request Id {0}", requestId));
+ }
+
+ internal void SendNotification(BluetoothGattCharacteristic characteristic, string clientAddress)
+ {
+ int err = Interop.Bluetooth.BtGattServerNotify(characteristic.GetHandle(), null, clientAddress, IntPtr.Zero);
+ GattUtil.ThrowForError(err, string.Format("Failed to send value changed notification for characteristic uuid {0}", characteristic.Uuid));
+ }
+
+ internal Task<bool> SendIndicationAsync(BluetoothGattServer server, BluetoothGattCharacteristic characteristic, string clientAddress)
+ {
+ TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
+ Interop.Bluetooth.BtGattServerNotificationSentCallback cb = (result, address, serverHandle, characteristicHandle, completed, userData) =>
+ {
+ _notificationSent?.Invoke(characteristic, new NotificationSentEventArg(server, address, result, completed));
+ if (completed)
+ {
+ tcs.SetResult(true);
+ }
+ };
+
+ int err = Interop.Bluetooth.BtGattServerNotify(characteristic.GetHandle(), cb, clientAddress, IntPtr.Zero);
+ GattUtil.ThrowForError(err, string.Format("Failed to send value changed indication for characteristic uuid {0}", characteristic.Uuid));
+
+ return tcs.Task;
+ }
+
+ internal BluetoothGattServerHandle GetHandle()
+ {
+ return _handle;
+ }
+ }
+
+ internal class BluetoothGattClientImpl
+ {
+ private BluetoothGattClientHandle _handle;
+
+ internal BluetoothGattClientImpl(string remoteAddress)
+ {
+ int err = Interop.Bluetooth.BtGattClientCreate(remoteAddress, out _handle);
+ GattUtil.ThrowForError(err, "Failed to get native client handle");
+ }
+
+ internal string GetRemoteAddress()
+ {
+ string remoteAddress;
+ int err = Interop.Bluetooth.BtGattClientGetRemoteAddress(_handle, out remoteAddress);
+ GattUtil.ThrowForError(err, "Failed to get remote address for this client");
+
+ return remoteAddress;
+ }
+
+ internal BluetoothGattService GetService(BluetoothGattClient client, string uuid)
+ {
+ BluetoothGattAttributeHandle serviceHandle;
+ int err = Interop.Bluetooth.BtGattClientGetService(_handle, uuid, out serviceHandle);
+ if (err.IsFailed())
+ {
+ GattUtil.Error(err, string.Format("Failed to get service with UUID ({0})", uuid));
+ return null;
+ }
+
+ BluetoothGattService service = new BluetoothGattService(new BluetoothGattServiceImpl(serviceHandle), uuid); ;
+ service.SetParent(client);
+ return service;
+ }
+
+ internal IEnumerable<BluetoothGattService> GetServices(BluetoothGattClient client)
+ {
+ List<BluetoothGattService> attribututeList = new List<BluetoothGattService>();
+ Interop.Bluetooth.BtGattForeachCallback cb = (total, index, attributeHandle, userData) =>
+ {
+ BluetoothGattAttributeHandle handle = new BluetoothGattAttributeHandle(attributeHandle, false);
+ BluetoothGattService service = BluetoothGattServiceImpl.CreateBluetoothGattService(handle, "");
+ if (service != null)
+ {
+ service.SetParent(client);
+ attribututeList.Add(service);
+ }
+ return true;
+ };
+
+ int err = Interop.Bluetooth.BtGattClientForeachServices(_handle, cb, IntPtr.Zero);
+ GattUtil.Error(err, "Failed to get all services");
+
+ return attribututeList;
+ }
+
+ internal Task<bool> ReadValueAsyncTask(BluetoothGattAttributeHandle handle)
+ {
+ TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
+ Interop.Bluetooth.BtGattClientRequestCompletedCallback cb = (result, requestHandle, userData) =>
+ {
+ if (result == (int)BluetoothError.None)
+ tcs.SetResult(true);
+ else
+ tcs.SetResult(false);
+ };
+
+ int err = Interop.Bluetooth.BtGattClientReadValue(handle, cb, IntPtr.Zero);
+ if (err.IsFailed())
+ {
+ GattUtil.Error(err, "Failed to read value from remote device");
+ tcs.SetResult(false);
+ BluetoothErrorFactory.ThrowBluetoothException(err);
+ }
+ return tcs.Task;
+ }
+
+ internal Task<bool> WriteValueAsyncTask(BluetoothGattAttributeHandle handle)
+ {
+ TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
+ Interop.Bluetooth.BtGattClientRequestCompletedCallback cb = (result, requestHandle, userData) =>
+ {
+ if (result == (int)BluetoothError.None)
+ tcs.SetResult(true);
+ else
+ tcs.SetResult(false);
+ };
+
+ int err = Interop.Bluetooth.BtGattClientWriteValue(handle, cb, IntPtr.Zero);
+ if (err.IsFailed())
+ {
+ GattUtil.Error(err, "Failed to write value to remote device");
+ tcs.SetResult(false);
+ BluetoothErrorFactory.ThrowBluetoothException(err);
+ }
+ return tcs.Task;
+ }
+
+ internal BluetoothGattClientHandle GetHandle()
+ {
+ return _handle;
+ }
+ }
+
+ internal class BluetoothGattServiceImpl : BluetoothGattAttributeImpl
+ {
+ internal BluetoothGattServiceImpl(string uuid, BluetoothGattServiceType type)
+ {
+ int err = Interop.Bluetooth.BtGattServiceCreate(uuid, (int)type, out _handle);
+ GattUtil.ThrowForError(err, "Failed to get native service handle");
+ }
+
+ internal BluetoothGattServiceImpl(BluetoothGattAttributeHandle handle)
+ {
+ _handle = handle;
+ }
+
+ internal static BluetoothGattService CreateBluetoothGattService(BluetoothGattAttributeHandle handle, string uuid)
+ {
+ if (uuid == "")
+ {
+ int err = Interop.Bluetooth.BtGattGetUuid(handle, out uuid);
+ GattUtil.ThrowForError(err, "Failed to get UUID");
+ }
+
+ BluetoothGattServiceImpl impl = new BluetoothGattServiceImpl(handle);
+ return new BluetoothGattService(impl, uuid);
+ }
+
+ internal void AddCharacteristic(BluetoothGattCharacteristic characteristic)
+ {
+ int err = Interop.Bluetooth.BtGattServiceAddCharacteristic(_handle, characteristic.GetHandle());
+ GattUtil.ThrowForError(err, string.Format("Failed to add characteristic with UUID ({0})", characteristic.Uuid));
+ }
+
+ internal BluetoothGattCharacteristic GetCharacteristic(BluetoothGattService service, string uuid)
+ {
+ BluetoothGattAttributeHandle attributeHandle;
+ int err = Interop.Bluetooth.BtGattServiceGetCharacteristic(_handle, uuid, out attributeHandle);
+ if (err.IsFailed())
+ {
+ GattUtil.Error(err, string.Format("Failed to get Characteristic with UUID ({0})", uuid));
+ return null;
+ }
+
+ BluetoothGattCharacteristic Characteristic = BluetoothGattCharacteristicImpl.CreateBluetoothGattGattCharacteristic(attributeHandle, uuid);
+ Characteristic.SetParent(service);
+ return Characteristic;
+ }
+
+ internal IEnumerable<BluetoothGattCharacteristic> GetCharacteristics(BluetoothGattService service)
+ {
+ List<BluetoothGattCharacteristic> attribututeList = new List<BluetoothGattCharacteristic>();
+ Interop.Bluetooth.BtGattForeachCallback cb = (total, index, attributeHandle, userData) =>
+ {
+ BluetoothGattAttributeHandle handle = new BluetoothGattAttributeHandle(attributeHandle, false);
+ BluetoothGattCharacteristic Characteristic = BluetoothGattCharacteristicImpl.CreateBluetoothGattGattCharacteristic(handle, "");
+ if (Characteristic != null)
+ {
+ Characteristic.SetParent(service);
+ attribututeList.Add(Characteristic);
+ }
+ return true;
+ };
+
+ int err = Interop.Bluetooth.BtGattServiceForeachCharacteristics(service.GetHandle(), cb, IntPtr.Zero);
+ GattUtil.Error(err, "Failed to get all Characteristic");
+
+ return attribututeList;
+ }
+
+ internal void AddIncludeService(BluetoothGattService includedService)
+ {
+ int err = Interop.Bluetooth.BtGattServiceAddIncludedService(_handle, includedService.GetHandle());
+ GattUtil.ThrowForError(err, string.Format("Failed to add service with UUID ({0})", includedService.Uuid));
+ }
+
+ internal BluetoothGattService GetIncludeService(BluetoothGattService parentService, string uuid)
+ {
+ BluetoothGattAttributeHandle attributeHandle;
+ int err = Interop.Bluetooth.BtGattServiceGetIncludedService(_handle, uuid, out attributeHandle);
+ if (err.IsFailed())
+ {
+ GattUtil.Error(err, string.Format("Failed to get included service with UUID ({0})", uuid));
+ return null;
+ }
+
+ BluetoothGattService service = new BluetoothGattService(new BluetoothGattServiceImpl(attributeHandle), uuid);
+ service.SetParent(parentService);
+ return service;
+ }
+
+ internal IEnumerable<BluetoothGattService> GetIncludeServices(BluetoothGattService parentService)
+ {
+ List<BluetoothGattService> attribututeList = new List<BluetoothGattService>();
+ Interop.Bluetooth.BtGattForeachCallback cb = (total, index, attributeHandle, userData) =>
+ {
+ BluetoothGattAttributeHandle handle = new BluetoothGattAttributeHandle(attributeHandle, false);
+ BluetoothGattService service = BluetoothGattServiceImpl.CreateBluetoothGattService(handle, "");
+ if (service != null)
+ {
+ service.SetParent(parentService);
+ attribututeList.Add(service);
+ }
+ return true;
+ };
+
+ int err = Interop.Bluetooth.BtGattServiceForeachIncludedServices(parentService.GetHandle(), cb, IntPtr.Zero);
+ GattUtil.Error(err, "Failed to get all services");
+
+ return attribututeList;
+ }
+ }
+
+ internal class BluetoothGattCharacteristicImpl : BluetoothGattAttributeImpl
+ {
+ internal BluetoothGattCharacteristicImpl(string uuid, BluetoothGattPermission permission, BluetoothGattProperty property, byte[] value)
+ {
+ int err = Interop.Bluetooth.BtGattCharacteristicCreate(uuid, (int)permission, (int)property, value, value.Length, out _handle);
+ GattUtil.ThrowForError(err, "Failed to get native characteristic handle");
+ }
+
+ internal BluetoothGattCharacteristicImpl(BluetoothGattAttributeHandle handle)
+ {
+ _handle = handle;
+ }
+
+ internal static BluetoothGattCharacteristic CreateBluetoothGattGattCharacteristic(BluetoothGattAttributeHandle handle, string uuid)
+ {
+ int permission;
+ int err = Interop.Bluetooth.BtGattCharacteristicGetPermissions(handle, out permission);
+ GattUtil.ThrowForError(err, "Failed to get permissions");
+
+ if (uuid == "")
+ {
+ err = Interop.Bluetooth.BtGattGetUuid(handle, out uuid);
+ GattUtil.ThrowForError(err, "Failed to get UUID");
+ }
+
+ BluetoothGattCharacteristicImpl impl = new BluetoothGattCharacteristicImpl(handle);
+ return new BluetoothGattCharacteristic(impl, uuid, (BluetoothGattPermission)permission);
+ }
+
+ internal void SetCharacteristicValueChangedEvent(Interop.Bluetooth.BtClientCharacteristicValueChangedCallback callback)
+ {
+ int err = Interop.Bluetooth.BtGattClientSetCharacteristicValueChangedCallback(_handle, callback, IntPtr.Zero);
+ GattUtil.Error(err, "Failed to set client characteristic value changed callback");
+ }
+
+ internal void UnsetCharacteristicValueChangedEvent()
+ {
+ int err = Interop.Bluetooth.BtGattClientUnsetCharacteristicValueChangedCallback(_handle);
+ GattUtil.Error(err, "Failed to unset client characteristic value changed callback");
+ }
+
+ internal void SetNotificationStateChangedEvent(Interop.Bluetooth.BtGattServerNotificationStateChangeCallback callback)
+ {
+ int err = Interop.Bluetooth.BtGattServeSetNotificationStateChangeCallback(_handle, callback, IntPtr.Zero);
+ GattUtil.Error(err, "Failed to set characteristic notification state changed callback");
+ }
+
+ internal BluetoothGattProperty GetProperties()
+ {
+ int properties = 0 ;
+ int err = Interop.Bluetooth.BtGattCharacteristicGetProperties(_handle, out properties);
+ GattUtil.Error(err, "Failed to get characteristic properties");
+ return (BluetoothGattProperty)properties;
+ }
+
+ internal void SetProperties(BluetoothGattProperty perperties)
+ {
+ int err = Interop.Bluetooth.BtGattCharacteristicSetProperties(_handle, (int)perperties);
+ GattUtil.Error(err, "Failed to set characteristic properties");
+ }
+
+ internal BluetoothGattWriteType GetWriteType()
+ {
+ int writeType;
+ int err = Interop.Bluetooth.BtGattCharacteristicGetWriteType(_handle, out writeType);
+ GattUtil.Error(err, "Failed to get characteristic writetype");
+ return (BluetoothGattWriteType) writeType;
+ }
+
+ internal void SetWriteType(BluetoothGattWriteType writeType)
+ {
+ int err = Interop.Bluetooth.BtGattCharacteristicSetWriteType(_handle, (int)writeType);
+ GattUtil.Error(err, "Failed to get characteristic writetype");
+ }
+
+ internal void AddDescriptor(BluetoothGattDescriptor descriptor)
+ {
+ int err = Interop.Bluetooth.BtGattCharacteristicAddDescriptor(_handle, descriptor.GetHandle());
+ GattUtil.ThrowForError(err, string.Format("Failed to add descriptor with UUID ({0})", descriptor.Uuid));
+ }
+
+ internal BluetoothGattDescriptor GetDescriptor(BluetoothGattCharacteristic characteristic, string uuid)
+ {
+ BluetoothGattAttributeHandle handle;
+ int err = Interop.Bluetooth.BtGattCharacteristicGetDescriptor(_handle, uuid, out handle);
+ if (err.IsFailed())
+ {
+ GattUtil.Error(err, string.Format("Failed to get descriptor with UUID ({0})", uuid));
+ return null;
+ }
+ BluetoothGattDescriptor descriptor = BluetoothGattDescriptorImpl.CreateBluetoothGattDescriptor(handle, uuid);
+ descriptor.SetParent(characteristic);
+ return descriptor;
+ }
+
+ internal IEnumerable<BluetoothGattDescriptor> GetDescriptors(BluetoothGattCharacteristic characteristic)
+ {
+ List<BluetoothGattDescriptor> attribututeList = new List<BluetoothGattDescriptor>();
+ Interop.Bluetooth.BtGattForeachCallback cb = (total, index, attributeHandle, userData) =>
+ {
+ BluetoothGattAttributeHandle handle = new BluetoothGattAttributeHandle(attributeHandle, false);
+ BluetoothGattDescriptor descriptor = BluetoothGattDescriptorImpl.CreateBluetoothGattDescriptor(handle, "");
+ if (descriptor != null)
+ {
+ descriptor.SetParent(characteristic);
+ attribututeList.Add(descriptor);
+ }
+ return true;
+ };
+
+ int err = Interop.Bluetooth.BtGattCharacteristicForeachDescriptors(characteristic.GetHandle(), cb, IntPtr.Zero);
+ GattUtil.Error(err, "Failed to get all descriptor");
+
+ return attribututeList;
+ }
+ }
+
+ internal class BluetoothGattDescriptorImpl : BluetoothGattAttributeImpl
+ {
+ internal BluetoothGattDescriptorImpl(string uuid, BluetoothGattPermission permission, byte[] value)
+ {
+ int err = Interop.Bluetooth.BtGattDescriptorCreate(uuid, (int)permission, value, value.Length, out _handle);
+ GattUtil.ThrowForError(err, "Failed to get native descriptor handle");
+ }
+
+ internal BluetoothGattDescriptorImpl(BluetoothGattAttributeHandle handle)
+ {
+ _handle = handle;
+ }
+
+ internal static BluetoothGattDescriptor CreateBluetoothGattDescriptor(BluetoothGattAttributeHandle handle, string uuid)
+ {
+ int permission;
+ int err = Interop.Bluetooth.BtGattDescriptorGetPermissions(handle, out permission);
+ GattUtil.ThrowForError(err, string.Format("Failed to get permissions with UUID ({0})", uuid));
+
+ if (uuid == "")
+ {
+ int ret = Interop.Bluetooth.BtGattGetUuid(handle, out uuid);
+ GattUtil.ThrowForError(ret, "Failed to get UUID");
+ }
+
+ BluetoothGattDescriptorImpl impl = new BluetoothGattDescriptorImpl(handle);
+ return new BluetoothGattDescriptor(impl, uuid, (BluetoothGattPermission)permission);
+ }
+ }
+
+ internal abstract class BluetoothGattAttributeImpl
+ {
+ protected BluetoothGattAttributeHandle _handle;
+
+ internal string GetUuid()
+ {
+ string uuid;
+ int err = Interop.Bluetooth.BtGattGetUuid(_handle, out uuid);
+ GattUtil.Error(err, "Failed to get attribute uuid");
+
+ return uuid;
+ }
+
+ internal byte[] GetValue()
+ {
+ IntPtr nativeValue;
+ int nativeValueLength;
+ int err = Interop.Bluetooth.BtGattGetValue(_handle, out nativeValue, out nativeValueLength);
+ GattUtil.Error(err, "Failed to get attribute value");
+
+ return GattUtil.IntPtrToByteArray(nativeValue, nativeValueLength);
+ }
+
+ internal void SetValue(byte[] value)
+ {
+ int err = Interop.Bluetooth.BtGattSetValue(_handle, value, value.Length);
+ GattUtil.ThrowForError(err, "Failed to set attribute value");
+ }
+
+ internal string GetValue(int offset)
+ {
+ byte[] value = GetValue();
+
+ int nullPos = value.Length - offset;
+ for (int i = offset; i < value.Length; ++i)
+ {
+ if (value[i] == '\0')
+ {
+ nullPos = i;
+ break;
+ }
+ }
+
+ string strValue = "";
+ strValue = Encoding.UTF8.GetString(value, offset, nullPos - offset);
+ return strValue;
+ }
+
+ internal int GetValue(IntDataType type, int offset)
+ {
+ int value;
+ int err = Interop.Bluetooth.BtGattGetIntValue(_handle, (int)type, offset, out value);
+ GattUtil.Error(err, "Failed to get attribute int value at offset");
+ return value;
+ }
+
+ internal void SetValue(IntDataType type, int value, int offset)
+ {
+ int err = Interop.Bluetooth.BtGattSetIntValue(_handle, (int)type, value, offset);
+ GattUtil.ThrowForError(err, "Failed to set attribute int value at offset");
+ }
+
+ internal float GetValue(FloatDataType type, int offset)
+ {
+ float value;
+ int err = Interop.Bluetooth.BtGattGetFloatValue(_handle, (int)type, offset, out value);
+ GattUtil.Error(err, "Failed to get attribute float value at offset");
+ return value;
+ }
+
+ internal void SetValue(FloatDataType type, int mantissa, int exponent, int offset)
+ {
+ int err = Interop.Bluetooth.BtGattSetFloatValue(_handle, (int)type, mantissa, exponent, offset);
+ GattUtil.ThrowForError(err, "Failed to set attribute float value at offset");
+ }
+
+ internal void SetReadValueRequestedEventCallback(Interop.Bluetooth.BtGattServerReadValueRequestedCallback callback)
+ {
+ int err = Interop.Bluetooth.BtGattServerSetReadValueRequestedCallback(_handle, callback, IntPtr.Zero);
+ GattUtil.ThrowForError(err, "Failed to set attribute read value requested callback");
+ }
+
+ internal void SetWriteValueRequestedEventCallback(Interop.Bluetooth.BtGattServerWriteValueRequestedCallback callback)
+ {
+ int err = Interop.Bluetooth.BtGattServerSetWriteValueRequestedCallback(_handle, callback, IntPtr.Zero);
+ GattUtil.ThrowForError(err, "Failed to set attribute write value requested callback");
+ }
+
+ internal BluetoothGattAttributeHandle GetHandle()
+ {
+ return _handle;
+ }
+
+ internal void ReleaseHandleOwnership()
+ {
+ _handle.ReleaseOwnership();
+ }
+ }
+
+
+ internal class BluetoothGattAttributeHandle : BluetoothGattHandle
+ {
+ public BluetoothGattAttributeHandle(IntPtr nativeHandle, bool hasOwnership) : base(nativeHandle, hasOwnership)
+ {
+ }
+
+ public BluetoothGattAttributeHandle()
+ {
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ if (_hasOwnership == true)
+ {
+ Interop.Bluetooth.BtGattDestroy(handle);
+ }
+ SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+
+ internal class BluetoothGattClientHandle : BluetoothGattHandle
+ {
+ protected override bool ReleaseHandle()
+ {
+ if (_hasOwnership == true)
+ {
+ Interop.Bluetooth.BtGattClientDestroy(handle);
+ }
+ SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+
+ internal class BluetoothGattServerHandle : BluetoothGattHandle
+ {
+ protected override bool ReleaseHandle()
+ {
+ if (_hasOwnership == true)
+ {
+ Interop.Bluetooth.BtGattServerDeinitialize();
+ Interop.Bluetooth.BtGattServerDestroy(handle);
+ }
+ SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+
+ internal abstract class BluetoothGattHandle : SafeHandle
+ {
+ protected bool _hasOwnership;
+
+ public BluetoothGattHandle() : base(IntPtr.Zero, true)
+ {
+ _hasOwnership = true;
+ }
+
+ public BluetoothGattHandle(IntPtr nativeHandle, bool hasOwnership) : base(nativeHandle, true)
+ {
+ _hasOwnership = hasOwnership;
+ }
+
+ public override bool IsInvalid
+ {
+ get { return handle == IntPtr.Zero; }
+ }
+
+ public void ReleaseOwnership()
+ {
+ _hasOwnership = false;
+ }
+ }
+
+ internal static class GattUtil
+ {
+ internal static byte[] IntPtrToByteArray(IntPtr nativeValue, int lenght)
+ {
+ byte[] value = new byte[lenght];
+ if (nativeValue != IntPtr.Zero)
+ {
+ Marshal.Copy(nativeValue, value, 0, lenght);
+ }
+ return value;
+ }
+
+ internal static void Error(int err, string message, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ if (err.IsFailed())
+ {
+ Log.Error(Globals.LogTag, string.Format("{0}, err: {1}", message, (BluetoothError)err), file, func, line);
+ }
+ }
+
+ internal static void ThrowForError(int err, string message, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+ {
+ if (err.IsFailed())
+ {
+ Log.Error(Globals.LogTag, string.Format("{0}, err: {1}", message, (BluetoothError)err), file, func, line);
+ BluetoothErrorFactory.ThrowBluetoothException(err);
+ }
+ }
+
+ internal static bool IsFailed(this int err)
+ {
+ return err != (int)BluetoothError.None;
+ }
+ }
+}
diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothHid.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothHid.cs
new file mode 100644
index 0000000..e546dd1
--- /dev/null
+++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothHid.cs
@@ -0,0 +1,75 @@
+using System;
+
+namespace Tizen.Network.Bluetooth
+{
+ /// <summary>
+ /// A class which is used to handle the connection to Bluetooth HID like keyboards and mouse.
+ /// </summary>
+ /// <privilege> http://tizen.org/privilege/bluetooth </privilege>
+ public class BluetoothHid : BluetoothProfile
+ {
+ internal BluetoothHid()
+ {
+ }
+
+ /// <summary>
+ /// (event) HidConnectionStateChanged is called when hid host connection state is changed.
+ /// </summary>
+ public event EventHandler<HidConnectionStateChangedEventArgs> HidConnectionStateChanged
+ {
+ add
+ {
+ BluetoothHidImpl.Instance.HidConnectionStateChanged += value;
+ }
+ remove
+ {
+ BluetoothHidImpl.Instance.HidConnectionStateChanged -= value;
+ }
+ }
+
+ /// <summary>
+ /// Connect the remote device with the Hid service.
+ /// </summary>
+ /// <remarks>
+ /// The device must be bonded with remote device by CreateBond().
+ /// If connection request succeeds, HidConnectionStateChanged event will be invoked.
+ /// </remarks>
+ public void Connect()
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ int ret = BluetoothHidImpl.Instance.Connect(RemoteAddress);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to Connect - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+ else
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
+ }
+ }
+
+ /// <summary>
+ /// Disconnects the remote device with the Hid service.
+ /// </summary>
+ public void Disconnect()
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ int ret = BluetoothHidImpl.Instance.Disconnect(RemoteAddress);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to Disconnect - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+ else
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
+ }
+ }
+ }
+}
+
diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothHidImpl.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothHidImpl.cs
new file mode 100644
index 0000000..b8a9122
--- /dev/null
+++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothHidImpl.cs
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Network.Bluetooth
+{
+ internal class BluetoothHidImpl : IDisposable
+ {
+ private event EventHandler<HidConnectionStateChangedEventArgs> _hidConnectionChanged;
+ private Interop.Bluetooth.HidConnectionStateChangedCallback _hidConnectionChangedCallback;
+
+ private static readonly BluetoothHidImpl _instance = new BluetoothHidImpl();
+ private bool disposed = false;
+
+ internal event EventHandler<HidConnectionStateChangedEventArgs> HidConnectionStateChanged
+ {
+ add
+ {
+ _hidConnectionChanged += value;
+ }
+ remove
+ {
+ //nothing to be done
+ }
+ }
+
+ internal int Connect(string deviceAddress)
+ {
+ if (Globals.IsHidInitialize)
+ {
+ int ret = Interop.Bluetooth.Connect (deviceAddress);
+ if (ret != (int)BluetoothError.None) {
+ Log.Error (Globals.LogTag, "Failed to connect device with the hid service, Error - " + (BluetoothError)ret);
+ }
+ return ret;
+ }
+ return (int)BluetoothError.NotInitialized;
+ }
+
+ internal int Disconnect(string deviceAddress)
+ {
+ if (Globals.IsHidInitialize)
+ {
+ int ret = Interop.Bluetooth.Disconnect (deviceAddress);
+ if (ret != (int)BluetoothError.None) {
+ Log.Error (Globals.LogTag, "Failed to disconnect device with the hid service, Error - " + (BluetoothError)ret);
+ }
+ return ret;
+ }
+ return (int)BluetoothError.NotInitialized;
+ }
+
+ internal static BluetoothHidImpl Instance
+ {
+ get
+ {
+ return _instance;
+ }
+ }
+ private BluetoothHidImpl ()
+ {
+ initialize();
+ }
+ ~BluetoothHidImpl()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects.
+ }
+ //Free unmanaged objects
+ deinitialize();
+ disposed = true;
+ }
+
+ private void initialize()
+ {
+ if (Globals.IsInitialize)
+ {
+ _hidConnectionChangedCallback = (int result, bool connected, string deviceAddress, IntPtr userData) =>
+ {
+ if (_hidConnectionChanged != null)
+ {
+ _hidConnectionChanged(null, new HidConnectionStateChangedEventArgs(result, connected, deviceAddress));
+ }
+ };
+
+ int ret = Interop.Bluetooth.InitializeHid (_hidConnectionChangedCallback, IntPtr.Zero);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to initialize bluetooth hid, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException (ret);
+ }
+ else
+ {
+ Globals.IsHidInitialize = true;
+ }
+ }
+ else
+ {
+ Log.Error(Globals.LogTag, "Failed to initialize HID, BT not initialized");
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotInitialized);
+ }
+ }
+
+ private void deinitialize()
+ {
+ if (Globals.IsHidInitialize)
+ {
+ int ret = Interop.Bluetooth.DeinitializeHid ();
+ if (ret != (int)BluetoothError.None) {
+ Log.Error (Globals.LogTag, "Failed to deinitialize bluetooth hid, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException (ret);
+ } else {
+ Globals.IsHidInitialize = false;
+ }
+ }
+ }
+ }
+}
+
diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothLeAdapter.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothLeAdapter.cs
new file mode 100644
index 0000000..9d7da13
--- /dev/null
+++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothLeAdapter.cs
@@ -0,0 +1,774 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Threading.Tasks;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Network.Bluetooth {
+
+ /// <summary>
+ /// This class is BluetoothLeAdvertiser. Handles the Le Advertising operation amd callback.
+ /// </summary>
+ public class BluetoothLeAdvertiser
+ {
+ private static readonly BluetoothLeAdvertiser _instance = new BluetoothLeAdvertiser();
+
+ internal static BluetoothLeAdvertiser Instance
+ {
+ get
+ {
+ return _instance;
+ }
+ }
+
+ private BluetoothLeAdvertiser()
+ {
+ }
+
+ /// <summary>
+ /// Event that is called when the LE advertising state changes
+ /// </summary>
+ public event EventHandler<AdvertisingStateChangedEventArgs> AdvertisingStateChanged
+ {
+ add
+ {
+ BluetoothLeImplAdapter.Instance.AdapterLeAdvertisingStateChanged += value;
+ }
+ remove
+ {
+ BluetoothLeImplAdapter.Instance.AdapterLeAdvertisingStateChanged -= value;
+ }
+ }
+ /// <summary>
+ /// Start advertising using the advertisedata object.
+ /// </summary>
+ /// <remarks>
+ /// Bluetooth must be enabled.
+ /// </remarks>
+ /// <param name="advertiseData">The advertiser object carrying information of the advertising.</param>
+ public void StartAdvertising(BluetoothLeAdvertiseData advertiseData)
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ int ret = BluetoothLeImplAdapter.Instance.StartAdvertising (advertiseData.GetHandle ());
+ if (ret != (int)BluetoothError.None) {
+ Log.Error (Globals.LogTag, "Failed to start advertising- " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+ else
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
+ }
+ }
+
+ /// <summary>
+ /// Stops the advertising.
+ /// </summary>
+ /// <remarks>
+ /// Bluetooth must be enabled.
+ /// </remarks>
+ /// <param name="advertiseData">The advertiser object carrying information of the advertising.</param>
+ public void StopAdvertising(BluetoothLeAdvertiseData advertiseData)
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ int ret = BluetoothLeImplAdapter.Instance.StopAdvertising (advertiseData.GetHandle ());
+ if (ret != (int)BluetoothError.None) {
+ Log.Error (Globals.LogTag, "Failed to stop advertising operation- " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+ else
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
+ }
+ }
+ }
+
+ /// <summary>
+ /// This class is BluetoothLeDevice.
+ /// Handles the Le device operations like getting data from the scan result information.
+ /// </summary>
+ public class BluetoothLeDevice
+ {
+ //properties of Bluetoothlesacandata
+ private string _remoteAddress;
+ private BluetoothLeDeviceAddressType _addressType;
+ private int _rssi;
+ private byte[] _advDataValue;
+ private byte[] _scanDataValue;
+ private BluetoothLePacketType _packetType;
+ private BluetoothLeScanData _scanData;
+
+ /// <summary>
+ /// Event that is called when the Gatt client connects/disconnects with the server
+ /// </summary>
+ public event EventHandler<GattConnectionStateChangedEventArgs> GattConnectionStateChanged
+ {
+ add
+ {
+ BluetoothLeImplAdapter.Instance.LeGattConnectionStateChanged += value;
+ }
+ remove
+ {
+ BluetoothLeImplAdapter.Instance.LeGattConnectionStateChanged -= value;
+ }
+ }
+
+ internal BluetoothLeDevice(BluetoothLeScanData scanData)
+ {
+ _scanData = new BluetoothLeScanData ();
+ _scanData = scanData;
+
+ Log.Info (Globals.LogTag, "Rssi" + _scanData.Rssi);
+ _rssi = scanData.Rssi;
+ Log.Info (Globals.LogTag, "RemoteAddress" + _scanData.RemoteAddress);
+ if (scanData.RemoteAddress != null)
+ _remoteAddress = scanData.RemoteAddress;
+ Log.Info (Globals.LogTag, "AddressType" + _scanData.AddressType);
+ _addressType = scanData.AddressType;
+
+ Log.Info (Globals.LogTag, "AdvDataLength" + _scanData.AdvDataLength);
+ if (_scanData.AdvDataLength > 0)
+ {
+ _advDataValue = new byte[_scanData.AdvDataLength];
+ scanData.AdvData.CopyTo(_advDataValue, 0);
+ }
+
+ Log.Info(Globals.LogTag, "ScanDataLength" + _scanData.ScanDataLength);
+ // Check length before copying
+ if (_scanData.ScanDataLength > 0)
+ {
+ _scanDataValue = new byte[_scanData.ScanDataLength];
+ scanData.ScanData.CopyTo(_scanDataValue, 0);
+ }
+ }
+
+ ~BluetoothLeDevice()
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ BluetoothLeImplAdapter.Instance.FreeServiceDataList();
+ }
+ }
+
+ /// <summary>
+ /// The remote address.
+ /// </summary>
+ public string RemoteAddress
+ {
+ get
+ {
+ return _remoteAddress;
+ }
+ }
+
+ /// <summary>
+ /// The type of the address.
+ /// </summary>
+ public BluetoothLeDeviceAddressType AddressType
+ {
+ get
+ {
+ return _addressType;
+ }
+ }
+
+ /// <summary>
+ /// The rssi value.
+ /// </summary>
+ public int Rssi
+ {
+ get
+ {
+ return _rssi;
+ }
+ }
+
+ /// <summary>
+ /// The advertsing data information.
+ /// </summary>
+ public byte[] AdvertsingDataInformation
+ {
+ get
+ {
+ return _advDataValue;
+ }
+ }
+
+ /// <summary>
+ /// The scan data information.
+ /// </summary>
+ public byte[] ScanDataInformation
+ {
+ get
+ {
+ return _scanDataValue;
+ }
+ }
+
+ /// <summary>
+ /// The type of the packet.
+ /// </summary>
+ public BluetoothLePacketType PacketType
+ {
+ get
+ {
+ return _packetType;
+ }
+ set
+ {
+ _packetType = value;
+ }
+ }
+
+ /// <summary>
+ /// Get service uuids list from the Le scan result information
+ /// </summary>
+ /// <value> Gets list of string service uuids.</value>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ public IEnumerable<string> ServiceUuid
+ {
+ get
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ Log.Info(Globals.LogTag, "Retrieving Service uuid- ");
+ return BluetoothLeImplAdapter.Instance.GetLeScanResultServiceUuids(_scanData, _packetType);
+ }
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Get device name from the Le scan result information
+ /// </summary>
+ /// <value> Gets device name.</value>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ public string DeviceName
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Retrieving device name- ");
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ return BluetoothLeImplAdapter.Instance.GetLeScanResultDeviceName(_scanData, _packetType);
+ }
+ return null;
+ }
+ }
+ /// <summary>
+ /// Get transmission power level from the Le scan result information
+ /// </summary>
+ /// <value> Gets the transmission power level in dB.</value>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ public int TxPowerLevel
+ {
+ get
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ return BluetoothLeImplAdapter.Instance.GetScanResultTxPowerLevel(_scanData, _packetType);
+ }
+ return -1;
+ }
+ }
+
+ /// <summary>
+ /// Get service solicitation uuid list from the scan result information
+ /// </summary>
+ /// <value> Gets list of service solicitation uuids.</value>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ public IEnumerable<string> ServiceSolictationUuid
+ {
+ get
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ return BluetoothLeImplAdapter.Instance.GetScanResultSvcSolicitationUuids(_scanData, _packetType);
+ }
+ return null;
+ }
+ }
+ /// <summary>
+ /// Gets the manufacturer data from the scan result information
+ /// </summary>
+ /// <value> Gets the appearance value.</value>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ public int Appearance
+ {
+ get
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ return BluetoothLeImplAdapter.Instance.GetScanResultAppearance(_scanData, _packetType);
+ }
+ return -1;
+ }
+ }
+ /// <summary>
+ /// Gets the manufacturer data from the scan result information
+ /// </summary>
+ /// <value> Gets the manufacturer data containing the manucturer data and id information.</value>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ public ManufacturerData ManufacturerData
+ {
+ get
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ return BluetoothLeImplAdapter.Instance.GetScanResultManufacturerData(_scanData, _packetType);
+ }
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Get service data list from the scan result information
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ /// <returns> Returns the service data list.</returns>
+ public IEnumerable<BluetoothLeServiceData> GetServiceDataList()
+ {
+ int serviceCount = 0;
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ return BluetoothLeImplAdapter.Instance.GetScanResultServiceDataList(_scanData,
+ _packetType, out serviceCount);
+ }
+ return null;
+ }
+
+
+ /// <summary>
+ /// Creates a GATT connection with the remote device.
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ /// <param name="autoConnect"> The auto connect flag</param>
+ /// <returns>client instance</returns>
+ public BluetoothGattClient GattConnect(bool autoConnect)
+ {
+ BluetoothGattClient client = null;
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ int ret = BluetoothLeImplAdapter.Instance.GattConnect (_remoteAddress, autoConnect);
+ if (ret != (int)BluetoothError.None) {
+ Log.Error (Globals.LogTag, "Failed to create GATT Connection with remote device- " + (BluetoothError)ret);
+ }
+ else
+ {
+ client = BluetoothGattClient.CreateClient(_remoteAddress);
+ }
+ }
+ else
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
+ }
+ return client;
+ }
+
+ /// <summary>
+ /// Disconnect a GATT connection with the remote device.
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ public void GattDisconnect()
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ int ret = BluetoothLeImplAdapter.Instance.GattDisconnect (_remoteAddress);
+ if (ret != (int)BluetoothError.None) {
+ Log.Error (Globals.LogTag, "Failed to disconnect GATT connection with remote device- " + (BluetoothError)ret);
+ }
+ }
+ else
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Bluetooth le advertise data. Handles the data advertising.
+ /// </summary>
+ public class BluetoothLeAdvertiseData:IDisposable
+ {
+ private IntPtr _handle = IntPtr.Zero;
+ private BluetoothLeAdvertisingMode _mode;
+ private bool _advertisingConnectable;
+ private BluetoothLePacketType _packetType;
+ private int _appearance;
+ private bool _includePowerLevel;
+ private bool _includeDeviceName;
+
+ /// <summary>
+ /// Default Constructor.Initializes an object of BluetoothLeAdvertiseData
+ /// </summary>
+ public BluetoothLeAdvertiseData()
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ Log.Debug(Globals.LogTag, " Creating LeAdvertiser()");
+ int ret = Interop.Bluetooth.CreateAdvertiser(out _handle);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to create advertiser object- " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+ else
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
+ }
+ }
+
+ ~BluetoothLeAdvertiseData()
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ //clean-up
+ ClearAdvertisingData (BluetoothLePacketType.BluetoothLeAdvertisingPacket);
+ ClearAdvertisingData (BluetoothLePacketType.BluetoothLeScanResponsePacket);
+ BluetoothLeImplAdapter.Instance.DestroyAdvertiser (_handle);
+ }
+ Dispose(false);
+ }
+
+ internal IntPtr GetHandle()
+ {
+ return _handle;
+ }
+
+ /// <summary>
+ /// The advertising mode to control the advertising power and latency.
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ public BluetoothLeAdvertisingMode AdvertisingMode
+ {
+ get
+ {
+ return _mode;
+ }
+ set
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ _mode = value;
+ int ret = Interop.Bluetooth.SetAdvertisingMode (GetHandle (), _mode);
+ if (ret != (int)BluetoothError.None) {
+ Log.Error (Globals.LogTag, "Failed to set advertising mode- " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException (ret);
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// The advertising connectable type.
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ public bool AdvertisingConnectable
+ {
+ get
+ {
+ return _advertisingConnectable;
+ }
+ set
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ _advertisingConnectable = value;
+ int ret = Interop.Bluetooth.SetAdvertisingConnectable (GetHandle (), _advertisingConnectable);
+ if (ret != (int)BluetoothError.None) {
+ Log.Error (Globals.LogTag, "Failed to set advertising connectable value- " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException (ret);
+ }
+ }
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ //todo...
+ }
+
+ /// <summary>
+ /// The type of the packet.
+ /// </summary>
+ public BluetoothLePacketType PacketType
+ {
+ get
+ {
+ return _packetType;
+ }
+ set
+ {
+ _packetType = value;
+ }
+ }
+ /// <summary>
+ /// Sets the external appearance of this device to advertise or scan response data
+ /// Please refer to the adopted Bluetooth specification for the the appearance..
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ public int Appearance
+ {
+ get
+ {
+ return _appearance;
+ }
+ set
+ {
+ _appearance = value;
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) {
+ int ret = Interop.Bluetooth.SetAdvertisingAppearance (GetHandle (), _packetType, _appearance);
+ if (ret != (int)BluetoothError.None) {
+ Log.Error (Globals.LogTag, "Failed to add appearance value to advertising data- " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+ }
+ }
+ /// <summary>
+ /// Sets whether the device name has to be incuded in the advertise or scan response data
+ /// The maximum advertised or responded data size is 31 bytes including data type and system wide data.
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ public bool IncludeDeviceName
+ {
+ get
+ {
+ return _includeDeviceName;
+ }
+ set
+ {
+ _includeDeviceName = value;
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ int ret = Interop.Bluetooth.SetAdvertisingDeviceName(GetHandle(), _packetType, _includeDeviceName);
+ if (ret != (int)BluetoothError.None) {
+ Log.Error (Globals.LogTag, "Failed to add device name to advertising data- " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+ }
+ }
+
+
+ /// <summary>
+ /// Set whether the transmission power level should be included in advertise or scan response data.
+ /// The maximum advertised or responded data size is 31 bytes including data type and system wide data.
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ public bool IncludeTxPowerLevel
+ {
+ get
+ {
+ return _includePowerLevel;
+ }
+ set
+ {
+ _includePowerLevel = value;
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ int ret = Interop.Bluetooth.SetAdvertisingTxPowerLevel(GetHandle(), _packetType, _includePowerLevel);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to add advertising service solicitation uuid- " + (BluetoothError)ret);
+ }
+ }
+ }
+ }
+ /// <summary>
+ /// Add a service UUID to advertise or scan response data.
+ /// The maximum advertised or responded data size is 31 bytes
+ /// including data type and system wide data
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ /// <param name="packetType">The packet type </param>
+ /// <param name="serviceUuid"> The service uuid to add to advertise data</param>
+ public void AddAdvertisingServiceUuid(BluetoothLePacketType packetType, string serviceUuid)
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ int ret = Interop.Bluetooth.AddAdvertisingServiceUuid (GetHandle (), packetType, serviceUuid);
+ if (ret != (int)BluetoothError.None) {
+ Log.Error (Globals.LogTag, "Failed to add service uuid to advertising data- " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException (ret);
+ }
+ }
+ else
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
+ }
+ }
+
+ /// <summary>
+ /// Add a service solicitation UUID to advertise or scan response data.
+ /// The maximum advertised or responded data size is 31 bytes
+ /// including data type and system wide data.
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ /// <param name="packetType">The packet type </param>
+ /// <param name="serviceSolicitationUuid"> The service solicitation uuid to add to advertise data</param>
+ public void AddAdvertisingServiceSolicitationUuid(BluetoothLePacketType packetType,
+ string serviceSolicitationUuid)
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ int ret = Interop.Bluetooth.AddAdvertisingServiceSolicitationUuid(GetHandle(), packetType,
+ serviceSolicitationUuid);
+ if (ret != (int)BluetoothError.None) {
+ Log.Error (Globals.LogTag, "Failed to add service solicitation uuid to advertising data- " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+ else
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
+ }
+ }
+
+ /// <summary>
+ /// Add a service data to advertise or scan response data.
+ /// The maximum advertised or responded data size is 31 bytes
+ /// including data type and system wide data.
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ /// <param name="packetType">The packet type </param>
+ /// <param name="data"> The service data to be added to advertising</param>
+ public void AddAdvertisingServiceData(BluetoothLePacketType packetType, BluetoothServiceData data)
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ IntPtr serviceDataPtr;
+ serviceDataPtr = Marshal.AllocHGlobal(data.DataLength);
+ Marshal.Copy(data.Data, 0, serviceDataPtr, data.DataLength);
+
+ for (int i = 0; i < 3; i++)
+ Log.Error (Globals.LogTag, " service data is " + data.Data [i]);
+ int ret = Interop.Bluetooth.AddAdvertisingServiceData(GetHandle(), packetType,
+ data.Uuid, serviceDataPtr, data.DataLength);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to add service data to advertising data- " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+ else
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
+ }
+ }
+
+ /// <summary>
+ /// Add manufacturer specific data to advertise or scan response data.
+ /// Please refer to the adopted Bluetooth specification for the the appearance..
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ /// <param name="packetType">The packet type</param>
+ /// <param name="manufacturerData"> The manufacturer specific data</param>
+ public void AddAdvertisingManufacturerData(BluetoothLePacketType packetType,
+ ManufacturerData manufacturerData)
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ IntPtr manufDataPtr;
+ manufDataPtr = Marshal.AllocHGlobal(manufacturerData.DataLength);
+ Marshal.Copy(manufacturerData.Data, 0, manufDataPtr, manufacturerData.DataLength);
+
+ int ret = Interop.Bluetooth.AddAdvertisingManufData(GetHandle(), packetType,
+ manufacturerData.Id, manufDataPtr, manufacturerData.DataLength);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to add service solicitation uuid to advertising data- " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+ else
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
+ }
+ }
+
+ /// <summary>
+ /// Clear all data to be advertised or responded to scan request from LE scanning device.
+ /// </summary>
+ /// <remarks>
+ /// The Bluetooth must be enabled.
+ /// </remarks>
+ /// <param name="packetType">The packet type to be cleared</param>
+ internal void ClearAdvertisingData(BluetoothLePacketType packetType)
+ {
+ if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize)
+ {
+ int ret = Interop.Bluetooth.ClearAdvertisingData (GetHandle (), packetType);
+ if (ret != (int)BluetoothError.None) {
+ Log.Error (Globals.LogTag, "Failed to Clear Advertising Data- " + (BluetoothError)ret);
+ }
+ }
+ else
+ {
+ BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothLeAdapterImpl.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothLeAdapterImpl.cs
new file mode 100755
index 0000000..1fb02de
--- /dev/null
+++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothLeAdapterImpl.cs
@@ -0,0 +1,452 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Threading.Tasks;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Network.Bluetooth
+{
+ internal class BluetoothLeImplAdapter : IDisposable
+ {
+ private static readonly BluetoothLeImplAdapter _instance = new BluetoothLeImplAdapter();
+
+ private bool disposed = false;
+
+ private event EventHandler<AdapterLeScanResultChangedEventArgs> _adapterLeScanResultChanged = null;
+ private Interop.Bluetooth.AdapterLeScanResultChangedCallBack _adapterLeScanResultChangedCallback;
+
+ private event EventHandler<AdvertisingStateChangedEventArgs> _advertisingStateChanged = null;
+ private Interop.Bluetooth.AdvertisingStateChangedCallBack _advertisingStateChangedCallback;
+
+ private event EventHandler<GattConnectionStateChangedEventArgs> _gattConnectionStateChanged = null;
+ private Interop.Bluetooth.GattConnectionStateChangedCallBack _gattConnectionStateChangedCallback;
+
+ private int _serviceListCount = 0;
+ private IList<BluetoothLeServiceData> _list = new List<BluetoothLeServiceData>();
+ private bool _scanStarted;
+
+ internal static BluetoothLeImplAdapter Instance
+ {
+ get
+ {
+ return _instance;
+ }
+ }
+
+ private BluetoothLeImplAdapter()
+ {
+ }
+
+ ~BluetoothLeImplAdapter()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects.
+ }
+ //Free unmanaged objects
+ if (_gattConnectionStateChanged != null)
+ {
+ UnRegisterGattConnectionStateChangedEvent();
+ }
+
+ //stop scan operation in progress
+ StopScan ();
+
+ disposed = true;
+ }
+
+ internal event EventHandler<AdapterLeScanResultChangedEventArgs> AdapterLeScanResultChanged
+ {
+ add
+ {
+ _adapterLeScanResultChanged += value;
+ }
+ remove {
+ _adapterLeScanResultChanged -= value;
+ }
+ }
+
+ internal event EventHandler<AdvertisingStateChangedEventArgs> AdapterLeAdvertisingStateChanged
+ {
+ add
+ {
+ _advertisingStateChanged += value;
+ }
+ remove
+ {
+ _advertisingStateChanged -= value;
+ }
+ }
+
+ internal event EventHandler<GattConnectionStateChangedEventArgs> LeGattConnectionStateChanged
+ {
+ add
+ {
+ if (_gattConnectionStateChanged == null)
+ {
+ RegisterGattConnectionStateChangedEvent();
+ }
+ _gattConnectionStateChanged += value;
+ }
+ remove
+ {
+ _gattConnectionStateChanged -= value;
+ if (_gattConnectionStateChanged == null)
+ {
+ UnRegisterGattConnectionStateChangedEvent();
+ }
+ }
+ }
+
+ internal void RegisterGattConnectionStateChangedEvent()
+ {
+ _gattConnectionStateChangedCallback = (int result, bool connected,
+ string remoteDeviceAddress, IntPtr userData) =>
+ {
+ if (_gattConnectionStateChanged != null)
+ {
+ Log.Info(Globals.LogTag, "Setting gatt connection state changed callback" );
+ GattConnectionStateChangedEventArgs e = new GattConnectionStateChangedEventArgs (result,
+ connected, remoteDeviceAddress);
+
+ _gattConnectionStateChanged(null, e);
+ }
+ };
+
+ int ret = Interop.Bluetooth.SetGattConnectionStateChangedCallback(
+ _gattConnectionStateChangedCallback, IntPtr.Zero);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set gatt connection state changed callback, Error - " + (BluetoothError)ret);
+ }
+ }
+
+ internal void UnRegisterGattConnectionStateChangedEvent()
+ {
+ int ret = Interop.Bluetooth.UnsetGattConnectionStateChangedCallback();
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset gatt connection state changed callback, Error - " + (BluetoothError)ret);
+ }
+ }
+
+ internal int StartScan()
+ {
+ _adapterLeScanResultChangedCallback = (int result, ref BluetoothLeScanDataStruct scanData, IntPtr userData) =>
+ {
+ Log.Info(Globals.LogTag, "Inside Le scan callback " );
+ BluetoothLeScanData scanDataInfo = BluetoothUtils.ConvertStructToLeScanData(scanData);
+
+ BluetoothLeDevice device = new BluetoothLeDevice(scanDataInfo);
+ BluetoothError res = (BluetoothError)result;
+
+ AdapterLeScanResultChangedEventArgs e = new AdapterLeScanResultChangedEventArgs (res,
+ device);
+ _adapterLeScanResultChanged (null, e);
+ };
+
+ IntPtr data = IntPtr.Zero;
+ int ret = Interop.Bluetooth.StartScan(_adapterLeScanResultChangedCallback, data);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to start BLE scan - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ _scanStarted = true;
+ return ret;
+ }
+
+ internal int StopScan()
+ {
+ int ret = (int)BluetoothError.None;
+
+ if (_scanStarted)
+ {
+ ret = Interop.Bluetooth.StopScan ();
+ if (ret != (int)BluetoothError.None) {
+ Log.Error (Globals.LogTag, "Failed to stop BLE scan - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException (ret);
+ }
+ }
+ return ret;
+ }
+
+ internal IList<string> GetLeScanResultServiceUuids(BluetoothLeScanData scanData, BluetoothLePacketType packetType)
+ {
+ IntPtr uuidListArray = IntPtr.Zero;
+ int count = -1;
+
+ BluetoothLeScanDataStruct scanDataStruct = BluetoothUtils.ConvertLeScanDataToStruct(scanData);
+
+ int ret = Interop.Bluetooth.GetScanResultServiceUuid(ref scanDataStruct, packetType,
+ ref uuidListArray, ref count);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Info(Globals.LogTag, "Failed to service uuids list- " + (BluetoothError)ret);
+ return null;
+ }
+
+ Log.Info(Globals.LogTag, "count of uuids : " + count);
+
+ IntPtr[] uuidList = new IntPtr[count];
+ Marshal.Copy(uuidListArray, uuidList, 0, count);
+ IList<string> list = new List<string>();
+ foreach(IntPtr uuids in uuidList)
+ {
+ list.Add(Marshal.PtrToStringAnsi(uuids));
+ Interop.Libc.Free(uuids);
+ }
+
+ Interop.Libc.Free(uuidListArray);
+ return list;
+ }
+
+ internal string GetLeScanResultDeviceName(BluetoothLeScanData scanData, BluetoothLePacketType packetType)
+ {
+ string deviceName;
+
+ BluetoothLeScanDataStruct scanDataStruct = BluetoothUtils.ConvertLeScanDataToStruct (scanData);
+
+ int ret = Interop.Bluetooth.GetLeScanResultDeviceName(ref scanDataStruct, packetType, out deviceName);
+ if (ret != (int)BluetoothError.None) {
+ Log.Error(Globals.LogTag, "Failed to get Device name- " + (BluetoothError)ret);
+ return null;
+ }
+ Log.Info (Globals.LogTag, "Device name " + deviceName);
+ return deviceName;
+ }
+
+ internal int GetScanResultTxPowerLevel(BluetoothLeScanData scanData, BluetoothLePacketType packetType)
+ {
+ int powerLevel = -1;
+ BluetoothLeScanDataStruct scanDataStruct = BluetoothUtils.ConvertLeScanDataToStruct (scanData);
+
+ int ret = Interop.Bluetooth.GetScanResultTxPowerLevel(ref scanDataStruct, packetType, out powerLevel);
+ if (ret != (int)BluetoothError.None) {
+ Log.Error(Globals.LogTag, "Failed to get tx power level- " + (BluetoothError)ret);
+ }
+ Log.Info (Globals.LogTag, "TxPowerLevel is --- " + powerLevel);
+ return powerLevel;
+ }
+
+ internal IList<string> GetScanResultSvcSolicitationUuids(BluetoothLeScanData scanData, BluetoothLePacketType packetType)
+ {
+ IntPtr uuidListArray;
+ int count;
+
+ BluetoothLeScanDataStruct scanDataStruct = BluetoothUtils.ConvertLeScanDataToStruct(scanData);
+
+ int ret = Interop.Bluetooth.GetScaResultSvcSolicitationUuids(ref scanDataStruct, packetType, out uuidListArray, out count);
+ if (ret != (int)BluetoothError.None) {
+ Log.Error(Globals.LogTag, "Failed to get service solicitation uuids " + (BluetoothError)ret);
+ return null;
+ }
+
+ IntPtr[] uuidList = new IntPtr[count];
+ Marshal.Copy(uuidListArray, uuidList, 0, count);
+ IList<string> list = new List<string>();
+ foreach(IntPtr uuids in uuidList)
+ {
+ list.Add(Marshal.PtrToStringAnsi(uuids));
+ Interop.Libc.Free(uuids);
+ }
+
+ Interop.Libc.Free(uuidListArray);
+ return list;
+ }
+
+ internal IList<BluetoothLeServiceData> GetScanResultServiceDataList(BluetoothLeScanData scanData,
+ BluetoothLePacketType packetType, out int serviceCount)
+ {
+ int ret = 0;
+ IntPtr serviceListArray;
+ _serviceListCount = 0;
+
+ BluetoothLeScanDataStruct scanDataStruct = BluetoothUtils.ConvertLeScanDataToStruct (scanData);
+
+ ret = Interop.Bluetooth.GetScanResultServiceDataList(ref scanDataStruct, packetType, out serviceListArray, out _serviceListCount);
+ Log.Info(Globals.LogTag, "ServiceListCount : " + _serviceListCount + " PacketType : " + packetType + " Error: " + (BluetoothError)ret);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Info(Globals.LogTag, "Failed to get Service Data List, Error - " + (BluetoothError)ret);
+ serviceCount = 0;
+ Marshal.FreeHGlobal(serviceListArray);
+ Marshal.FreeHGlobal(scanDataStruct.AdvData);
+ Marshal.FreeHGlobal(scanDataStruct.ScanData);
+ return null;
+ }
+
+ BluetoothLeServiceDataStruct[] svcList = new BluetoothLeServiceDataStruct[_serviceListCount];
+ int sizePointerToABC = Marshal.SizeOf(new BluetoothLeServiceDataStruct());
+ for (int i = 0; i < _serviceListCount; i++)
+ {
+ svcList[i] = (BluetoothLeServiceDataStruct)Marshal.PtrToStructure(new IntPtr(serviceListArray.ToInt32() + (i * sizePointerToABC)), typeof(BluetoothLeServiceDataStruct));
+ Log.Info(Globals.LogTag, " Uuid : " + svcList[i].ServiceUuid + "length : " + svcList[i].ServiceDataLength);
+
+ _list.Add(BluetoothUtils.ConvertStructToLeServiceData(svcList[i]));
+ }
+
+ serviceCount = _serviceListCount;
+
+ Interop.Libc.Free(serviceListArray);
+ Marshal.FreeHGlobal(scanDataStruct.AdvData);
+ Marshal.FreeHGlobal(scanDataStruct.ScanData);
+ return _list;
+ }
+
+ internal int FreeServiceDataList()
+ {
+ if (_list.Count > 0)
+ {
+ int iServiceDataSize = Marshal.SizeOf(typeof(BluetoothLeServiceData));
+ IntPtr structServiceData = Marshal.AllocHGlobal(iServiceDataSize);
+ Marshal.StructureToPtr(_list, structServiceData, false);
+
+ int ret = Interop.Bluetooth.FreeServiceDataList(structServiceData, _serviceListCount);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to free Service Data List, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+
+ Marshal.FreeHGlobal(structServiceData);
+ }
+ return 0;
+ }
+
+ internal int GetScanResultAppearance(BluetoothLeScanData scanData, BluetoothLePacketType packetType)
+ {
+ int appearance;
+
+ BluetoothLeScanDataStruct scanDataStruct = BluetoothUtils.ConvertLeScanDataToStruct (scanData);
+
+ int ret = Interop.Bluetooth.GetScanResultAppearance(ref scanDataStruct, packetType, out appearance);
+ if (ret != (int)BluetoothError.None) {
+ Log.Error(Globals.LogTag, "Failed to get Appearance value- " + (BluetoothError)ret);
+ }
+ return appearance;
+ }
+
+ internal ManufacturerData GetScanResultManufacturerData(BluetoothLeScanData scanData, BluetoothLePacketType packetType)
+ {
+ int dataId = 0;
+ int dataLength = 0;
+ IntPtr manufData;
+
+ BluetoothLeScanDataStruct scanDataStruct = BluetoothUtils.ConvertLeScanDataToStruct (scanData);
+ ManufacturerData data = new ManufacturerData();
+
+ int ret = Interop.Bluetooth.GetScanResultManufacturerData(ref scanDataStruct, packetType, out dataId,
+ out manufData, out dataLength);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get Manufacturer data - " + (BluetoothError)ret);
+ return null;
+ }
+
+ data.Id = dataId;
+ data.DataLength = dataLength;
+ if (data.DataLength > 0)
+ {
+ data.Data = new byte[data.DataLength];
+ Marshal.Copy(manufData, data.Data, 0, data.DataLength);
+ }
+
+ return data;
+ }
+
+ internal int GattConnect(string remoteAddress, bool autoConnect)
+ {
+ int ret = Interop.Bluetooth.GattConnect (remoteAddress, autoConnect);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to establish GATT connection - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ return ret;
+ }
+
+ internal int GattDisconnect(string remoteAddress)
+ {
+ int ret = Interop.Bluetooth.GattDisconnect (remoteAddress);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to disconnect GATT connection - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ return ret;
+ }
+
+ internal int CreateAdvertiser(out IntPtr advertiserHandle)
+ {
+ return Interop.Bluetooth.CreateAdvertiser (out advertiserHandle);
+ }
+
+ internal int DestroyAdvertiser(IntPtr advertiserHandle)
+ {
+ int ret = Interop.Bluetooth.DestroyAdvertiser (advertiserHandle);
+ if (ret != (int)BluetoothError.None) {
+ Log.Error(Globals.LogTag, "Failed to destroy the Advertiser- " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ return ret;
+ }
+
+ internal int StartAdvertising(IntPtr advertisingHandle)
+ {
+ _advertisingStateChangedCallback = (int result, IntPtr advertiserHandle,
+ BluetoothLeAdvertisingState state, IntPtr userData) =>
+ {
+ Log.Info(Globals.LogTag, "Setting advertising state changed callback !! " );
+ AdvertisingStateChangedEventArgs e = new AdvertisingStateChangedEventArgs(result, advertiserHandle, state);
+ _advertisingStateChanged(null, e);
+ };
+
+ IntPtr uData = IntPtr.Zero;
+ int ret = Interop.Bluetooth.BluetoothLeStartAdvertising (advertisingHandle,
+ _advertisingStateChangedCallback, uData );
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to start BLE advertising - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ return ret;
+ }
+
+
+ internal int StopAdvertising(IntPtr advertisingHandle)
+ {
+ return Interop.Bluetooth.BluetoothLeStopAdvertising (advertisingHandle);
+ }
+ }
+}
diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothProfile.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothProfile.cs
new file mode 100644
index 0000000..6dff1cf
--- /dev/null
+++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothProfile.cs
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Network.Bluetooth
+{
+ /// <summary>
+ /// A generic class to represent all Bluetooth profiles.<br>
+ /// Any common properties/functions to be added in this class in future.
+ /// </summary>
+ /// <privilege> http://tizen.org/privilege/bluetooth </privilege>
+ public abstract class BluetoothProfile
+ {
+ internal string RemoteAddress { get; set; }
+ }
+}
diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothServerSocket.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothServerSocket.cs
new file mode 100755
index 0000000..b7bed91
--- /dev/null
+++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothServerSocket.cs
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Network.Bluetooth
+{
+ /// <summary>
+ /// BluetoothSocket provides functions for managing connections to other devices and exchanging data.
+ /// </summary>
+ public class BluetoothServerSocket : IDisposable
+ {
+ private event EventHandler<AcceptStateChangedEventArgs> _acceptStateChanged;
+ private Interop.Bluetooth.SocketConnectionStateChangedCallback _connectionStateChangedCallback;
+ internal int socketFd;
+ private bool disposed = false;
+
+ /// <summary>
+ /// (event) AcceptStateChanged is raised when socket connection state is changed.
+ /// </summary>
+ public event EventHandler<AcceptStateChangedEventArgs> AcceptStateChanged
+ {
+ add
+ {
+ if (_acceptStateChanged == null)
+ {
+ RegisterAcceptStateChangedEvent();
+ }
+ _acceptStateChanged += value;
+ }
+ remove
+ {
+ _acceptStateChanged -= value;
+ if (_acceptStateChanged == null)
+ {
+ UnregisterAcceptStateChangedEvent();
+ }
+ }
+ }
+
+ private void RegisterAcceptStateChangedEvent()
+ {
+ _connectionStateChangedCallback = (int result, BluetoothSocketState connectionState, ref SocketConnectionStruct socketConnection, IntPtr userData) =>
+ {
+ Log.Info(Globals.LogTag, "AcceptStateChanged cb is called");
+ if (_acceptStateChanged != null)
+ {
+ BluetoothSocket socket = new BluetoothSocket();
+ socket.connectedSocket = socketConnection.SocketFd;
+ GCHandle handle2 = (GCHandle) userData;
+ _acceptStateChanged(handle2.Target as BluetoothServerSocket, new AcceptStateChangedEventArgs((BluetoothError)result, connectionState, BluetoothUtils.ConvertStructToSocketConnection(socketConnection), socket));
+ }
+ };
+ GCHandle handle1 = GCHandle.Alloc(this);
+ IntPtr data = (IntPtr) handle1;
+ int ret = Interop.Bluetooth.SetConnectionStateChangedCallback(_connectionStateChangedCallback, data);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set accept state changed callback, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+
+ private void UnregisterAcceptStateChangedEvent()
+ {
+ int ret = Interop.Bluetooth.UnsetSocketConnectionStateChangedCallback();
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset accept state changed callback, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+
+ internal BluetoothServerSocket(int socketFd)
+ {
+ Log.Info (Globals.LogTag, "Constructing server socket");
+ this.socketFd = socketFd;
+ }
+
+ /// <summary>
+ /// Starts listening on passed rfcomm socket and accepts connection requests.
+ /// </summary>
+ /// <remarks>
+ /// The socket must be created with CreateServerSocket(). This API invokes ConnectionStateChanged event.
+ /// </remarks>
+ public void Listen()
+ {
+ int ret = Interop.Bluetooth.Listen(socketFd, 1);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to accept connection, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+
+ ~BluetoothServerSocket()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects.
+ }
+ //Free unmanaged objects
+ RemoveRegisteredEvents();
+ disposed = true;
+ }
+
+ private void RemoveRegisteredEvents()
+ {
+ //unregister all remaining events when this object is released.
+ if (_acceptStateChanged != null)
+ {
+ UnregisterAcceptStateChangedEvent();
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothSocket.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothSocket.cs
new file mode 100755
index 0000000..a44fd31
--- /dev/null
+++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothSocket.cs
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Network.Bluetooth
+{
+ /// <summary>
+ /// IBluetoothServerSocket interface. Handles the server socket operations.
+ /// </summary>
+ public interface IBluetoothServerSocket
+ {
+ event EventHandler<SocketDataReceivedEventArgs> DataReceived;
+ event EventHandler<SocketConnectionStateChangedEventArgs> ConnectionStateChanged;
+ int SendData(string data);
+ }
+
+ /// <summary>
+ /// IBluetoothClientSocket interface. Handles the client socket operations.
+ /// </summary>
+ public interface IBluetoothClientSocket : IBluetoothServerSocket
+ {
+ void Connect();
+ void Disconnect();
+ }
+
+ internal class BluetoothSocket : IBluetoothClientSocket, IDisposable
+ {
+ private event EventHandler<SocketDataReceivedEventArgs> _dataReceived;
+ private event EventHandler<SocketConnectionStateChangedEventArgs> _connectionStateChanged;
+ private Interop.Bluetooth.DataReceivedCallback _dataReceivedCallback;
+ private Interop.Bluetooth.SocketConnectionStateChangedCallback _connectionStateChangedCallback;
+ private bool disposed = false;
+ internal int connectedSocket;
+ internal string remoteAddress;
+ internal string serviceUuid;
+
+ /// <summary>
+ /// This event occurs when socket server received data from client.
+ /// </summary>
+ public event EventHandler<SocketDataReceivedEventArgs> DataReceived
+ {
+ add
+ {
+ if (_dataReceived == null)
+ {
+ RegisterDataReceivedEvent();
+ }
+ _dataReceived += value;
+ }
+ remove
+ {
+ _dataReceived -= value;
+ if (_dataReceived == null)
+ {
+ UnregisterDataReceivedEvent();
+ }
+ }
+ }
+
+ /// <summary>
+ /// This event occurs when connection state between two devices is changed.
+ /// </summary>
+ public event EventHandler<SocketConnectionStateChangedEventArgs> ConnectionStateChanged
+ {
+ add
+ {
+ if (_connectionStateChanged == null)
+ {
+ RegisterConnectionStateChangedEvent();
+ }
+ _connectionStateChanged += value;
+ }
+ remove
+ {
+ _connectionStateChanged -= value;
+ if (_connectionStateChanged == null)
+ {
+ UnregisterConnectionStateChangedEvent();
+ }
+ }
+ }
+
+ private void RegisterDataReceivedEvent()
+ {
+ _dataReceivedCallback = (ref SocketDataStruct socketData, IntPtr userData) =>
+ {
+ Log.Info(Globals.LogTag, "DataReceivedCallback is called");
+ if (_dataReceived != null)
+ {
+ GCHandle handle2 = (GCHandle) userData;
+ _dataReceived(handle2.Target as IBluetoothServerSocket, new SocketDataReceivedEventArgs(BluetoothUtils.ConvertStructToSocketData(socketData)));
+ }
+ };
+ GCHandle handle1 = GCHandle.Alloc (this);
+ IntPtr uData = (IntPtr) handle1;
+ int ret = Interop.Bluetooth.SetDataReceivedCallback(_dataReceivedCallback, uData);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set data received callback, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+
+ private void UnregisterDataReceivedEvent()
+ {
+ int ret = Interop.Bluetooth.UnsetDataReceivedCallback();
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset data received callback, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+
+ private void RegisterConnectionStateChangedEvent()
+ {
+ _connectionStateChangedCallback = (int result, BluetoothSocketState connectionState, ref SocketConnectionStruct socketConnection, IntPtr userData) =>
+ {
+ Log.Info(Globals.LogTag, "ConnectionStateChangedCallback is called");
+ if (_connectionStateChanged != null)
+ {
+ connectedSocket = socketConnection.SocketFd;
+ GCHandle handle2 = (GCHandle) userData;
+ _connectionStateChanged(handle2.Target as IBluetoothServerSocket, new SocketConnectionStateChangedEventArgs((BluetoothError)result, connectionState, BluetoothUtils.ConvertStructToSocketConnection(socketConnection)));
+ }
+ };
+ GCHandle handle1 = GCHandle.Alloc(this);
+ IntPtr data = (IntPtr) handle1;
+ int ret = Interop.Bluetooth.SetConnectionStateChangedCallback(_connectionStateChangedCallback, data);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set connection state changed callback, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+
+ private void UnregisterConnectionStateChangedEvent()
+ {
+ int ret = Interop.Bluetooth.UnsetSocketConnectionStateChangedCallback();
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset connection state changed callback, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Connects to a specific RFCOMM based service on a remote Bluetooth device UUID.
+ /// </summary>
+ /// <remarks>
+ /// The bluetooth must be enabled, discoverable with StartDiscovery(), bonded with the remote device using CreateBond(). ConnectionStateChanged event is raised once this API is called.
+ /// </remarks>
+ /// <param name="address">The address of the remote Bluetooth device.</param>
+ /// <param name="serviceUuid">The UUID of service provided by the remote Bluetooth device.</param>
+ void IBluetoothClientSocket.Connect()
+ {
+ int ret = Interop.Bluetooth.ConnectSocket(remoteAddress, serviceUuid);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to connect to socket, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Disconnects the RFCOMM connection with the given file descriptor of conneted socket.
+ /// </summary>
+ /// <remarks>
+ /// The connection must be established.
+ /// </remarks>
+ /// <param name="socketFd">The file descriptor of socket to close.</param>
+ void IBluetoothClientSocket.Disconnect()
+ {
+ int ret = Interop.Bluetooth.DisconnectSocket(connectedSocket);
+ if (ret != (int)BluetoothError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to disconnect socket, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Sends data to the connected device.
+ /// </summary>
+ /// <returns>The number of bytes written (zero indicates nothing was written).</returns>
+ /// <remarks>
+ /// The connection must be established.
+ /// </remarks>
+ /// <param name="socketFd">The file descriptor of connected socket.</param>
+ /// <param name="data">The data to be sent.</param>
+ public int SendData(string data)
+ {
+ int ret = Interop.Bluetooth.SendData(connectedSocket, data, data.Length);
+ if (ret < 0)
+ {
+ Log.Error(Globals.LogTag, "Failed to send data, Error - " + (BluetoothError)ret);
+ BluetoothErrorFactory.ThrowBluetoothException(ret);
+ }
+ return ret;
+ }
+
+ ~BluetoothSocket()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects.
+ }
+ //Free unmanaged objects
+ RemoveRegisteredEvents();
+ disposed = true;
+ }
+
+ private void RemoveRegisteredEvents()
+ {
+ //unregister all remaining events when this object is released.
+ if (_dataReceived != null)
+ {
+ UnregisterDataReceivedEvent();
+ }
+ if (_connectionStateChanged != null)
+ {
+ UnregisterConnectionStateChangedEvent();
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothStructs.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothStructs.cs
new file mode 100755
index 0000000..ec41b9c
--- /dev/null
+++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothStructs.cs
@@ -0,0 +1,390 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Reflection;
+using System.Linq;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Collections.Specialized;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Network.Bluetooth
+{
+ /// <summary>
+ /// Structure of device class type and service.
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct BluetoothClassStruct
+ {
+ /// <summary>
+ /// Type of the major device class.
+ /// </summary>
+ internal BluetoothMajorDeviceClassType MajorDeviceClassType;
+ /// <summary>
+ /// Type of the minor device class.
+ /// </summary>
+ internal BluetoothMinorDeviceClassType MinorDeviceClassType;
+ /// <summary>
+ /// Major service class mask.
+ /// </summary>
+ internal int MajorServiceClassMask;
+ }
+
+ /// <summary>
+ /// Structure containing the information of Bluetooth device.
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct BluetoothDeviceStruct
+ {
+ /// <summary>
+ /// Address of device.
+ /// </summary>
+ [MarshalAsAttribute(UnmanagedType.LPStr)]
+ internal string Address;
+
+ /// <summary>
+ /// Name of device.
+ /// </summary>
+ [MarshalAsAttribute(UnmanagedType.LPStr)]
+ internal string Name;
+
+ /// <summary>
+ /// Class of device.
+ /// </summary>
+ internal BluetoothClassStruct Class;
+
+ /// <summary>
+ /// Service UUID list of device.
+ /// </summary>
+ internal IntPtr ServiceUuidList;
+
+ /// <summary>
+ /// Service count of device.
+ /// </summary>
+ internal int ServiceCount;
+
+ /// <summary>
+ /// The paired state of device.
+ /// </summary>
+ [MarshalAsAttribute(UnmanagedType.I1)]
+ internal bool IsPaired;
+
+ /// <summary>
+ /// The connection state of device.
+ /// </summary>
+ [MarshalAsAttribute(UnmanagedType.I1)]
+ internal bool IsConnected;
+
+ /// <summary>
+ /// The authorization state of device.
+ /// </summary>
+ [MarshalAsAttribute(UnmanagedType.I1)]
+ internal bool IsAuthorized;
+
+ /// <summary>
+ /// The length of the manufacturer data.
+ /// </summary>
+ internal int ManufacturerDataLength;
+
+ /// <summary>
+ /// The manufacturer data.
+ /// </summary>
+ [MarshalAsAttribute(UnmanagedType.LPStr)]
+ internal string ManufacturerData;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct BluetoothDiscoveredDeviceStruct
+ {
+ [MarshalAsAttribute(UnmanagedType.LPStr)]
+ internal string Address;
+
+ [MarshalAsAttribute(UnmanagedType.LPStr)]
+ internal string Name;
+
+ internal BluetoothClassStruct Class;
+
+ internal int Rssi;
+
+ [MarshalAsAttribute(UnmanagedType.I1)]
+ internal bool IsPaired;
+
+ internal IntPtr ServiceUuidList;
+
+ internal int ServiceCount;
+
+ internal BluetoothAppearanceType AppearanceType;
+
+ internal int ManufacturerDataLength;
+
+ [MarshalAsAttribute(UnmanagedType.LPStr)]
+ internal string ManufacturerData;
+ }
+
+ internal struct BluetoothDeviceSdpStruct
+ {
+ [MarshalAsAttribute(UnmanagedType.LPStr)]
+ internal string DeviceAddress;
+ internal IntPtr ServiceUuid;
+ internal int ServiceCount;
+ }
+
+ internal struct BluetoothDeviceConnectionStruct
+ {
+ internal string Address;
+ internal BluetoothConnectionLinkType LinkType;
+ internal BluetoothDisconnectReason DisconnectReason;
+ }
+
+ internal struct SocketDataStruct
+ {
+ internal int SocketFd;
+ internal int DataSize;
+ internal IntPtr Data;
+ }
+
+ internal struct SocketConnectionStruct
+ {
+ internal int SocketFd;
+ internal int ServerFd;
+ internal BluetoothSocketRole LocalRole;
+ internal string Address;
+ internal string ServiceUuid;
+ }
+
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct BluetoothLeScanDataStruct
+ {
+ [MarshalAsAttribute(UnmanagedType.LPStr)]
+ internal string RemoteAddress;
+
+ internal BluetoothLeDeviceAddressType AddressType;
+
+ internal int Rssi;
+
+ internal int AdvDataLength;
+
+ internal IntPtr AdvData;
+
+ internal int ScanDataLength;
+
+ internal IntPtr ScanData;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct BluetoothLeServiceDataStruct
+ {
+ /// <summary>
+ /// Bluetooth Le service uuid.
+ /// </summary>
+ [MarshalAs(UnmanagedType.LPStr)]
+ internal string ServiceUuid;
+ /// <summary>
+ /// Bluetooth Le service data
+ /// </summary>
+ internal IntPtr ServiceData;
+
+ internal int ServiceDataLength;
+ }
+
+ internal static class BluetoothUtils
+ {
+ internal static BluetoothDevice ConvertStructToDeviceClass(BluetoothDeviceStruct device)
+ {
+ BluetoothDevice resultDevice = new BluetoothDevice();
+ Collection<string> uuidList = null;
+
+ if (device.ServiceCount > 0)
+ {
+ IntPtr[] extensionList = new IntPtr[device.ServiceCount];
+ Marshal.Copy (device.ServiceUuidList, extensionList, 0, device.ServiceCount);
+ uuidList = new Collection<string> ();
+ foreach (IntPtr extension in extensionList) {
+ string uuid = Marshal.PtrToStringAnsi (extension);
+ uuidList.Add (uuid);
+ }
+ }
+
+ resultDevice.RemoteDeviceAddress = device.Address;
+ resultDevice.RemoteDeviceName = device.Name;
+ resultDevice.RemoteDeviceClass = new BluetoothClass();
+ resultDevice.Class.MajorType = device.Class.MajorDeviceClassType;
+ resultDevice.Class.MinorType = device.Class.MinorDeviceClassType;
+ resultDevice.Class.Mask = device.Class.MajorServiceClassMask;
+ resultDevice.RemotePaired = device.IsPaired;
+ resultDevice.RemoteConnected = device.IsConnected;
+ resultDevice.RemoteAuthorized = device.IsAuthorized;
+ resultDevice.RemoteDeviceService = uuidList;
+ resultDevice.RemoteDeviceCount = device.ServiceCount;
+ resultDevice.RemoteManufLength = device.ManufacturerDataLength;
+ resultDevice.RemoteManufData = device.ManufacturerData;
+
+ return resultDevice;
+ }
+
+ internal static BluetoothDevice ConvertStructToDiscoveredDevice(BluetoothDiscoveredDeviceStruct structDevice)
+ {
+ BluetoothDevice resultDevice = new BluetoothDevice();
+ Collection<string> uuidList = null;
+
+ if (structDevice.ServiceCount > 0) {
+ IntPtr[] extensionList = new IntPtr[structDevice.ServiceCount];
+ Marshal.Copy (structDevice.ServiceUuidList, extensionList, 0, structDevice.ServiceCount);
+ uuidList = new Collection<string> ();
+ foreach (IntPtr extension in extensionList) {
+ string uuid = Marshal.PtrToStringAnsi (extension);
+ uuidList.Add (uuid);
+ }
+ }
+
+ resultDevice.RemoteDeviceAddress = structDevice.Address;
+ resultDevice.RemoteDeviceName = structDevice.Name;
+
+ resultDevice.RemoteDeviceClass = new BluetoothClass();
+ resultDevice.Class.MajorType = structDevice.Class.MajorDeviceClassType;
+ resultDevice.Class.MinorType = structDevice.Class.MinorDeviceClassType;
+ resultDevice.Class.Mask = structDevice.Class.MajorServiceClassMask;
+
+ resultDevice.RemoteDeviceRssi = structDevice.Rssi;
+ resultDevice.RemoteAppearance = structDevice.AppearanceType;
+
+ if (structDevice.ServiceCount > 0) {
+ resultDevice.RemoteDeviceService = uuidList;
+ resultDevice.RemoteDeviceCount = structDevice.ServiceCount;
+ }
+
+ resultDevice.RemotePaired = structDevice.IsPaired;
+ resultDevice.RemoteManufData = structDevice.ManufacturerData;
+ resultDevice.RemoteManufLength = structDevice.ManufacturerDataLength;
+ return resultDevice;
+ }
+
+ internal static BluetoothDeviceSdpData ConvertStructToSdpData(BluetoothDeviceSdpStruct structData)
+ {
+ BluetoothDeviceSdpData resultData = new BluetoothDeviceSdpData();
+ Collection<string> uuidList = null;
+
+ if (structData.ServiceCount > 0) {
+ IntPtr[] extensionList = new IntPtr[structData.ServiceCount];
+ Marshal.Copy (structData.ServiceUuid, extensionList, 0, structData.ServiceCount);
+ uuidList = new Collection<string> ();
+ foreach (IntPtr extension in extensionList) {
+ string uuid = Marshal.PtrToStringAnsi (extension);
+ uuidList.Add (uuid);
+ }
+ }
+
+ resultData.Uuid = uuidList;
+ resultData.Address = structData.DeviceAddress;
+
+ return resultData;
+ }
+
+ internal static BluetoothDeviceConnectionData ConvertStructToConnectionData(BluetoothDeviceConnectionStruct structInfo)
+ {
+ BluetoothDeviceConnectionData resultData = new BluetoothDeviceConnectionData();
+ resultData.RemoteAddress = structInfo.Address;
+ resultData.Link = structInfo.LinkType;
+ resultData.Reason = structInfo.DisconnectReason;
+ return resultData;
+ }
+
+ internal static BluetoothLeScanData ConvertStructToLeScanData(BluetoothLeScanDataStruct structScanData)
+ {
+ BluetoothLeScanData scanData = new BluetoothLeScanData();
+
+ scanData.RemoteAddress = structScanData.RemoteAddress;
+ scanData.AddressType = structScanData.AddressType;
+ scanData.Rssi = structScanData.Rssi;
+
+ if (structScanData.AdvDataLength > 0)
+ {
+ scanData.AdvDataLength = structScanData.AdvDataLength;
+ scanData.AdvData = new byte[scanData.AdvDataLength];
+ Marshal.Copy (structScanData.AdvData, scanData.AdvData, 0, scanData.AdvDataLength);
+ }
+
+ if (structScanData.ScanDataLength > 0)
+ {
+ scanData.ScanDataLength = structScanData.ScanDataLength;
+ scanData.ScanData = new byte[scanData.ScanDataLength];
+ Marshal.Copy (structScanData.ScanData, scanData.ScanData, 0, scanData.ScanDataLength);
+ }
+ return scanData;
+ }
+
+ internal static BluetoothLeScanDataStruct ConvertLeScanDataToStruct(BluetoothLeScanData scanData)
+ {
+ BluetoothLeScanDataStruct scanDataStruct = new BluetoothLeScanDataStruct();
+
+ scanDataStruct.RemoteAddress = scanData.RemoteAddress;
+ scanDataStruct.AddressType = scanData.AddressType;
+ scanDataStruct.Rssi = scanData.Rssi;
+
+ if (scanData.AdvDataLength > 0)
+ {
+ scanDataStruct.AdvDataLength = scanData.AdvDataLength;
+ scanDataStruct.AdvData = Marshal.AllocHGlobal(scanData.AdvDataLength);
+ Marshal.Copy (scanData.AdvData, 0, scanDataStruct.AdvData, scanData.AdvDataLength);
+ }
+
+ if (scanData.ScanDataLength > 0)
+ {
+ scanDataStruct.ScanDataLength = scanData.ScanDataLength;
+ scanDataStruct.ScanData = Marshal.AllocHGlobal(scanData.ScanDataLength);
+ Marshal.Copy (scanData.ScanData, 0, scanDataStruct.ScanData, scanData.ScanDataLength);
+ }
+
+ return scanDataStruct;
+ }
+
+ internal static BluetoothLeServiceData ConvertStructToLeServiceData(BluetoothLeServiceDataStruct structServiceData)
+ {
+ BluetoothLeServiceData serviceData = new BluetoothLeServiceData();
+ Log.Info(Globals.LogTag, "ServiceDataLength" + structServiceData.ServiceDataLength);
+
+ if (structServiceData.ServiceDataLength > 0)
+ {
+ serviceData.Uuid = structServiceData.ServiceUuid;
+ serviceData.Length = structServiceData.ServiceDataLength;
+ serviceData.Data = new byte[serviceData.Length];
+ Marshal.Copy(structServiceData.ServiceData, serviceData.Data, 0, serviceData.Length);
+ }
+ return serviceData;
+ }
+
+ internal static SocketData ConvertStructToSocketData(SocketDataStruct structInfo)
+ {
+ SocketData data = new SocketData();
+ data.Fd = structInfo.SocketFd;
+ data.Size = structInfo.DataSize;
+ data.RecvData = Marshal.PtrToStringAnsi(structInfo.Data);
+ return data;
+ }
+
+ internal static SocketConnection ConvertStructToSocketConnection(SocketConnectionStruct structInfo)
+ {
+ SocketConnection connectionInfo = new SocketConnection();
+ connectionInfo.Fd = structInfo.SocketFd;
+ connectionInfo.RemoteAddress = structInfo.Address;
+ connectionInfo.Uuid = structInfo.ServiceUuid;
+ return connectionInfo;
+ }
+ }
+}
+
diff --git a/src/Tizen.Network.Connection/Interop/Interop.Connection.cs b/src/Tizen.Network.Connection/Interop/Interop.Connection.cs
new file mode 100755
index 0000000..89011c8
--- /dev/null
+++ b/src/Tizen.Network.Connection/Interop/Interop.Connection.cs
@@ -0,0 +1,337 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Network.Connection;
+
+internal static partial class Interop
+{
+ internal static partial class Connection
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate void ConnectionTypeChangedCallback(ConnectionType type, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate void EthernetCableStateChangedCallback(EthernetCableState state, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate void ConnectionAddressChangedCallback(IntPtr ipv4, IntPtr ipv6, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate void ConnectionCallback(ConnectionError result, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate bool IPv6AddressCallback(IntPtr ipv6, IntPtr userData);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_create")]
+ public static extern int Create(out IntPtr handle);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_destroy")]
+ public static extern int Destroy(IntPtr handle);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_get_type")]
+ public static extern int GetType(IntPtr handle, out int type);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_get_ip_address")]
+ public static extern int GetIPAddress(IntPtr handle, int family, out IntPtr address);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_foreach_ipv6_address")]
+ public static extern int GetAllIPv6Addresses(IntPtr handle, int type, IPv6AddressCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_get_proxy")]
+ public static extern int GetProxy(IntPtr handle, int family, out IntPtr address);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_get_mac_address")]
+ public static extern int GetMacAddress(IntPtr handle, int family, out IntPtr address);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_get_wifi_state")]
+ public static extern int GetWiFiState(IntPtr handle, out int state);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_get_cellular_state")]
+ public static extern int GetCellularState(IntPtr handle, out int state);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_get_ethernet_state")]
+ public static extern int GetEthernetState(IntPtr handle, out int state);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_get_ethernet_cable_state")]
+ public static extern int GetEthernetCableState(IntPtr handle, out int state);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_get_bt_state")]
+ public static extern int GetBtState(IntPtr handle, out int state);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_get_statistics")]
+ public static extern int GetStatistics(IntPtr handle, int connectionType, int statisticsType, out long size);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_reset_statistics")]
+ public static extern int ResetStatistics(IntPtr handle, int connectionType, int statisticsType);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_add_route_entry")]
+ public static extern int AddRoute(IntPtr handle, AddressFamily family, string interfaceName, string address, string gateway);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_remove_route_entry")]
+ public static extern int RemoveRoute(IntPtr handle, AddressFamily family, string interfaceName, string address, string gateway);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_set_type_changed_cb")]
+ public static extern int SetTypeChangedCallback(IntPtr handle, ConnectionTypeChangedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_set_ip_address_changed_cb")]
+ public static extern int SetIPAddressChangedCallback(IntPtr handle, ConnectionAddressChangedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_set_ethernet_cable_state_chaged_cb")]
+ public static extern int SetEthernetCableStateChagedCallback(IntPtr handle, EthernetCableStateChangedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_set_proxy_address_changed_cb")]
+ public static extern int SetProxyAddressChangedCallback(IntPtr handle, ConnectionAddressChangedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_unset_type_changed_cb")]
+ public static extern int UnsetTypeChangedCallback(IntPtr handle);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_unset_ip_address_changed_cb")]
+ public static extern int UnsetIPAddressChangedCallback(IntPtr handle);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_unset_ethernet_cable_state_chaged_cb")]
+ public static extern int UnsetEthernetCableStateChagedCallback(IntPtr handle);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_unset_proxy_address_changed_cb")]
+ public static extern int UnsetProxyAddressChangedCallback(IntPtr handle);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_add_profile")]
+ public static extern int AddProfile(IntPtr handle, IntPtr profileHandle);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_remove_profile")]
+ public static extern int RemoveProfile(IntPtr handle, IntPtr profileHandle);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_update_profile")]
+ public static extern int UpdateProfile(IntPtr handle, IntPtr profileHandle);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_get_default_cellular_service_profile")]
+ public static extern int GetDefaultCellularServiceProfile(IntPtr handle, int type, out IntPtr profileHandle);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_get_current_profile")]
+ public static extern int GetCurrentProfile(IntPtr handle, out IntPtr profileHandle);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_open_profile")]
+ public static extern int OpenProfile(IntPtr handle, IntPtr profileHandle, ConnectionCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_close_profile")]
+ public static extern int CloseProfile(IntPtr handle, IntPtr profileHandle, ConnectionCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_reset_profile")]
+ public static extern int ResetProfile(IntPtr handle, int Option, int Id, ConnectionCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_set_default_cellular_service_profile_async")]
+ public static extern int SetDefaultCellularServiceProfileAsync(IntPtr handle, int Type, IntPtr profileHandle, ConnectionCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_get_profile_iterator")]
+ public static extern int GetProfileIterator(IntPtr handle, int type, out IntPtr iterHandle);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_iterator_next")]
+ public static extern int GetNextProfileIterator(IntPtr iterHandle, out IntPtr profileHandle);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_iterator_has_next")]
+ public static extern bool HasNextProfileIterator(IntPtr iterHandle);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_destroy_profile_iterator")]
+ public static extern int DestroyProfileIterator(IntPtr iterHandle);
+ }
+
+ internal static partial class ConnectionProfile
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate void ProfileStateChangedCallback(ProfileState type, IntPtr userData);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_create")]
+ public static extern int Create(int ProfileType, string Keyword, out IntPtr profileHandle);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_clone")]
+ public static extern int Clone(out IntPtr cloneHandle, IntPtr profileHandle);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_destroy")]
+ public static extern int Destroy(IntPtr profileHandle);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_get_id")]
+ public static extern int GetId(IntPtr profileHandle, out IntPtr profileId);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_get_name")]
+ public static extern int GetName(IntPtr profileHandle, out IntPtr name);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_get_type")]
+ public static extern int GetType(IntPtr profileHandle, out int type);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_get_network_interface_name")]
+ public static extern int GetNetworkInterfaceName(IntPtr profileHandle, out IntPtr interfaceName);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_get_state")]
+ public static extern int GetState(IntPtr profileHandle, out int type);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_get_ipv6_state")]
+ public static extern int GetIPv6State(IntPtr profileHandle, out int type);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_get_ip_config_type")]
+ public static extern int GetIPConfigType(IntPtr profileHandle, int family, out int type);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_get_proxy_type")]
+ public static extern int GetProxyType(IntPtr profileHandle, out int type);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_get_ip_address")]
+ public static extern int GetIPAddress(IntPtr profileHandle, int family, out IntPtr address);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_get_subnet_mask")]
+ public static extern int GetSubnetMask(IntPtr profileHandle, int family, out IntPtr address);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_get_gateway_address")]
+ public static extern int GetGatewayAddress(IntPtr profileHandle, int family, out IntPtr address);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_get_dns_address")]
+ public static extern int GetDnsAddress(IntPtr profileHandle, int order, int Family, out IntPtr address);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_get_proxy_address")]
+ public static extern int GetProxyAddress(IntPtr profileHandle, int family, out IntPtr address);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_get_prefix_length")]
+ public static extern int GetPrefixLength(IntPtr profileHandle, int family, out int length);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_get_dns_config_type")]
+ public static extern int GetDnsConfigType(IntPtr profileHandle, int family, out int type);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_get_dhcp_server_address")]
+ public static extern int GetDhcpServerAddress(IntPtr profileHandle, AddressFamily family, out string dhcpServerAddress);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_refresh")]
+ public static extern int Refresh(IntPtr profileHandle);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_set_ip_config_type")]
+ public static extern int SetIPConfigType(IntPtr profileHandle, int family, int type);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_set_proxy_type")]
+ public static extern int SetProxyType(IntPtr profileHandle, int type);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_set_ip_address")]
+ public static extern int SetIPAddress(IntPtr profileHandle, int family, string address);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_set_subnet_mask")]
+ public static extern int SetSubnetMask(IntPtr profileHandle, int family, string address);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_set_gateway_address")]
+ public static extern int SetGatewayAddress(IntPtr profileHandle, int family, string address);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_set_dns_address")]
+ public static extern int SetDnsAddress(IntPtr profileHandle, int order, int family, string address);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_set_proxy_address")]
+ public static extern int SetProxyAddress(IntPtr profileHandle, int family, string address);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_set_prefix_length")]
+ public static extern int SetPrefixLength(IntPtr profileHandle, int family, int length);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_set_dns_config_type")]
+ public static extern int SetDnsConfigType(IntPtr profileHandle, int family, int type);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_set_state_changed_cb")]
+ public static extern int SetStateChangeCallback(IntPtr profileHandle, ProfileStateChangedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_unset_state_changed_cb")]
+ public static extern int UnsetStateChangeCallback(IntPtr profileHandle);
+ }
+
+ internal static partial class ConnectionCellularProfile
+ {
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_get_cellular_service_type")]
+ public static extern int GetServiceType(IntPtr profileHandle, out int type);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_get_cellular_apn")]
+ public static extern int GetApn(IntPtr profileHandle, out IntPtr apn);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_get_cellular_auth_info")]
+ public static extern int GetAuthInfo(IntPtr profileHandle, out int authType, out string name, out string password);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_get_cellular_home_url")]
+ public static extern int GetHomeUrl(IntPtr profileHandle, out IntPtr homeUrl);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_get_cellular_pdn_type")]
+ public static extern int GetPdnType(IntPtr profileHandle, out int pdnType);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_get_cellular_roam_pdn_type")]
+ public static extern int GetRoamingPdnType(IntPtr profileHandle, out int roamPdnType);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_is_cellular_roaming")]
+ public static extern int IsRoaming(IntPtr profileHandle, out bool roaming);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_is_cellular_hidden")]
+ public static extern int IsHidden(IntPtr profileHandle, out bool hidden);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_is_cellular_editable")]
+ public static extern int IsEditable(IntPtr profileHandle, out bool editable);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_is_cellular_default")]
+ public static extern int IsDefault(IntPtr profileHandle, out bool isDefault);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_set_cellular_service_type")]
+ public static extern int SetServiceType(IntPtr profileHandle, int type);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_set_cellular_apn")]
+ public static extern int SetApn(IntPtr profileHandle, string apn);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_set_cellular_auth_info")]
+ public static extern int SetAuthInfo(IntPtr profileHandle, int authType, string name, string password);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_set_cellular_home_url")]
+ public static extern int SetHomeUrl(IntPtr profileHandle, string homeUrl);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_set_cellular_pdn_type")]
+ public static extern int SetPdnType(IntPtr profileHandle, int pdnType);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_set_cellular_roam_pdn_type")]
+ public static extern int SetRoamingPdnType(IntPtr profileHandle, int roamPdnType);
+ }
+
+ internal static partial class ConnectionWiFiProfile
+ {
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_get_wifi_essid")]
+ public static extern int GetEssid(IntPtr profileHandle, out IntPtr essid);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_get_wifi_bssid")]
+ public static extern int GetBssid(IntPtr profileHandle, out IntPtr bssid);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_get_wifi_rssi")]
+ public static extern int GetRssi(IntPtr profileHandle, out int rssi);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_get_wifi_frequency")]
+ public static extern int GetFrequency(IntPtr profileHandle, out int frequency);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_get_wifi_max_speed")]
+ public static extern int GetMaxSpeed(IntPtr profileHandle, out int maxSpeed);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_get_wifi_security_type")]
+ public static extern int GetSecurityType(IntPtr profileHandle, out int type);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_get_wifi_encryption_type")]
+ public static extern int GetEncryptionType(IntPtr profileHandle, out int type);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_is_wifi_passphrase_required")]
+ public static extern int IsRequiredPassphrase(IntPtr profileHandle, out bool required);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_set_wifi_passphrase")]
+ public static extern int SetPassphrase(IntPtr profileHandle, string passphrase);
+
+ [DllImport(Libraries.Connection, EntryPoint = "connection_profile_is_wifi_wps_supported")]
+ public static extern int IsSupportedWps(IntPtr profileHandle, out bool supported);
+ }
+
+ internal static partial class Libc
+ {
+ [DllImport(Libraries.Libc, EntryPoint = "free")]
+ public static extern void Free(IntPtr userData);
+
+ }
+}
diff --git a/src/Tizen.Network.Connection/Interop/Interop.Libraries.cs b/src/Tizen.Network.Connection/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..03ee0cd
--- /dev/null
+++ b/src/Tizen.Network.Connection/Interop/Interop.Libraries.cs
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string Connection = "libcapi-network-connection.so.1";
+ public const string WiFi = "libcapi-network-wifi.so.1";
+ public const string Bluetooth = "libcapi-network-bluetooth.so.0";
+ public const string Smartcard = "libcapi-network-smartcard.so.0";
+ public const string Nfc = "libcapi-network-nfc.so.0";
+ public const string WiFiDirect = "libwifi-direct.so.1";
+ public const string Glib = "libglib-2.0.so.0";
+ public const string Libc = "libc.so.6";
+ }
+}
diff --git a/src/Tizen.Network.Connection/Tizen.Network.Connection.csproj b/src/Tizen.Network.Connection/Tizen.Network.Connection.csproj
new file mode 100644
index 0000000..d5717a4
--- /dev/null
+++ b/src/Tizen.Network.Connection/Tizen.Network.Connection.csproj
@@ -0,0 +1,15 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
+
diff --git a/src/Tizen.Network.Connection/Tizen.Network.Connection/CellularProfile.cs b/src/Tizen.Network.Connection/Tizen.Network.Connection/CellularProfile.cs
new file mode 100755
index 0000000..325bc45
--- /dev/null
+++ b/src/Tizen.Network.Connection/Tizen.Network.Connection/CellularProfile.cs
@@ -0,0 +1,399 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Network.Connection
+{
+ /// <summary>
+ /// This Class is CellularProfile. It provides functions to manage the cellular profile.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class CellularProfile : ConnectionProfile
+ {
+ internal CellularProfile(IntPtr handle): base(handle)
+ {
+ }
+
+ ~CellularProfile()
+ {
+ }
+
+ /// <summary>
+ /// The APN (access point name).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Cellular access point name.</value>
+ /// <exception cref="System.NotSupportedException">Thrown during set when feature is not supported.</exception>
+ /// <exception cref="System.ArgumentException">Thrown during set when value is invalid parameter.</exception>
+ /// <exception cref="System.ArgumentNullException">Thrown during set when value is null.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown during set when profile instance is invalid or when method failed due to invalid operation.</exception>
+ /// <exception cref="System.ObjectDisposedException">Thrown when operation is performed on a disposed object.</exception>
+ public string Apn
+ {
+ get
+ {
+ Log.Debug(Globals.LogTag, "Get Apn");
+ IntPtr Value;
+ int ret = Interop.ConnectionCellularProfile.GetApn(ProfileHandle, out Value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get apn, " + (ConnectionError)ret);
+ }
+ string result = Marshal.PtrToStringAnsi(Value);
+ Interop.Libc.Free(Value);
+ return result;
+ }
+
+ set
+ {
+ Log.Debug(Globals.LogTag, "Set Apn");
+ CheckDisposed();
+ if (value != null)
+ {
+ int ret = Interop.ConnectionCellularProfile.SetApn(ProfileHandle, value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to set apn, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (ProfileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ }
+
+ else
+ {
+ throw new ArgumentNullException("Value of Apn is null");
+ }
+ }
+ }
+
+ /// <summary>
+ /// The home URL.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Cellular home URL.</value>
+ /// <exception cref="System.NotSupportedException">Thrown during set when feature is not supported.</exception>
+ /// <exception cref="System.ArgumentException">Thrown during set when value is invalid parameter.</exception>
+ /// <exception cref="System.ArgumentNullException">Thrown during set when value is null.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown during set when profile instance is invalid or when method failed due to invalid operation.</exception>
+ /// <exception cref="System.ObjectDisposedException">Thrown when operation is performed on a disposed object.</exception>
+ public string HomeUri
+ {
+ get
+ {
+ Log.Debug(Globals.LogTag, "Get HomeUri");
+ IntPtr Value;
+ int ret = Interop.ConnectionCellularProfile.GetHomeUrl(ProfileHandle, out Value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get home url, " + (ConnectionError)ret);
+ }
+ string result = Marshal.PtrToStringAnsi(Value);
+ Interop.Libc.Free(Value);
+ return result;
+ }
+
+ set
+ {
+ Log.Debug(Globals.LogTag, "Set HomeUri");
+ CheckDisposed();
+ if (value != null)
+ {
+ int ret = Interop.ConnectionCellularProfile.SetHomeUrl(ProfileHandle, value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to set home url, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (ProfileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ }
+
+ else
+ {
+ throw new ArgumentNullException("Value of HomeUri is null");
+ }
+ }
+ }
+
+ /// <summary>
+ /// The service type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Cellular service type.</value>
+ /// <exception cref="System.NotSupportedException">Thrown during set when feature is not supported.</exception>
+ /// <exception cref="System.ArgumentException">Thrown during set when value is invalid parameter.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown during set when profile instance is invalid or when method failed due to invalid operation.</exception>
+ /// <exception cref="System.ObjectDisposedException">Thrown when operation is performed on a disposed object.</exception>
+ public CellularServiceType ServiceType
+ {
+ get
+ {
+ Log.Debug(Globals.LogTag, "Get ServiceType");
+ int value;
+ int ret = Interop.ConnectionCellularProfile.GetServiceType(ProfileHandle, out value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get service type, " + (ConnectionError)ret);
+ }
+ return (CellularServiceType)value;
+ }
+
+ set
+ {
+ Log.Debug(Globals.LogTag, "Set ServiceType");
+ CheckDisposed();
+ int ret = Interop.ConnectionCellularProfile.SetServiceType(ProfileHandle, (int)value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to set service type, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (ProfileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The cellular pdn type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Cellular pdn type.</value>
+ /// <exception cref="System.NotSupportedException">Thrown during set when feature is not supported.</exception>
+ /// <exception cref="System.ArgumentException">Thrown during set when value is invalid parameter.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown during set when profile instance is invalid or when method failed due to invalid operation.</exception>
+ /// <exception cref="System.ObjectDisposedException">Thrown when operation is performed on a disposed object.</exception>
+ public CellularPdnType PdnType
+ {
+ get
+ {
+ Log.Debug(Globals.LogTag, "Get PdnType");
+ int value;
+ int ret = Interop.ConnectionCellularProfile.GetPdnType(ProfileHandle, out value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get pdn type, " + (ConnectionError)ret);
+ }
+ return (CellularPdnType)value;
+ }
+
+ set
+ {
+ Log.Debug(Globals.LogTag, "Set PdnType");
+ CheckDisposed();
+ int ret = Interop.ConnectionCellularProfile.SetPdnType(ProfileHandle, (int)value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to set pdn type, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (ProfileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The cellular roaming pdn type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Cellular roaming pdn type.</value>
+ /// <exception cref="System.NotSupportedException">Thrown during set when feature is not supported.</exception>
+ /// <exception cref="System.ArgumentException">Thrown during set when value is invalid parameter.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown during set when profile instance is invalid or when method failed due to invalid operation.</exception>
+ /// <exception cref="System.ObjectDisposedException">Thrown when operation is performed on a disposed object.</exception>
+ public CellularPdnType RoamingPdnType
+ {
+ get
+ {
+ Log.Debug(Globals.LogTag, "Get RoamingPdnType");
+ int value;
+ int ret = Interop.ConnectionCellularProfile.GetRoamingPdnType(ProfileHandle, out value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get roam pdn type, " + (ConnectionError)ret);
+ }
+ return (CellularPdnType)value;
+ }
+
+ set
+ {
+ Log.Debug(Globals.LogTag, "Set RoamingPdnType");
+ CheckDisposed();
+ int ret = Interop.ConnectionCellularProfile.SetRoamingPdnType(ProfileHandle, (int)value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to set roam pdn type, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (ProfileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Cellular Authentication Information.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Instance of CellularAuthInformation.</value>
+ /// <exception cref="System.NotSupportedException">Thrown during set when feature is not supported.</exception>
+ /// <exception cref="System.ArgumentException">Thrown during set when value is invalid parameter.</exception>
+ /// <exception cref="System.ArgumentNullException">Thrown during set when value is null.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown during set when profile instance is invalid or when method failed due to invalid operation.</exception>
+ /// <exception cref="System.ObjectDisposedException">Thrown when operation is performed on a disposed object.</exception>
+ public CellularAuthInformation CellularAuthInfo
+ {
+ get
+ {
+ int type;
+ string name;
+ string password;
+ int ret = Interop.ConnectionCellularProfile.GetAuthInfo(ProfileHandle, out type, out name, out password);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get cellular authentication information, " + (ConnectionError)ret);
+ return null;
+ }
+
+ CellularAuthInformation AuthInfo = new CellularAuthInformation();
+ AuthInfo.AuthType = (CellularAuthType)type;
+ AuthInfo.UserName = name;
+ AuthInfo.Password = password;
+ return AuthInfo;
+ }
+
+ set
+ {
+ CheckDisposed();
+ if (value != null)
+ {
+ CellularAuthInformation AuthInfo = value;
+ int type = (int)AuthInfo.AuthType;
+ string name = AuthInfo.UserName;
+ string password = AuthInfo.Password;
+ int ret = Interop.ConnectionCellularProfile.SetAuthInfo(ProfileHandle, type, name, password);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to set auth information, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (ProfileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ }
+
+ else
+ {
+ throw new ArgumentNullException("CellularAuthInformation value is null");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Checks whether the profile is hidden.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>True if the cellular profile is hidden, otherwise false.</value>
+ public bool Hidden
+ {
+ get
+ {
+ bool value;
+ int ret = Interop.ConnectionCellularProfile.IsHidden(ProfileHandle, out value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get hidden value, " + (ConnectionError)ret);
+ }
+ return value;
+ }
+ }
+
+ /// <summary>
+ /// Checks whether the profile is editable.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>True if the cellular profile is editable, otherwise false.</value>
+ public bool Editable
+ {
+ get
+ {
+ bool value;
+ int ret = Interop.ConnectionCellularProfile.IsEditable(ProfileHandle, out value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get editable value, " + (ConnectionError)ret);
+ }
+ return value;
+ }
+ }
+
+ /// <summary>
+ /// Checks whether the profile is default.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>True if the cellular profile is default, otherwise false.</value>
+ public bool IsDefault
+ {
+ get
+ {
+ bool value;
+ int ret = Interop.ConnectionCellularProfile.IsDefault(ProfileHandle, out value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get IsDefault value, " + (ConnectionError)ret);
+ }
+ return value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// This Class is CellularAuthInformation. It provides the properties to get and set the cellular authentication information.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class CellularAuthInformation
+ {
+ /// <summary>
+ /// Default Constructor.Initializes an object of CellularAuthInformation.
+ /// </summary>
+ public CellularAuthInformation()
+ {
+ }
+
+ /// <summary>
+ /// The user name.
+ /// <since_tizen> 3 </since_tizen>
+ /// </summary>
+ /// <value>Cellular user name.</value>
+ public string UserName { get; set;}
+ /// <summary>
+ /// The password
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Cellular password.</value>
+ public string Password { get; set; }
+
+ /// <summary>
+ /// The authentication type
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Cellular authentication type.</value>
+ public CellularAuthType AuthType { get; set; }
+ }
+}
diff --git a/src/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionError.cs b/src/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionError.cs
new file mode 100755
index 0000000..9e8d587
--- /dev/null
+++ b/src/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionError.cs
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tizen.Network.Connection
+{
+ internal static class ConnectionErrorFactory
+ {
+ internal static void CheckFeatureUnsupportedException(int err, string message)
+ {
+ if ((ConnectionError)err == ConnectionError.NotSupported)
+ {
+ ThrowConnectionException(err, message);
+ }
+ }
+
+ internal static void CheckPermissionDeniedException(int err, string message)
+ {
+ if ((ConnectionError)err == ConnectionError.PermissionDenied)
+ {
+ ThrowConnectionException(err, message);
+ }
+ }
+
+ internal static void CheckHandleNullException(int err, bool isHandleInvalid, string message)
+ {
+ if ((ConnectionError)err == ConnectionError.InvalidParameter)
+ {
+ if (isHandleInvalid)
+ {
+ ThrowConnectionException((int)ConnectionError.InvalidOperation, message);
+ }
+ }
+ }
+
+ internal static void ThrowConnectionException(int errno , string message = "")
+ {
+ ConnectionError _error = (ConnectionError)errno;
+ Log.Debug(Globals.LogTag, "ThrowConnectionException " + _error);
+ switch (_error)
+ {
+ case ConnectionError.AddressFamilyNotSupported:
+ throw new InvalidOperationException("Address Family Not Supported");
+ case ConnectionError.AlreadyExists:
+ throw new InvalidOperationException("Already Exists");
+ case ConnectionError.DhcpFailed:
+ throw new InvalidOperationException("DHCP Failed");
+ case ConnectionError.EndOfIteration:
+ throw new InvalidOperationException("End Of Iteration");
+ case ConnectionError.InvalidKey:
+ throw new InvalidOperationException("Invalid Key");
+ case ConnectionError.InvalidOperation:
+ throw new InvalidOperationException("Invalid Operation " + message);
+ case ConnectionError.InvalidParameter:
+ throw new ArgumentException("Invalid Parameter");
+ case ConnectionError.NoConnection:
+ throw new InvalidOperationException("No Connection");
+ case ConnectionError.NoReply:
+ throw new InvalidOperationException("No Reply");
+ case ConnectionError.NotSupported:
+ throw new NotSupportedException("Unsupported feature " + message);
+ case ConnectionError.NowInProgress:
+ throw new InvalidOperationException("Now In Progress");
+ case ConnectionError.OperationAborted:
+ throw new InvalidOperationException("Operation Aborted");
+ case ConnectionError.OperationFailed:
+ throw new InvalidOperationException("Operation Failed");
+ case ConnectionError.OutOfMemoryError:
+ throw new OutOfMemoryException("Out Of Memory Error");
+ case ConnectionError.PermissionDenied:
+ throw new UnauthorizedAccessException("Permission Denied " + message);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionInternalManager.cs b/src/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionInternalManager.cs
new file mode 100755
index 0000000..cad51a7
--- /dev/null
+++ b/src/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionInternalManager.cs
@@ -0,0 +1,945 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Runtime.InteropServices;
+using System.Collections;
+using System.Threading;
+
+namespace Tizen.Network.Connection
+{
+ class HandleHolder : IDisposable
+ {
+ private IntPtr Handle;
+ private bool disposed = false;
+
+ public HandleHolder()
+ {
+ Log.Debug(Globals.LogTag, "Handle: " + Handle);
+ int ret = Interop.Connection.Create(out Handle);
+ if(ret != (int)ConnectionError.None)
+ {
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
+ ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.get)");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ }
+
+ ~HandleHolder()
+ {
+ Dispose(false);
+ }
+
+ internal IntPtr GetHandle()
+ {
+ Log.Debug(Globals.LogTag, "handleholder handle = " + Handle);
+ return Handle;
+ }
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ Log.Debug(Globals.LogTag, ">>> HandleHolder Dispose with " + disposing);
+ Log.Debug(Globals.LogTag, ">>> Handle: " + Handle);
+ if (disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects.
+ Destroy();
+ }
+ disposed = true;
+ }
+
+ private void Destroy()
+ {
+ Interop.Connection.Destroy(Handle);
+ if (Handle != IntPtr.Zero)
+ {
+ Handle = IntPtr.Zero;
+ }
+ }
+ }
+
+ internal class ConnectionInternalManager
+ {
+ private bool disposed = false;
+ private static ConnectionInternalManager s_instance = null;
+
+ private EventHandler _ConnectionTypeChanged = null;
+ private EventHandler _IPAddressChanged = null;
+ private EventHandler _EthernetCableStateChanged = null;
+ private EventHandler _ProxyAddressChanged = null;
+
+ private Interop.Connection.ConnectionAddressChangedCallback _connectionAddressChangedCallback;
+ private Interop.Connection.ConnectionTypeChangedCallback _connectionTypeChangedCallback;
+ private Interop.Connection.ConnectionAddressChangedCallback _proxyAddressChangedCallback;
+
+ internal static ConnectionInternalManager Instance
+ {
+ get
+ {
+ if (s_instance == null)
+ {
+ s_instance = new ConnectionInternalManager();
+ }
+
+ return s_instance;
+ }
+ }
+
+ private static ThreadLocal<HandleHolder> s_threadName = new ThreadLocal<HandleHolder>(() =>
+ {
+ Log.Info(Globals.LogTag, "In threadlocal delegate");
+ return new HandleHolder();
+ });
+
+ private ConnectionInternalManager()
+ {
+
+ }
+
+ ~ConnectionInternalManager()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ Log.Debug(Globals.LogTag, ">>> ConnectionInternalManager Dispose with disposing " + disposing + ", disposed " + disposed);
+ Log.Debug(Globals.LogTag, ">>> Handle: " + GetHandle());
+ if (disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects.
+ }
+
+ UnregisterEvents();
+ disposed = true;
+ }
+
+ internal IntPtr GetHandle()
+ {
+ return s_threadName.Value.GetHandle();
+ }
+
+ internal event EventHandler ConnectionTypeChanged
+ {
+ add
+ {
+ if (_ConnectionTypeChanged == null)
+ {
+ ConnectionTypeChangedStart();
+ }
+
+ _ConnectionTypeChanged += value;
+ }
+ remove
+ {
+ _ConnectionTypeChanged -= value;
+ if (_ConnectionTypeChanged == null)
+ {
+ ConnectionTypeChangedStop();
+ }
+ }
+ }
+
+ private void ConnectionTypeChangedStart()
+ {
+ _connectionTypeChangedCallback = (ConnectionType type, IntPtr user_data) =>
+ {
+ if (_ConnectionTypeChanged != null)
+ {
+ _ConnectionTypeChanged(null, new ConnectionTypeEventArgs(type));
+ }
+ };
+
+ int ret = Interop.Connection.SetTypeChangedCallback(GetHandle(), _connectionTypeChangedCallback, IntPtr.Zero);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to register connection type changed callback, " + (ConnectionError)ret);
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ }
+
+ private void ConnectionTypeChangedStop()
+ {
+ int ret = Interop.Connection.UnsetTypeChangedCallback(GetHandle());
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to unregister connection type changed callback, " + (ConnectionError)ret);
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ }
+
+ internal event EventHandler EthernetCableStateChanged
+ {
+ add
+ {
+ if (_EthernetCableStateChanged == null)
+ {
+ EthernetCableStateChangedStart();
+ }
+ _EthernetCableStateChanged += value;
+ }
+ remove
+ {
+ _EthernetCableStateChanged -= value;
+ if (_EthernetCableStateChanged == null)
+ {
+ EthernetCableStateChangedStop();
+ }
+ }
+ }
+
+ private void EthernetCableStateChangedStart()
+ {
+ int ret = Interop.Connection.SetEthernetCableStateChagedCallback(GetHandle(), EthernetCableStateChangedCallback, IntPtr.Zero);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to register ethernet cable state changed callback, " + (ConnectionError)ret);
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ }
+
+ private void EthernetCableStateChangedStop()
+ {
+ int ret = Interop.Connection.UnsetEthernetCableStateChagedCallback(GetHandle());
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to unregister ethernet cable state changed callback, " + (ConnectionError)ret);
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ }
+
+ private void EthernetCableStateChangedCallback(EthernetCableState state, IntPtr user_data)
+ {
+ if (_EthernetCableStateChanged != null)
+ {
+ _EthernetCableStateChanged(null, new EthernetCableStateEventArgs(state));
+ }
+ }
+
+ internal event EventHandler IPAddressChanged
+ {
+ add
+ {
+ if (_IPAddressChanged == null)
+ {
+ IPAddressChangedStart();
+ }
+ _IPAddressChanged += value;
+ }
+
+ remove
+ {
+ _IPAddressChanged -= value;
+ if (_IPAddressChanged == null)
+ {
+ IPAddressChangedStop();
+ }
+ }
+ }
+
+ private void IPAddressChangedStart()
+ {
+ _connectionAddressChangedCallback = (IntPtr IPv4, IntPtr IPv6, IntPtr UserData) =>
+ {
+ if (_IPAddressChanged != null)
+ {
+ string ipv4 = Marshal.PtrToStringAnsi(IPv4);
+ string ipv6 = Marshal.PtrToStringAnsi(IPv6);
+
+ if ((string.IsNullOrEmpty(ipv4) == false) || (string.IsNullOrEmpty(ipv6) == false))
+ {
+ _IPAddressChanged(null, new AddressEventArgs(ipv4, ipv6));
+ }
+ }
+ };
+
+ int ret = Interop.Connection.SetIPAddressChangedCallback(GetHandle(), _connectionAddressChangedCallback, IntPtr.Zero);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to register callback for changing IP address, " + (ConnectionError)ret);
+ }
+ }
+
+ private void IPAddressChangedStop()
+ {
+ int ret = Interop.Connection.UnsetIPAddressChangedCallback(GetHandle());
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to unregister callback for changing IP address, " + (ConnectionError)ret);
+ }
+ }
+
+ internal event EventHandler ProxyAddressChanged
+ {
+ add
+ {
+ //Console.WriteLine("ProxyAddressChanged Add **");
+ if (_ProxyAddressChanged == null)
+ {
+ ProxyAddressChangedStart();
+ }
+
+ _ProxyAddressChanged += value;
+ }
+ remove
+ {
+ //Console.WriteLine("ProxyAddressChanged Remove");
+ _ProxyAddressChanged -= value;
+ if (_ProxyAddressChanged == null)
+ {
+ ProxyAddressChangedStop();
+ }
+ }
+ }
+
+ private void ProxyAddressChangedStart()
+ {
+ _proxyAddressChangedCallback = (IntPtr IPv4, IntPtr IPv6, IntPtr UserData) =>
+ {
+ if (_ProxyAddressChanged != null)
+ {
+ string ipv4 = Marshal.PtrToStringAnsi(IPv4);
+ string ipv6 = Marshal.PtrToStringAnsi(IPv6);
+
+ if ((string.IsNullOrEmpty(ipv4) == false) || (string.IsNullOrEmpty(ipv6) == false))
+ {
+ _ProxyAddressChanged(null, new AddressEventArgs(ipv4, ipv6));
+ }
+ }
+ };
+
+ int ret = Interop.Connection.SetProxyAddressChangedCallback(GetHandle(), _proxyAddressChangedCallback, IntPtr.Zero);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to register callback for changing proxy address, " + (ConnectionError)ret);
+ }
+ }
+
+ private void ProxyAddressChangedStop()
+ {
+ int ret = Interop.Connection.UnsetProxyAddressChangedCallback(GetHandle());
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to unregister callback for changing proxy address, " + (ConnectionError)ret);
+ }
+ }
+
+ private void UnregisterEvents()
+ {
+ if (_ConnectionTypeChanged != null)
+ {
+ ConnectionTypeChangedStop();
+ }
+ if (_IPAddressChanged != null)
+ {
+ IPAddressChangedStop();
+ }
+ if (_EthernetCableStateChanged != null)
+ {
+ EthernetCableStateChangedStop();
+ }
+ if (_ProxyAddressChanged != null)
+ {
+ ProxyAddressChangedStop();
+ }
+ }
+
+ internal int GetProfileIterator(ProfileListType type, out IntPtr iterator)
+ {
+ return Interop.Connection.GetProfileIterator(GetHandle(), (int)type, out iterator);
+ }
+
+ internal bool HasNext(IntPtr iterator)
+ {
+ return Interop.Connection.HasNextProfileIterator(iterator);
+ }
+
+ internal int NextProfileIterator(IntPtr iterator, out IntPtr profileHandle)
+ {
+ return Interop.Connection.GetNextProfileIterator(iterator, out profileHandle);
+ }
+
+ internal int DestoryProfileIterator(IntPtr iterator)
+ {
+ return Interop.Connection.DestroyProfileIterator(iterator);
+ }
+
+ internal System.Net.IPAddress GetIPAddress(AddressFamily family)
+ {
+ Log.Debug(Globals.LogTag, "GetIPAddress " + family);
+ IntPtr ip;
+ int ret = Interop.Connection.GetIPAddress(GetHandle(), (int)family, out ip);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get IP address, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+
+ string result = Marshal.PtrToStringAnsi(ip);
+ Interop.Libc.Free(ip);
+ return System.Net.IPAddress.Parse(result);;
+ }
+
+ internal IEnumerable<System.Net.IPAddress> GetAllIPv6Addresses(ConnectionType type)
+ {
+ Log.Debug(Globals.LogTag, "GetAllIPv6Addresses");
+ List<System.Net.IPAddress> ipList = new List<System.Net.IPAddress>();
+ Interop.Connection.IPv6AddressCallback callback = (IntPtr ipv6Address, IntPtr userData) =>
+ {
+ if (ipv6Address != IntPtr.Zero)
+ {
+ string ipv6 = Marshal.PtrToStringAnsi(ipv6Address);
+ ipList.Add(System.Net.IPAddress.Parse(ipv6));
+ return true;
+ }
+ return false;
+ };
+
+ int ret = Interop.Connection.GetAllIPv6Addresses(GetHandle(), (int)type, callback, IntPtr.Zero);
+ if (ret != (int)ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get all IPv6 addresses, Error - " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+
+ return ipList;
+ }
+
+ internal string GetProxy(AddressFamily family)
+ {
+ Log.Debug(Globals.LogTag, "GetProxy " + family);
+ IntPtr ip;
+ int ret = Interop.Connection.GetProxy(GetHandle(), (int)family, out ip);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get proxy, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+
+ string result = Marshal.PtrToStringAnsi(ip);
+ Interop.Libc.Free(ip);
+ return result;
+ }
+
+ internal string GetMacAddress(ConnectionType type)
+ {
+ Log.Debug(Globals.LogTag, "GetMacAddress " + type);
+ IntPtr mac;
+ int ret = Interop.Connection.GetMacAddress(GetHandle(), (int)type, out mac);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get mac address, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.ethernet");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+
+ string result = Marshal.PtrToStringAnsi(mac);
+ Interop.Libc.Free(mac);
+ return result;
+ }
+
+ internal long GetStatistics(ConnectionType connectionType, StatisticsType statisticsType)
+ {
+ Log.Debug(Globals.LogTag, "GetStatistics " + connectionType + ", " + statisticsType);
+ long size;
+ int ret = Interop.Connection.GetStatistics(GetHandle(), (int)connectionType,
+ (int)statisticsType, out size);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get statistics, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.telephony");
+ ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.get)");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ return size;
+ }
+
+ internal void ResetStatistics(ConnectionType connectionType, StatisticsType statisticsType)
+ {
+ Log.Debug(Globals.LogTag, "ResetStatistics " + connectionType + ", " + statisticsType);
+ int ret = Interop.Connection.ResetStatistics(GetHandle(), (int)connectionType,
+ (int)statisticsType);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to reset statistics, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.telephony");
+ ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.set)");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ }
+
+ internal void AddRoute(AddressFamily family, string interfaceName, System.Net.IPAddress address, System.Net.IPAddress gateway)
+ {
+ if (interfaceName != null && address != null && gateway != null)
+ {
+ Log.Debug(Globals.LogTag, "AddRoute " + family + ", " + interfaceName + ", " + address + ", " + gateway);
+ int ret = Interop.Connection.AddRoute(GetHandle(), family, interfaceName, address.ToString(), gateway.ToString());
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to add route to the routing table, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
+ ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.set)");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ }
+
+ else
+ {
+ throw new ArgumentNullException("Arguments are null");
+ }
+ }
+
+ internal void RemoveRoute(AddressFamily family, string interfaceName, System.Net.IPAddress address, System.Net.IPAddress gateway)
+ {
+ if (interfaceName != null && address != null && gateway != null)
+ {
+ Log.Debug(Globals.LogTag, "RemoveRoute " + family + ", " + interfaceName + ", " + address + ", " + gateway);
+ int ret = Interop.Connection.RemoveRoute(GetHandle(), family, interfaceName, address.ToString(), gateway.ToString());
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to remove route from the routing table, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
+ ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.set)");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ }
+
+ else
+ {
+ throw new ArgumentNullException("Arguments are null");
+ }
+ }
+
+ internal ConnectionType ConnectionType
+ {
+ get
+ {
+ Log.Debug(Globals.LogTag, "get ConnectionType");
+ int type = 0;
+ int ret = Interop.Connection.GetType(GetHandle(), out type);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get connection type, " + (ConnectionError)ret);
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ return (ConnectionType)type;
+ }
+ }
+
+ internal CellularState CellularState
+ {
+ get
+ {
+ Log.Debug(Globals.LogTag, "get CellularState");
+ int type = 0;
+ int ret = Interop.Connection.GetCellularState(GetHandle(), out type);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get cellular state, " + (ConnectionError)ret);
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ return (CellularState)type;
+ }
+ }
+
+ internal ConnectionState WiFiState
+ {
+ get
+ {
+ Log.Debug(Globals.LogTag, "get WiFiState");
+ int type = 0;
+ int ret = Interop.Connection.GetWiFiState(GetHandle(), out type);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get wifi state, " + (ConnectionError)ret);
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ return (ConnectionState)type;
+ }
+ }
+
+ internal ConnectionState BluetoothState
+ {
+ get
+ {
+ Log.Debug(Globals.LogTag, "get BluetoothState");
+ int type = 0;
+ int ret = Interop.Connection.GetBtState(GetHandle(), out type);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get bluetooth state, " + (ConnectionError)ret);
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ return (ConnectionState)type;
+ }
+ }
+
+ internal ConnectionState EthernetState
+ {
+ get
+ {
+ Log.Debug(Globals.LogTag, "get ConnectionType");
+ int type = 0;
+ int ret = Interop.Connection.GetEthernetState(GetHandle(), out type);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get ethernet state, " + (ConnectionError)ret);
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ return (ConnectionState)type;
+ }
+ }
+
+ internal EthernetCableState EthernetCableState
+ {
+ get
+ {
+ Log.Debug(Globals.LogTag, "get EthernetCableState");
+ int type = 0;
+ int ret = Interop.Connection.GetEthernetCableState(GetHandle(), out type);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get ethernet cable state, " + (ConnectionError)ret);
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ return (EthernetCableState)type;
+ }
+ }
+
+ internal IntPtr CreateCellularProfile(ConnectionProfileType type, string keyword)
+ {
+ Log.Debug(Globals.LogTag, "CreateCellularProfile, " + type + ", " + keyword);
+ if (keyword != null)
+ {
+ IntPtr handle = IntPtr.Zero;
+ int ret = Interop.ConnectionProfile.Create((int)type, keyword, out handle);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to Create profile, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.telephony");
+ ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.get)");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+
+ return handle;
+ }
+
+ else
+ {
+ throw new ArgumentNullException("Keyword is null");
+ }
+ }
+
+ internal void AddCellularProfile(CellularProfile profile)
+ {
+
+ Log.Debug(Globals.LogTag, "AddCellularProfile");
+ if (profile != null)
+ {
+ if (profile.Type == ConnectionProfileType.Cellular)
+ {
+ int ret = Interop.Connection.AddProfile(GetHandle(), profile.ProfileHandle);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to add cellular profile, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony");
+ ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.profile)");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero || profile.ProfileHandle == IntPtr.Zero), "Connection or Profile Handle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ }
+
+ else
+ {
+ throw new ArgumentException("Profile type is not cellular");
+ }
+ }
+
+ else
+ {
+ throw new ArgumentNullException("Profile is null");
+ }
+ }
+
+ internal void RemoveProfile(ConnectionProfile profile)
+ {
+ Log.Debug(Globals.LogTag, "RemoveProfile");
+ if (profile != null)
+ {
+ int ret = Interop.Connection.RemoveProfile(GetHandle(), profile.ProfileHandle);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to remove profile, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.telephony");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero || profile.ProfileHandle == IntPtr.Zero), "Connection or Profile Handle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ }
+
+ else
+ {
+ throw new ArgumentNullException("Profile is null");
+ }
+ }
+
+ internal void UpdateProfile(ConnectionProfile profile)
+ {
+ Log.Debug(Globals.LogTag, "UpdateProfile");
+ if (profile != null)
+ {
+ int ret = Interop.Connection.UpdateProfile(GetHandle(), profile.ProfileHandle);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to update profile, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.ethernet");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero || profile.ProfileHandle == IntPtr.Zero), "Connection or Profile Handle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ }
+
+ else
+ {
+ throw new ArgumentNullException("Profile is null");
+ }
+ }
+
+ internal ConnectionProfile GetCurrentProfile()
+ {
+ Log.Debug(Globals.LogTag, "GetCurrentProfile");
+ IntPtr ProfileHandle;
+ int ret = Interop.Connection.GetCurrentProfile(GetHandle(), out ProfileHandle);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get current profile, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
+ ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.get)");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+
+ ConnectionProfile Profile = new ConnectionProfile(ProfileHandle);
+ return Profile;
+ }
+
+ internal ConnectionProfile GetDefaultCellularProfile(CellularServiceType type)
+ {
+ Log.Debug(Globals.LogTag, "GetDefaultCellularProfile");
+ IntPtr ProfileHandle;
+ int ret = Interop.Connection.GetDefaultCellularServiceProfile(GetHandle(), (int)type, out ProfileHandle);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "Error: " + ret);
+ Log.Error(Globals.LogTag, "It failed to get default cellular profile, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony");
+ ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.get)");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+
+ CellularProfile Profile = new CellularProfile(ProfileHandle);
+ return Profile;
+ }
+
+ internal Task SetDefaultCellularProfile(CellularServiceType type, ConnectionProfile profile)
+ {
+ Log.Debug(Globals.LogTag, "SetDefaultCellularProfile");
+ if (profile != null)
+ {
+ TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
+ Interop.Connection.ConnectionCallback Callback = (ConnectionError Result, IntPtr Data) =>
+ {
+ if (Result != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "Error occurs during set default cellular profile, " + Result);
+ task.SetException(new InvalidOperationException("Error occurs during set default cellular profile, " + Result));
+ }
+
+ task.SetResult(true);
+ };
+
+ int ret = Interop.Connection.SetDefaultCellularServiceProfileAsync(GetHandle(), (int)type, profile.ProfileHandle, Callback, (IntPtr)0);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to set default cellular profile, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero || profile.ProfileHandle == IntPtr.Zero), "Connection or Profile Handle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+
+ return task.Task;
+ }
+
+ else
+ {
+ throw new ArgumentNullException("Profile is null");
+ }
+ }
+
+
+ internal Task<IEnumerable<ConnectionProfile>> GetProfileListAsync(ProfileListType type)
+ {
+ Log.Debug(Globals.LogTag, "GetProfileListAsync");
+ var task = new TaskCompletionSource<IEnumerable<ConnectionProfile>>();
+
+ List<ConnectionProfile> Result = new List<ConnectionProfile>();
+ IntPtr iterator;
+ int ret = Interop.Connection.GetProfileIterator(GetHandle(), (int)type, out iterator);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get profile iterator, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
+ ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.get)");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+
+ while (Interop.Connection.HasNextProfileIterator(iterator))
+ {
+ IntPtr nextH;
+ IntPtr profileH;
+ Interop.Connection.GetNextProfileIterator(iterator, out nextH);
+ Interop.ConnectionProfile.Clone(out profileH, nextH);
+
+ int profileType;
+ Interop.ConnectionProfile.GetType(profileH, out profileType);
+
+ if ((ConnectionProfileType)profileType == ConnectionProfileType.WiFi)
+ {
+ WiFiProfile cur = new WiFiProfile(profileH);
+ Result.Add(cur);
+ }
+ else if ((ConnectionProfileType)profileType == ConnectionProfileType.Cellular)
+ {
+ CellularProfile cur = new CellularProfile(profileH);
+ Result.Add(cur);
+ }
+ else {
+ ConnectionProfile cur = new ConnectionProfile(profileH);
+ Result.Add(cur);
+ }
+ }
+ Interop.Connection.DestroyProfileIterator(iterator);
+ task.SetResult(Result);
+ return task.Task;
+ }
+
+ internal Task OpenProfileAsync(ConnectionProfile profile)
+ {
+ Log.Debug(Globals.LogTag, "OpenProfileAsync");
+ if (profile != null)
+ {
+ Log.Debug(Globals.LogTag, "OpenProfileAsync " + profile.Name);
+ TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
+ Interop.Connection.ConnectionCallback Callback = (ConnectionError Result, IntPtr Data) =>
+ {
+ Log.Debug(Globals.LogTag, "Connected " + profile.Name);
+ if (Result != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "Error occurs during connecting profile, " + Result);
+ task.SetException(new InvalidOperationException("Error occurs during connecting profile, " + Result));
+ }
+
+ task.SetResult(true);
+ };
+
+ int ret = Interop.Connection.OpenProfile(GetHandle(), profile.ProfileHandle, Callback, IntPtr.Zero);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to connect profile, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero || profile.ProfileHandle == IntPtr.Zero), "Connection or Profile Handle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+
+ return task.Task;
+ }
+
+ else
+ {
+ throw new ArgumentNullException("Profile is null");
+ }
+ }
+
+ internal Task CloseProfileAsync(ConnectionProfile profile)
+ {
+ Log.Debug(Globals.LogTag, "CloseProfileAsync");
+ if (profile != null)
+ {
+ Log.Debug(Globals.LogTag, "CloseProfileAsync " + profile.Name);
+ TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
+ Interop.Connection.ConnectionCallback Callback = (ConnectionError Result, IntPtr Data) =>
+ {
+ if (Result != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "Error occurs during disconnecting profile, " + Result);
+ task.SetException(new InvalidOperationException("Error occurs during disconnecting profile, " + Result));
+ }
+
+ task.SetResult(true);
+ };
+
+ int ret = Interop.Connection.CloseProfile(GetHandle(), profile.ProfileHandle, Callback, IntPtr.Zero);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to disconnect profile, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth");
+ ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.set)");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero || profile.ProfileHandle == IntPtr.Zero), "Connection or Profile Handle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+
+ return task.Task;
+ }
+
+ else
+ {
+ throw new ArgumentNullException("Profile is null");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionManager.cs b/src/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionManager.cs
new file mode 100755
index 0000000..0b574b5
--- /dev/null
+++ b/src/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionManager.cs
@@ -0,0 +1,628 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Runtime.InteropServices;
+
+/// <summary>
+/// The Connection API provides functions, enumerations to get the status of network and current profile and manage profiles.
+/// </summary>
+namespace Tizen.Network.Connection
+{
+ /// <summary>
+ /// This class manages the connection handle resources.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public sealed class SafeConnectionHandle : SafeHandle
+ {
+ internal SafeConnectionHandle(IntPtr handle) : base(handle, true)
+ {
+ }
+
+ /// <summary>
+ /// Checks whether the handle value is valid or not.
+ /// </summary>
+ /// <value>True if the handle is invalid, otherwise false.</value>
+ public override bool IsInvalid
+ {
+ get
+ {
+ return this.handle == IntPtr.Zero;
+ }
+ }
+
+ /// <summary>
+ /// Frees the handle.
+ /// </summary>
+ /// <returns>True if the handle is released successfully, otherwise false.</returns>
+ protected override bool ReleaseHandle()
+ {
+ this.SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+
+ /// <summary>
+ /// This class is ConnectionManager. It provides functions to manage data connections.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static class ConnectionManager
+ {
+ private static ConnectionItem _currentConnection = null;
+
+ /// <summary>
+ /// Event that is called when the type of the current connection is changed.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <feature>http://tizen.org/feature/network.ethernet</feature>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <feature>http://tizen.org/feature/network.tethering.bluetooth</feature>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ public static event EventHandler ConnectionTypeChanged
+ {
+ add
+ {
+ ConnectionInternalManager.Instance.ConnectionTypeChanged += value;
+ }
+
+ remove
+ {
+ ConnectionInternalManager.Instance.ConnectionTypeChanged -= value;
+ }
+ }
+
+ /// <summary>
+ /// Event for ethernet cable is plugged [in/out] event.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <feature>http://tizen.org/feature/network.ethernet</feature>
+ public static event EventHandler EthernetCableStateChanged
+ {
+ add
+ {
+ ConnectionInternalManager.Instance.EthernetCableStateChanged += value;
+ }
+
+ remove
+ {
+ ConnectionInternalManager.Instance.EthernetCableStateChanged -= value;
+ }
+ }
+
+ /// <summary>
+ /// Event that is called when the IP address is changed.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <feature>http://tizen.org/feature/network.ethernet</feature>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <feature>http://tizen.org/feature/network.tethering.bluetooth</feature>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ public static event EventHandler IPAddressChanged
+ {
+ add
+ {
+ ConnectionInternalManager.Instance.IPAddressChanged += value;
+ }
+
+ remove
+ {
+ ConnectionInternalManager.Instance.IPAddressChanged -= value;
+ }
+ }
+
+ /// <summary>
+ /// Event that is called when the proxy address is changed.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <feature>http://tizen.org/feature/network.ethernet</feature>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <feature>http://tizen.org/feature/network.tethering.bluetooth</feature>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ public static event EventHandler ProxyAddressChanged
+ {
+ add
+ {
+ ConnectionInternalManager.Instance.ProxyAddressChanged += value;
+ }
+
+ remove
+ {
+ ConnectionInternalManager.Instance.ProxyAddressChanged -= value;
+ }
+ }
+
+ /// <summary>
+ /// Gets the connection handle.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>Instance of SafeConnectionHandle</returns>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static SafeConnectionHandle GetConnectionHandle()
+ {
+ IntPtr handle = ConnectionInternalManager.Instance.GetHandle();
+ return new SafeConnectionHandle(handle);
+ }
+
+ /// <summary>
+ /// Gets the IP address of the current connection.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="family">The address family</param>
+ /// <returns>IP address of the connection (global address in case of IPv6).</returns>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <feature>http://tizen.org/feature/network.ethernet</feature>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <feature>http://tizen.org/feature/network.tethering.bluetooth</feature>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when value is invalid parameter.</exception>
+ /// <exception cref="System.OutOfMemoryException">Thrown when memory is not enough to continue execution.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when connection instance is invalid or when method failed due to invalid operation.</exception>
+ public static System.Net.IPAddress GetIPAddress(AddressFamily family)
+ {
+ return ConnectionInternalManager.Instance.GetIPAddress(family);
+ }
+
+ /// <summary>
+ /// Gets the all IPv6 addresses of the current connection.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="type">The type of current network connection</param>
+ /// <returns>A list of IPv6 addresses of the connection.</returns>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <feature>http://tizen.org/feature/network.ethernet</feature>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <feature>http://tizen.org/feature/network.tethering.bluetooth</feature>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when value is invalid parameter.</exception>
+ /// <exception cref="System.OutOfMemoryException">Thrown when memory is not enough to continue execution.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when connection instance is invalid or when method failed due to invalid operation.</exception>
+ public static IEnumerable<System.Net.IPAddress> GetAllIPv6Addresses(ConnectionType type)
+ {
+ return ConnectionInternalManager.Instance.GetAllIPv6Addresses(type);
+ }
+
+ /// <summary>
+ /// Gets the proxy address of the current connection.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="family">The address family</param>
+ /// <returns>Proxy address of the connection.</returns>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <feature>http://tizen.org/feature/network.ethernet</feature>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <feature>http://tizen.org/feature/network.tethering.bluetooth</feature>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when value is invalid parameter.</exception>
+ /// <exception cref="System.OutOfMemoryException">Thrown when memory is not enough to continue execution.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when connection instance is invalid or when method failed due to invalid operation.</exception>
+ public static string GetProxy(AddressFamily family)
+ {
+ return ConnectionInternalManager.Instance.GetProxy(family);
+ }
+
+ /// <summary>
+ /// Gets the MAC address of the Wi-Fi or ethernet.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="type">The type of current network connection</param>
+ /// <returns>MAC address of the Wi-Fi or ethernet.</returns>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <feature>http://tizen.org/feature/network.ethernet</feature>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <feature>http://tizen.org/feature/network.tethering.bluetooth</feature>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when value is invalid parameter.</exception>
+ /// <exception cref="System.OutOfMemoryException">Thrown when memory is not enough to continue execution.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when connection instance is invalid or when method failed due to invalid operation.</exception>
+ public static string GetMacAddress(ConnectionType type)
+ {
+ return ConnectionInternalManager.Instance.GetMacAddress(type);
+ }
+
+ /// <summary>
+ /// Gets the statistics information.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="connectionType">The type of connection (only WiFi and Cellular are supported)</param>
+ /// <param name="statisticsType">The type of statistics</param>
+ /// <returns>The statistics information associated with statisticsType</returns>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <feature>http://tizen.org/feature/network.ethernet</feature>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <feature>http://tizen.org/feature/network.tethering.bluetooth</feature>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when value is invalid parameter.</exception>
+ /// <exception cref="System.OutOfMemoryException">Thrown when memory is not enough to continue execution.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when connection instance is invalid or when method failed due to invalid operation.</exception>
+ public static long GetStatistics(ConnectionType connectionType, StatisticsType statisticsType)
+ {
+ return ConnectionInternalManager.Instance.GetStatistics(connectionType, statisticsType);
+ }
+
+ /// <summary>
+ /// Resets the statistics information.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="connectionType">The type of connection (only WiFi and Cellular are supported)</param>
+ /// <param name="statisticsType">The type of statistics</param>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <privilege>http://tizen.org/privilege/network.set</privilege>
+ /// <feature>http://tizen.org/feature/network.ethernet</feature>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <feature>http://tizen.org/feature/network.tethering.bluetooth</feature>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when value is invalid parameter.</exception>
+ /// <exception cref="System.OutOfMemoryException">Thrown when memory is not enough to continue execution.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when connection instance is invalid or when method failed due to invalid operation.</exception>
+ public static void ResetStatistics(ConnectionType connectionType, StatisticsType statisticsType)
+ {
+ ConnectionInternalManager.Instance.ResetStatistics(connectionType, statisticsType);
+ }
+
+ /// <summary>
+ /// Adds a route to the routing table.
+ /// </summary>
+ /// <param name="family">The address family</param>
+ /// <param name="interfaceName">The name of network interface</param>
+ /// <param name="hostAddress">The IP address of the host</param>
+ /// <param name="gateway">The gateway address</param>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <privilege>http://tizen.org/privilege/network.set</privilege>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <feature>http://tizen.org/feature/network.tethering.bluetooth</feature>
+ /// <feature>http://tizen.org/feature/network.ethernet</feature>
+ /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when value is invalid parameter.</exception>
+ /// <exception cref="System.ArgumentNullException">Thrown when interfaceName or hostAddress or gateway is null.</exception>
+ /// <exception cref="System.OutOfMemoryException">Thrown when memory is not enough to continue execution.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when connection instance is invalid or when method failed due to invalid operation.</exception>
+ public static void AddRoute(AddressFamily family, string interfaceName, System.Net.IPAddress hostAddress, System.Net.IPAddress gateway)
+ {
+ ConnectionInternalManager.Instance.AddRoute(family, interfaceName, hostAddress, gateway);
+ }
+
+ /// <summary>
+ /// Removes a route from the routing table.
+ /// </summary>
+ /// <param name="family">The address family</param>
+ /// <param name="interfaceName">The name of network interface</param>
+ /// <param name="hostAddress">The IP address of the host</param>
+ /// <param name="gateway">The gateway address</param>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <privilege>http://tizen.org/privilege/network.set</privilege>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <feature>http://tizen.org/feature/network.tethering.bluetooth</feature>
+ /// <feature>http://tizen.org/feature/network.ethernet</feature>
+ /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when value is invalid parameter.</exception>
+ /// <exception cref="System.ArgumentNullException">Thrown when interfaceName or hostAddress or gateway is null.</exception>
+ /// <exception cref="System.OutOfMemoryException">Thrown when memory is not enough to continue execution.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when connection instance is invalid or when method failed due to invalid operation.</exception>
+ public static void RemoveRoute(AddressFamily family, string interfaceName, System.Net.IPAddress hostAddress, System.Net.IPAddress gateway)
+ {
+ ConnectionInternalManager.Instance.RemoveRoute(family, interfaceName, hostAddress, gateway);
+ }
+
+ /// <summary>
+ /// Type and state of the current profile for data connection
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Instance of ConnectionItem</value>
+ public static ConnectionItem CurrentConnection
+ {
+ get
+ {
+ if (_currentConnection == null)
+ {
+ _currentConnection = new ConnectionItem();
+ }
+
+ return _currentConnection;
+ }
+ }
+
+ /// <summary>
+ /// Creates a cellular profile handle.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="type">The type of profile. Cellular profile type is supported.</param>
+ /// <param name="keyword">The keyword included in profile name.</param>
+ /// <returns>CellularProfile object</returns>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when value is invalid parameter.</exception>
+ /// <exception cref="System.ArgumentNullException">Thrown when keyword value is null.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
+ public static CellularProfile CreateCellularProfile(ConnectionProfileType type, string keyword)
+ {
+ IntPtr profileHandle = IntPtr.Zero;
+ if (type == ConnectionProfileType.Cellular)
+ {
+ profileHandle = ConnectionInternalManager.Instance.CreateCellularProfile(type, keyword);
+ }
+
+ else
+ {
+ Log.Error(Globals.LogTag, "ConnectionProfile Type is not supported");
+ ConnectionErrorFactory.ThrowConnectionException((int)ConnectionError.InvalidParameter);
+ }
+
+ return new CellularProfile(profileHandle);
+ }
+
+ /// <summary>
+ /// The state of cellular connection.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Cellular network state.</value>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ public static CellularState CellularState
+ {
+ get
+ {
+ return ConnectionInternalManager.Instance.CellularState;
+ }
+ }
+
+ /// <summary>
+ /// The state of the Wi-Fi.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>WiFi connection state.</value>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ public static ConnectionState WiFiState
+ {
+ get
+ {
+ return ConnectionInternalManager.Instance.WiFiState;
+ }
+ }
+
+ /// <summary>
+ /// The state of the Bluetooth.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Bluetooth connection state.</value>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ public static ConnectionState BluetoothState
+ {
+ get
+ {
+ return ConnectionInternalManager.Instance.BluetoothState;
+ }
+ }
+
+ /// <summary>
+ /// The Ethernet connection state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Ethernet connection state.</value>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ public static ConnectionState EthernetState
+ {
+ get
+ {
+ return ConnectionInternalManager.Instance.EthernetState;
+ }
+ }
+
+ /// <summary>
+ /// Checks for ethernet cable is attached or not.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Ethernet cable state.</value>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ public static EthernetCableState EthernetCableState
+ {
+ get
+ {
+ return ConnectionInternalManager.Instance.EthernetCableState;
+ }
+ }
+
+ } // class ConnectionManager
+
+ /// <summary>
+ /// This class contains connection information such as connection type and state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class ConnectionItem
+ {
+ internal ConnectionItem()
+ {
+ }
+
+ /// <summary>
+ /// The type of the current profile for data connection.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Data connection current profile.</value>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ public ConnectionType Type
+ {
+ get
+ {
+ return ConnectionInternalManager.Instance.ConnectionType;
+ }
+ }
+
+ /// <summary>
+ /// The state of the current profile for data connection.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Connection state of the current connection type.</value>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ public ConnectionState State
+ {
+ get
+ {
+ if (ConnectionInternalManager.Instance.ConnectionType == ConnectionType.Cellular)
+ {
+ if (ConnectionInternalManager.Instance.CellularState == CellularState.Connected)
+ {
+ return ConnectionState.Connected;
+ }
+ else if (ConnectionInternalManager.Instance.CellularState == CellularState.Available)
+ {
+ return ConnectionState.Disconnected;
+ }
+ else {
+ return ConnectionState.Deactivated;
+ }
+ }
+ else if (ConnectionInternalManager.Instance.ConnectionType == ConnectionType.Bluetooth)
+ {
+ return ConnectionInternalManager.Instance.BluetoothState;
+ }
+ else if (ConnectionInternalManager.Instance.ConnectionType == ConnectionType.WiFi)
+ {
+ return ConnectionInternalManager.Instance.WiFiState;
+ }
+ else if (ConnectionInternalManager.Instance.ConnectionType == ConnectionType.Ethernet)
+ {
+ return ConnectionInternalManager.Instance.EthernetState;
+ }
+ else { // TO DO : Add Net Proxy
+ return ConnectionState.Disconnected;
+ }
+ }
+ }
+ } // class ConnectionItem
+
+ /// <summary>
+ /// An extended EventArgs class which contains changed connection type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class ConnectionTypeEventArgs : EventArgs
+ {
+ private ConnectionType Type = ConnectionType.Disconnected;
+
+ internal ConnectionTypeEventArgs(ConnectionType type)
+ {
+ Type = type;
+ }
+
+ /// <summary>
+ /// The connection type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Type of the connection.</value>
+ public ConnectionType ConnectionType
+ {
+ get
+ {
+ return Type;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains changed ethernet cable state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class EthernetCableStateEventArgs : EventArgs
+ {
+ private EthernetCableState State;
+
+ internal EthernetCableStateEventArgs(EthernetCableState state)
+ {
+ State = state;
+ }
+
+ /// <summary>
+ /// The ethernet cable state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Attached or detached state of the ethernet cable.</value>
+ public EthernetCableState EthernetCableState
+ {
+ get
+ {
+ return State;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains changed address.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class AddressEventArgs : EventArgs
+ {
+ private string IPv4 = "";
+ private string IPv6 = "";
+
+ internal AddressEventArgs(string ipv4, string ipv6)
+ {
+ IPv4 = ipv4;
+ IPv6 = ipv6;
+ }
+
+ /// <summary>
+ /// The IPV4 address.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>IP address in the format of IPV4 syntax.</value>
+ public string IPv4Address
+ {
+ get
+ {
+ return IPv4;
+ }
+ }
+
+ /// <summary>
+ /// The IPV6 address.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>IP address in the format of IPV6 syntax.</value>
+ public string IPv6Address
+ {
+ get
+ {
+ return IPv6;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionProfile.cs b/src/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionProfile.cs
new file mode 100755
index 0000000..87fc8a2
--- /dev/null
+++ b/src/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionProfile.cs
@@ -0,0 +1,450 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Network.Connection
+{
+ /// <summary>
+ /// This Class is ConnectionProfile. It provides event and propeties of the connection profile.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class ConnectionProfile : IDisposable
+ {
+ internal IntPtr ProfileHandle = IntPtr.Zero;
+ private IAddressInformation IPv4;
+ private IAddressInformation IPv6;
+ private bool disposed = false;
+ private EventHandler _ProfileStateChanged = null;
+
+ private Interop.ConnectionProfile.ProfileStateChangedCallback _profileChangedCallback;
+
+ internal IntPtr GetHandle()
+ {
+ return ProfileHandle;
+ }
+
+ /// <summary>
+ /// The event that is called when the state of profile is changed.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>http://tizen.org/feature/network.ethernet</feature>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <feature>http://tizen.org/feature/network.tethering.bluetooth</feature>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ public event EventHandler ProfileStateChanged
+ {
+ add
+ {
+ Log.Debug(Globals.LogTag, "ProfileStateChanged add");
+ if (_ProfileStateChanged == null)
+ {
+ ProfileStateChangedStart();
+ }
+ _ProfileStateChanged += value;
+ }
+ remove
+ {
+ Log.Debug(Globals.LogTag, "ProfileStateChanged remove");
+ _ProfileStateChanged -= value;
+ if (_ProfileStateChanged == null)
+ {
+ ProfileStateChangedStop();
+ }
+ }
+ }
+
+ private void ProfileStateChangedStart()
+ {
+ _profileChangedCallback = (ProfileState state, IntPtr userData) =>
+ {
+ if (_ProfileStateChanged != null)
+ {
+ _ProfileStateChanged(null, new ProfileStateEventArgs(state));
+ }
+ };
+
+ Log.Debug(Globals.LogTag, "ProfileStateChangedStart");
+ int ret = Interop.ConnectionProfile.SetStateChangeCallback(ProfileHandle, _profileChangedCallback, IntPtr.Zero);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to register callback for changing profile state, " + (ConnectionError)ret);
+ }
+ }
+
+ private void ProfileStateChangedStop()
+ {
+ Log.Debug(Globals.LogTag, "ProfileStateChangedStop");
+ int ret = Interop.ConnectionProfile.UnsetStateChangeCallback(ProfileHandle);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to unregister callback for changing profile state, " + (ConnectionError)ret);
+ }
+ }
+
+ internal ConnectionProfile(IntPtr handle)
+ {
+ ProfileHandle = handle;
+ IPv4 = new ConnectionAddressInformation(ProfileHandle, AddressFamily.IPv4);
+ IPv6 = new ConnectionAddressInformation(ProfileHandle, AddressFamily.IPv6);
+ }
+
+ ~ConnectionProfile()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Disposes the memory allocated to unmanaged resources.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ Log.Debug(Globals.LogTag, ">>> ConnectionProfile Dispose with " + disposing);
+ if (disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects.
+ UnregisterEvents();
+ Destroy();
+ }
+ disposed = true;
+ }
+
+ private void UnregisterEvents()
+ {
+ if (_ProfileStateChanged != null)
+ {
+ ProfileStateChangedStop();
+ }
+ }
+
+ private void Destroy()
+ {
+ Interop.ConnectionProfile.Destroy(ProfileHandle);
+ ProfileHandle = IntPtr.Zero;
+ }
+
+ internal void CheckDisposed()
+ {
+ if (disposed)
+ {
+ throw new ObjectDisposedException(GetType().FullName);
+ }
+ }
+
+ /// <summary>
+ /// The profile ID.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Unique ID of the profile.</value>
+ public string Id
+ {
+ get
+ {
+ IntPtr Value;
+ int ret = Interop.ConnectionProfile.GetId(ProfileHandle, out Value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get id of connection profile, " + (ConnectionError)ret);
+ }
+ string result = Marshal.PtrToStringAnsi(Value);
+ Interop.Libc.Free(Value);
+ return result;
+ }
+ }
+
+ /// <summary>
+ /// The profile name.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>User friendly name of the profile.</value>
+ public string Name
+ {
+ get
+ {
+ IntPtr Value;
+ int ret = Interop.ConnectionProfile.GetName(ProfileHandle, out Value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get name of connection profile, " + (ConnectionError)ret);
+ }
+ string result = Marshal.PtrToStringAnsi(Value);
+ Interop.Libc.Free(Value);
+ return result;
+ }
+ }
+
+ /// <summary>
+ /// The network type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Profile type of the network connection.</value>
+ public ConnectionProfileType Type
+ {
+ get
+ {
+ int Value;
+ int ret = Interop.ConnectionProfile.GetType(ProfileHandle, out Value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get type of connection profile, " + (ConnectionError)ret);
+ }
+ return (ConnectionProfileType)Value;
+ }
+ }
+
+ /// <summary>
+ /// The name of the network interface.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Network interface name, e.g. eth0 and pdp0.</value>
+ public string InterfaceName
+ {
+ get
+ {
+ IntPtr Value;
+ int ret = Interop.ConnectionProfile.GetNetworkInterfaceName(ProfileHandle, out Value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get network interface name, " + (ConnectionError)ret);
+ }
+ string result = Marshal.PtrToStringAnsi(Value);
+ Interop.Libc.Free(Value);
+ return result;
+ }
+ }
+
+ /// <summary>
+ /// Refreshes the profile information.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <feature>http://tizen.org/feature/network.ethernet</feature>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <feature>http://tizen.org/feature/network.tethering.bluetooth</feature>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when value is invalid parameter.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when profile instance is invalid or when method failed due to invalid operation</exception>
+ /// <exception cref="System.ObjectDisposedException">Thrown when operation is performed on a disposed object.</exception>
+ public void Refresh()
+ {
+ CheckDisposed();
+ int ret = Interop.ConnectionProfile.Refresh(ProfileHandle);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get network interface name, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
+ ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.get)");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (ProfileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Get the network state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="family">The address family</param>
+ /// <returns>The network state.</returns>
+ /// <feature>http://tizen.org/feature/network.ethernet</feature>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <feature>http://tizen.org/feature/network.tethering.bluetooth</feature>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when value is invalid parameter.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when profile instance is invalid or when method failed due to invalid operation</exception>
+ /// <exception cref="System.ObjectDisposedException">Thrown when operation is performed on a disposed object.</exception>
+ public ProfileState GetState(AddressFamily family)
+ {
+ CheckDisposed();
+ int Value;
+ int ret = (int)ConnectionError.None;
+ if (family == AddressFamily.IPv4)
+ {
+ ret = Interop.ConnectionProfile.GetState(ProfileHandle, out Value);
+ }
+
+ else
+ {
+ ret = Interop.ConnectionProfile.GetIPv6State(ProfileHandle, out Value);
+ }
+
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get profile state, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (ProfileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+
+ return (ProfileState)Value;
+ }
+
+ /// <summary>
+ /// The Proxy type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Proxy type of the connection.</value>
+ /// <exception cref="System.NotSupportedException">Thrown during set when feature is not supported.</exception>
+ /// <exception cref="System.ArgumentException">Thrown during set when value is invalid parameter.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown during set when profile instance is invalid or when method failed due to invalid operation.</exception>
+ /// <exception cref="System.ObjectDisposedException">Thrown during set when operation is performed on a disposed object.</exception>
+ public ProxyType ProxyType
+ {
+ get
+ {
+ int Value;
+ int ret = Interop.ConnectionProfile.GetProxyType(ProfileHandle, out Value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get proxy type, " + (ConnectionError)ret);
+ }
+ return (ProxyType)Value;
+
+ }
+
+ set
+ {
+ CheckDisposed();
+ int ret = Interop.ConnectionProfile.SetProxyType(ProfileHandle, (int)value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to set proxy type, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (ProfileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The proxy address.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Proxy address of the connection.</value>
+ /// <exception cref="System.NotSupportedException">Thrown during set when feature is not supported.</exception>
+ /// <exception cref="System.ArgumentException">Thrown during set when value is invalid parameter.</exception>
+ /// <exception cref="System.ArgumentNullException">Thrown during set when value is null.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown during set when profile instance is invalid or when method failed due to invalid operation.</exception>
+ /// <exception cref="System.ObjectDisposedException">Thrown when operation is performed on a disposed object.</exception>
+ public string ProxyAddress
+ {
+ get
+ {
+ IntPtr Value;
+ int ret = Interop.ConnectionProfile.GetProxyAddress(ProfileHandle, (int)AddressFamily.IPv4, out Value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get proxy address, " + (ConnectionError)ret);
+ }
+ string result = Marshal.PtrToStringAnsi(Value);
+ Interop.Libc.Free(Value);
+ return result;
+
+ }
+
+ set
+ {
+ CheckDisposed();
+ if (value != null)
+ {
+ int ret = Interop.ConnectionProfile.SetProxyAddress(ProfileHandle, (int)AddressFamily.IPv4, value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to set proxy address, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (ProfileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ }
+
+ else
+ {
+ throw new ArgumentNullException("ProxyAddress is null");
+ }
+ }
+ }
+
+ /// <summary>
+ /// The address information (IPv4)
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Instance of IAddressInformation with IPV4 address.</value>
+ public IAddressInformation IPv4Settings
+ {
+ get
+ {
+ return IPv4;
+
+ }
+ }
+
+ /// <summary>
+ /// The address information (IPv6)
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Instance of IAddressInformation with IPV6 address.</value>
+ public IAddressInformation IPv6Settings
+ {
+ get
+ {
+ return IPv6;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains changed profile state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class ProfileStateEventArgs : EventArgs
+ {
+ private ProfileState _State = ProfileState.Disconnected;
+
+ internal ProfileStateEventArgs(ProfileState state)
+ {
+ _State = state;
+ }
+
+ /// <summary>
+ /// The profile state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>State type of the connection profile.</value>
+ public ProfileState State
+ {
+ get
+ {
+ return _State;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionProfileManager.cs b/src/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionProfileManager.cs
new file mode 100755
index 0000000..5049686
--- /dev/null
+++ b/src/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionProfileManager.cs
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Collections;
+
+namespace Tizen.Network.Connection
+{
+ /// <summary>
+ /// This class is ConnectionProfileManager. It provides functions to add, get, connect or modify the connection profile.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static class ConnectionProfileManager
+ {
+ /// <summary>
+ /// Adds a new profile
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="profile">The cellular profile object</param>
+ /// <privilege>http://tizen.org/privilege/network.profile</privilege>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <feature>http://tizen.org/feature/network.tethering.bluetooth</feature>
+ /// <feature>http://tizen.org/feature/network.ethernet</feature>
+ /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when value is invalid parameter.</exception>
+ /// <exception cref="System.ArgumentNullException">Thrown when value is null.</exception>
+ /// <exception cref="System.OutOfMemoryException">Thrown when memory is not enough to continue execution.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when connection or profile instance is invalid or when method failed due to invalid operation</exception>
+ public static void AddCellularProfile(CellularProfile profile)
+ {
+ Log.Debug(Globals.LogTag, "AddCellularProfile");
+ ConnectionInternalManager.Instance.AddCellularProfile(profile);
+ }
+
+ /// <summary>
+ /// Gets the list of profile with profile list type
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="type">The type of profile</param>
+ /// <returns>List of connection profile objects.</returns>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <feature>http://tizen.org/feature/network.tethering.bluetooth</feature>
+ /// <feature>http://tizen.org/feature/network.ethernet</feature>
+ /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when value is invalid parameter.</exception>
+ /// <exception cref="System.OutOfMemoryException">Thrown when memory is not enough to continue execution.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when connection instance has been disposed.</exception>
+ public static Task<IEnumerable<ConnectionProfile>> GetProfileListAsync(ProfileListType type)
+ {
+ Log.Debug(Globals.LogTag, "GetProfileListAsync");
+ return ConnectionInternalManager.Instance.GetProfileListAsync(type);
+ }
+
+ /// <summary>
+ /// Opens a connection of profile, asynchronously.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="profile">The connection profile object</param>
+ /// <returns>A task indicates whether the ConnectProfileAsync method is done successfully or not.</returns>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <privilege>http://tizen.org/privilege/network.set</privilege>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <feature>http://tizen.org/feature/network.tethering.bluetooth</feature>
+ /// <feature>http://tizen.org/feature/network.ethernet</feature>
+ /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when value is invalid parameter.</exception>
+ /// <exception cref="System.ArgumentNullException">Thrown when value is null.</exception>
+ /// <exception cref="System.OutOfMemoryException">Thrown when memory is not enough to continue execution.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when connection or profile instance is invalid or when method failed due to invalid operation</exception>
+ public static Task ConnectProfileAsync(ConnectionProfile profile)
+ {
+ Log.Debug(Globals.LogTag, "ConnectProfile");
+ return ConnectionInternalManager.Instance.OpenProfileAsync(profile);
+ }
+
+ /// <summary>
+ /// Closes a connection of profile.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="profile">The connection profile object</param>
+ /// <returns>A task indicates whether the DisconnectProfileAsync method is done successfully or not.</returns>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <privilege>http://tizen.org/privilege/network.set</privilege>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <feature>http://tizen.org/feature/network.tethering.bluetooth</feature>
+ /// <feature>http://tizen.org/feature/network.ethernet</feature>
+ /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when value is invalid parameter.</exception>
+ /// <exception cref="System.ArgumentNullException">Thrown when value is null.</exception>
+ /// <exception cref="System.OutOfMemoryException">Thrown when memory is not enough to continue execution.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when connection or profile instance is invalid or when method failed due to invalid operation</exception>
+ public static Task DisconnectProfileAsync(ConnectionProfile profile)
+ {
+ Log.Debug(Globals.LogTag, "DisconnectProfileAsync");
+ return ConnectionInternalManager.Instance.CloseProfileAsync(profile);
+ }
+
+ /// <summary>
+ /// Removes an existing profile.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="profile">The connection profile object</param>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <privilege>http://tizen.org/privilege/network.profile</privilege>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <feature>http://tizen.org/feature/network.tethering.bluetooth</feature>
+ /// <feature>http://tizen.org/feature/network.ethernet</feature>
+ /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when value is invalid parameter.</exception>
+ /// <exception cref="System.ArgumentNullException">Thrown when value is null.</exception>
+ /// <exception cref="System.OutOfMemoryException">Thrown when memory is not enough to continue execution.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when connection or profile instance is invalid or when method failed due to invalid operation</exception>
+ public static void RemoveProfile(ConnectionProfile profile)
+ {
+ Log.Debug(Globals.LogTag, "RemoveProfile. Id: " + profile.Id + ", Name: " + profile.Name + ", Type: " + profile.Type);
+ ConnectionInternalManager.Instance.RemoveProfile(profile);
+ }
+
+ /// <summary>
+ /// Updates an existing profile.
+ /// When a profile is changed, these changes will be not applied to the ConnectionProfileManager immediately.
+ /// When you call this function, your changes affect the ConnectionProfileManager and the existing profile is updated.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="profile">The connection profile object</param>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <privilege>http://tizen.org/privilege/network.profile</privilege>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <feature>http://tizen.org/feature/network.tethering.bluetooth</feature>
+ /// <feature>http://tizen.org/feature/network.ethernet</feature>
+ /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when value is invalid parameter.</exception>
+ /// <exception cref="System.ArgumentNullException">Thrown when value is null.</exception>
+ /// <exception cref="System.OutOfMemoryException">Thrown when memory is not enough to continue execution.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when connection or profile instance is invalid or when method failed due to invalid operation</exception>
+ public static void UpdateProfile(ConnectionProfile profile)
+ {
+ Log.Debug(Globals.LogTag, "UpdateProfile");
+ ConnectionInternalManager.Instance.UpdateProfile(profile);
+ }
+
+ /// <summary>
+ /// Gets the name of the default profile.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>Connection profile object.</returns>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <feature>http://tizen.org/feature/network.tethering.bluetooth</feature>
+ /// <feature>http://tizen.org/feature/network.ethernet</feature>
+ /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when value is invalid parameter.</exception>
+ /// <exception cref="System.OutOfMemoryException">Thrown when memory is not enough to continue execution.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when connection instance is invalid or when method failed due to invalid operation</exception>
+ public static ConnectionProfile GetCurrentProfile()
+ {
+ Log.Debug(Globals.LogTag, "GetCurrentProfile");
+ return ConnectionInternalManager.Instance.GetCurrentProfile();
+ }
+
+ /// <summary>
+ /// Gets the default profile which provides the given cellular service.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="type">The cellular service type</param>
+ /// <returns>Connection profile object.</returns>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <feature>http://tizen.org/feature/network.tethering.bluetooth</feature>
+ /// <feature>http://tizen.org/feature/network.ethernet</feature>
+ /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when value is invalid parameter.</exception>
+ /// <exception cref="System.OutOfMemoryException">Thrown when memory is not enough to continue execution.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when connection instance is invalid or when method failed due to invalid operation</exception>
+ public static ConnectionProfile GetDefaultCellularProfile(CellularServiceType type)
+ {
+ Log.Debug(Globals.LogTag, "GetDefaultCurrentProfile");
+ return ConnectionInternalManager.Instance.GetDefaultCellularProfile(type);
+ }
+
+ /// <summary>
+ /// Sets the default profile which provides the given cellular service.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="type">The cellular service type</param>
+ /// <param name="profile">The connection profile object</param>
+ /// <returns>A task indicates whether the SetDefaultCellularProfile method is done successfully or not.</returns>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <privilege>http://tizen.org/privilege/network.profile</privilege>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <feature>http://tizen.org/feature/network.tethering.bluetooth</feature>
+ /// <feature>http://tizen.org/feature/network.ethernet</feature>
+ /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when value is invalid parameter.</exception>
+ /// <exception cref="System.ArgumentNullException">Thrown when value is null.</exception>
+ /// <exception cref="System.OutOfMemoryException">Thrown when memory is not enough to continue execution.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when connection or profile instance is invalid or when method failed due to invalid operation</exception>
+ public static Task SetDefaultCellularProfile(CellularServiceType type, ConnectionProfile profile)
+ {
+ Log.Debug(Globals.LogTag, "SetDefaultCellularProfile");
+ return ConnectionInternalManager.Instance.SetDefaultCellularProfile(type, profile);
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains the state of changed connection profile.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class ConnectionProfileStateEventArgs : EventArgs
+ {
+ private ConnectionProfileState State;
+
+ internal ConnectionProfileStateEventArgs(ConnectionProfileState state)
+ {
+ State = state;
+ }
+
+ /// <summary>
+ /// The connection profile state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>State of the connection profile.</value>
+ public ConnectionProfileState ConnectionProfileState
+ {
+ get
+ {
+ return State;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionTypes.cs b/src/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionTypes.cs
new file mode 100755
index 0000000..6c206ff
--- /dev/null
+++ b/src/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionTypes.cs
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Tizen.Internals.Errors;
+
+
+namespace Tizen.Network.Connection
+{
+ /// <summary>
+ /// Enumeration for connection type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum ConnectionType
+ {
+ Disconnected = 0, /**< Disconnected */
+ WiFi = 1, /**< Wi-Fi type */
+ Cellular = 2, /**< Cellular type */
+ Ethernet = 3, /**< Ethernet type */
+ Bluetooth = 4, /**< Bluetooth type */
+ NetProxy = 5 /**< Proxy type for internet connection */
+ }
+
+ /// <summary>
+ /// Enumeration for address family.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum AddressFamily
+ {
+ IPv4 = 0, /**< IPv4 Address */
+ IPv6 = 1 /**< IPv6 Address */
+ }
+
+ /// <summary>
+ /// Enumeration for cellular network state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CellularState
+ {
+ OutOfService = 0, /**< Out of service */
+ FlightMode = 1, /**< Flight mode */
+ RoamingOff = 2, /**< Roaming is turned off */
+ CallOnlyAvailable = 3, /**< Call is only available */
+ Available = 4, /**< Available but not connected yet */
+ Connected = 5, /**< Connected */
+ }
+
+ /// <summary>
+ /// Enumeration for connection state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum ConnectionState
+ {
+ Deactivated = 0, /**< Deactivated */
+ Disconnected = 1, /**< Disconnected */
+ Connected = 2, /**< Connected */
+ }
+
+ /// <summary>
+ /// This enumeration defines the attached or detached state of ethernet cable.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum EthernetCableState
+ {
+ Detached = 0, /**< Ethernet cable is detached */
+ Attached = 1, /**< Ethernet cable is attached */
+ }
+
+ /// <summary>
+ /// Enumeration for statistics type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum StatisticsType
+ {
+ LastReceivedData = 0, /**< Last received data */
+ LastSentData = 1, /**< Last sent data */
+ TotalReceivedData = 2, /**< Total received data */
+ TotalSentData = 3, /**< Total sent data */
+ }
+
+ /// <summary>
+ /// Enumeration for network connection type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum ConnectionProfileType
+ {
+ Cellular = 0, /**< Cellular type */
+ WiFi = 1, /**< Wi-Fi type */
+ Ethernet = 2, /**< Ethernet type */
+ Bt = 3, /**< Bluetooth type */
+ }
+
+ /// <summary>
+ /// Enumeration for profile state type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum ProfileState
+ {
+ Disconnected = 0, /**< Disconnected state */
+ Association = 1, /**< Association state */
+ Configuration = 2, /**< Configuration state */
+ Connected = 3, /**< Connected state */
+ }
+
+ /// <summary>
+ /// Enumeration for proxy method type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum ProxyType
+ {
+ Direct = 0, /**< Direct connection */
+ Auto = 1, /**< Auto configuration(Use PAC file). If URL property is not set, DHCP/WPAD auto-discover will be tried */
+ Manual = 2, /**< Manual configuration */
+ }
+
+ /// <summary>
+ /// Enumeration for IP configuration type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum IPConfigType
+ {
+ None = 0, /**< Not defined */
+ Static = 1, /**< Manual IP configuration */
+ Dynamic = 2, /**< Config IP using DHCP client*/
+ Auto = 3, /**< Config IP from Auto IP pool (169.254/16). Later with DHCP client, if available */
+ Fixed = 4, /**< Indicates an IP address that can not be modified */
+ }
+
+ /// <summary>
+ /// Enumeration for cellular service type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CellularServiceType
+ {
+ Unknown = 0, /**< Unknown */
+ Internet = 1, /**< Internet */
+ MMS = 2, /**< MMS */
+ PrepaidInternet = 3, /**< Prepaid internet */
+ PrepaidMMS = 4, /**< Prepaid MMS */
+ Tethering = 5, /**< Tethering */
+ Application = 6, /**< Specific application */
+ }
+
+ /// <summary>
+ /// Enumeration for cellular pdn type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CellularPdnType
+ {
+ Unknown = 0, /**< Unknown */
+ IPv4 = 1, /**< IPv4 */
+ IPv6 = 2, /**< IPv6 */
+ IPv4_IPv6 = 3, /**< Both IPv4 and IPv6 */
+ }
+
+ /// <summary>
+ /// Enumeration for DNS configuration type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum DnsConfigType
+ {
+ None = 0, /**< Not defined */
+ Static = 1, /**< Manual DNS configuration */
+ Dynamic = 2, /**< Config DNS using DHCP client */
+ }
+
+ static internal class ConnectionErrorValue
+ {
+ internal const int Base = -0x01C10000;
+ }
+
+
+ /// <summary>
+ /// Enumeration for connection errors.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ // To do : have to assign valid error code
+ public enum ConnectionError
+ {
+ None = ErrorCode.None, /**< Successful */
+ InvalidParameter = ErrorCode.InvalidParameter, /**< Invalid parameter */
+ OutOfMemoryError = ErrorCode.OutOfMemory, /**< Out of memory error */
+ InvalidOperation = ErrorCode.InvalidOperation, /**< Invalid Operation */
+ AddressFamilyNotSupported = ErrorCode.AddressFamilyNotSupported, /**< Address family not supported */
+ OperationFailed = ConnectionErrorValue.Base | 0x0401, /**< Operation failed */
+ EndOfIteration = ConnectionErrorValue.Base | 0x0402, /**< End of iteration */
+ NoConnection = ConnectionErrorValue.Base | 0x0403, /**< There is no connection */
+ NowInProgress = ErrorCode.NowInProgress, /** Now in progress */
+ AlreadyExists = ConnectionErrorValue.Base | 0x0404, /**< Already exists */
+ OperationAborted = ConnectionErrorValue.Base | 0x0405, /**< Operation is aborted */
+ DhcpFailed = ConnectionErrorValue.Base | 0x0406, /**< DHCP failed */
+ InvalidKey = ConnectionErrorValue.Base | 0x0407, /**< Invalid key */
+ NoReply = ConnectionErrorValue.Base | 0x0408, /**< No reply */
+ PermissionDenied = ErrorCode.PermissionDenied, /**< Permission denied */
+ NotSupported = ErrorCode.NotSupported /**< Not Supported */
+ }
+
+ /// <summary>
+ /// Enumeration for profile list type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum ProfileListType
+ {
+ Registered = 0, /**< The iterator of the registered profile */
+ Connected = 1, /**< The iterator of the connected profile */
+ Default = 2, /**< The iterator of the default profile */
+ }
+
+ /// <summary>
+ /// Enumeration for security type of Wi-Fi.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum WiFiSecurityType
+ {
+ None = 0, /**< Security disabled */
+ Wep = 1, /**< WEP */
+ WpaPsk = 2, /**< WPA-PSK */
+ Wpa2Psk = 3, /**< WPA2-PSK */
+ Eap = 4, /**< EAP */
+ }
+
+ /// <summary>
+ /// Enumeration for encryption modes.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum WiFiEncryptionType
+ {
+ None = 0, /**< Encryption disabled */
+ Wep = 1, /**< WEP */
+ Tkip = 2, /**< TKIP */
+ Aes = 3, /**< AES */
+ TkipAesMixed = 4, /**< TKIP and AES are both supported */
+ }
+
+ /// <summary>
+ /// Enumeration for connection profile state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum ConnectionProfileState
+ {
+ Disconnected = 0, /**< Disconnected state */
+ Association = 1, /**< Association state */
+ Configuration = 2, /**< Configuration state */
+ Connected = 3, /**< Connected state */
+ }
+
+ /// <summary>
+ /// Enumeration for cellular authentication type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CellularAuthType
+ {
+ None = 0, /**< No authentication */
+ Pap = 1, /**< PAP authentication */
+ Chap = 2, /**< CHAP authentication */
+ }
+
+ public enum AddressInformationType
+ {
+ Connection = 0,
+ WiFi = 1
+ }
+
+ static internal class Globals
+ {
+ internal const string LogTag = "Tizen.Network.Connection";
+ }
+}
diff --git a/src/Tizen.Network.Connection/Tizen.Network.Connection/IAddressInformation.cs b/src/Tizen.Network.Connection/Tizen.Network.Connection/IAddressInformation.cs
new file mode 100755
index 0000000..5185186
--- /dev/null
+++ b/src/Tizen.Network.Connection/Tizen.Network.Connection/IAddressInformation.cs
@@ -0,0 +1,383 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Collections;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Network.Connection
+{
+ /// <summary>
+ /// This interface provides properties to manage address information of the connection.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public interface IAddressInformation
+ {
+ /// <summary>
+ /// The DNS address.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>First DNS address of the connection.</value>
+ /// <exception cref="System.NotSupportedException">Thrown during set when feature is not supported.</exception>
+ /// <exception cref="System.ArgumentException">Thrown during set when value is invalid parameter.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown during set when profile instance is invalid or when method failed due to invalid operation.</exception>
+ System.Net.IPAddress Dns1 { get; set; }
+
+ /// <summary>
+ /// The DNS address.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Second DNS address of the connection.</value>
+ /// <exception cref="System.NotSupportedException">Thrown during set when feature is not supported.</exception>
+ /// <exception cref="System.ArgumentException">Thrown during set when value is invalid parameter.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown during set when profile instance is invalid or when method failed due to invalid operation.</exception>
+ System.Net.IPAddress Dns2 { get; set; }
+
+ /// <summary>
+ /// The gateway address.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Gateway address of the connection.</value>
+ /// <exception cref="System.NotSupportedException">Thrown during set when feature is not supported.</exception>
+ /// <exception cref="System.ArgumentException">Thrown during set when value is invalid parameter.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown during set when profile instance is invalid or when method failed due to invalid operation.</exception>
+ System.Net.IPAddress Gateway { get; set; }
+
+ /// <summary>
+ /// The subnet mask address.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Subnet mask of the connection.</value>
+ /// <exception cref="System.NotSupportedException">Thrown during set when feature is not supported.</exception>
+ /// <exception cref="System.ArgumentException">Thrown during set when value is invalid parameter.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown during set when profile instance is invalid or when method failed due to invalid operation.</exception>
+ System.Net.IPAddress SubnetMask { get; set; }
+
+ /// <summary>
+ /// The IP address.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>IP address of the connection.</value>
+ /// <exception cref="System.NotSupportedException">Thrown during set when feature is not supported.</exception>
+ /// <exception cref="System.ArgumentException">Thrown during set when value is invalid parameter.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown during set when profile instance is invalid or when method failed due to invalid operation.</exception>
+ System.Net.IPAddress IP { get; set; }
+
+ /// <summary>
+ /// The type of IP config.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>IP config type of the connection.</value>
+ /// <exception cref="System.NotSupportedException">Thrown during set when feature is not supported.</exception>
+ /// <exception cref="System.ArgumentException">Thrown during set when value is invalid parameter.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown during set when profile instance is invalid or when method failed due to invalid operation.</exception>
+ IPConfigType IPConfigType { get; set; }
+
+ /// <summary>
+ /// The prefix length.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Prefix length of the connection.</value>
+ /// <exception cref="System.NotSupportedException">Thrown during set when feature is not supported.</exception>
+ /// <exception cref="System.ArgumentException">Thrown during set when value is invalid parameter.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown during set when profile instance is invalid or when method failed due to invalid operation.</exception>
+ int PrefixLength { get; set; }
+
+ /// <summary>
+ /// The DNS config type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Config type of the DNS.</value>
+ /// <exception cref="System.NotSupportedException">Thrown during set when feature is not supported.</exception>
+ /// <exception cref="System.ArgumentException">Thrown during set when value is invalid parameter.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown during set when profile instance is invalid or when method failed due to invalid operation.</exception>
+ DnsConfigType DnsConfigType { get; set; }
+
+ /// <summary>
+ /// The DHCP server address. It is only supported for IPV4 address family.
+ /// </summary>
+ /// <value>Server address of the DHCP.</value>
+ System.Net.IPAddress DhcpServerAddress { get; }
+ }
+
+ internal class ConnectionAddressInformation : IAddressInformation
+ {
+ private IntPtr _profileHandle;
+ private AddressFamily _family;
+
+ internal ConnectionAddressInformation(IntPtr handle, AddressFamily family)
+ {
+ _profileHandle = handle;
+ _family = family;
+ }
+
+ public System.Net.IPAddress Dns1
+ {
+ get
+ {
+ IntPtr Value;
+ int ret = Interop.ConnectionProfile.GetDnsAddress(_profileHandle, 1, (int)_family, out Value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get dns1 address, " + (ConnectionError)ret);
+ }
+ string result = Marshal.PtrToStringAnsi(Value);
+ Interop.Libc.Free(Value);
+ if (result == null)
+ return System.Net.IPAddress.Parse("0.0.0.0");
+ return System.Net.IPAddress.Parse(result);
+ }
+
+ set
+ {
+ int ret = Interop.ConnectionProfile.SetDnsAddress(_profileHandle, 1, (int)_family, value.ToString());
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to set dns1 address, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (_profileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ }
+ }
+ public System.Net.IPAddress Dns2
+ {
+ get
+ {
+ IntPtr Value;
+ int ret = Interop.ConnectionProfile.GetDnsAddress(_profileHandle, 2, (int)_family, out Value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get dns2 address, " + (ConnectionError)ret);
+ }
+ string result = Marshal.PtrToStringAnsi(Value);
+ Interop.Libc.Free(Value);
+ if (result == null)
+ return System.Net.IPAddress.Parse("0.0.0.0");
+ return System.Net.IPAddress.Parse(result);
+ }
+
+ set
+ {
+ int ret = Interop.ConnectionProfile.SetDnsAddress(_profileHandle, 2, (int)_family, value.ToString());
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to set dns2 address, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (_profileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ }
+ }
+
+ public System.Net.IPAddress Gateway
+ {
+ get
+ {
+ IntPtr Value;
+ int ret = Interop.ConnectionProfile.GetGatewayAddress(_profileHandle, (int)_family, out Value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get gateway, " + (ConnectionError)ret);
+ }
+ string result = Marshal.PtrToStringAnsi(Value);
+ Interop.Libc.Free(Value);
+ if (result == null)
+ return System.Net.IPAddress.Parse("0.0.0.0");
+ return System.Net.IPAddress.Parse(result);
+ }
+
+ set
+ {
+ int ret = Interop.ConnectionProfile.SetGatewayAddress(_profileHandle, (int)_family, value.ToString());
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to set gateway, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (_profileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ }
+ }
+
+
+ public System.Net.IPAddress SubnetMask
+ {
+ get
+ {
+ IntPtr Value;
+ int ret = Interop.ConnectionProfile.GetSubnetMask(_profileHandle, (int)_family, out Value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get subnet mask, " + (ConnectionError)ret);
+ }
+ string result = Marshal.PtrToStringAnsi(Value);
+ Interop.Libc.Free(Value);
+ if (result == null)
+ return System.Net.IPAddress.Parse("0.0.0.0");
+ return System.Net.IPAddress.Parse(result);
+ }
+
+ set
+ {
+ int ret = Interop.ConnectionProfile.SetSubnetMask(_profileHandle, (int)_family, value.ToString());
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to set subnet mask, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (_profileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ }
+ }
+
+
+ public System.Net.IPAddress IP
+ {
+ get
+ {
+ IntPtr Value;
+ int ret = Interop.ConnectionProfile.GetIPAddress(_profileHandle, (int)_family, out Value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get ip, " + (ConnectionError)ret);
+ }
+ string result = Marshal.PtrToStringAnsi(Value);
+ Interop.Libc.Free(Value);
+ if (result == null)
+ return System.Net.IPAddress.Parse("0.0.0.0");
+ return System.Net.IPAddress.Parse(result);
+ }
+
+ set
+ {
+ int ret = Interop.ConnectionProfile.SetIPAddress(_profileHandle, (int)_family, value.ToString());
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to set ip, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (_profileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ }
+ }
+
+ public IPConfigType IPConfigType
+ {
+ get
+ {
+ int Value;
+ int ret = Interop.ConnectionProfile.GetIPConfigType(_profileHandle, (int)_family, out Value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get ip config type, " + (ConnectionError)ret);
+ }
+ return (IPConfigType)Value;
+ }
+
+ set
+ {
+ int ret = Interop.ConnectionProfile.SetIPConfigType(_profileHandle, (int)_family, (int)value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to set ip config type, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (_profileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ }
+ }
+
+ public int PrefixLength
+ {
+ get
+ {
+ int Value;
+ int ret = Interop.ConnectionProfile.GetPrefixLength(_profileHandle, (int)_family, out Value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get prefix length, " + (ConnectionError)ret);
+ }
+ return Value;
+ }
+
+ set
+ {
+ int ret = Interop.ConnectionProfile.SetPrefixLength(_profileHandle, (int)_family, value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to set prefix length, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (_profileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ }
+ }
+
+ public DnsConfigType DnsConfigType
+ {
+ get
+ {
+ int Value;
+ int ret = Interop.ConnectionProfile.GetDnsConfigType(_profileHandle, (int)_family, out Value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get DNS config type, " + (ConnectionError)ret);
+ }
+ return (DnsConfigType)Value;
+ }
+
+ set
+ {
+ int ret = Interop.ConnectionProfile.SetDnsConfigType(_profileHandle, (int)_family, (int)value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to set DNS config type, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (_profileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ }
+ }
+
+ public System.Net.IPAddress DhcpServerAddress
+ {
+ get
+ {
+ string dhcpServer;
+ int ret = Interop.ConnectionProfile.GetDhcpServerAddress(_profileHandle, _family, out dhcpServer);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get the DHCP server address, " + (ConnectionError)ret);
+ }
+
+ if (dhcpServer == null)
+ {
+ return System.Net.IPAddress.Parse("0.0.0.0");
+ }
+
+ else
+ {
+ return System.Net.IPAddress.Parse(dhcpServer);
+ }
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.Connection/Tizen.Network.Connection/WiFiProfile.cs b/src/Tizen.Network.Connection/Tizen.Network.Connection/WiFiProfile.cs
new file mode 100755
index 0000000..8ac6234
--- /dev/null
+++ b/src/Tizen.Network.Connection/Tizen.Network.Connection/WiFiProfile.cs
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Network.Connection
+{
+ /// <summary>
+ /// This Class is WiFiProfile. It provides functions to manage the WiFi profile.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class WiFiProfile : ConnectionProfile
+ {
+ internal WiFiProfile(IntPtr Handle) : base(Handle)
+ {
+ }
+
+ ~WiFiProfile()
+ {
+ }
+
+ /// <summary>
+ /// The ESSID (Extended Service Set Identifier).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>ESSID of the WiFi.</value>
+ public string Essid
+ {
+ get
+ {
+ IntPtr value;
+ int ret = Interop.ConnectionWiFiProfile.GetEssid(ProfileHandle, out value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to create profile handle, " + (ConnectionError)ret);
+ }
+ string result = Marshal.PtrToStringAnsi(value);
+ Interop.Libc.Free(value);
+ return result;
+ }
+ }
+
+ /// <summary>
+ /// The BSSID (Basic Service Set Identifier).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>BSSID of the WiFi.</value>
+ public string Bssid
+ {
+ get
+ {
+ IntPtr value;
+ int ret = Interop.ConnectionWiFiProfile.GetBssid(ProfileHandle, out value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get bssid, " + (ConnectionError)ret);
+ }
+ string result = Marshal.PtrToStringAnsi(value);
+ Interop.Libc.Free(value);
+ return result;
+ }
+ }
+
+ /// <summary>
+ /// The RSSI.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>RSSI of the WiFi.</value>
+ public int Rssi
+ {
+ get
+ {
+ int value;
+ int ret = Interop.ConnectionWiFiProfile.GetRssi(ProfileHandle, out value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get rssi, " + (ConnectionError)ret);
+ }
+ return value;
+ }
+ }
+
+ /// <summary>
+ /// The frequency (MHz).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Frequency of the WiFi.</value>
+ public int Frequency
+ {
+ get
+ {
+ int value;
+ int ret = Interop.ConnectionWiFiProfile.GetFrequency(ProfileHandle, out value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get frequency, " + (ConnectionError)ret);
+ }
+ return value;
+ }
+ }
+
+ /// <summary>
+ /// The max speed (Mbps).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Maximum speed of the WiFi.</value>
+ public int MaxSpeed
+ {
+ get
+ {
+ int value;
+ int ret = Interop.ConnectionWiFiProfile.GetMaxSpeed(ProfileHandle, out value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get max speed, " + (ConnectionError)ret);
+ }
+ return value;
+ }
+ }
+
+ /// <summary>
+ /// The security type of WiFi.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Security type of the WiFi.</value>
+ public WiFiSecurityType SecurityType
+ {
+ get
+ {
+ int value;
+ int ret = Interop.ConnectionWiFiProfile.GetSecurityType(ProfileHandle, out value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get security type, " + (ConnectionError)ret);
+ }
+ return (WiFiSecurityType)value;
+ }
+ }
+
+ /// <summary>
+ /// The encryption type of WiFi.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Encryption mode of the WiFi.</value>
+ public WiFiEncryptionType EncryptionType
+ {
+ get
+ {
+ int value;
+ int ret = Interop.ConnectionWiFiProfile.GetEncryptionType(ProfileHandle, out value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get encryption type, " + (ConnectionError)ret);
+ }
+ return (WiFiEncryptionType)value;
+ }
+ }
+
+ /// <summary>
+ /// Checks whether passphrase is required.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>True if a passphrase is required, otherwise false.</value>
+ /// <remarks>This property is not valid if <c>WiFiSecurityType</c> is <c>Eap</c>.</remarks>
+ public bool PassphraseRequired
+ {
+ get
+ {
+ bool value;
+ int ret = Interop.ConnectionWiFiProfile.IsRequiredPassphrase(ProfileHandle, out value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get PassphraseRequired, " + (ConnectionError)ret);
+ }
+ return value;
+ }
+ }
+
+ /// <summary>
+ /// Checks whether the WPS (Wi-Fi Protected Setup) is supported.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>True if WPS is supported, otherwise false.</value>
+ public bool WpsSupported
+ {
+ get
+ {
+ bool value;
+ int ret = Interop.ConnectionWiFiProfile.IsSupportedWps(ProfileHandle, out value);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get IsSupportedWps, " + (ConnectionError)ret);
+ }
+ return value;
+ }
+ }
+
+ /// <summary>
+ /// Sets the passphrase of the Wi-Fi WPA.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="passphrase">The passphrase of Wi-Fi security</param>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when value is invalid parameter.</exception>
+ /// <exception cref="System.ArgumentNullException">Thrown when passphrase is null.</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when profile instance is invalid or when method failed due to invalid operation.</exception>
+ /// <exception cref="System.ObjectDisposedException">Thrown when operation is performed on a disposed object.</exception>
+ public void SetPassphrase(string passphrase)
+ {
+ CheckDisposed();
+ if (passphrase != null)
+ {
+ int ret = Interop.ConnectionWiFiProfile.SetPassphrase(ProfileHandle, passphrase);
+ if ((ConnectionError)ret != ConnectionError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to set passphrase, " + (ConnectionError)ret);
+ ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.wifi");
+ ConnectionErrorFactory.CheckHandleNullException(ret, (ProfileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
+ ConnectionErrorFactory.ThrowConnectionException(ret);
+ }
+ }
+
+ else
+ {
+ throw new ArgumentNullException("Value of passphrase is null");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Interop/Interop.IoTConnectivity.Client.cs b/src/Tizen.Network.IoTConnectivity/Interop/Interop.IoTConnectivity.Client.cs
new file mode 100755
index 0000000..f1d4ace
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Interop/Interop.IoTConnectivity.Client.cs
@@ -0,0 +1,244 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class IoTConnectivity
+ {
+ internal static partial class Client
+ {
+ internal static partial class DeviceInformation
+ {
+ internal delegate bool DeviceInformationCallback(IntPtr deviceInfoHandle, int result, IntPtr userData);
+
+ internal enum Property
+ {
+ Name = 0,
+ SpecVersion,
+ Id,
+ DataModelVersion,
+ }
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_find_device_info")]
+ internal static extern int Find(string hostAddress, int connectivityType, IntPtr query, DeviceInformationCallback cb, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_device_info_get_property")]
+ internal static extern int GetProperty(IntPtr deviceInfoHandle, int property, out IntPtr value);
+ }
+
+ internal static partial class PlatformInformation
+ {
+ internal delegate bool PlatformInformationCallback(IntPtr platformInfoHandle, int result, IntPtr userData);
+
+ internal enum Propery
+ {
+ Id = 0,
+ MfgName,
+ MfgUrl,
+ ModelNumber,
+ DateOfMfg,
+ PlatformVer,
+ OsVer,
+ HardwareVer,
+ FirmwareVer,
+ SupportUrl,
+ SystemTime
+ }
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_find_platform_info")]
+ internal static extern int Find(string hostAddress, int connectivityType, IntPtr query, PlatformInformationCallback cb, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_platform_info_get_property")]
+ internal static extern int GetProperty(IntPtr platformInfoHandle, int property, out IntPtr value);
+ }
+
+ internal static partial class RemoteResource
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ResponseCallback(IntPtr resource, int err, int requestType, IntPtr response, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ObserveCallback(IntPtr resource, int err, int sequenceNumber, IntPtr response, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void CachedRepresentationChangedCallback(IntPtr resource, IntPtr representation, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void StateChangedCallback(IntPtr resource, int state, IntPtr userData);
+
+ internal enum ConnectivityType
+ {
+ None = -1,
+ All,
+ Ip,
+ Ipv4,
+ Ipv6
+ }
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_remote_resource_create")]
+ internal static extern int Create(string hostAddress, int connectivityType, string uriPath, int properties, IntPtr resourceTypes, IntPtr resourceInterfaces, out IntPtr remoteResource);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_remote_resource_destroy")]
+ internal static extern void Destroy(IntPtr resource);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_remote_resource_clone")]
+ internal static extern int Clone(IntPtr src, out IntPtr dest);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_remote_resource_observe_register")]
+ internal static extern int RegisterObserve(IntPtr resource, int observePolicy, IntPtr query, ObserveCallback cb, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_remote_resource_observe_deregister")]
+ internal static extern int DeregisterObserve(IntPtr resource);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_remote_resource_get")]
+ internal static extern int Get(IntPtr resource, IntPtr query, ResponseCallback cb, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_remote_resource_put")]
+ internal static extern int Put(IntPtr resource, IntPtr repr, IntPtr query, ResponseCallback cb, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_remote_resource_post")]
+ internal static extern int Post(IntPtr resource, IntPtr repr, IntPtr query, ResponseCallback cb, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_remote_resource_delete")]
+ internal static extern int Delete(IntPtr resource, ResponseCallback cb, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_remote_resource_start_caching")]
+ internal static extern int StartCaching(IntPtr resource, CachedRepresentationChangedCallback cb, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_remote_resource_stop_caching")]
+ internal static extern int StopCaching(IntPtr resource);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_remote_resource_start_monitoring")]
+ internal static extern int StartMonitoring(IntPtr resource, StateChangedCallback cb, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_remote_resource_stop_monitoring")]
+ internal static extern int StopMonitoring(IntPtr resource);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_remote_resource_get_uri_path")]
+ internal static extern int GetUriPath(IntPtr resource, out IntPtr uriPath);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_remote_resource_get_connectivity_type")]
+ internal static extern int GetConnectivityType(IntPtr resource, out int connectivityType);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_remote_resource_get_host_address")]
+ internal static extern int GetHostAddress(IntPtr resource, out IntPtr hostAddress);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_remote_resource_get_device_id")]
+ internal static extern int GetDeviceId(IntPtr resource, out IntPtr deviceId);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_remote_resource_get_types")]
+ internal static extern int GetTypes(IntPtr resource, out IntPtr types);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_remote_resource_get_interfaces")]
+ internal static extern int GetInterfaces(IntPtr resource, out IntPtr ifaces);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_remote_resource_get_policies")]
+ internal static extern int GetPolicies(IntPtr resource, out int properties);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_remote_resource_get_options")]
+ internal static extern int GetOptions(IntPtr resource, out IntPtr options);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_remote_resource_set_options")]
+ internal static extern int SetOptions(IntPtr resource, IntPtr options);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_remote_resource_get_cached_representation")]
+ internal static extern int GetCachedRepresentation(IntPtr resource, out IntPtr representation);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_remote_resource_get_checking_interval")]
+ internal static extern int GetTimeInterval(IntPtr resource, out int timeInterval);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_remote_resource_set_checking_interval")]
+ internal static extern int SetTimeInterval(IntPtr resource, int timeInterval);
+ }
+
+ internal static partial class IoTCon
+ {
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_initialize")]
+ internal static extern int Initialize(string filePath);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_deinitialize")]
+ internal static extern void Deinitialize();
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_get_timeout")]
+ internal static extern int GetTimeout(out int timeoutSeconds);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_set_timeout")]
+ internal static extern int SetTimeout(int timeoutSeconds);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_polling_get_interval")]
+ internal static extern int GetPollingInterval(out int interval);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_polling_set_interval")]
+ internal static extern int SetPollingInterval(int interval);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_polling_invoke")]
+ internal static extern int InvokePolling();
+ }
+
+ internal static partial class ResourceFinder
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool FoundResourceCallback(IntPtr remoteResourceHandle, int result, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_find_resource")]
+ internal static extern int AddResourceFoundCb(string hostAddress, int connectivityType, IntPtr query, FoundResourceCallback cb, IntPtr userData);
+ }
+
+ internal static partial class Presence
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void PresenceCallback(IntPtr presenceResponseHandle, int err, IntPtr response, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_add_presence_cb")]
+ internal static extern int AddPresenceCb(string hostAddress, int connectivityType, string resourceType, PresenceCallback cb, IntPtr userData, out IntPtr presenceHandle);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_remove_presence_cb")]
+ internal static extern int RemovePresenceCb(IntPtr presenceHandle);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_presence_get_host_address")]
+ internal static extern int GetHostAddress(IntPtr presence, out IntPtr hostAddress);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_presence_get_connectivity_type")]
+ internal static extern int GetConnectivityType(IntPtr presence, out int connectivityType);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_presence_get_resource_type")]
+ internal static extern int GetResourceType(IntPtr presence, out IntPtr resourceType);
+ }
+
+ internal static partial class PresenceResponse
+ {
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_presence_response_get_result")]
+ internal static extern int GetResult(IntPtr response, out int result);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_presence_response_get_trigger")]
+ internal static extern int GetTrigger(IntPtr response, out int trigger);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_presence_response_get_host_address")]
+ internal static extern int GetHostAddress(IntPtr response, out IntPtr hostAddress);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_presence_response_get_connectivity_type")]
+ internal static extern int GetConnectivityType(IntPtr response, out int connectivityType);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_presence_response_get_resource_type")]
+ internal static extern int GetResourceType(IntPtr response, out IntPtr resourceType);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Interop/Interop.IoTConnectivity.Common.cs b/src/Tizen.Network.IoTConnectivity/Interop/Interop.IoTConnectivity.Common.cs
new file mode 100755
index 0000000..9b4fa48
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Interop/Interop.IoTConnectivity.Common.cs
@@ -0,0 +1,368 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class IoTConnectivity
+ {
+ internal static partial class Common
+ {
+ internal enum DataType
+ {
+ None = 0,
+ Int,
+ Bool,
+ Double,
+ String,
+ ByteStr,
+ Null,
+ List,
+ Attributes
+ }
+
+ internal static partial class ResourceTypes
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool ForeachCallback(string type, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_resource_types_create")]
+ internal static extern int Create(out IntPtr types);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_resource_types_destroy")]
+ internal static extern void Destroy(IntPtr types);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_resource_types_add")]
+ internal static extern int Add(IntPtr types, string type);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_resource_types_remove")]
+ internal static extern int Remove(IntPtr types, string type);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_resource_types_foreach")]
+ internal static extern int Foreach(IntPtr types, ForeachCallback cb, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_resource_types_clone")]
+ internal static extern int Clone(IntPtr src, out IntPtr dest);
+ }
+
+ internal static partial class ResourceInterfaces
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool ForeachCallback(string iface, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_resource_interfaces_create")]
+ internal static extern int Create(out IntPtr ifaces);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_resource_interfaces_destroy")]
+ internal static extern void Destroy(IntPtr ifaces);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_resource_interfaces_add")]
+ internal static extern int Add(IntPtr ifaces, string iface);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_resource_interfaces_remove")]
+ internal static extern int Remove(IntPtr ifaces, string iface);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_resource_interfaces_foreach")]
+ internal static extern int Foreach(IntPtr ifaces, ForeachCallback cb, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_resource_interfaces_clone")]
+ internal static extern int Clone(IntPtr src, out IntPtr dest);
+ }
+
+ internal static partial class Attributes
+ {
+ internal delegate bool AttributesCallback(IntPtr attributes, string key, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_attributes_create")]
+ internal static extern int Create(out IntPtr attributes);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_attributes_destroy")]
+ internal static extern void Destroy(IntPtr attributes);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_attributes_clone")]
+ internal static extern int Clone(IntPtr attributes, out IntPtr attributes_clone);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_attributes_add_int")]
+ internal static extern int AddInt(IntPtr attributes, string key, int val);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_attributes_add_bool")]
+ internal static extern int AddBool(IntPtr attributes, string key, bool val);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_attributes_add_double")]
+ internal static extern int AddDouble(IntPtr attributes, string key, double val);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_attributes_add_str")]
+ internal static extern int AddStr(IntPtr attributes, string key, string val);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_attributes_add_byte_str")]
+ internal static extern int AddByteStr(IntPtr attributes, string key, byte[] val, int len);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_attributes_add_list")]
+ internal static extern int AddList(IntPtr attributes, string key, IntPtr list);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_attributes_add_attributes")]
+ internal static extern int AddAttributes(IntPtr dest, string key, IntPtr src);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_attributes_add_null")]
+ internal static extern int AddNull(IntPtr attributes, string key);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_attributes_get_int")]
+ internal static extern int GetInt(IntPtr attributes, string key, out int val);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_attributes_get_bool")]
+ internal static extern int GetBool(IntPtr attributes, string key, out bool val);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_attributes_get_double")]
+ internal static extern int GetDouble(IntPtr attributes, string key, out double val);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_attributes_get_str")]
+ internal static extern int GetStr(IntPtr attributes, string key, out IntPtr val);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_attributes_get_byte_str")]
+ internal static extern int GetByteStr(IntPtr attributes, string key, out IntPtr value, out int size);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_attributes_get_list")]
+ internal static extern int GetList(IntPtr attributes, string key, out IntPtr list);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_attributes_get_attributes")]
+ internal static extern int GetAttributes(IntPtr src, string key, out IntPtr dest);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_attributes_is_null")]
+ internal static extern int IsNull(IntPtr attributes, string key, out bool isNull);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_attributes_remove")]
+ internal static extern int Remove(IntPtr attributes, string key);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_attributes_get_type")]
+ internal static extern int GetType(IntPtr attributes, string key, out DataType type);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_attributes_foreach")]
+ internal static extern int Foreach(IntPtr attributes, AttributesCallback cb, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_attributes_get_keys_count")]
+ internal static extern int GetKeysCount(IntPtr attributes, out int count);
+ }
+
+ internal static partial class Query
+ {
+ internal delegate bool QueryCallback(string key, string value, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_query_create")]
+ internal static extern int Create(out IntPtr query);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_query_destroy")]
+ internal static extern void Destroy(IntPtr query);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_query_get_resource_type")]
+ internal static extern int GetResourceType(IntPtr query, out IntPtr resourceType);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_query_get_interface")]
+ internal static extern int GetInterface(IntPtr query, out IntPtr resourceInterface);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_query_set_resource_type")]
+ internal static extern int SetResourceType(IntPtr query, string resourceType);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_query_set_interface")]
+ internal static extern int SetInterface(IntPtr query, string resourceInterface);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_query_add")]
+ internal static extern int Add(IntPtr query, string key, string value);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_query_remove")]
+ internal static extern int Remove(IntPtr query, string key);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_query_lookup")]
+ internal static extern int Lookup(IntPtr query, string key, out IntPtr data);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_query_foreach")]
+ internal static extern int Foreach(IntPtr query, QueryCallback cb, IntPtr userData);
+ }
+
+ internal static partial class Representation
+ {
+ internal delegate bool RepresentationChildrenCallback(IntPtr child, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_representation_create")]
+ internal static extern int Create(out IntPtr repr);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_representation_destroy")]
+ internal static extern void Destroy(IntPtr repr);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_representation_clone")]
+ internal static extern int Clone(IntPtr src, out IntPtr dest);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_representation_set_uri_path")]
+ internal static extern int SetUriPath(IntPtr repr, string uriPath);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_representation_get_uri_path")]
+ internal static extern int GetUriPath(IntPtr repr, out IntPtr uriPath);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_representation_set_resource_types")]
+ internal static extern int SetResourceTypes(IntPtr repr, IntPtr types);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_representation_get_resource_types")]
+ internal static extern int GetResourceTypes(IntPtr repr, out IntPtr types);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_representation_set_resource_interfaces")]
+ internal static extern int SetResourceInterfaces(IntPtr repr, IntPtr ifaces);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_representation_get_resource_interfaces")]
+ internal static extern int GetResourceInterfaces(IntPtr repr, out IntPtr ifaces);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_representation_set_attributes")]
+ internal static extern int SetAttributes(IntPtr repr, IntPtr attribs);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_representation_get_attributes")]
+ internal static extern int GetAttributes(IntPtr repr, out IntPtr attribs);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_representation_add_child")]
+ internal static extern int AddChild(IntPtr parent, IntPtr child);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_representation_remove_child")]
+ internal static extern int RemoveChild(IntPtr parent, IntPtr child);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_representation_foreach_children")]
+ internal static extern int ForeachChildren(IntPtr parent, RepresentationChildrenCallback cb, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_representation_get_children_count")]
+ internal static extern int GetChildrenCount(IntPtr parent, out int count);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_representation_get_nth_child")]
+ internal static extern int GetNthChild(IntPtr parent, int pos, out IntPtr child);
+ }
+
+ internal static partial class Options
+ {
+ internal delegate bool OptionsCallback(ushort id, string data, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_options_create")]
+ internal static extern int Create(out IntPtr options);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_options_destroy")]
+ internal static extern void Destroy(IntPtr options);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_options_add")]
+ internal static extern int Add(IntPtr options, ushort id, string data);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_options_remove")]
+ internal static extern int Remove(IntPtr options, ushort id);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_options_lookup")]
+ internal static extern int Lookup(IntPtr options, ushort id, out IntPtr data);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_options_foreach")]
+ internal static extern int ForEach(IntPtr options, OptionsCallback cb, IntPtr userData);
+ }
+
+ internal static partial class List
+ {
+ internal delegate bool IntCallback(int pos, int value, IntPtr userData);
+
+ internal delegate bool BoolCallback(int pos, bool value, IntPtr userData);
+
+ internal delegate bool DoubleCallback(int pos, double value, IntPtr userData);
+
+ internal delegate bool ByteStrCallback(int pos, byte[] value, int len, IntPtr userData);
+
+ internal delegate bool StrCallback(int pos, string value, IntPtr userData);
+
+ internal delegate bool ListCallback(int pos, IntPtr value, IntPtr userData);
+
+ internal delegate bool AttribsCallback(int pos, IntPtr value, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_list_create")]
+ internal static extern int Create(DataType type, out IntPtr list);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_list_destroy")]
+ internal static extern void Destroy(IntPtr list);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_list_add_int")]
+ internal static extern int AddInt(IntPtr list, int val, int pos);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_list_add_bool")]
+ internal static extern int AddBool(IntPtr list, bool val, int pos);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_list_add_double")]
+ internal static extern int AddDouble(IntPtr list, double val, int pos);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_list_add_str")]
+ internal static extern int AddStr(IntPtr list, string val, int pos);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_list_add_byte_str")]
+ internal static extern int AddByteStr(IntPtr list, byte[] val, int len, int pos);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_list_add_list")]
+ internal static extern int AddList(IntPtr list, IntPtr val, int pos);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_list_add_attributes")]
+ internal static extern int AddAttributes(IntPtr list, IntPtr val, int pos);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_list_get_nth_int")]
+ internal static extern int GetNthInt(IntPtr list, int pos, out int val);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_list_get_nth_bool")]
+ internal static extern int GetNthBool(IntPtr list, int pos, out bool val);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_list_get_nth_double")]
+ internal static extern int GetNthDouble(IntPtr list, int pos, out double val);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_list_get_nth_str")]
+ internal static extern int GetNthStr(IntPtr list, int pos, out IntPtr val);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_list_get_nth_byte_str")]
+ internal static extern int GetNthByteStr(IntPtr list, int pos, out IntPtr val, out int len);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_list_get_nth_list")]
+ internal static extern int GetNthList(IntPtr src, int pos, out IntPtr dest);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_list_get_nth_attributes")]
+ internal static extern int GetNthAttributes(IntPtr list, int pos, out IntPtr attribs);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_list_remove_nth")]
+ internal static extern int RemoveNth(IntPtr list, int pos);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_list_get_type")]
+ internal static extern int GetType(IntPtr list, out int type);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_list_get_length")]
+ internal static extern int GetLength(IntPtr list, out int length);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_list_foreach_int")]
+ internal static extern int ForeachInt(IntPtr list, IntCallback cb, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_list_foreach_bool")]
+ internal static extern int ForeachBool(IntPtr list, BoolCallback cb, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_list_foreach_double")]
+ internal static extern int ForeachDouble(IntPtr list, DoubleCallback cb, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_list_foreach_byte_str")]
+ internal static extern int ForeachByteStr(IntPtr list, ByteStrCallback cb, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_list_foreach_str")]
+ internal static extern int ForeachStr(IntPtr list, StrCallback cb, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_list_foreach_list")]
+ internal static extern int ForeachList(IntPtr list, ListCallback cb, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_list_foreach_attributes")]
+ internal static extern int ForeachAttributes(IntPtr list, AttribsCallback cb, IntPtr userData);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Interop/Interop.IoTConnectivity.Server.cs b/src/Tizen.Network.IoTConnectivity/Interop/Interop.IoTConnectivity.Server.cs
new file mode 100755
index 0000000..59b9355
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Interop/Interop.IoTConnectivity.Server.cs
@@ -0,0 +1,169 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class IoTConnectivity
+ {
+ internal static partial class Server
+ {
+ internal enum RequestType
+ {
+ Unknown = 0,
+ Get = 1,
+ Put = 2,
+ Post = 3,
+ Delete = 4,
+ }
+
+ internal static partial class IoTCon
+ {
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_start_presence")]
+ internal static extern int StartPresence(uint time);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_stop_presence")]
+ internal static extern int StopPresence();
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_set_device_name")]
+ internal static extern int SetDeviceName(string deviceName);
+ }
+
+ internal static partial class Resource
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void RequestHandlerCallback(IntPtr resource, IntPtr request, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_resource_create")]
+ internal static extern int Create(string uriPath, IntPtr resTypes, IntPtr ifaces, int properties, RequestHandlerCallback cb, IntPtr userData, out IntPtr resourceHandle);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_resource_destroy")]
+ internal static extern int Destroy(IntPtr resourceHandle);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_resource_bind_interface")]
+ internal static extern int BindInterface(IntPtr resource, string iface);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_resource_bind_type")]
+ internal static extern int BindType(IntPtr resourceHandle, string resourceType);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_resource_set_request_handler")]
+ internal static extern int SetRequestHandler(IntPtr resource, RequestHandlerCallback cb, IntPtr userData);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_resource_bind_child_resource")]
+ internal static extern int BindChildResource(IntPtr parent, IntPtr child);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_resource_unbind_child_resource")]
+ internal static extern int UnbindChildResource(IntPtr parent, IntPtr child);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_resource_notify")]
+ internal static extern int Notify(IntPtr resource, IntPtr repr, IntPtr observers, int qos);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_resource_get_number_of_children")]
+ internal static extern int GetNumberOfChildren(IntPtr resource, out int number);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_resource_get_nth_child")]
+ internal static extern int GetNthChild(IntPtr parent, int index, out IntPtr child);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_resource_get_uri_path")]
+ internal static extern int GetUriPath(IntPtr resource, out IntPtr uriPath);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_resource_get_types")]
+ internal static extern int GetTypes(IntPtr resource, out IntPtr types);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_resource_get_interfaces")]
+ internal static extern int GetInterfaces(IntPtr resource, out IntPtr ifaces);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_resource_get_properties")]
+ internal static extern int GetProperties(IntPtr resource, out int properties);
+ }
+
+ internal static partial class Request
+ {
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_request_get_host_address")]
+ internal static extern int GetHostAddress(IntPtr request, out IntPtr hostAddress);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_request_get_connectivity_type")]
+ internal static extern int GetConnectivityType(IntPtr request, out int connectivityType);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_request_get_representation")]
+ internal static extern int GetRepresentation(IntPtr request, out IntPtr repr);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_request_get_request_type")]
+ internal static extern int GetRequestType(IntPtr request, out int type);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_request_get_options")]
+ internal static extern int GetOptions(IntPtr request, out IntPtr options);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_request_get_query")]
+ internal static extern int GetQuery(IntPtr request, out IntPtr query);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_request_get_observe_type")]
+ internal static extern int GetObserveType(IntPtr request, out int observeType);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_request_get_observe_id")]
+ internal static extern int GetObserveId(IntPtr request, out int observeId);
+ }
+
+ internal static partial class Response
+ {
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_response_create")]
+ internal static extern int Create(IntPtr request, out IntPtr response);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_response_destroy")]
+ internal static extern void Destroy(IntPtr resp);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_response_get_options")]
+ internal static extern int GetOptions(IntPtr resp, out IntPtr options);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_response_get_representation")]
+ internal static extern int GetRepresentation(IntPtr resp, out IntPtr repr);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_response_get_result")]
+ internal static extern int GetResult(IntPtr resp, out int result);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_response_set_result")]
+ internal static extern int SetResult(IntPtr resp, int result);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_response_set_representation")]
+ internal static extern int SetRepresentation(IntPtr resp, IntPtr repr);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_response_set_options")]
+ internal static extern int SetOptions(IntPtr resp, IntPtr options);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_response_send")]
+ internal static extern int Send(IntPtr resp);
+ }
+
+ internal static partial class Observers
+ {
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_observers_create")]
+ internal static extern int Create(out IntPtr observers);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_observers_destroy")]
+ internal static extern void Destroy(IntPtr observers);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_observers_add")]
+ internal static extern int Add(IntPtr observers, int observeId);
+
+ [DllImport(Libraries.IoTCon, EntryPoint = "iotcon_observers_remove")]
+ internal static extern int Remove(IntPtr observers, int observeId);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Interop/Interop.Libraries.cs b/src/Tizen.Network.IoTConnectivity/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..b918618
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Interop/Interop.Libraries.cs
@@ -0,0 +1,25 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string IoTCon = "libiotcon.so.0";
+ public const string Glib = "libglib-2.0.so.0";
+ public const string Libc = "libc.so.6";
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity.csproj b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity.csproj
new file mode 100644
index 0000000..d5717a4
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity.csproj
@@ -0,0 +1,15 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
+
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/Attributes.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/Attributes.cs
new file mode 100755
index 0000000..e7bb84c
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/Attributes.cs
@@ -0,0 +1,860 @@
+/// Copyright 2016 by Samsung Electronics, Inc.,
+///
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// This class represents current attributes of a resource.
+ /// It provides API to manage attributes.
+ /// This class is accessed by using a constructor to create a new instance of this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class Attributes : IDictionary<string, object>, IDisposable
+ {
+ internal IntPtr _resourceAttributesHandle = IntPtr.Zero;
+ private readonly IDictionary<string, object> _attributes = new Dictionary<string, object>();
+ private bool _disposed = false;
+
+ /// <summary>
+ /// The Attributes constructor
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory</exception>
+ /// <code>
+ /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes();
+ /// </code>
+ public Attributes()
+ {
+ int ret = Interop.IoTConnectivity.Common.Attributes.Create(out _resourceAttributesHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create attributes handle");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+
+ internal Attributes(IntPtr attributesHandleToClone)
+ {
+ int ret = Interop.IoTConnectivity.Common.Attributes.Clone(attributesHandleToClone, out _resourceAttributesHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create attributes handle");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+
+ SetAttributes(_resourceAttributesHandle);
+ }
+
+ /// <summary>
+ /// Destructor of the Attributes class.
+ /// </summary>
+ ~Attributes()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Gets the number of keys
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The number of keys.</value>
+ /// <code>
+ /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes() {
+ /// attributes.Add("brightness", 50);
+ /// var count = attributes.Count;
+ /// Console.WriteLine("There are {0} keys in the attribute object", count);
+ /// </code>
+ public int Count
+ {
+ get
+ {
+ return _attributes.Count;
+ }
+ }
+
+ /// <summary>
+ /// Represents whether attribute is readonly
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Whether attribute is readonly.</value>
+ /// <code>
+ /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes() {
+ /// { "state", "ON" },
+ /// { "dim", 10 }
+ /// };
+ /// if (attributes.IsReadOnly)
+ /// Console.WriteLine("Read only attribute");
+ /// </code>
+ public bool IsReadOnly
+ {
+ get
+ {
+ return _attributes.IsReadOnly;
+ }
+ }
+
+ /// <summary>
+ /// Contains all the attribute keys
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>All the attribute keys.</value>
+ /// <code>
+ /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes() {
+ /// { "state", "ON" },
+ /// { "dim", 10 }
+ /// };
+ /// var keys = attributes.Keys;
+ /// Console.WriteLine("Attribute contains keys {0} and {1}", keys.ElementAt(0), keys.ElementAt(1));
+ /// </code>
+ public ICollection<string> Keys
+ {
+ get
+ {
+ return _attributes.Keys;
+ }
+ }
+
+ /// <summary>
+ /// Contains all the attribute values
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>All the attribute values.</value>
+ /// <code>
+ /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes() {
+ /// { "state", "ON" },
+ /// { "dim", 10 }
+ /// };
+ /// var values = attributes.Values;
+ /// Console.WriteLine("Attribute contains values {0} and {1}", values.ElementAt(0), values.ElementAt(1));
+ /// </code>
+ public ICollection<object> Values
+ {
+ get
+ {
+ return _attributes.Values;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the attribute with the specified key.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The attribute with the specified key.</value>
+ /// <param name="key">The key of the attribute to get or set.</param>
+ /// <returns>The element with the specified key.</returns>
+ /// <code>
+ /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes();
+ /// attributes["state"] = "ON";
+ /// Console.WriteLine("Attribute value for key 'state' : {0}", attributes["state"]);
+ /// </code>
+ public object this[string key]
+ {
+ get
+ {
+ if (_attributes.ContainsKey(key))
+ return _attributes[key];
+ else
+ return null;
+ }
+
+ set
+ {
+ Add(key, value);
+ }
+ }
+
+ /// <summary>
+ /// Adds attribute key and value as a key value pair
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="item">The key value pair to add</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <code>
+ /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes();
+ /// attributes.Add(new KeyValuePair<string, object> ("state", "ON"));
+ /// </code>
+ public void Add(KeyValuePair<string, object> item)
+ {
+ Add(item.Key, item.Value);
+ }
+
+ /// <summary>
+ /// Adds an attribute
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="key">The key representing the attribute</param>
+ /// <param name="value">The value representing the attribute</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <code>
+ /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes();
+ /// attributes.Add("brightness", 50);
+ /// </code>
+ public void Add(string key, object value)
+ {
+ int ret = 0;
+ if (value is int)
+ {
+ ret = Interop.IoTConnectivity.Common.Attributes.AddInt(_resourceAttributesHandle, key, (int)value);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add int");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ else if (value is Attributes)
+ {
+ Attributes attribs = (Attributes)value;
+ ret = Interop.IoTConnectivity.Common.Attributes.AddAttributes(_resourceAttributesHandle, key, attribs._resourceAttributesHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add attributes");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ else if (value is string)
+ {
+ ret = Interop.IoTConnectivity.Common.Attributes.AddStr(_resourceAttributesHandle, key, (string)value);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add string");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ else if (value is double)
+ {
+ ret = Interop.IoTConnectivity.Common.Attributes.AddDouble(_resourceAttributesHandle, key, (double)value);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add double");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ else if (value is bool)
+ {
+ ret = Interop.IoTConnectivity.Common.Attributes.AddBool(_resourceAttributesHandle, key, (bool)value);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add bool");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ else if (value is byte[])
+ {
+ byte[] val = value as byte[];
+ if (val == null)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get byte[] val");
+ throw new ArgumentException("Invalid Parameter");
+ }
+ ret = Interop.IoTConnectivity.Common.Attributes.AddByteStr(_resourceAttributesHandle, key, val, val.Length);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add bool");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ else if (value is IEnumerable)
+ {
+ IntPtr listHandle = List.GetListHandle(value);
+ ret = Interop.IoTConnectivity.Common.Attributes.AddList(_resourceAttributesHandle, key, listHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add list");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ else
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to Add");
+ throw IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.InvalidParameter);
+ }
+ _attributes.Add(key, value);
+ }
+
+ /// <summary>
+ /// Clears attributes collection
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
+ /// <code>
+ /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes();
+ /// attributes.Add("brightness", 50);
+ /// attributes.Clear();
+ /// </code>
+ public void Clear()
+ {
+ foreach (string key in _attributes.Keys)
+ {
+ int ret = Interop.IoTConnectivity.Common.Attributes.Remove(_resourceAttributesHandle, key);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to clear attributes");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ _attributes.Clear();
+ }
+
+ /// <summary>
+ /// Checks whether the given key value pair exists in attributes collection
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="item">The status key value pair</param>
+ /// <returns>true if exists. Otherwise, false</returns>
+ /// <code>
+ /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes() {
+ /// { "state", "ON" },
+ /// { "dim", 10 }
+ /// };
+ /// if (attributes.Contains(new KeyValuePair<string, object> ("dim", 10))
+ /// Console.WriteLine("Attribute conatins pair ('dim', 10)");
+ /// </code>
+ public bool Contains(KeyValuePair<string, object> item)
+ {
+ return _attributes.Contains(item);
+ }
+
+ /// <summary>
+ /// Checks whether the given key exists in attributes collection
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="key">The status key to look for</param>
+ /// <returns>true if exists. Otherwise, false</returns>
+ /// <code>
+ /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes() {
+ /// { "state", "ON" },
+ /// { "dim", 10 }
+ /// };
+ /// if (attributes.ContainsKey("dim"))
+ /// Console.WriteLine("Attribute conatins key : dim");
+ /// </code>
+ public bool ContainsKey(string key)
+ {
+ return _attributes.ContainsKey(key);
+ }
+
+ /// <summary>
+ /// Copies the elements of the attributes to an array, starting at a particular index.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="array">The destination array</param>
+ /// <param name="arrayIndex">The zero-based index in array at which copying begins.</param>
+ /// <code>
+ /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes() {
+ /// { "state", "ON" },
+ /// { "dim", 10 }
+ /// };
+ /// KeyValuePair<string, object>[] dest = new KeyValuePair<string, object>[attributes.Count];
+ /// int index = 0;
+ /// attributes.CopyTo(dest, index);
+ /// Console.WriteLine("Dest conatins ({0}, {1})", dest[0].Key, dest[0].Value);
+ /// </code>
+ public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
+ {
+ _attributes.CopyTo(array, arrayIndex);
+ }
+
+ /// <summary>
+ /// Returns an enumerator that iterates through the collection.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <returns> An enumerator that can be used to iterate through the collection.</returns>
+ /// <code>
+ /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes() {
+ /// { "state", "ON" },
+ /// { "dim", 10 }
+ /// };
+ /// foreach (KeyValuePair<string, object> pair in attributes)
+ /// {
+ /// Console.WriteLine("key : {0}, value : {1}", pair.Key, pair.Value);
+ /// }
+ /// </code>
+ public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
+ {
+ return _attributes.GetEnumerator();
+ }
+
+ /// <summary>
+ /// Removes an attribute from collection
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="item">The attributes element to remove</param>
+ /// <returns>true if operation is success. Otherwise, false</returns>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
+ /// <code>
+ /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes() {
+ /// { "state", "ON" },
+ /// { "dim", 10 }
+ /// };
+ /// if (attributes.Remove(new KeyValuePair<string, object>("dim", 10)))
+ /// Console.WriteLine("Remove was successful");
+ /// </code>
+ public bool Remove(KeyValuePair<string, object> item)
+ {
+ return Remove(item.Key);
+ }
+
+ /// <summary>
+ /// Removes an attribute from collection using key
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="key">The attributes element to remove</param>
+ /// <returns>true if operation is successful, Otherwise, false</returns>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
+ /// <code>
+ /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes() {
+ /// { "state", "ON" },
+ /// { "dim", 10 }
+ /// };
+ /// if (attributes.Remove("state"))
+ /// Console.WriteLine("Remove was successful");
+ /// </code>
+ public bool Remove(string key)
+ {
+ int ret = Interop.IoTConnectivity.Common.Attributes.Remove(_resourceAttributesHandle, key);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove attributes");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+
+ bool isRemoved = _attributes.Remove(key);
+
+ return isRemoved;
+ }
+
+ /// <summary>
+ /// Gets the value associated with the specified key.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="key">The key whose value to get.</param>
+ /// <param name="value"> The value associated with the specified key</param>
+ /// <returns> true if the attributes collection contains an element with the specified key; otherwise, false.</returns>
+ /// <code>
+ /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes() {
+ /// { "state", "ON" }
+ /// };
+ /// object value;
+ /// var isPresent = attributes.TryGetValue("state", out value);
+ /// if (isPresent)
+ /// Console.WriteLine("value : {0}", value);
+ /// </code>
+ public bool TryGetValue(string key, out object value)
+ {
+ return _attributes.TryGetValue(key, out value);
+ }
+
+ /// <summary>
+ /// Returns an enumerator that iterates through the collection.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return _attributes.GetEnumerator();
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects
+ }
+
+ Interop.IoTConnectivity.Common.Attributes.Destroy(_resourceAttributesHandle);
+ _disposed = true;
+ }
+
+ private void SetAttributes(IntPtr attributesHandle)
+ {
+ Interop.IoTConnectivity.Common.Attributes.AttributesCallback cb = (IntPtr attributes, string key, IntPtr userData) =>
+ {
+ Interop.IoTConnectivity.Common.DataType dataType;
+ int ret = Interop.IoTConnectivity.Common.Attributes.GetType(attributes, key, out dataType);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get type");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+
+ switch ((Interop.IoTConnectivity.Common.DataType)dataType)
+ {
+ case Interop.IoTConnectivity.Common.DataType.Int:
+ {
+ int value;
+ ret = Interop.IoTConnectivity.Common.Attributes.GetInt(attributes, key, out value);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get attributes");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ _attributes.Add(key, value);
+ break;
+ }
+ case Interop.IoTConnectivity.Common.DataType.Bool:
+ {
+ bool value;
+ ret = Interop.IoTConnectivity.Common.Attributes.GetBool(attributes, key, out value);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get attributes");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ _attributes.Add(key, value);
+ break;
+ }
+ case Interop.IoTConnectivity.Common.DataType.Double:
+ {
+ double value;
+ ret = Interop.IoTConnectivity.Common.Attributes.GetDouble(attributes, key, out value);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get attributes");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ _attributes.Add(key, value);
+ break;
+ }
+ case Interop.IoTConnectivity.Common.DataType.String:
+ {
+ IntPtr value;
+ string Str;
+ ret = Interop.IoTConnectivity.Common.Attributes.GetStr(attributes, key, out value);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get attributes");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ Str = (value != IntPtr.Zero) ? Marshal.PtrToStringAnsi(value) : string.Empty;
+ _attributes.Add(key, Str);
+ break;
+ }
+ case Interop.IoTConnectivity.Common.DataType.ByteStr:
+ {
+ IntPtr byteStrPtr;
+ int byteStrSize;
+ ret = Interop.IoTConnectivity.Common.Attributes.GetByteStr(attributes, key, out byteStrPtr, out byteStrSize);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get attributes");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ byte[] byteStr = new byte[byteStrSize];
+ Marshal.Copy(byteStrPtr, byteStr, 0, byteStrSize);
+ _attributes.Add(key, byteStr);
+ break;
+ }
+ case Interop.IoTConnectivity.Common.DataType.Null:
+ {
+ _attributes.Add(key, null);
+ break;
+ }
+ case Interop.IoTConnectivity.Common.DataType.List:
+ {
+ IntPtr listHandle;
+ ret = Interop.IoTConnectivity.Common.Attributes.GetList(attributes, key, out listHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get attributes");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ _attributes.Add(key, List.GetList(listHandle));
+ break;
+ }
+ case Interop.IoTConnectivity.Common.DataType.Attributes:
+ {
+ IntPtr attribsHandle;
+ ret = Interop.IoTConnectivity.Common.Attributes.GetAttributes(attributes, key, out attribsHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get attributes");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ _attributes.Add(key, new Attributes(attribsHandle));
+ break;
+ }
+ default:
+ break;
+ }
+
+ return true;
+ };
+
+ int res = Interop.IoTConnectivity.Common.Attributes.Foreach(attributesHandle, cb, IntPtr.Zero);
+ if (res != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove attributes");
+ throw IoTConnectivityErrorFactory.GetException(res);
+ }
+ }
+ }
+
+ internal static class List
+ {
+ internal static IntPtr GetListHandle(object list)
+ {
+ IntPtr listHandle = IntPtr.Zero;
+ int ret;
+ int pos = 0;
+
+ if (list is IEnumerable<IEnumerable>)
+ {
+ ret = Interop.IoTConnectivity.Common.List.Create(Interop.IoTConnectivity.Common.DataType.List, out listHandle);
+ pos = 0;
+ foreach (IEnumerable val in (IEnumerable<IEnumerable>)list)
+ {
+ IntPtr childList = GetListHandle(val);
+ ret = Interop.IoTConnectivity.Common.List.AddList(listHandle, childList, pos++);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add attributes");
+ Interop.IoTConnectivity.Common.List.Destroy(childList);
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ }
+ else if (list is IEnumerable<int>)
+ {
+ ret = Interop.IoTConnectivity.Common.List.Create(Interop.IoTConnectivity.Common.DataType.Int, out listHandle);
+ pos = 0;
+ foreach (int val in (IEnumerable<int>)list)
+ {
+ ret = Interop.IoTConnectivity.Common.List.AddInt(listHandle, val, pos++);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add attributes");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ }
+ else if (list is IEnumerable<string>)
+ {
+ ret = Interop.IoTConnectivity.Common.List.Create(Interop.IoTConnectivity.Common.DataType.String, out listHandle);
+ pos = 0;
+ foreach (string val in (IEnumerable<string>)list)
+ {
+ ret = Interop.IoTConnectivity.Common.List.AddStr(listHandle, val, pos++);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add str");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ }
+ else if (list is IEnumerable<double>)
+ {
+ ret = Interop.IoTConnectivity.Common.List.Create(Interop.IoTConnectivity.Common.DataType.Double, out listHandle);
+ pos = 0;
+ foreach (double val in (IEnumerable<double>)list)
+ {
+ ret = Interop.IoTConnectivity.Common.List.AddDouble(listHandle, val, pos++);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add double");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ }
+ else if (list is IEnumerable<bool>)
+ {
+ ret = Interop.IoTConnectivity.Common.List.Create(Interop.IoTConnectivity.Common.DataType.Bool, out listHandle);
+ pos = 0;
+ foreach (bool val in (IEnumerable<bool>)list)
+ {
+ ret = Interop.IoTConnectivity.Common.List.AddBool(listHandle, val, pos++);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add bool");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ }
+ else if (list is IEnumerable<Attributes>)
+ {
+ ret = Interop.IoTConnectivity.Common.List.Create(Interop.IoTConnectivity.Common.DataType.Attributes, out listHandle);
+ pos = 0;
+ foreach (Attributes val in (IEnumerable<Attributes>)list)
+ {
+ ret = Interop.IoTConnectivity.Common.List.AddAttributes(listHandle, val._resourceAttributesHandle, pos++);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add attributes");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ }
+ else if (list is IEnumerable<byte[]>)
+ {
+ ret = Interop.IoTConnectivity.Common.List.Create(Interop.IoTConnectivity.Common.DataType.ByteStr, out listHandle);
+ pos = 0;
+ foreach (byte[] val in (IEnumerable<byte[]>)list)
+ {
+ ret = Interop.IoTConnectivity.Common.List.AddByteStr(listHandle, val, val.Length, pos++);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add byte[]");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ }
+ else
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to GetListHandle");
+ throw IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.InvalidParameter);
+ }
+ return listHandle;
+ }
+
+ internal static object GetList(IntPtr listHandle)
+ {
+ IList list = null;
+ int type;
+ int ret = Interop.IoTConnectivity.Common.List.GetType(listHandle, out type);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get type");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ switch ((Interop.IoTConnectivity.Common.DataType)type)
+ {
+ case Interop.IoTConnectivity.Common.DataType.Int:
+ {
+ list = new List<int>();
+ Interop.IoTConnectivity.Common.List.IntCallback cb = (int pos, int value, IntPtr userData) =>
+ {
+ list.Add(value);
+ return true;
+ };
+ ret = Interop.IoTConnectivity.Common.List.ForeachInt(listHandle, cb, IntPtr.Zero);
+ break;
+ }
+ case Interop.IoTConnectivity.Common.DataType.Bool:
+ {
+ list = new List<bool>();
+ Interop.IoTConnectivity.Common.List.BoolCallback cb = (int pos, bool value, IntPtr userData) =>
+ {
+ list.Add(value);
+ return true;
+ };
+ ret = Interop.IoTConnectivity.Common.List.ForeachBool(listHandle, cb, IntPtr.Zero);
+ break;
+ }
+ case Interop.IoTConnectivity.Common.DataType.Double:
+ {
+ list = new List<double>();
+ Interop.IoTConnectivity.Common.List.DoubleCallback cb = (int pos, double value, IntPtr userData) =>
+ {
+ list.Add(value);
+ return true;
+ };
+ ret = Interop.IoTConnectivity.Common.List.ForeachDouble(listHandle, cb, IntPtr.Zero);
+ break;
+ }
+ case Interop.IoTConnectivity.Common.DataType.String:
+ {
+ list = new List<string>();
+ Interop.IoTConnectivity.Common.List.StrCallback cb = (int pos, string value, IntPtr userData) =>
+ {
+ list.Add(value);
+ return true;
+ };
+ ret = Interop.IoTConnectivity.Common.List.ForeachStr(listHandle, cb, IntPtr.Zero);
+ break;
+ }
+ case Interop.IoTConnectivity.Common.DataType.Attributes:
+ {
+ list = new List<Attributes>();
+ Interop.IoTConnectivity.Common.List.AttribsCallback cb = (int pos, IntPtr value, IntPtr userData) =>
+ {
+ list.Add(new Attributes(value));
+ return true;
+ };
+ ret = Interop.IoTConnectivity.Common.List.ForeachAttributes(listHandle, cb, IntPtr.Zero);
+ break;
+ }
+ case Interop.IoTConnectivity.Common.DataType.ByteStr:
+ {
+ list = new List<byte[]>();
+ Interop.IoTConnectivity.Common.List.ByteStrCallback cb = (int pos, byte[] value, int len, IntPtr userData) =>
+ {
+ list.Add(value);
+ return true;
+ };
+ ret = Interop.IoTConnectivity.Common.List.ForeachByteStr(listHandle, cb, IntPtr.Zero);
+ break;
+ }
+ case Interop.IoTConnectivity.Common.DataType.List:
+ {
+ list = new List<List<object>>();
+ Interop.IoTConnectivity.Common.List.ListCallback cb = (int pos, IntPtr value, IntPtr userData) =>
+ {
+ object childList = GetList(value);
+ if (childList != null)
+ list.Add(childList);
+ return true;
+ };
+ ret = Interop.IoTConnectivity.Common.List.ForeachList(listHandle, cb, IntPtr.Zero);
+ break;
+ }
+ default:
+ break;
+ }
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get attributes");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ return list;
+ }
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/CacheUpdatedEventArgs.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/CacheUpdatedEventArgs.cs
new file mode 100755
index 0000000..45292f8
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/CacheUpdatedEventArgs.cs
@@ -0,0 +1,37 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// This class represents event arguments of the CacheUpdated event.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class CacheUpdatedEventArgs : EventArgs
+ {
+ internal CacheUpdatedEventArgs() { }
+
+ /// <summary>
+ /// Indicates the updated representation of the resource
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The updated representation of the resource.</value>
+ public Representation Representation { get; internal set; }
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/DeviceInformationFoundEventArgs.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/DeviceInformationFoundEventArgs.cs
new file mode 100755
index 0000000..3a1b30d
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/DeviceInformationFoundEventArgs.cs
@@ -0,0 +1,70 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// This class represents event arguments of the DeviceInformationFound event.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class DeviceInformationFoundEventArgs
+ {
+ internal DeviceInformationFoundEventArgs() { }
+
+ /// <summary>
+ /// The request id
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The request id.</value>
+ public int RequestId { get; internal set; }
+
+ /// <summary>
+ /// Indicates to continuously receive the event for finding device information.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Continuously receive the event for finding device information.</value>
+ public bool EventContinue { get; set; }
+
+ /// <summary>
+ /// Indicates human friendly name for device
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Human friendly name for device.</value>
+ public string Name { get; internal set; }
+
+ /// <summary>
+ /// Indicates spec version of the core specification
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Spec version of the core specification.</value>
+ public string SpecVersion { get; internal set; }
+
+ /// <summary>
+ /// Indicates unique identifier for OIC device
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Unique identifier for OIC device.</value>
+ public string DeviceId { get; internal set; }
+
+ /// <summary>
+ /// Indicates version of the specs this device data model is implemented to
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Version of the specs this device data model is implemented to.</value>
+ public string DataModelVersion { get; internal set; }
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/FindingError.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/FindingError.cs
new file mode 100755
index 0000000..4a77587
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/FindingError.cs
@@ -0,0 +1,74 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// Enumeration for resource found errors
+ /// </summary>
+ internal enum FindingError
+ {
+ /// <summary>
+ /// I/O error
+ /// </summary>
+ Io = 1,
+ /// <summary>
+ /// Out of memory
+ /// </summary>
+ OutOfMemory,
+ /// <summary>
+ /// Permission denied
+ /// </summary>
+ PermissionDenied,
+ /// <summary>
+ /// Not supported
+ /// </summary>
+ NotSupported,
+ /// <summary>
+ /// Invalid parameter
+ /// </summary>
+ InvalidParameter,
+ /// <summary>
+ /// No data available
+ /// </summary>
+ NoData,
+ /// <summary>
+ /// Time out
+ /// </summary>
+ TimeOut,
+ /// <summary>
+ /// IoTivity errors
+ /// </summary>
+ Iotivity,
+ /// <summary>
+ /// Representation errors
+ /// </summary>
+ Representation,
+ /// <summary>
+ /// Invalid type
+ /// </summary>
+ InvalidType,
+ /// <summary>
+ /// Already
+ /// </summary>
+ Already,
+ /// <summary>
+ /// System errors
+ /// </summary>
+ System
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/FindingErrorOccurredEventArgs.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/FindingErrorOccurredEventArgs.cs
new file mode 100755
index 0000000..6179747
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/FindingErrorOccurredEventArgs.cs
@@ -0,0 +1,44 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// This class represents event arguments of the FindingErrorOccurred event.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class FindingErrorOccurredEventArgs : EventArgs
+ {
+ internal FindingErrorOccurredEventArgs() { }
+
+ /// <summary>
+ /// The request id of the operation which caused this error
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The request id of the operation which caused this error.</value>
+ public int RequestId { get; internal set; }
+
+ /// <summary>
+ /// Contains error details.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Error details.</value>
+ public Exception Error { get; internal set; }
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/IoTConnectivityClientManager.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/IoTConnectivityClientManager.cs
new file mode 100755
index 0000000..2fc8c10
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/IoTConnectivityClientManager.cs
@@ -0,0 +1,966 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// IoT connectivity client manager consists of client side APIs.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public static class IoTConnectivityClientManager
+ {
+ /// <summary>
+ /// The IP Address for multicast
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public const string MulticastAddress = null;
+
+ private static int s_presenceListenerId = 1;
+ private static Dictionary<IntPtr, Interop.IoTConnectivity.Client.Presence.PresenceCallback> s_presenceCallbacksMap = new Dictionary<IntPtr, Interop.IoTConnectivity.Client.Presence.PresenceCallback>();
+ private static Dictionary<IntPtr, IntPtr> s_presenceHandlesMap = new Dictionary<IntPtr, IntPtr>();
+
+ private static int s_requestId = 1;
+ private static Dictionary<IntPtr, Interop.IoTConnectivity.Client.ResourceFinder.FoundResourceCallback> s_resourceFoundCallbacksMap = new Dictionary<IntPtr, Interop.IoTConnectivity.Client.ResourceFinder.FoundResourceCallback>();
+ private static Dictionary<IntPtr, Interop.IoTConnectivity.Client.DeviceInformation.DeviceInformationCallback> s_deviceInformationCallbacksMap = new Dictionary<IntPtr, Interop.IoTConnectivity.Client.DeviceInformation.DeviceInformationCallback>();
+ private static Dictionary<IntPtr, Interop.IoTConnectivity.Client.PlatformInformation.PlatformInformationCallback> s_platformInformationCallbacksMap = new Dictionary<IntPtr, Interop.IoTConnectivity.Client.PlatformInformation.PlatformInformationCallback>();
+
+ /// <summary>
+ /// PresenceReceived event. This event is occurred when server starts sending presence of a resource.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public static event EventHandler<PresenceReceivedEventArgs> PresenceReceived;
+
+ /// <summary>
+ /// ResourceFound event. This event is occurred when a resource is found from the remote server
+ /// after sending request using API StartFindingResource().
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public static event EventHandler<ResourceFoundEventArgs> ResourceFound;
+
+ /// <summary>
+ /// PlatformInformationFound event. This event is occurred when platform information is found
+ /// after sending request using API StartFindingPlatformInformation().
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public static event EventHandler<PlatformInformationFoundEventArgs> PlatformInformationFound;
+
+ /// <summary>
+ /// DeviceInformationFound event. This event is occurred when device information is found
+ /// after sending request using API StartFindingDeviceInformation().
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public static event EventHandler<DeviceInformationFoundEventArgs> DeviceInformationFound;
+
+ /// <summary>
+ /// FindingError event. This event is occurred when an error is found.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public static event EventHandler<FindingErrorOccurredEventArgs> FindingErrorOccurred;
+
+ /// <summary>
+ /// Timeout in seconds
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>
+ /// Value to be set must be in range from 1 to 3600. Default timeout interval value is 30.\n
+ /// Sets/gets the timeout of StartFindingResource(), StartFindingDeviceInformation(), StartFindingPlatformInformation(),
+ /// RemoteResource.GetAsync(), RemoteResource.PutAsync(), RemoteResource.PostAsync() and RemoteResource.DeleteAsync() APIs.\n
+ /// Setter can throw exception.
+ /// </value>
+ /// <pre>
+ /// Initialize() should be called to initialize
+ /// </pre>
+ /// <code>
+ /// IoTConnectivityClientManager.Initialize();
+ /// IoTConnectivityClientManager.TimeOut = 120;
+ /// </code>
+ public static int TimeOut
+ {
+ get
+ {
+ int timeout;
+ int ret = Interop.IoTConnectivity.Client.IoTCon.GetTimeout(out timeout);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Warn(IoTConnectivityErrorFactory.LogTag, "Failed to get timeout");
+ return 0;
+ }
+ return timeout;
+ }
+ set
+ {
+ int ret = Interop.IoTConnectivity.Client.IoTCon.SetTimeout(value);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set timeout");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Polling interval of IoTConnectivity
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>
+ /// Sets/Gets the polling inerval(milliseconds) of IoTCon. Default value is 100 milliseconds.
+ /// Value to be set must be in range from 1 to 999. The closer to 0, the faster it operates.
+ /// Setter is invoked immediately for changing the interval.
+ /// If you want the faster operation, we recommend you set 10 milliseconds for polling interval.
+ /// Setter can throw exception.
+ /// </value>
+ /// <pre>
+ /// Initialize() should be called to initialize
+ /// </pre>
+ /// <code>
+ /// IoTConnectivityClientManager.Initialize();
+ /// IoTConnectivityClientManager.PollingInterval = 100;
+ /// </code>
+ public static int PollingInterval
+ {
+ get
+ {
+ int interval;
+ int ret = Interop.IoTConnectivity.Client.IoTCon.GetPollingInterval(out interval);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Warn(IoTConnectivityErrorFactory.LogTag, "Failed to get polling interval");
+ return 0;
+ }
+ return interval;
+ }
+ set
+ {
+ int ret = Interop.IoTConnectivity.Client.IoTCon.SetPollingInterval(value);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set polling interval");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Initializes IoTCon.
+ /// Call this function to start IoTCon.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>
+ /// @a filePath point to a file for handling secure virtual resources.
+ /// The file that is CBOR(Concise Binary Object Representation)-format must already exist
+ /// in @a filePath. We recommend to use application-local file for @a filePath.
+ /// </remarks>
+ /// <privilege>
+ /// http://tizen.org/privilege/network.get \n
+ /// http://tizen.org/privilege/internet
+ /// </privilege>
+ /// <privlevel>public</privlevel>
+ /// <param name="filePath">The file path to point to storage for handling secure virtual resources.</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <post>
+ /// You must call Deinitialize() if IoTCon API is no longer needed.
+ /// </post>
+ /// <seealso cref="Deinitialize()"/>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
+ /// <code>
+ /// string filePath = "../../res/iotcon-test-svr-db-client.dat";
+ /// IoTConnectivityClientManager.Initialize(filePath);
+ /// </code>
+ public static void Initialize(string filePath)
+ {
+ int ret = Interop.IoTConnectivity.Client.IoTCon.Initialize(filePath);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to initialize");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Deinitializes IoTCon.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>
+ /// This API must be called if IoTCon API is no longer needed.
+ /// </remarks>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <pre>
+ /// Initialize() should be called to initialize.
+ /// </pre>
+ /// <seealso cref="Initialize()"/>
+ /// <seealso cref="SecureInitialize()"/>
+ /// <code>
+ /// IoTConnectivityClientManager.Deinitialize();
+ /// </code>
+ public static void Deinitialize()
+ {
+ s_presenceListenerId = 1;
+ s_presenceCallbacksMap.Clear();
+ s_presenceHandlesMap.Clear();
+
+ s_requestId = 1;
+ s_resourceFoundCallbacksMap.Clear();
+ s_deviceInformationCallbacksMap.Clear();
+ s_platformInformationCallbacksMap.Clear();
+
+ PresenceReceived = delegate{};
+ ResourceFound = delegate{};
+ PlatformInformationFound = delegate{};
+ DeviceInformationFound = delegate{};
+ FindingErrorOccurred = delegate{};
+
+ Interop.IoTConnectivity.Client.IoTCon.Deinitialize();
+ }
+
+ /// <summary>
+ /// Invokes a next message from a queue for receiving messages from others, immediately.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>
+ /// This API invokes a next message from a queue for receiving messages from others, immediately.
+ /// After calling the API, it continues the polling with existing interval.
+ /// </remarks>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <pre>
+ /// Initialize() should be called to initialize.
+ /// </pre>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <code>
+ /// IoTConnectivityClientManager.InvokePolling();
+ /// </code>
+ public static void InvokePolling()
+ {
+ int ret = Interop.IoTConnectivity.Client.IoTCon.InvokePolling();
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to invoke polling");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Starts receiving presence events
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>
+ /// Sends request to receive presence to an interested server's resource with resourceType.
+ /// If succeeded, <see cref="PresenceReceived"/> event handler will be triggered when the server sends presence.
+ /// A server sends presence events when adds / removes / alters a resource or start / stop presence.\n
+ /// @a hostAddress could be <see cref="MulticastAddress"/> for IPv4 multicast.
+ /// The length of @ resourceType should be less than or equal to 61. The @ resourceType must start with a lowercase alphabetic character, followed by a sequence
+ /// of lowercase alphabetic, numeric, ".", or "-" characters, and contains no white space.
+ /// </remarks>
+ /// <privilege>
+ /// http://tizen.org/privilege/internet
+ /// </privilege>
+ /// <privlevel>public</privlevel>
+ /// <param name="hostAddress">The address or addressable name of the server</param>
+ /// <param name="resourceType">A resource type that a client is interested in</param>
+ /// <returns>PresenceId - An identifier for this request</returns>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <pre>Initialize() should be called to initialize.</pre>
+ /// <post>
+ /// When the resource receive presence, <see cref="PresenceReceived"/> event handler will be invoked.\n
+ /// You must destroy presence by calling StopReceivingPresence() if presence event is no longer needed.
+ /// </post>
+ /// <seealso cref="IoTConnectivityServerManager.StartSendingPresence()"/>
+ /// <seealso cref="IoTConnectivityServerManager.StopSendingPresence()"/>
+ /// <seealso cref="StopReceivingPresence()"/>
+ /// <seealso cref="PresenceReceived"/>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory</exception>
+ /// <code>
+ /// EventHandler<PresenceReceivedEventArgs> handler = (sender, e) => {
+ /// Console.Log("PresenceReceived, presence id :" + e.PresenceId);
+ /// }
+ /// EventHandler<FindingErrorOccurredEventArgs> errorHandler = (sender, e) => {
+ /// Console.Log("Found error :" + e.Error.Message);
+ /// }
+ /// IoTConnectivityClientManager.PresenceReceived += handler;
+ /// IoTConnectivityClientManager.FindingErrorOccurred += errorHandler;
+ /// // Do not forget to remove these event handlers when they are not required any more.
+ /// int id = IoTConnectivityClientManager.StartReceivingPresence(IoTConnectivityClientManager.MulticastAddress, "oic.iot.door");
+ /// </code>
+ public static int StartReceivingPresence(string hostAddress, string resourceType)
+ {
+ Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType connectivityType = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ip;
+
+ if (resourceType != null && !ResourceTypes.IsValid(resourceType))
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Invalid type");
+ throw new ArgumentException("Invalid type");
+ }
+
+ IntPtr id = IntPtr.Zero;
+ lock (s_presenceCallbacksMap)
+ {
+ id = (IntPtr)s_presenceListenerId++;
+ }
+ s_presenceCallbacksMap[id] = (IntPtr presence, int result, IntPtr presenceResponseHandle, IntPtr userData) =>
+ {
+ int presenceId = (int)userData;
+ if (result == (int)IoTConnectivityError.None)
+ {
+ if (presenceResponseHandle != IntPtr.Zero)
+ {
+ PresenceReceivedEventArgs e = GetPresenceReceivedEventArgs(presenceId, presenceResponseHandle);
+ if (e == null)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Can't get PresenceReceivedEventArgs");
+ return;
+ }
+ PresenceReceived?.Invoke(null, e);
+ }
+ else
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Handle is null");
+ return;
+ }
+ }
+ else
+ {
+ FindingErrorOccurredEventArgs e = GetFindingErrorOccurredEventArgs(presenceId, result);
+ FindingErrorOccurred?.Invoke(null, e);
+ }
+ };
+
+ IntPtr presenceHandle;
+ int errorCode = Interop.IoTConnectivity.Client.Presence.AddPresenceCb(hostAddress, (int)connectivityType, resourceType, s_presenceCallbacksMap[id], id, out presenceHandle);
+ if (errorCode != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to register presence event handler");
+ lock (s_presenceCallbacksMap)
+ {
+ s_presenceCallbacksMap.Remove(id);
+ }
+ throw IoTConnectivityErrorFactory.GetException(errorCode);
+ }
+
+ lock (s_presenceHandlesMap)
+ {
+ s_presenceHandlesMap[id] = presenceHandle;
+ }
+ return (int)id;
+ }
+
+ /// <summary>
+ /// Stops receiving presence events
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>
+ /// Sends request to not to receive server's presence any more.
+ /// </remarks>
+ /// <privilege>
+ /// http://tizen.org/privilege/internet
+ /// </privilege>
+ /// <privlevel>public</privlevel>
+ /// <param name="presenceId">The start presence request identifier</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <pre>
+ /// Initialize() should be called to initialize.
+ /// </pre>
+ /// <seealso cref="IoTConnectivityServerManager.StartSendingPresence()"/>
+ /// <seealso cref="IoTConnectivityServerManager.StopSendingPresence()"/>
+ /// <seealso cref="StartReceivingPresence()"/>
+ /// <seealso cref="PresenceReceived"/>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory</exception>
+ /// <code>
+ /// EventHandler<PresenceReceivedEventArgs> handler = (sender, e) => {
+ /// Console.Log("PresenceReceived, presence id :" + e.PresenceId);
+ /// }
+ /// EventHandler<FindingErrorOccurredEventArgs> errorHandler = (sender, e) => {
+ /// Console.Log("Found error :" + e.Error.Message);
+ /// }
+ /// IoTConnectivityClientManager.PresenceReceived += handler;
+ /// IoTConnectivityClientManager.FindingErrorOccurred += errorHandler;
+ /// int id = IoTConnectivityClientManager.StartReceivingPresence(IoTConnectivityClientManager.MulticastAddress, "oic.iot.door");
+ /// await Task.Delay(5000); // Do other things here
+ /// // Call StopReceivingPresence() when receiving presence is not required any more
+ /// IoTConnectivityClientManager.PresenceReceived -= handler;
+ /// IoTConnectivityClientManager.FindingErrorOccurred -= errorHandler;
+ /// IoTConnectivityClientManager.StopReceivingPresence(id);
+ /// </code>
+ public static void StopReceivingPresence(int presenceId)
+ {
+ if (!s_presenceHandlesMap.ContainsKey((IntPtr)presenceId))
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "this presenceId does not exist");
+ throw new ArgumentException("this presenceId does not exist");
+ }
+
+ if (s_presenceHandlesMap.ContainsKey((IntPtr)presenceId))
+ {
+ IntPtr presenceHandle = s_presenceHandlesMap[(IntPtr)presenceId];
+ int ret = Interop.IoTConnectivity.Client.Presence.RemovePresenceCb(presenceHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to deregister presence event handler");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+
+ lock (s_presenceHandlesMap)
+ {
+ s_presenceHandlesMap.Remove((IntPtr)presenceId);
+ }
+ }
+
+ if (s_presenceCallbacksMap.ContainsKey((IntPtr)presenceId))
+ {
+ lock (s_presenceCallbacksMap)
+ {
+ s_presenceCallbacksMap.Remove((IntPtr)presenceId);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Starts finding resources.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>
+ /// Sends request to find a resource of @a hostAddress server with @a resourceType.
+ /// If succeeded, <see cref="ResourceFound"/> event handler will be triggered with information of the resource.\n
+ /// @a hostAddress could be <see cref="MulticastAddress"/> for IPv4 multicast.
+ /// The length of @a resourceType should be less than or equal to 61. The @ resourceType must start with a lowercase alphabetic character, followed by a sequence
+ /// of lowercase alphabetic, numeric, ".", or "-" characters, and contains no white space.
+ /// </remarks>
+ /// <privilege>
+ /// http://tizen.org/privilege/internet
+ /// </privilege>
+ /// <privlevel>public</privlevel>
+ /// <param name="hostAddress">The address or addressable name of the server. The address includes a protocol like coaps://</param>
+ /// <param name="query">The query specified as a filter for founding resources</param>
+ /// <returns>RequestId - An identifier for this request</returns>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <pre>Initialize() should be called to initialize.</pre>
+ /// <post>
+ /// When the resource is found, <see cref="ResourceFound"/> event handler will be invoked.
+ /// </post>
+ /// <seealso cref="ResourceFound"/>
+ /// <seealso cref="ResourceFoundEventArgs"/>
+ /// <seealso cref="TimeOut"/>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory</exception>
+ /// <code>
+ /// EventHandler<ResourceFoundEventArgs> handler = (sender, e) => {
+ /// Console.Log("Found resource at host address :" + e.Resource.HostAddress + ", uri :" + e.Resource.UriPath);
+ /// }
+ /// EventHandler<FindingErrorOccurredEventArgs> errorHandler = (sender, e) => {
+ /// Console.Log("Found error :" + e.Error.Message);
+ /// }
+ /// IoTConnectivityClientManager.ResourceFound += handler;
+ /// IoTConnectivityClientManager.FindingErrorOccurred += errorHandler;
+ /// ResourceQuery query = new ResourceQuery();
+ /// query.Type = "oic.iot.door";
+ /// // Do not forget to remove these event handlers when they are not required any more.
+ /// int id = IoTConnectivityClientManager.StartFindingResource(null, query);
+ /// </code>
+ public static int StartFindingResource(string hostAddress, ResourceQuery query = null)
+ {
+ Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType connectivityType = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ip;
+
+ IntPtr id = IntPtr.Zero;
+ lock (s_resourceFoundCallbacksMap)
+ {
+ id = (IntPtr)s_requestId++;
+ }
+ s_resourceFoundCallbacksMap[id] = (IntPtr remoteResourceHandle, int result, IntPtr userData) =>
+ {
+ if (ResourceFound == null)
+ return false;
+
+ int requestId = (int)userData;
+ if (result == (int)IoTConnectivityError.None)
+ {
+ if (remoteResourceHandle != IntPtr.Zero)
+ {
+ RemoteResource resource = null;
+ try
+ {
+ resource = new RemoteResource(remoteResourceHandle);
+ }
+ catch (Exception exp)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Can't clone RemoteResource's handle: " + exp.Message);
+ return true;
+ }
+ ResourceFoundEventArgs e = new ResourceFoundEventArgs()
+ {
+ RequestId = requestId,
+ Resource = resource
+ };
+ ResourceFound?.Invoke(null, e);
+ Log.Info(IoTConnectivityErrorFactory.LogTag, "e.EventContinue : " + e.EventContinue);
+ return e.EventContinue;
+ }
+ else
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Handle is null");
+ }
+ }
+ else
+ {
+ FindingErrorOccurredEventArgs e = GetFindingErrorOccurredEventArgs(requestId, result);
+ FindingErrorOccurred?.Invoke(null, e);
+
+ lock (s_resourceFoundCallbacksMap)
+ {
+ s_resourceFoundCallbacksMap.Remove(id);
+ }
+ }
+ return true;
+ };
+ IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
+ int errorCode = Interop.IoTConnectivity.Client.ResourceFinder.AddResourceFoundCb(hostAddress, (int)connectivityType, queryHandle, s_resourceFoundCallbacksMap[id], id);
+ if (errorCode != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to register resource found event handler");
+ lock (s_resourceFoundCallbacksMap)
+ {
+ s_resourceFoundCallbacksMap.Remove(id);
+ }
+ throw IoTConnectivityErrorFactory.GetException(errorCode);
+ }
+ return (int)id;
+ }
+
+ /// <summary>
+ /// Starts finding the device information of remote server.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>
+ /// Requests server for device information.
+ /// If succeeded, <see cref="DeviceInformationFound"/> event handler will be triggered with information of the device.\n
+ /// @a hostAddress could be <see cref="MulticastAddress"/> for IPv4 multicast.
+ /// </remarks>
+ /// <privilege>
+ /// http://tizen.org/privilege/internet
+ /// </privilege>
+ /// <privlevel>public</privlevel>
+ /// <param name="hostAddress">The host address of remote server</param>
+ /// <param name="query">The query specified as a filter for founding resources</param>
+ /// <returns>RequestId - An identifier for this request</returns>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <pre>Initialize() should be called to initialize.</pre>
+ /// <post>
+ /// <see cref="DeviceInformationFound" /> event handler will be invoked.
+ /// </post>
+ /// <seealso cref="IoTConnectivityServerManager.SetDeviceName()"/>
+ /// <seealso cref="DeviceInformationFound"/>
+ /// <seealso cref="DeviceInformationFoundEventArgs"/>
+ /// <seealso cref="TimeOut"/>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory</exception>
+ /// <code>
+ /// EventHandler<DeviceInformationFoundEventArgs> handler = (sender, e) => {
+ /// Console.Log("Device information found, id : " + e.RequestId + ", name : " + e.Name);
+ /// }
+ /// EventHandler<FindingErrorOccurredEventArgs> errorHandler = (sender, e) => {
+ /// Console.Log("Found error :" + e.Error.Message);
+ /// }
+ /// IoTConnectivityClientManager.DeviceInformationFound += handler;
+ /// IoTConnectivityClientManager.FindingErrorOccurred += errorHandler;
+ /// // Do not forget to remove these event handlers when they are not required any more.
+ /// int id = IoTConnectivityClientManager.StartFindingDeviceInformation(IoTConnectivityClientManager.MulticastAddress);
+ /// </code>
+ public static int StartFindingDeviceInformation(string hostAddress, ResourceQuery query = null)
+ {
+ Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType connectivityType = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ip;
+
+ IntPtr id = IntPtr.Zero;
+ lock (s_deviceInformationCallbacksMap)
+ {
+ id = (IntPtr)s_requestId++;
+ }
+ s_deviceInformationCallbacksMap[id] = (IntPtr deviceInfoHandle, int result, IntPtr userData) =>
+ {
+ if (DeviceInformationFound == null)
+ return false;
+
+ int requestId = (int)userData;
+ if (result == (int)IoTConnectivityError.None)
+ {
+ if (deviceInfoHandle != IntPtr.Zero)
+ {
+ DeviceInformationFoundEventArgs e = GetDeviceInformationFoundEventArgs(requestId, deviceInfoHandle);
+ if (e == null)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Can't get DeviceInformationFoundEventArgs");
+ return true;
+ }
+ DeviceInformationFound?.Invoke(null, e);
+ Log.Info(IoTConnectivityErrorFactory.LogTag, "e.EventContinue : " + e.EventContinue);
+ return e.EventContinue;
+ }
+ else
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Handle is null");
+ }
+ }
+ else
+ {
+ FindingErrorOccurredEventArgs e = GetFindingErrorOccurredEventArgs(requestId, result);
+ FindingErrorOccurred?.Invoke(null, e);
+
+ lock (s_deviceInformationCallbacksMap)
+ {
+ s_deviceInformationCallbacksMap.Remove(id);
+ }
+ }
+ return true;
+ };
+
+ IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
+ int errorCode = Interop.IoTConnectivity.Client.DeviceInformation.Find(hostAddress, (int)connectivityType, queryHandle, s_deviceInformationCallbacksMap[id], id);
+ if (errorCode != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get device information");
+ lock (s_deviceInformationCallbacksMap)
+ {
+ s_deviceInformationCallbacksMap.Remove(id);
+ }
+ throw IoTConnectivityErrorFactory.GetException(errorCode);
+ }
+
+ return (int)id;
+ }
+
+ /// <summary>
+ /// Starts finding the platform information of remote server.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>
+ /// Requests server for platform information.
+ /// If succeeded, <see cref="PlatformInformationFound" /> event handler will be triggered with information of the platform.\n
+ /// @a hostAddress could be <see cref="MulticastAddress"/> for IPv4 multicast.
+ /// </remarks>
+ /// <privilege>
+ /// http://tizen.org/privilege/internet
+ /// </privilege>
+ /// <privlevel>public</privlevel>
+ /// <param name="hostAddress">The host address of remote server</param>
+ /// <param name="query">The query specified as a filter for founding resources</param>
+ /// <returns>RequestId - An identifier for this request</returns>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <pre>Initialize() should be called to initialize.</pre>
+ /// <post>
+ /// <see cref="PlatformInformationFound" /> event handler will be invoked.
+ /// </post>
+ /// <seealso cref="PlatformInformationFound"/>
+ /// <seealso cref="PlatformInformationFoundEventArgs"/>
+ /// <seealso cref="TimeOut"/>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory</exception>
+ /// <code>
+ /// EventHandler<PlatformInformationFoundEventArgs> handler = (sender, e) => {
+ /// Console.Log("PlatformInformationFound :" + e.RequestId);
+ /// }
+ /// EventHandler<FindingErrorOccurredEventArgs> errorHandler = (sender, e) => {
+ /// Console.Log("Found error :" + e.Error.Message);
+ /// }
+ /// IoTConnectivityClientManager.PlatformInformationFound += handler;
+ /// IoTConnectivityClientManager.FindingErrorOccurred += errorHandler;
+ /// // Do not forget to remove these event handlers when they are not required any more.
+ /// int id = IoTConnectivityClientManager.StartFindingPlatformInformation(IoTConnectivityClientManager.MulticastAddress);
+ /// </code>
+ public static int StartFindingPlatformInformation(string hostAddress, ResourceQuery query = null)
+ {
+ Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType connectivityType = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ip;
+
+ IntPtr id = IntPtr.Zero;
+ lock (s_platformInformationCallbacksMap)
+ {
+ id = (IntPtr)s_requestId++;
+ }
+ s_platformInformationCallbacksMap[id] = (IntPtr platformInfoHandle, int result, IntPtr userData) =>
+ {
+ if (PlatformInformationFound == null)
+ return false;
+
+ int requestId = (int)userData;
+ if (result == (int)IoTConnectivityError.None)
+ {
+ if (platformInfoHandle != IntPtr.Zero)
+ {
+ PlatformInformationFoundEventArgs e = GetPlatformInformationFoundEventArgs(requestId, platformInfoHandle);
+ if (e == null)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Can't get PlatformInformationFoundEventArgs");
+ return true;
+ }
+ PlatformInformationFound?.Invoke(null, e);
+ Log.Info(IoTConnectivityErrorFactory.LogTag, "e.EventContinue : " + e.EventContinue);
+ return e.EventContinue;
+ }
+ else
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Handle is null");
+ }
+ }
+ else
+ {
+ FindingErrorOccurredEventArgs e = GetFindingErrorOccurredEventArgs(requestId, result);
+ FindingErrorOccurred?.Invoke(null, e);
+
+ lock (s_platformInformationCallbacksMap)
+ {
+ s_platformInformationCallbacksMap.Remove(id);
+ }
+ }
+ return true;
+ };
+
+ IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
+ int errorCode = Interop.IoTConnectivity.Client.PlatformInformation.Find(hostAddress, (int)connectivityType, queryHandle, s_platformInformationCallbacksMap[id], id);
+ if (errorCode != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get platform information");
+ lock (s_platformInformationCallbacksMap)
+ {
+ s_platformInformationCallbacksMap.Remove(id);
+ }
+ throw IoTConnectivityErrorFactory.GetException(errorCode);
+ }
+
+ return (int)id;
+ }
+
+ // Private methods
+ private static PresenceReceivedEventArgs GetPresenceReceivedEventArgs(int presenceId, IntPtr presenceResponseHandle)
+ {
+ int trigger;
+ IntPtr host, type;
+
+ int ret = Interop.IoTConnectivity.Client.PresenceResponse.GetHostAddress(presenceResponseHandle, out host);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get host address");
+ return null;
+ }
+
+ ret = Interop.IoTConnectivity.Client.PresenceResponse.GetResourceType(presenceResponseHandle, out type);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get resource type");
+ return null;
+ }
+
+ ret = Interop.IoTConnectivity.Client.PresenceResponse.GetTrigger(presenceResponseHandle, out trigger);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get event type");
+ return null;
+ }
+
+ PresenceReceivedEventArgs e = new PresenceReceivedEventArgs()
+ {
+ PresenceId = presenceId,
+ HostAddress = (host != IntPtr.Zero) ? Marshal.PtrToStringAnsi(host) : string.Empty,
+ Type = (type != IntPtr.Zero) ? Marshal.PtrToStringAnsi(type) : string.Empty,
+ EventType = (PresenceEventType)trigger
+ };
+
+ return e;
+ }
+
+ private static DeviceInformationFoundEventArgs GetDeviceInformationFoundEventArgs(int requestId, IntPtr deviceInfoHandle)
+ {
+ IntPtr name, specVersion, deviceId, dataModelVersion;
+
+ int ret = Interop.IoTConnectivity.Client.DeviceInformation.GetProperty(deviceInfoHandle, (int)Interop.IoTConnectivity.Client.DeviceInformation.Property.Name, out name);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get name");
+ return null;
+ }
+
+ ret = Interop.IoTConnectivity.Client.DeviceInformation.GetProperty(deviceInfoHandle, (int)Interop.IoTConnectivity.Client.DeviceInformation.Property.SpecVersion, out specVersion);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get spec version");
+ return null;
+ }
+
+ ret = Interop.IoTConnectivity.Client.DeviceInformation.GetProperty(deviceInfoHandle, (int)Interop.IoTConnectivity.Client.DeviceInformation.Property.Id, out deviceId);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get device id");
+ return null;
+ }
+
+ ret = Interop.IoTConnectivity.Client.DeviceInformation.GetProperty(deviceInfoHandle, (int)Interop.IoTConnectivity.Client.DeviceInformation.Property.DataModelVersion, out dataModelVersion);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get data model version");
+ return null;
+ }
+
+ DeviceInformationFoundEventArgs e = new DeviceInformationFoundEventArgs()
+ {
+ RequestId = requestId,
+ EventContinue = true,
+ Name = (name != IntPtr.Zero) ? Marshal.PtrToStringAnsi(name) : string.Empty,
+ SpecVersion = (specVersion != IntPtr.Zero) ? Marshal.PtrToStringAnsi(specVersion) : string.Empty,
+ DeviceId = (deviceId != IntPtr.Zero) ? Marshal.PtrToStringAnsi(deviceId) : string.Empty,
+ DataModelVersion = (dataModelVersion != IntPtr.Zero) ? Marshal.PtrToStringAnsi(dataModelVersion) : string.Empty
+ };
+
+ return e;
+ }
+
+ private static PlatformInformationFoundEventArgs GetPlatformInformationFoundEventArgs(int requestId, IntPtr platformInfoHandle)
+ {
+ IntPtr platformId, manufacturerName, manufacturerUrl, modelNumber, dateOfManufacture, platformVersion, osVersion, hardwareVersion, firmwareVersion, supportUrl, systemTime;
+
+ int ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.Id, out platformId);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get platform id");
+ return null;
+ }
+
+ ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.MfgName, out manufacturerName);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get manufacturer name");
+ return null;
+ }
+
+ ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.MfgUrl, out manufacturerUrl);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get manufacturer url");
+ return null;
+ }
+
+ ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.ModelNumber, out modelNumber);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get model number");
+ return null;
+ }
+
+ ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.DateOfMfg, out dateOfManufacture);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get date of manufacture");
+ return null;
+ }
+
+ ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.PlatformVer, out platformVersion);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get platform version");
+ return null;
+ }
+
+ ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.OsVer, out osVersion);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to os version");
+ return null;
+ }
+
+ ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.HardwareVer, out hardwareVersion);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to hardware version");
+ return null;
+ }
+
+ ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.FirmwareVer, out firmwareVersion);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get firmware version");
+ return null;
+ }
+
+ ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.SupportUrl, out supportUrl);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get support url");
+ return null;
+ }
+
+ ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.SystemTime, out systemTime);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get system time");
+ return null;
+ }
+
+ PlatformInformationFoundEventArgs e = new PlatformInformationFoundEventArgs()
+ {
+ RequestId = requestId,
+ PlatformId = (platformId != IntPtr.Zero) ? Marshal.PtrToStringAnsi(platformId) : string.Empty,
+ ManufacturerName = (manufacturerName != IntPtr.Zero) ? Marshal.PtrToStringAnsi(manufacturerName) : string.Empty,
+ ManufacturerURL = (manufacturerUrl != IntPtr.Zero) ? Marshal.PtrToStringAnsi(manufacturerUrl) : string.Empty,
+ DateOfManufacture = (dateOfManufacture != IntPtr.Zero) ? Marshal.PtrToStringAnsi(dateOfManufacture) : string.Empty,
+ ModelNumber = (modelNumber != IntPtr.Zero) ? Marshal.PtrToStringAnsi(modelNumber) : string.Empty,
+ PlatformVersion = (platformVersion != IntPtr.Zero) ? Marshal.PtrToStringAnsi(platformVersion) : string.Empty,
+ OsVersion = (osVersion != IntPtr.Zero) ? Marshal.PtrToStringAnsi(osVersion) : string.Empty,
+ HardwareVersion = (hardwareVersion != IntPtr.Zero) ? Marshal.PtrToStringAnsi(hardwareVersion) : string.Empty,
+ FirmwareVersion = (firmwareVersion != IntPtr.Zero) ? Marshal.PtrToStringAnsi(firmwareVersion) : string.Empty,
+ SupportUrl = (supportUrl != IntPtr.Zero) ? Marshal.PtrToStringAnsi(supportUrl) : string.Empty,
+ SystemTime = (systemTime != IntPtr.Zero) ? Marshal.PtrToStringAnsi(systemTime) : string.Empty
+ };
+
+ Log.Info(IoTConnectivityErrorFactory.LogTag, "e.RequestId is " + e.RequestId);
+ Log.Info(IoTConnectivityErrorFactory.LogTag, "e.PlatformId is " + e.PlatformId);
+ Log.Info(IoTConnectivityErrorFactory.LogTag, "e.ManufacturerName is " + e.ManufacturerName);
+ Log.Info(IoTConnectivityErrorFactory.LogTag, "e.ManufacturerURL is " + e.ManufacturerURL);
+ Log.Info(IoTConnectivityErrorFactory.LogTag, "e.DateOfManufacture is " + e.DateOfManufacture);
+ Log.Info(IoTConnectivityErrorFactory.LogTag, "e.ModelNumber is " + e.ModelNumber);
+ Log.Info(IoTConnectivityErrorFactory.LogTag, "e.PlatformVersion is " + e.PlatformVersion);
+ Log.Info(IoTConnectivityErrorFactory.LogTag, "e.OsVersion is " + e.OsVersion);
+ Log.Info(IoTConnectivityErrorFactory.LogTag, "e.HardwareVersion is " + e.HardwareVersion);
+ Log.Info(IoTConnectivityErrorFactory.LogTag, "e.FirmwareVersion is " + e.FirmwareVersion);
+ Log.Info(IoTConnectivityErrorFactory.LogTag, "e.SupportUrl is " + e.SupportUrl);
+ Log.Info(IoTConnectivityErrorFactory.LogTag, "e.SystemTime is " + e.SystemTime);
+
+ return e;
+ }
+
+ private static FindingErrorOccurredEventArgs GetFindingErrorOccurredEventArgs(int requestId, int err)
+ {
+ FindingErrorOccurredEventArgs e = new FindingErrorOccurredEventArgs()
+ {
+ RequestId = requestId,
+ Error = IoTConnectivityErrorFactory.GetException(err)
+ };
+ return e;
+ }
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/IoTConnectivityErrorFactory.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/IoTConnectivityErrorFactory.cs
new file mode 100755
index 0000000..338a093
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/IoTConnectivityErrorFactory.cs
@@ -0,0 +1,103 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+using System.IO;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Network.IoTConnectivity
+{
+ internal enum IoTConnectivityError
+ {
+ None = ErrorCode.None,
+ InvalidParameter = ErrorCode.InvalidParameter,
+ OutOfMemory = ErrorCode.OutOfMemory,
+ Io = ErrorCode.IoError,
+ PermissionDenied = ErrorCode.PermissionDenied,
+ NotSupported = ErrorCode.NotSupported,
+ NoData = ErrorCode.NoData,
+ TimedOut = ErrorCode.TimedOut,
+ Iotivity = -0x01C80000 | 0x01,
+ Representation = -0x01C80000 | 0x02,
+ InvalidType = -0x01C80000 | 0x03,
+ Already = -0x01C80000 | 0x04,
+ System = -0x01C80000 | 0x06,
+ }
+
+ internal static class IoTConnectivityErrorFactory
+ {
+ internal const string LogTag = "Tizen.Network.IoTConnectivity";
+
+ internal static void ThrowException(int err)
+ {
+ throw GetException(err);
+ }
+
+ internal static Exception GetException(int err)
+ {
+ IoTConnectivityError error = (IoTConnectivityError)err;
+ if (error == IoTConnectivityError.OutOfMemory)
+ {
+ return new OutOfMemoryException("Out of memory");
+ }
+ else if (error == IoTConnectivityError.InvalidParameter)
+ {
+ return new ArgumentException("Invalid parameter");
+ }
+ else if (error == IoTConnectivityError.Io)
+ {
+ return new IOException("I/O Error");
+ }
+ else if (error == IoTConnectivityError.NoData)
+ {
+ return new InvalidOperationException("No data found");
+ }
+ else if (error == IoTConnectivityError.TimedOut)
+ {
+ return new TimeoutException("timed out");
+ }
+ else if (error == IoTConnectivityError.PermissionDenied)
+ {
+ return new UnauthorizedAccessException("Permission denied");
+ }
+ else if (error == IoTConnectivityError.NotSupported)
+ {
+ return new NotSupportedException("Not supported");
+ }
+ else if (error == IoTConnectivityError.Representation)
+ {
+ return new InvalidOperationException("Representation error");
+ }
+ else if (error == IoTConnectivityError.InvalidType)
+ {
+ return new ArgumentException("Invalid type");
+ }
+ else if (error == IoTConnectivityError.Already)
+ {
+ return new InvalidOperationException("Duplicate");
+ }
+ else if (error == IoTConnectivityError.System)
+ {
+ return new InvalidOperationException("System error");
+ }
+ else
+ {
+ return new InvalidOperationException("Invalid operation");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/IoTConnectivityServerManager.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/IoTConnectivityServerManager.cs
new file mode 100755
index 0000000..4256414
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/IoTConnectivityServerManager.cs
@@ -0,0 +1,315 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// IoT connectivity server manager consists of server side APIs.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public static class IoTConnectivityServerManager
+ {
+ private static int s_requestId = 1;
+ private static Dictionary<IntPtr, Interop.IoTConnectivity.Server.Resource.RequestHandlerCallback> s_RequestHandlerCallbackMap = new Dictionary<IntPtr, Interop.IoTConnectivity.Server.Resource.RequestHandlerCallback>();
+
+ /// <summary>
+ /// Initializes IoTCon. Call this API to start IoTCon.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>
+ /// @a filePath point to a file for handling secure virtual resources.
+ /// The file that is CBOR(Concise Binary Object Representation)-format must already exist
+ /// in @a filePath. We recommend to use application-local file for @a filePath.
+ /// </remarks>
+ /// <privilege>
+ /// http://tizen.org/privilege/network.get \n
+ /// http://tizen.org/privilege/internet
+ /// </privilege>
+ /// <privlevel>public</privlevel>
+ /// <param name="filePath">The file path to point to storage for handling secure virtual resources.</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <post>
+ /// You must call Deinitialize() if IoTCon API is no longer needed.
+ /// </post>
+ /// <seealso cref="Deinitialize()"/>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
+ /// <code>
+ /// string filePath = "../../res/iotcon-test-svr-db-server.dat";
+ /// IoTConnectivityServerManager.Initialize(filePath);
+ /// </code>
+ public static void Initialize(string filePath)
+ {
+ int ret = Interop.IoTConnectivity.Client.IoTCon.Initialize(filePath);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to initialize");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Deinitializes IoTCon.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>
+ /// This API must be called if IoTCon API is no longer needed.
+ /// </remarks>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <pre>
+ /// Initialize() should be called to initialize.
+ /// </pre>
+ /// <seealso cref="Initialize()"/>
+ /// <code>
+ /// IoTConnectivityServerManager.Deinitialize();
+ /// </code>
+ public static void Deinitialize()
+ {
+ _resources.Clear();
+ s_requestId = 1;
+ s_RequestHandlerCallbackMap.Clear();
+
+ Interop.IoTConnectivity.Client.IoTCon.Deinitialize();
+ }
+
+ /// <summary>
+ /// Registers a resource in IoTCon server
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/internet
+ /// </privilege>
+ /// <privlevel>public</privlevel>
+ /// <param name="resource">The resource to register</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <pre>
+ /// Initialize() should be called to initialize.
+ /// </pre>
+ /// <seealso cref="Resource"/>
+ /// <seealso cref="LiteResource"/>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
+ /// <code>
+ /// ResourceTypes types = new ResourceTypes(new List<string>(){ "org.tizen.light" });
+ /// Attributes attributes = new Attributes { { "state", "ON" }};
+ /// Resource res = new LiteResource("/room/1", types, ResourcePolicy.Discoverable, attributes);
+ /// try {
+ /// IoTConnectivityServerManager.RegisterResource(res);
+ /// } catch(Exception ex) {
+ /// Console.Log("Exception caught : " + ex.Message);
+ /// }
+ /// </code>
+ public static void RegisterResource(Resource resource)
+ {
+ Log.Info(IoTConnectivityErrorFactory.LogTag, "...");
+
+ IntPtr id = IntPtr.Zero;
+ lock (s_RequestHandlerCallbackMap)
+ {
+ id = (IntPtr)s_requestId++;
+ }
+
+ s_RequestHandlerCallbackMap[id] = (IntPtr r_resource, IntPtr request, IntPtr userData) =>
+ {
+ int requestId = (int)userData;
+
+ Log.Info(IoTConnectivityErrorFactory.LogTag, "Received s_RequestHandlerCallbackMap : " + requestId);
+
+ if (request == IntPtr.Zero)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "request is IntPtr.Zero");
+ return;
+ }
+ resource.OnRequest(r_resource, request, userData);
+ };
+
+ IntPtr handle = IntPtr.Zero;
+ int errorCode = Interop.IoTConnectivity.Server.Resource.Create(resource.UriPath, resource.Types._resourceTypeHandle, resource.Interfaces.ResourceInterfacesHandle, (int)resource.Policy, s_RequestHandlerCallbackMap[id], id, out handle);
+ if (errorCode != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed create resource");
+ lock (s_RequestHandlerCallbackMap)
+ {
+ s_RequestHandlerCallbackMap.Remove(id);
+ }
+ throw IoTConnectivityErrorFactory.GetException(errorCode);
+ }
+ else
+ {
+ resource.ResourceHandle = handle;
+ }
+ _resources.Add(resource);
+ }
+
+ /// <summary>
+ /// Unregisters a resource in IoTCon server
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/internet
+ /// </privilege>
+ /// <privlevel>public</privlevel>
+ /// <param name="resource">The resource to unregister</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <pre>
+ /// Initialize() should be called to initialize.
+ /// </pre>
+ /// <seealso cref="Resource"/>
+ /// <seealso cref="LiteResource"/>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
+ /// <code>
+ /// ResourceTypes types = new ResourceTypes(new List<string>(){ "org.tizen.light" });
+ /// Attributes attributes = new Attributes { { "state", "ON" }};
+ /// Resource res = new LiteResource("/room/1", types, ResourcePolicy.Discoverable, attributes);
+ /// IoTConnectivityServerManager.RegisterResource(res);
+ /// try {
+ /// IoTConnectivityServerManager.UnregisterResource(res);
+ /// } catch(Exception ex) {
+ /// Console.Log("Exception caught : " + ex.Message);
+ /// }
+ /// </code>
+ public static void UnregisterResource(Resource resource)
+ {
+ if (resource != null)
+ {
+ if (resource.ResourceHandle != IntPtr.Zero)
+ {
+ Interop.IoTConnectivity.Server.Resource.Destroy(resource.ResourceHandle);
+ resource.ResourceHandle = IntPtr.Zero;
+ }
+
+ _resources.Remove(resource);
+ }
+ }
+
+ /// <summary>
+ /// Starts presence of a server
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>
+ /// Use this API to send server's announcements to clients.
+ /// Server can call this API when online for the first time or come back from offline to online.\n
+ /// If @a time is 0, server will set default value as 60 seconds.\n
+ /// If @a time is very big, server will set maximum value as (60 * 60 * 24) seconds, (24 hours).
+ /// </remarks>
+ /// <privilege>
+ /// http://tizen.org/privilege/internet
+ /// </privilege>
+ /// <privlevel>public</privlevel>
+ /// <param name="time">The interval of announcing presence in seconds.</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <pre>
+ /// Initialize() should be called to initialize.
+ /// </pre>
+ /// <seealso cref="IoTConnectivityClientManager.StartReceivingPresence()"/>
+ /// <seealso cref="IoTConnectivityClientManager.StopReceivingPresence()"/>
+ /// <seealso cref="IoTConnectivityClientManager.PresenceReceived"/>
+ /// <seealso cref="StopSendingPresence()"/>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
+ /// <code>
+ /// try {
+ /// IoTConnectivityServerManager.StartSendingPresence(120);
+ /// } catch(Exception ex) {
+ /// Console.Log("Exception caught : " + ex.Message);
+ /// }
+ /// </code>
+ public static void StartSendingPresence(uint time)
+ {
+ int ret = Interop.IoTConnectivity.Server.IoTCon.StartPresence(time);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to start presence");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Stops presence of a server.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>
+ /// Use this API to stop sending server's announcements to clients.
+ /// Server can call this API when terminating, entering to offline or out of network.
+ /// </remarks>
+ /// <privilege>
+ /// http://tizen.org/privilege/internet
+ /// </privilege>
+ /// <privlevel>public</privlevel>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <pre>
+ /// Initialize() should be called to initialize.
+ /// </pre>
+ /// <seealso cref="IoTConnectivityClientManager.StartReceivingPresence()"/>
+ /// <seealso cref="IoTConnectivityClientManager.StopReceivingPresence()"/>
+ /// <seealso cref="IoTConnectivityClientManager.PresenceReceived"/>
+ /// <seealso cref="StartSendingPresence()"/>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
+ /// <code>
+ /// IoTConnectivityServerManager.StopSendingPresence();
+ /// </code>
+ public static void StopSendingPresence()
+ {
+ int ret = Interop.IoTConnectivity.Server.IoTCon.StopPresence();
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed cancel presence");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Sets the device name
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>
+ /// This API sets the name of the local device (the device calling the API).\n
+ /// If the device name is set, clients can get the name using <see cref="IoTConnectivityClientManager.StartFindingDeviceInformation()"/>.
+ /// </remarks>
+ /// <param name="deviceName">The device name</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <seealso cref="IoTConnectivityClientManager.DeviceInformationFound"/>
+ /// <seealso cref="IoTConnectivityClientManager.StartFindingDeviceInformation()"/>
+ /// <seealso cref="DeviceInformationFoundEventArgs"/>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
+ /// <code>
+ /// IoTConnectivityServerManager.SetDeviceName("my-tizen");
+ /// </code>
+ public static void SetDeviceName(string deviceName)
+ {
+ int ret = Interop.IoTConnectivity.Server.IoTCon.SetDeviceName(deviceName);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed set device name");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ private static List<Resource> _resources = new List<Resource>();
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/LiteResource.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/LiteResource.cs
new file mode 100755
index 0000000..f6238c6
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/LiteResource.cs
@@ -0,0 +1,179 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// This class represents a lite resource.
+ /// It provides APIs to encapsulate resources.
+ /// This class is accessed by using a constructor to create a new instance of this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class LiteResource : Resource
+ {
+ /// <summary>
+ /// The LiteResource constructor
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>
+ /// Creates a lite resource which can then be registered in server using <see cref="IoTConnectivityServerManager.RegisterResource()"/>.\n
+ /// When client requests some operations, it send a response to client, automatically.\n
+ /// @a uri length must be less than 128.
+ /// </remarks>
+ /// <privilege>
+ /// http://tizen.org/privilege/internet
+ /// </privilege>
+ /// <privlevel>public</privlevel>
+ /// <param name="uri">The uri path of the lite resource</param>
+ /// <param name="types">The type of the resource</param>
+ /// <param name="policy">Policy of the resource</param>
+ /// <param name="attribs">Optional attributes of the resource</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <pre>
+ /// IoTConnectivityServerManager.Initialize() should be called to initialize
+ /// </pre>
+ /// <seealso cref="ResourceTypes"/>
+ /// <seealso cref="ResourcePolicy"/>
+ /// <seealso cref="Attributes"/>
+ /// <code>
+ /// List<string> list = new List<string>() { "org.tizen.light" };
+ /// Attributes attributes = new Attributes() {
+ /// { "state", "ON" }
+ /// };
+ /// LiteResource res = new LiteResource("/light/1", new ResourceTypes(list), ResourcePolicy.Discoverable, attributes);
+ /// </code>
+ public LiteResource(string uri, ResourceTypes types, ResourcePolicy policy, Attributes attribs = null)
+ : base(uri, types, new ResourceInterfaces(new string[] { ResourceInterfaces.DefaultInterface }), policy)
+ {
+ Attributes = attribs;
+ }
+
+ /// <summary>
+ /// Gets or sets the attributes of the lite resource
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The attributes of the lite resource.</value>
+ /// <code>
+ /// List<string> list = new List<string>() { "org.tizen.light" };
+ /// LiteResource res = new LiteResource("/light/1", new ResourceTypes(list), ResourcePolicy.Discoverable);
+ /// Attributes attributes = new Attributes() {
+ /// { "state", "ON" }
+ /// };
+ /// res.Attributes = newAttributes;
+ /// foreach (KeyValuePair<string, object> pair in res.Attributes)
+ /// {
+ /// Console.WriteLine("key : {0}, value : {1}", pair.Key, pair.Value);
+ /// }
+ /// </code>
+ public Attributes Attributes { get; set; }
+
+ /// <summary>
+ /// Decides whether to accept or reject a post request.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>
+ /// Child classes of this class can override this method to accept or reject post request.
+ /// </remarks>
+ /// <param name="attribs">The new attributes of the lite resource</param>
+ /// <returns>true to accept post request, false to reject it</returns>
+ /// <code>
+ /// public class MyLightResource : LiteResource
+ /// {
+ /// protected override bool OnPost(Attributes attributes)
+ /// {
+ /// object newAttributes;
+ /// attributes.TryGetValue("LIGHT_ATTRIBUTE", out newAttributes);
+ /// if((int)newAttributes == 1)
+ /// return true;
+ /// return false;
+ /// }
+ /// }
+ /// </code>
+ protected virtual bool OnPost(Attributes attribs)
+ {
+ return true;
+ }
+
+ // The code block untill @endcond should not appear in doxygen spec.
+ /// @cond
+ protected sealed override Response OnGet(Request request)
+ {
+ Representation representation = new Representation()
+ {
+ UriPath = UriPath,
+ Interface = Interfaces,
+ Type = Types,
+ Attributes = Attributes
+ };
+
+ Response response = new Response()
+ {
+ Representation = representation,
+ Result = ResponseCode.Ok
+ };
+
+ return response;
+ }
+
+ protected sealed override Response OnPut(Request request)
+ {
+ Response response = new Response();
+ response.Result = ResponseCode.Forbidden;
+ return response;
+ }
+
+ protected sealed override Response OnPost(Request request)
+ {
+ if (OnPost(request.Representation.Attributes))
+ {
+ Attributes = request.Representation.Attributes;
+ Representation representation = new Representation() {
+ UriPath = UriPath,
+ Interface = Interfaces,
+ Type = Types,
+ Attributes = Attributes
+ };
+
+ Response response = new Response() {
+ Representation = representation,
+ Result = ResponseCode.Ok
+ };
+
+ Notify(representation, QualityOfService.High);
+ return response;
+ }
+
+ return new Response()
+ {
+ Result = ResponseCode.Error
+ };
+ }
+
+ protected sealed override Response OnDelete(Request request)
+ {
+ Response response = new Response();
+ response.Result = ResponseCode.Forbidden;
+ return response;
+ }
+
+ protected sealed override bool OnObserving(Request request, ObserveType observeType, int observeId)
+ {
+ return true;
+ }
+ /// @endcond
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/NamespaceDoc.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/NamespaceDoc.cs
new file mode 100755
index 0000000..6c4b38f
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/NamespaceDoc.cs
@@ -0,0 +1,12 @@
+/**
+<summary>
+The Tizen.Network.IoTConnectivity namespace provides classes to manage
+Resource, RemoteResource, Request, Response and so on which are based on IoTivity project.
+</summary>
+<remarks>
+The Tizen.Network.IoTConnectivity namespace provides classes to manage
+Resource, RemoteResource, Request, Response and so on which are based on IoTivity project.
+</remarks>
+*/
+namespace Tizen.Network.IoTConnectivity {}
+
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ObservePolicy.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ObservePolicy.cs
new file mode 100755
index 0000000..f50901b
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ObservePolicy.cs
@@ -0,0 +1,37 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// Enumeration for policy of observation
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum ObservePolicy
+ {
+ /// <summary>
+ /// Indicates observation request for most up-to-date notifications only
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ IgnoreOutOfOrder = 0,
+ /// <summary>
+ /// Indicates observation request for all notifications including state notifications
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ AcceptOutOfOrder
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ObserveType.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ObserveType.cs
new file mode 100755
index 0000000..ca611bb
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ObserveType.cs
@@ -0,0 +1,45 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// Enumeration for type of observation
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum ObserveType
+ {
+ /// <summary>
+ /// No observe action
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ NoType = 0,
+
+ /// <summary>
+ /// Indicates action of registering observation
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ Register = 1,
+
+ /// <summary>
+ /// Indicates action of unregistering observation
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ Deregister = 2,
+ }
+}
+
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ObserverNotifiedEventArgs.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ObserverNotifiedEventArgs.cs
new file mode 100755
index 0000000..edbbef2
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ObserverNotifiedEventArgs.cs
@@ -0,0 +1,44 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// This class represents event arguments of the ObserverNotified event.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class ObserverNotifiedEventArgs : EventArgs
+ {
+ internal ObserverNotifiedEventArgs() { }
+
+ /// <summary>
+ /// Result of the observe response
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Result of the observe response.</value>
+ public ResponseCode Result { get; internal set; }
+
+ /// <summary>
+ /// Representation of the resource being observed.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Representation of the resource being observed.</value>
+ public Representation Representation { get; internal set; }
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/PlatformInformationFoundEventArgs.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/PlatformInformationFoundEventArgs.cs
new file mode 100755
index 0000000..312f05f
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/PlatformInformationFoundEventArgs.cs
@@ -0,0 +1,119 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// This class represents event arguments of the PlatformInformationFound event.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class PlatformInformationFoundEventArgs
+ {
+ internal PlatformInformationFoundEventArgs() { }
+
+ /// <summary>
+ /// Indicates the request id
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The request id.</value>
+ public int RequestId { get; internal set; }
+
+ /// <summary>
+ /// Indicates to continuously receive the event for finding platform information.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Continuously receive the event for finding platform information.</value>
+ public bool EventContinue { get; set; }
+
+ /// <summary>
+ /// Indicates the platform identifier
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The platform identifier.</value>
+ public string PlatformId { get; internal set; }
+
+ /// <summary>
+ /// Indicates the name of manufacturer
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The name of manufacturer.</value>
+ public string ManufacturerName { get; internal set; }
+
+ /// <summary>
+ /// Indicates URL of the manufacturer
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>URL of the manufacturer.</value>
+ public string ManufacturerURL { get; internal set; }
+
+ /// <summary>
+ /// Indicates model number as designated by manufacturer
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Model number as designated by manufacturer.</value>
+ public string ModelNumber { get; internal set; }
+
+ /// <summary>
+ /// Indicates manufacturing date of the device
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Manufacturing date of the device.</value>
+ public string DateOfManufacture { get; internal set; }
+
+ /// <summary>
+ /// Indicates version of platfrom defined by manufacturer
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Version of platfrom defined by manufacturer.</value>
+ public string PlatformVersion { get; internal set; }
+
+ /// <summary>
+ /// Indicates version of platfrom resident OS
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Version of platfrom resident OS.</value>
+ public string OsVersion { get; internal set; }
+
+ /// <summary>
+ /// Indicates version of platform Hardware
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Version of platform Hardware.</value>
+ public string HardwareVersion { get; internal set; }
+
+ /// <summary>
+ /// Indicates version of device firmware
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Version of device firmware.</value>
+ public string FirmwareVersion { get; internal set; }
+
+ /// <summary>
+ /// Indicates URL that points to support information from manufacturer
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>URL that points to support information from manufacturer.</value>
+ public string SupportUrl { get; internal set; }
+
+ /// <summary>
+ /// Indicates reference time of the device
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Reference time of the device.</value>
+ public string SystemTime { get; internal set; }
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/PresenceEventType.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/PresenceEventType.cs
new file mode 100755
index 0000000..77ba72a
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/PresenceEventType.cs
@@ -0,0 +1,42 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// Enumeration for operation of presence response.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum PresenceEventType
+ {
+ /// <summary>
+ /// Indicates for resource creation operation of server
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ ResourceCreated = 0,
+ /// <summary>
+ /// Indicates for resource updation operation of server
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ ResourceUpdated,
+ /// <summary>
+ /// Indicates for resource destruction operation of server
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ ResourceDestroyed
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/PresenceReceivedEventArgs.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/PresenceReceivedEventArgs.cs
new file mode 100755
index 0000000..0138c11
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/PresenceReceivedEventArgs.cs
@@ -0,0 +1,58 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// This class represents event arguments of the PresenceReceived event.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class PresenceReceivedEventArgs : EventArgs
+ {
+ internal PresenceReceivedEventArgs() { }
+
+ /// <summary>
+ /// Indicates request id of presence event.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Request id of presence event.</value>
+ public int PresenceId { get; internal set; }
+
+ /// <summary>
+ /// Indicates event type
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Event type.</value>
+ public PresenceEventType EventType { get; internal set; }
+
+ /// <summary>
+ /// Indicates host address of resource
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Host address of resource.</value>
+ public string HostAddress { get; internal set; }
+
+ /// <summary>
+ /// Indicates type of the resource
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Type of the resource.</value>
+ public string Type { get; internal set; }
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/QualityOfService.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/QualityOfService.cs
new file mode 100755
index 0000000..c05ffc9
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/QualityOfService.cs
@@ -0,0 +1,37 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// Enumeration for states of remote resource.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum QualityOfService
+ {
+ /// <summary>
+ /// Indicates low quality of service
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ Low = 0,
+ /// <summary>
+ /// Indicates high quality of service
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ High
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/RemoteResource.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/RemoteResource.cs
new file mode 100755
index 0000000..3844199
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/RemoteResource.cs
@@ -0,0 +1,893 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// This class represents a remote resource.
+ /// It provides APIs to manage remote resource.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class RemoteResource : IDisposable
+ {
+ internal const int TimeOutMax = 3600;
+ internal IntPtr _remoteResourceHandle = IntPtr.Zero;
+
+ private bool _disposed = false;
+ private bool _cacheEnabled = false;
+ private ResourceOptions _options;
+
+ private int _responseCallbackId = 1;
+ private static Dictionary<IntPtr, Interop.IoTConnectivity.Client.RemoteResource.ResponseCallback> _responseCallbacksMap = new Dictionary<IntPtr, Interop.IoTConnectivity.Client.RemoteResource.ResponseCallback>();
+
+ private Interop.IoTConnectivity.Client.RemoteResource.CachedRepresentationChangedCallback _cacheUpdatedCallback;
+ private Interop.IoTConnectivity.Client.RemoteResource.StateChangedCallback _stateChangedCallback;
+ private Interop.IoTConnectivity.Client.RemoteResource.ObserveCallback _observeCallback;
+
+ private EventHandler<StateChangedEventArgs> _stateChangedEventHandler;
+
+ /// <summary>
+ /// Creates a remote resource instance
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>
+ /// To use this API, you should provide all of the details required to correctly contact and
+ /// observe the object.\n
+ /// If not, you should discover the resource object manually.\n
+ /// The @a policy can contain multiple policies like ResourcePolicy.Discoverable | ResourcePolicy.Observable.
+ /// </remarks>
+ /// <param name="hostAddress">The host address of the resource</param>
+ /// <param name="uriPath">The URI path of the resource</param>
+ /// <param name="policy">The policies of the resource</param>
+ /// <param name="resourceTypes">The resource types of the resource</param>
+ /// <param name="resourceInterfaces">The resource interfaces of the resource</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory</exception>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ public RemoteResource(string hostAddress, string uriPath, ResourcePolicy policy, ResourceTypes resourceTypes, ResourceInterfaces resourceInterfaces)
+ {
+ if (hostAddress == null || uriPath == null || resourceTypes == null || resourceInterfaces == null)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Invalid parameters");
+ throw new ArgumentException("Invalid parameter");
+ }
+
+ HostAddress = hostAddress;
+ UriPath = uriPath;
+ Policy = policy;
+ Types = new List<string>(resourceTypes);
+ Interfaces = new List<string>(resourceInterfaces);
+ DeviceId = null;
+
+ CreateRemoteResource(resourceTypes._resourceTypeHandle, resourceInterfaces.ResourceInterfacesHandle);
+ }
+
+ internal RemoteResource(IntPtr handleToClone)
+ {
+ int ret = Interop.IoTConnectivity.Client.RemoteResource.Clone(handleToClone, out _remoteResourceHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Faled to clone");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ SetRemoteResource();
+ }
+
+ /// <summary>
+ /// Destructor of the RemoteResource class.
+ /// </summary>
+ ~RemoteResource()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Event that is invoked with cached resource attributes
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public event EventHandler<CacheUpdatedEventArgs> CacheUpdated;
+
+ /// <summary>
+ /// Observe event on the resource sent by the server
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public event EventHandler<ObserverNotifiedEventArgs> ObserverNotified;
+
+ /// <summary>
+ /// Event that is called when remote resource's state are changed
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public event EventHandler<StateChangedEventArgs> StateChanged
+ {
+ add
+ {
+ if (_stateChangedEventHandler == null)
+ {
+ RegisterStateChangedEvent();
+ }
+ _stateChangedEventHandler += value;
+ }
+ remove
+ {
+ _stateChangedEventHandler -= value;
+ if (_stateChangedEventHandler == null)
+ {
+ UnregisterStateChangedEvent();
+ }
+ }
+ }
+
+ /// <summary>
+ /// The host address of the resource
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The host address of the resource.</value>
+ public string HostAddress { get; private set; }
+
+ /// <summary>
+ /// The URI path of the resource
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The URI path of the resource.</value>
+ public string UriPath { get; private set; }
+
+ /// <summary>
+ /// The resource types of the remote resource
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The resource types of the remote resource.</value>
+ public IEnumerable<string> Types { get; private set; }
+
+ /// <summary>
+ /// The interfaces of the resource
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The interfaces of the resource.</value>
+ public IEnumerable<string> Interfaces { get; private set; }
+
+ /// <summary>
+ /// The policy of the resource
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The policy of the resource.</value>
+ public ResourcePolicy Policy { get; private set; }
+
+ /// <summary>
+ /// The header options of the resource
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The header options of the resource.</value>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ public ResourceOptions Options
+ {
+ get
+ {
+ return _options;
+ }
+ set
+ {
+ _options = value;
+ if (value != null)
+ {
+ int ret = Interop.IoTConnectivity.Client.RemoteResource.SetOptions(_remoteResourceHandle, value._resourceOptionsHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set options");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Indicates the CacheEnabled status of the remote resource.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>
+ /// Client can start caching only when this is set true. Set it to false to stop caching the resource attributes.
+ /// </value>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory</exception>
+ public bool CacheEnabled
+ {
+ get
+ {
+ return _cacheEnabled;
+ }
+ set
+ {
+ if (_cacheEnabled != value)
+ {
+ _cacheEnabled = value;
+ HandleCachePolicyChanged();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Time interval of monitoring and caching API
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>
+ /// Default time interval is 10 seconds.
+ /// Seconds for time interval (must be in range from 1 to 3600)
+ /// </value>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ public int TimeInterval
+ {
+ get
+ {
+ int interval;
+ int ret = Interop.IoTConnectivity.Client.RemoteResource.GetTimeInterval(_remoteResourceHandle, out interval);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Warn(IoTConnectivityErrorFactory.LogTag, "Failed to get time interval");
+ return 0;
+ }
+ return interval;
+ }
+ set
+ {
+ int ret = (int)IoTConnectivityError.InvalidParameter;
+ if (value <= TimeOutMax && value > 0)
+ {
+ ret = Interop.IoTConnectivity.Client.RemoteResource.SetTimeInterval(_remoteResourceHandle, value);
+ }
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set time interval");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The device id of the resource
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The device id of the resource.</value>
+ public string DeviceId { get; private set; }
+
+ /// <summary>
+ /// Gets cached representation from the remote resource
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <returns>cached representation from the remote resource</returns>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ public Representation CachedRepresentation()
+ {
+ IntPtr handle;
+ int ret = Interop.IoTConnectivity.Client.RemoteResource.GetCachedRepresentation(_remoteResourceHandle, out handle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Warn(IoTConnectivityErrorFactory.LogTag, "Failed to get CachedRepresentation");
+ return null;
+ }
+
+ Representation representation = new Representation(handle);
+ return representation;
+ }
+
+ /// <summary>
+ /// Starts observing on the resource
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>
+ /// When server sends notification message, <see cref="ObserverNotified"/> will be called.
+ /// </remarks>
+ /// <privilege>
+ /// http://tizen.org/privilege/internet
+ /// </privilege>
+ /// <privlevel>public</privlevel>
+ /// <param name="policy">The type to specify how client wants to observe</param>
+ /// <param name="query">The query to send to server</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory</exception>
+ public void StartObserving(ObservePolicy policy, ResourceQuery query = null)
+ {
+ _observeCallback = (IntPtr resource, int err, int sequenceNumber, IntPtr response, IntPtr userData) =>
+ {
+ int result;
+ IntPtr representationHandle;
+ int ret = Interop.IoTConnectivity.Server.Response.GetResult(response, out result);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get result");
+ return;
+ }
+
+ ret = Interop.IoTConnectivity.Server.Response.GetRepresentation(response, out representationHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get representation");
+ return;
+ }
+
+ Representation repr = null;
+ try
+ {
+ repr = new Representation(representationHandle);
+ }
+ catch (Exception exp)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to new representation: " + exp.Message);
+ return;
+ }
+
+ ObserverNotifiedEventArgs e = new ObserverNotifiedEventArgs()
+ {
+ Representation = repr,
+ Result = (ResponseCode)result
+ };
+ ObserverNotified?.Invoke(this, e);
+ };
+
+ IntPtr queryHandle = IntPtr.Zero;
+ if (query != null)
+ {
+ queryHandle = query._resourceQueryHandle;
+ }
+
+ int errCode = Interop.IoTConnectivity.Client.RemoteResource.RegisterObserve(_remoteResourceHandle, (int)policy, queryHandle, _observeCallback, IntPtr.Zero);
+ if (errCode != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to register observe callbacks");
+ throw IoTConnectivityErrorFactory.GetException(errCode);
+ }
+ }
+
+ /// <summary>
+ /// Stops observing on the resource
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/internet
+ /// </privilege>
+ /// <privlevel>public</privlevel>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
+ public void StopObserving()
+ {
+ int ret = Interop.IoTConnectivity.Client.RemoteResource.DeregisterObserve(_remoteResourceHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to deregister observe callbacks");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Gets the attributes of a resource, asynchronously
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/internet
+ /// </privilege>
+ /// <privlevel>public</privlevel>
+ /// <param name="query">The ResourceQuery to send to server</param>
+ /// <returns>Remote response with result and representation</returns>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ public async Task<RemoteResponse> GetAsync(ResourceQuery query = null)
+ {
+ TaskCompletionSource<RemoteResponse> tcsRemoteResponse = new TaskCompletionSource<RemoteResponse>();
+
+ IntPtr id = IntPtr.Zero;
+ lock (_responseCallbacksMap)
+ {
+ id = (IntPtr)_responseCallbackId++;
+ }
+ _responseCallbacksMap[id] = (IntPtr resource, int err, int requestType, IntPtr responseHandle, IntPtr userData) =>
+ {
+ IntPtr responseCallbackId = userData;
+ lock(_responseCallbacksMap)
+ {
+ _responseCallbacksMap.Remove(responseCallbackId);
+ }
+
+ if (responseHandle != IntPtr.Zero)
+ {
+ try
+ {
+ tcsRemoteResponse.TrySetResult(GetRemoteResponse(responseHandle));
+ }
+ catch(Exception exp)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get RemoteResponse: ", exp.Message);
+ tcsRemoteResponse.TrySetException(exp);
+ }
+ }
+ else
+ {
+ tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.System));
+ }
+ };
+
+ IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
+ int errCode = Interop.IoTConnectivity.Client.RemoteResource.Get(_remoteResourceHandle, queryHandle, _responseCallbacksMap[id], id);
+ if (errCode != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get resource attributes");
+ tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException(errCode));
+ }
+ return await tcsRemoteResponse.Task;
+ }
+
+ /// <summary>
+ /// Puts the representation of a resource, asynchronously.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/internet
+ /// </privilege>
+ /// <privlevel>public</privlevel>
+ /// <param name="representation">Resource representation to put</param>
+ /// <param name="query">The ResourceQuery to send to server</param>
+ /// <returns>Remote response with result and representation</returns>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ public async Task<RemoteResponse> PutAsync(Representation representation, ResourceQuery query = null)
+ {
+ TaskCompletionSource<RemoteResponse> tcsRemoteResponse = new TaskCompletionSource<RemoteResponse>();
+
+ IntPtr id = IntPtr.Zero;
+ lock (_responseCallbacksMap)
+ {
+ id = (IntPtr)_responseCallbackId++;
+ }
+ _responseCallbacksMap[id] = (IntPtr resource, int err, int requestType, IntPtr responseHandle, IntPtr userData) =>
+ {
+ IntPtr responseCallbackId = userData;
+ lock (_responseCallbacksMap)
+ {
+ _responseCallbacksMap.Remove(responseCallbackId);
+ }
+ if (err == (int)(IoTConnectivityError.Iotivity))
+ {
+ RemoteResponse response = new RemoteResponse();
+ response.Result = ResponseCode.Forbidden;
+ response.Representation = null;
+ tcsRemoteResponse.TrySetResult(response);
+ }
+ else if (responseHandle != IntPtr.Zero)
+ {
+ try
+ {
+ tcsRemoteResponse.TrySetResult(GetRemoteResponse(responseHandle));
+ }
+ catch (Exception exp)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get RemoteResponse: ", exp.Message);
+ tcsRemoteResponse.TrySetException(exp);
+ }
+ }
+ else
+ {
+ tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.System));
+ }
+ };
+ IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
+ int errCode = Interop.IoTConnectivity.Client.RemoteResource.Put(_remoteResourceHandle, representation._representationHandle, queryHandle, _responseCallbacksMap[id], id);
+ if (errCode != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to put resource representation");
+ tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException(errCode));
+ }
+ return await tcsRemoteResponse.Task;
+ }
+
+ /// <summary>
+ /// Post request on a resource, asynchronously
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/internet
+ /// </privilege>
+ /// <privlevel>public</privlevel>
+ /// <param name="representation">Resource representation of request</param>
+ /// <param name="query">The ResourceQuery to send to server</param>
+ /// <returns>Remote response with result and representation</returns>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ public async Task<RemoteResponse> PostAsync(Representation representation, ResourceQuery query = null)
+ {
+ TaskCompletionSource<RemoteResponse> tcsRemoteResponse = new TaskCompletionSource<RemoteResponse>();
+
+ IntPtr id = IntPtr.Zero;
+ lock (_responseCallbacksMap)
+ {
+ id = (IntPtr)_responseCallbackId++;
+ }
+ _responseCallbacksMap[id] = (IntPtr resource, int err, int requestType, IntPtr responseHandle, IntPtr userData) =>
+ {
+ IntPtr responseCallbackId = userData;
+ lock (_responseCallbacksMap)
+ {
+ _responseCallbacksMap.Remove(responseCallbackId);
+ }
+ if (responseHandle != IntPtr.Zero)
+ {
+ try
+ {
+ tcsRemoteResponse.TrySetResult(GetRemoteResponse(responseHandle));
+ }
+ catch (Exception exp)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get RemoteResponse: ", exp.Message);
+ tcsRemoteResponse.TrySetException(exp);
+ }
+ }
+ else
+ {
+ tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.System));
+ }
+ };
+ IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
+ int errCode = Interop.IoTConnectivity.Client.RemoteResource.Post(_remoteResourceHandle, representation._representationHandle, queryHandle, _responseCallbacksMap[id], id);
+ if (errCode != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to post request");
+ tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException(errCode));
+ }
+ return await tcsRemoteResponse.Task;
+ }
+
+ /// <summary>
+ /// Deletes the resource, asynchronously
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/internet
+ /// </privilege>
+ /// <privlevel>public</privlevel>
+ /// <returns>Remote response with result and representation</returns>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ public async Task<RemoteResponse> DeleteAsync()
+ {
+ TaskCompletionSource<RemoteResponse> tcsRemoteResponse = new TaskCompletionSource<RemoteResponse>();
+
+ IntPtr id = IntPtr.Zero;
+ lock (_responseCallbacksMap)
+ {
+ id = (IntPtr)_responseCallbackId++;
+ }
+ _responseCallbacksMap[id] = (IntPtr resource, int err, int requestType, IntPtr responseHandle, IntPtr userData) =>
+ {
+ IntPtr responseCallbackId = userData;
+ lock (_responseCallbacksMap)
+ {
+ _responseCallbacksMap.Remove(responseCallbackId);
+ }
+ if (err == (int)(IoTConnectivityError.Iotivity))
+ {
+ RemoteResponse response = new RemoteResponse();
+ response.Result = ResponseCode.Forbidden;
+ response.Representation = null;
+ tcsRemoteResponse.TrySetResult(response);
+ }
+ else if (responseHandle != IntPtr.Zero)
+ {
+ try
+ {
+ tcsRemoteResponse.TrySetResult(GetRemoteResponse(responseHandle));
+ }
+ catch (Exception exp)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get RemoteResponse: ", exp.Message);
+ tcsRemoteResponse.TrySetException(exp);
+ }
+ }
+ else
+ {
+ tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.System));
+ }
+ };
+
+ int errCode = Interop.IoTConnectivity.Client.RemoteResource.Delete(_remoteResourceHandle, _responseCallbacksMap[id], id);
+ if (errCode != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to delete");
+ tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException(errCode));
+ }
+ return await tcsRemoteResponse.Task;
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ internal static Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType GetConnectivityType(string hostAddress)
+ {
+ Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType type = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.None;
+
+ Log.Info(IoTConnectivityErrorFactory.LogTag, hostAddress);
+
+ if (hostAddress == IoTConnectivityClientManager.MulticastAddress)
+ {
+ type = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ipv4;
+ }
+ else
+ {
+ IPAddress address;
+ string hostName = hostAddress;
+ if (hostAddress.Contains(":"))
+ {
+ string[] hostParts = hostAddress.Split(':');
+ if (hostParts.Length == 2)
+ {
+ hostName = hostParts[0];
+ }
+ }
+ if (hostAddress.Contains("%"))
+ {
+ string[] hostParts = hostAddress.Split('%');
+ if (hostParts.Length == 2)
+ {
+ hostName = hostParts[0];
+ }
+ }
+ if (hostName.Contains("["))
+ {
+ string[] hostParts = hostName.Split('[');
+ if (hostParts.Length == 2)
+ {
+ hostName = hostParts[1];
+ }
+ }
+ Log.Info(IoTConnectivityErrorFactory.LogTag, hostName);
+ if (IPAddress.TryParse(hostName, out address))
+ {
+ switch (address.AddressFamily)
+ {
+ case System.Net.Sockets.AddressFamily.InterNetwork:
+ type = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ipv4;
+ break;
+ case System.Net.Sockets.AddressFamily.InterNetworkV6:
+ type = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ipv6;
+ break;
+ default:
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to parse for Ipv4 or Ipv6");
+ break;
+ }
+ }
+ else
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to parse hostname " + hostName);
+ }
+ }
+ return type;
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects
+ }
+
+ Interop.IoTConnectivity.Client.RemoteResource.Destroy(_remoteResourceHandle);
+ _disposed = true;
+ }
+
+ private void HandleCachePolicyChanged()
+ {
+ if (_cacheEnabled)
+ {
+ _cacheUpdatedCallback = (IntPtr resource, IntPtr representation, IntPtr userData) =>
+ {
+ if (CacheEnabled)
+ {
+ Representation repr = null;
+ try
+ {
+ repr = new Representation(representation);
+ }
+ catch (Exception exp)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to new Representation: " + exp.Message);
+ return;
+ }
+
+ CacheUpdatedEventArgs e = new CacheUpdatedEventArgs()
+ {
+ Representation = repr
+ };
+ CacheUpdated?.Invoke(this, e);
+ }
+ };
+
+ int ret = Interop.IoTConnectivity.Client.RemoteResource.StartCaching(_remoteResourceHandle, _cacheUpdatedCallback, IntPtr.Zero);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add cache updated event handler");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ else
+ {
+ int ret = Interop.IoTConnectivity.Client.RemoteResource.StopCaching(_remoteResourceHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove cache updated event handler");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ }
+
+ private void RegisterStateChangedEvent()
+ {
+ _stateChangedCallback = (IntPtr resource, int state, IntPtr userData) =>
+ {
+ StateChangedEventArgs e = new StateChangedEventArgs()
+ {
+ State = (ResourceState)state
+ };
+ _stateChangedEventHandler?.Invoke(null, e);
+ };
+
+ int ret = Interop.IoTConnectivity.Client.RemoteResource.StartMonitoring(_remoteResourceHandle, _stateChangedCallback, IntPtr.Zero);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add state changed event handler");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+
+ private void UnregisterStateChangedEvent()
+ {
+ int ret = Interop.IoTConnectivity.Client.RemoteResource.StopMonitoring(_remoteResourceHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove state changed event handler");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+
+ private void CreateRemoteResource(IntPtr resourceTypeHandle, IntPtr resourceInterfaceHandle)
+ {
+ Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType connectivityType = GetConnectivityType(HostAddress);
+ if (connectivityType == Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Unable to parse host address");
+ throw new ArgumentException("Unable to parse host address");
+ }
+ int ret = Interop.IoTConnectivity.Client.RemoteResource.Create(HostAddress, (int)connectivityType, UriPath, (int)Policy, resourceTypeHandle, resourceInterfaceHandle, out _remoteResourceHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get remote resource");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+
+ private void SetRemoteResource()
+ {
+ IntPtr hostAddressPtr, uriPathPtr;
+ int ret = Interop.IoTConnectivity.Client.RemoteResource.GetHostAddress(_remoteResourceHandle, out hostAddressPtr);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Faled to get host address");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+
+ ret = Interop.IoTConnectivity.Client.RemoteResource.GetUriPath(_remoteResourceHandle, out uriPathPtr);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Faled to get uri path");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+
+ int policy = (int)ResourcePolicy.NoProperty;
+ ret = Interop.IoTConnectivity.Client.RemoteResource.GetPolicies(_remoteResourceHandle, out policy);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Faled to get uri path");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+
+ IntPtr typesHandle, interfacesHandle;
+ ret = Interop.IoTConnectivity.Client.RemoteResource.GetTypes(_remoteResourceHandle, out typesHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get resource types");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+
+ ret = Interop.IoTConnectivity.Client.RemoteResource.GetInterfaces(_remoteResourceHandle, out interfacesHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get resource interfaces");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+
+ IntPtr deviceIdPtr;
+ ret = Interop.IoTConnectivity.Client.RemoteResource.GetDeviceId(_remoteResourceHandle, out deviceIdPtr);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get device id");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ DeviceId = (deviceIdPtr != IntPtr.Zero) ? Marshal.PtrToStringAnsi(deviceIdPtr) : string.Empty;
+ HostAddress = (hostAddressPtr != IntPtr.Zero) ? Marshal.PtrToStringAnsi(hostAddressPtr) : string.Empty;
+ UriPath = (uriPathPtr != IntPtr.Zero) ? Marshal.PtrToStringAnsi(uriPathPtr) : string.Empty;
+ Types = new ResourceTypes(typesHandle);
+ Interfaces = new ResourceInterfaces(interfacesHandle);
+ Policy = (ResourcePolicy)policy;
+ }
+
+ private RemoteResponse GetRemoteResponse(IntPtr response)
+ {
+ int result;
+ IntPtr representationHandle, optionsHandle;
+ int ret = Interop.IoTConnectivity.Server.Response.GetResult(response, out result);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get result");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+
+ ret = Interop.IoTConnectivity.Server.Response.GetRepresentation(response, out representationHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get representation");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+
+ ret = Interop.IoTConnectivity.Server.Response.GetOptions(response, out optionsHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get options");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ return new RemoteResponse()
+ {
+ Result = (ResponseCode)result,
+ Representation = new Representation(representationHandle),
+ Options = (optionsHandle == IntPtr.Zero)? null : new ResourceOptions(optionsHandle)
+ };
+ }
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/RemoteResponse.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/RemoteResponse.cs
new file mode 100755
index 0000000..667b5c3
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/RemoteResponse.cs
@@ -0,0 +1,50 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// This class represents a remote response.
+ /// It represents the response of all CRUD operations.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class RemoteResponse
+ {
+ internal RemoteResponse() { }
+
+ /// <summary>
+ /// Indicates the result of the response
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The result of the response.</value>
+ public ResponseCode Result { get; internal set; }
+
+ /// <summary>
+ /// Indicates representation of the response
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Representation of the response.</value>
+ public Representation Representation { get; internal set; }
+
+ /// <summary>
+ /// Indicates header options of the response
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Header options of the response.</value>
+ public ResourceOptions Options { get; internal set; }
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/Representation.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/Representation.cs
new file mode 100755
index 0000000..7f7b633
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/Representation.cs
@@ -0,0 +1,362 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// This class provides APIs to manage representation.
+ /// A representation is a payload of a request or a response.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class Representation : IDisposable
+ {
+ internal IntPtr _representationHandle = IntPtr.Zero;
+
+ private bool _disposed = false;
+ private ObservableCollection<Representation> _children = new ObservableCollection<Representation>();
+
+ /// <summary>
+ /// The Representation constructor
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory</exception>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ /// <code>
+ /// Representation repr = new Representation();
+ /// </code>
+ public Representation()
+ {
+ int ret = Interop.IoTConnectivity.Common.Representation.Create(out _representationHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create representation");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+
+ _children.CollectionChanged += ChildrenCollectionChanged;
+ }
+
+ // Constructor for cloning native representation object
+ internal Representation(IntPtr handleToClone)
+ {
+ int ret = (int)IoTConnectivityError.InvalidParameter;
+ if (handleToClone != IntPtr.Zero)
+ {
+ ret = Interop.IoTConnectivity.Common.Representation.Clone(handleToClone, out _representationHandle);
+ }
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create representation");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+
+ _children.CollectionChanged += ChildrenCollectionChanged;
+ }
+
+ /// <summary>
+ /// Destructor of the Representation class.
+ /// </summary>
+ ~Representation()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// The URI path of resource
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>
+ /// The URI path of resource.
+ /// Setter can throw exceptions
+ /// </value>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
+ /// <code>
+ /// Representation repr = new Representation();
+ /// repr.UriPath = "/a/light";
+ /// Console.WriteLine("URI is {0}", repr.UriPath); //Getter
+ /// </code>
+ public string UriPath
+ {
+ get
+ {
+ IntPtr path;
+ int ret = Interop.IoTConnectivity.Common.Representation.GetUriPath(_representationHandle, out path);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to Get uri");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ return (path != IntPtr.Zero) ? Marshal.PtrToStringAnsi(path) : string.Empty;
+ }
+ set
+ {
+ int ret = (int)IoTConnectivityError.InvalidParameter;
+ if (value != null)
+ ret = Interop.IoTConnectivity.Common.Representation.SetUriPath(_representationHandle, value);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set uri");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The type of resource
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The type of resource.</value>
+ /// <seealso cref="ResourceTypes"/>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
+ /// <code>
+ /// Representation repr = new Representation();
+ /// ResourceTypes types = new ResourceTypes (new List<string>(){ "org.tizen.light" });
+ /// repr.Type = types;
+ /// var type = repr.Type; // Getter
+ /// foreach (string item in type)
+ /// {
+ /// Console.WriteLine("Type is {0}", item);
+ /// }
+ /// </code>
+ public ResourceTypes Type
+ {
+ get
+ {
+ IntPtr typeHandle;
+ int ret = Interop.IoTConnectivity.Common.Representation.GetResourceTypes(_representationHandle, out typeHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get type");
+ return null;
+ }
+ return (typeHandle == IntPtr.Zero) ? null : new ResourceTypes(typeHandle);
+ }
+ set
+ {
+ int ret = (int)IoTConnectivityError.InvalidParameter;
+ if (value != null)
+ ret = Interop.IoTConnectivity.Common.Representation.SetResourceTypes(_representationHandle, value._resourceTypeHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set type");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The interface of the resource
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The interface of the resource.</value>
+ /// <seealso cref="ResourceInterfaces"/>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
+ /// <code>
+ /// Representation repr = new Representation();
+ /// ResourceInterfaces ifaces = new ResourceInterfaces (new List<string>(){ ResourceInterfaces.DefaultInterface });
+ /// repr.Interface = ifaces;
+ /// var iface = repr.Interface; // Getter
+ /// foreach (string item in iface)
+ /// {
+ /// Console.WriteLine("Interface is {0}", iface);
+ /// }
+ /// </code>
+ public ResourceInterfaces Interface
+ {
+ get
+ {
+ IntPtr interfaceHandle;
+ int ret = Interop.IoTConnectivity.Common.Representation.GetResourceInterfaces(_representationHandle, out interfaceHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get interface");
+ return null;
+ }
+ return (interfaceHandle == IntPtr.Zero) ? null : new ResourceInterfaces(interfaceHandle);
+ }
+ set
+ {
+ int ret = (int)IoTConnectivityError.InvalidParameter;
+ if (value != null)
+ ret = Interop.IoTConnectivity.Common.Representation.SetResourceInterfaces(_representationHandle, value.ResourceInterfacesHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set interface");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Current attributes of the resource
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Current attributes of the resource.</value>
+ /// <seealso cref="Attributes"/>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
+ /// <code>
+ /// Representation repr = new Representation();
+ /// Attributes attributes = new Attributes() {
+ /// { "state", "ON" },
+ /// { "dim", 10 }
+ /// };
+ /// repr.Attributes = attributes;
+ /// var newAttributes = repr.Attributes; // Getter
+ /// string strval = newAttributes["state"] as string;
+ /// int intval = (int)newAttributes["dim"];
+ /// Console.WriteLine("attributes are {0} and {1}", strval, intval);
+ /// </code>
+ public Attributes Attributes
+ {
+ get
+ {
+ IntPtr attributeHandle;
+ int ret = Interop.IoTConnectivity.Common.Representation.GetAttributes(_representationHandle, out attributeHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get attributes");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ return (attributeHandle == IntPtr.Zero) ? null : new Attributes(attributeHandle);
+ }
+ set
+ {
+ int ret = (int)IoTConnectivityError.InvalidParameter;
+ if (value != null)
+ {
+ ret = Interop.IoTConnectivity.Common.Representation.SetAttributes(_representationHandle, value._resourceAttributesHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set attributes");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// List of Child resource representation
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>List of Child resource representation.</value>
+ /// <code>
+ /// Representation repr = new Representation();
+ /// Representation child1 = new Representation();
+ /// ResourceTypes types1 = new ResourceTypes(new List<string>() { "org.tizen.light" });
+ /// child1.Type = types1;
+ /// ResourceInterfaces ifaces1 = new ResourceInterfaces(new List<string>() { ResourceInterfaces.DefaultInterface });
+ /// child1.Interface = ifaces1;
+ /// try
+ /// {
+ /// repr.Children.Add(child1);
+ /// Console.WriteLine("Number of children : {0}", repr.Children.Count);
+ /// Representation firstChild = repr.Children.ElementAt(0);
+ /// } catch(Exception ex)
+ /// {
+ /// Console.WriteLine("Exception caught : " + ex.Message);
+ /// }
+ /// </code>
+ public ICollection<Representation> Children
+ {
+ get
+ {
+ return _children;
+ }
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects
+ Type?.Dispose();
+ Interface?.Dispose();
+ Attributes?.Dispose();
+ foreach(var child in Children)
+ {
+ child.Dispose();
+ }
+ }
+
+ Interop.IoTConnectivity.Common.Representation.Destroy(_representationHandle);
+ _disposed = true;
+ }
+
+ private void ChildrenCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
+ {
+ if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
+ {
+ foreach (Representation r in e.NewItems)
+ {
+ int ret = Interop.IoTConnectivity.Common.Representation.AddChild(_representationHandle, r._representationHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add child");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ }
+ else if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
+ {
+ foreach (Representation r in e.NewItems)
+ {
+ int ret = Interop.IoTConnectivity.Common.Representation.RemoveChild(_representationHandle, r._representationHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove child");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/Request.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/Request.cs
new file mode 100755
index 0000000..93d5326
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/Request.cs
@@ -0,0 +1,103 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// Class respresenting request to a resource.
+ /// It provides APIs to manage client's request.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class Request : IDisposable
+ {
+ private bool _disposed = false;
+
+ internal Request()
+ {
+ }
+
+ /// <summary>
+ /// Destructor of the Request class.
+ /// </summary>
+ ~Request()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// The host address of the request
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The host address of the request.</value>
+ public string HostAddress { get; internal set; }
+
+ /// <summary>
+ /// The representation of the request
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The representation of the request.</value>
+ public Representation Representation { get; internal set; }
+
+ /// <summary>
+ /// The query of the request
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The query of the request.</value>
+ public ResourceQuery Query { get; internal set; }
+
+ /// <summary>
+ /// The options related to the request
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The options related to the request.</value>
+ public ResourceOptions Options { get; internal set; }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_disposed)
+ return;
+
+ if (disposing)
+ {
+ Representation?.Dispose();
+ Query?.Dispose();
+ Options?.Dispose();
+ }
+
+ _disposed = true;
+ }
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/Resource.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/Resource.cs
new file mode 100755
index 0000000..27f0c94
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/Resource.cs
@@ -0,0 +1,510 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// Abstract class respresenting a resource.
+ /// All resources need to inherit from this class.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public abstract class Resource : IDisposable
+ {
+ private IntPtr _resourceHandle = IntPtr.Zero;
+ private bool _disposed = false;
+ private ObservableCollection<Resource> _children = new ObservableCollection<Resource>();
+ private IntPtr _observerHandle = IntPtr.Zero;
+
+ /// <summary>
+ /// The constructor
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>
+ /// @a uri format would be relative URI path like '/a/light'
+ /// and its length must be less than 128.
+ /// </remarks>
+ /// <privilege>
+ /// http://tizen.org/privilege/internet
+ /// </privilege>
+ /// <privlevel>public</privlevel>
+ /// <param name="uri">The URI path of the resource</param>
+ /// <param name="types">Resource types</param>
+ /// <param name="interfaces">Resource interfaces</param>
+ /// <param name="policy">The policies of the resoruce</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <pre>
+ /// IoTConnectivityServerManager.Initialize() should be called to initialize
+ /// </pre>
+ /// <seealso cref="ResourceTypes"/>
+ /// <seealso cref="ResourceInterfaces"/>
+ /// <seealso cref="ResourcePolicy"/>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory</exception>
+ /// <code>
+ /// // Create a class which inherits from Resource
+ /// public class DoorResource : Resource
+ /// {
+ /// public DoorResource(string uri, ResourceTypes types, ResourceInterfaces interfaces, ResourcePolicy policy)
+ /// : base(uri, types, interfaces, policy) {
+ /// }
+ /// protected override Response OnDelete(Request request) {
+ /// // Do something
+ /// }
+ /// protected override Response OnGet(Request request) {
+ /// // Do something
+ /// }
+ /// // Override other abstract methods of Resource class
+ /// }
+ ///
+ /// // Use it like below
+ /// ResourceInterfaces ifaces = new ResourceInterfaces(new List<string>(){ ResourceInterfaces.DefaultInterface });
+ /// ResourceTypes types = new ResourceTypes(new List<string>(){ "oic.iot.door.new" });
+ /// Resource resource = new DoorResource("/door/uri1", types, ifaces, ResourcePolicy.Discoverable | ResourcePolicy.Observable);
+ /// </code>
+ protected Resource(string uri, ResourceTypes types, ResourceInterfaces interfaces, ResourcePolicy policy)
+ {
+ UriPath = uri;
+ Types = types;
+ Interfaces = interfaces;
+ Policy = policy;
+
+ _children.CollectionChanged += ChildrenCollectionChanged;
+
+ int ret = Interop.IoTConnectivity.Server.Observers.Create(out _observerHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create obsever handle");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Destructor of the Resource class.
+ /// </summary>
+ ~Resource()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Type details of the resource
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Type details of the resource.</value>
+ public ResourceTypes Types { get; internal set; }
+
+ /// <summary>
+ /// Interface details of the resource
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Interface details of the resource.</value>
+ public ResourceInterfaces Interfaces { get; internal set; }
+
+ /// <summary>
+ /// The policies of the resource
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The policies of the resource.</value>
+ public ResourcePolicy Policy { get; internal set; }
+
+ /// <summary>
+ /// URI path of the resource
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>URI path of the resource.</value>
+ public string UriPath { get; internal set; }
+
+ /// <summary>
+ /// List of Child resources
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>List of Child resources.</value>
+ public ICollection<Resource> Children
+ {
+ get
+ {
+ return _children;
+ }
+ }
+
+ internal IntPtr ResourceHandle
+ {
+ get
+ {
+ return _resourceHandle;
+ }
+ set
+ {
+ _resourceHandle = value;
+ }
+ }
+
+ /// <summary>
+ /// Notify the specified representation and qos.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/internet
+ /// </privilege>
+ /// <privlevel>public</privlevel>
+ /// <param name="representation">Representation.</param>
+ /// <param name="qos">The quality of service for message transfer.</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <pre>
+ /// IoTConnectivityServerManager.Initialize() should be called to initialize
+ /// </pre>
+ /// <seealso cref="Representation"/>
+ /// <seealso cref="QualityOfService"/>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
+ /// <code>
+ /// ResourceInterfaces ifaces = new ResourceInterfaces(new List<string>(){ ResourceInterfaces.DefaultInterface });
+ /// ResourceTypes types = new ResourceTypes(new List<string>(){ "oic.iot.door.new.notify" });
+ /// Resource resource = new DoorResource("/door/uri/new/notify", types, ifaces, ResourcePolicy.Discoverable | ResourcePolicy.Observable);
+ /// IoTConnectivityServerManager.RegisterResource(resource);
+ ///
+ /// Representation repr = new Representation();
+ /// repr.UriPath = "/door/uri/new/notify";
+ /// repr.Type = new ResourceTypes(new List<string>(){ "oic.iot.door.new.notify" });
+ /// repr.Attributes = new Attributes() {
+ /// _attribute, 1 }
+ /// };
+ /// resource.Notify(repr, QualityOfService.High);
+ /// </code>
+ public void Notify(Representation representation, QualityOfService qos)
+ {
+ int ret = (int)IoTConnectivityError.None;
+ ret = Interop.IoTConnectivity.Server.Resource.Notify(_resourceHandle, representation._representationHandle, _observerHandle, (int)qos);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to send notification");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+
+ /// <summary>
+ /// This is Called when the client performs get operation on this resource.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="request">A request from client</param>
+ /// <returns>A response having the representation and the result</returns>
+ protected abstract Response OnGet(Request request);
+
+ /// <summary>
+ /// This is Called when the client performs put operation on this resource.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="request">A request from client</param>
+ /// <returns>A response</returns>
+ protected abstract Response OnPut(Request request);
+
+ /// <summary>
+ /// This is Called when the client performs post operation on this resource.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="request">A request from client</param>
+ /// <returns>A response having the representation and the result</returns>
+ protected abstract Response OnPost(Request request);
+
+ /// <summary>
+ /// This is Called when the client performs delete operation on this resource.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="request">A request from client</param>
+ /// <returns>A response</returns>
+ protected abstract Response OnDelete(Request request);
+
+ /// <summary>
+ /// Called on the observing event.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="request">A request from client</param>
+ /// <param name="type">Observer type</param>
+ /// <param name="observeId">Observe identifier.</param>
+ /// <returns>Returns true if it wants to be observed, else false.</returns>
+ protected abstract bool OnObserving(Request request, ObserveType type, int observeId);
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_disposed)
+ return;
+
+ if (disposing)
+ {
+ Types?.Dispose();
+ Interfaces?.Dispose();
+ }
+
+ if (_resourceHandle != IntPtr.Zero)
+ Interop.IoTConnectivity.Server.Resource.Destroy(_resourceHandle);
+ if (_observerHandle != IntPtr.Zero)
+ Interop.IoTConnectivity.Server.Observers.Destroy(_observerHandle);
+ _disposed = true;
+ }
+
+ // This method is used as callback for Resource
+ internal void OnRequest(IntPtr resourceHandle, IntPtr requestHandle, IntPtr userData)
+ {
+ Request request = GetRequest(requestHandle);
+ Response response = null;
+
+ if (request == null)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get Request");
+ return;
+ }
+
+ try
+ {
+ int observeType;
+ int ret = Interop.IoTConnectivity.Server.Request.GetObserveType(requestHandle, out observeType);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to Get observe type");
+ return;
+ }
+ if ((ObserveType)observeType != ObserveType.NoType)
+ {
+ int observeId;
+ ret = Interop.IoTConnectivity.Server.Request.GetObserveId(requestHandle, out observeId);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to Get observe id");
+ return;
+ }
+ switch ((ObserveType)observeType)
+ {
+ case ObserveType.Register:
+ {
+ if (OnObserving(request, ObserveType.Register, observeId))
+ {
+ ret = Interop.IoTConnectivity.Server.Observers.Add(_observerHandle, observeId);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add observer id");
+ return;
+ }
+ break;
+ }
+ else
+ {
+ // If OnObserving for ObserveType.Register returns false, do not operate for Get operation after Observe operation.
+ return;
+ }
+ }
+ case ObserveType.Deregister:
+ {
+ if (OnObserving(request, ObserveType.Deregister, observeId))
+ {
+ ret = Interop.IoTConnectivity.Server.Observers.Remove(_observerHandle, observeId);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove observer id");
+ return;
+ }
+ break;
+ }
+ else
+ {
+ // If OnObserving for ObserveType.Deregister returns false, do not operate for Get operation after Observe operation.
+ return;
+ }
+ }
+ }
+ }
+ int requestType;
+ ret = Interop.IoTConnectivity.Server.Request.GetRequestType(requestHandle, out requestType);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to Get request type");
+ return;
+ }
+ switch ((Interop.IoTConnectivity.Server.RequestType)requestType)
+ {
+ case Interop.IoTConnectivity.Server.RequestType.Put:
+ {
+ response = OnPut(request);
+ break;
+ }
+ case Interop.IoTConnectivity.Server.RequestType.Get:
+ {
+ response = OnGet(request);
+ break;
+ }
+ case Interop.IoTConnectivity.Server.RequestType.Post:
+ {
+ response = OnPost(request);
+ break;
+ }
+ case Interop.IoTConnectivity.Server.RequestType.Delete:
+ {
+ response = OnDelete(request);
+ break;
+ }
+ default:
+ break;
+ }
+ if (response == null)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to send Response");
+ return;
+ }
+
+ if (!response.Send(requestHandle))
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to send Response");
+ return;
+ }
+ }
+ finally
+ {
+ request?.Dispose();
+ response?.Dispose();
+ }
+ }
+
+ private Request GetRequest(IntPtr requestHandle)
+ {
+ IntPtr hostAddressPtr;
+ int ret = Interop.IoTConnectivity.Server.Request.GetHostAddress(requestHandle, out hostAddressPtr);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to Get host address");
+ return null;
+ }
+
+ IntPtr optionsHandle = IntPtr.Zero;
+ ret = Interop.IoTConnectivity.Server.Request.GetOptions(requestHandle, out optionsHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to Get options");
+ return null;
+ }
+
+ IntPtr queryHandle = IntPtr.Zero;
+ ret = Interop.IoTConnectivity.Server.Request.GetQuery(requestHandle, out queryHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to Get Query");
+ return null;
+ }
+
+ IntPtr representationHandle = IntPtr.Zero;
+ ret = Interop.IoTConnectivity.Server.Request.GetRepresentation(requestHandle, out representationHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to Get representation");
+ return null;
+ }
+
+ ResourceOptions opts = null;
+ ResourceQuery query = null;
+ Representation representation = null;
+ try
+ {
+ opts = (optionsHandle == IntPtr.Zero) ? null : new ResourceOptions(optionsHandle);
+ }
+ catch (Exception exp)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to new ResourceOptions: " + exp.Message);
+ return null;
+ }
+
+ try
+ {
+ query = (queryHandle == IntPtr.Zero) ? null : new ResourceQuery(queryHandle);
+ }
+ catch (Exception exp)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to new ResourceQuery: " + exp.Message);
+ opts?.Dispose();
+ return null;
+ }
+
+ try
+ {
+ representation = (representationHandle == IntPtr.Zero) ? null : new Representation(representationHandle);
+ }
+ catch (Exception exp)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to new Representation: " + exp.Message);
+ opts?.Dispose();
+ query?.Dispose();
+ return null;
+ }
+
+ return new Request()
+ {
+ HostAddress = (hostAddressPtr != IntPtr.Zero) ? Marshal.PtrToStringAnsi(hostAddressPtr) : string.Empty,
+ Options = opts,
+ Query = query,
+ Representation = representation
+ };
+ }
+
+ private void ChildrenCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs eventArgs)
+ {
+ if (eventArgs.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
+ {
+ foreach (Resource r in eventArgs.NewItems)
+ {
+ int ret = Interop.IoTConnectivity.Server.Resource.BindChildResource(_resourceHandle, r._resourceHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to bind resource ");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ }
+ else if (eventArgs.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
+ {
+ foreach (Resource r in eventArgs.NewItems)
+ {
+ int ret = Interop.IoTConnectivity.Server.Resource.UnbindChildResource(_resourceHandle, r._resourceHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to unbind resource");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResourceFoundEventArgs.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResourceFoundEventArgs.cs
new file mode 100755
index 0000000..86a9c8a
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResourceFoundEventArgs.cs
@@ -0,0 +1,54 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// This class represents event arguments of the ResourceFound event.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class ResourceFoundEventArgs : EventArgs
+ {
+ internal ResourceFoundEventArgs() { }
+
+ /// <summary>
+ /// Indicates the request id.
+ /// This is the same request id returned by the <see cref="IoTConnectivityClientManager.StartFindingResource()"/> API.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The request id.</value>
+ public int RequestId { get; internal set; }
+
+ /// <summary>
+ /// Indicates to continuously receive the event for finding resource.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Continuously receive the event for finding resource.</value>
+ public bool EventContinue { get; set; }
+
+ /// <summary>
+ /// Remote resource which is found after <see cref="IoTConnectivityClientManager.StartFindingResource()"/>.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Remote resource which is found after <see cref="IoTConnectivityClientManager.StartFindingResource()"/>.</value>
+ /// <seealso cref="IoTConnectivityClientManager.ResourceFound"/>
+ /// <seealso cref="IoTConnectivityClientManager.StartFindingResource()"/>
+ public RemoteResource Resource { get; internal set; }
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResourceInterfaces.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResourceInterfaces.cs
new file mode 100755
index 0000000..8d0f789
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResourceInterfaces.cs
@@ -0,0 +1,312 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// This class contains resource interfaces and provides APIs to manage, add, remove those interfaces.
+ /// A resource interface indicates a class or category of resources.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class ResourceInterfaces : IEnumerable<string>, IDisposable
+ {
+ /// <summary>
+ /// Default Interface
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public const string DefaultInterface = "oic.if.baseline";
+
+ /// <summary>
+ /// List Links Interface which is used to list the references to other resources contained in a resource.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public const string LinkInterface = "oic.if.ll";
+
+ /// <summary>
+ /// Batch Interface which is used to manipulate (GET, PUT, POST, DELETE) on other resource contained in a resource.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public const string BatchInterface = "oic.if.b";
+
+ /// <summary>
+ /// Group Interface which is used to manipulate (GET, PUT, POST) a group of remote resources.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public const string GroupInterface = "oic.mi.grp";
+
+ /// <summary>
+ /// Read-Only Interface which is used to limit the methods that can be applied to a resource to GET only.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public const string ReadonlyInterface = "oic.if.r";
+
+ private readonly IntPtr _resourceInterfacesHandle = IntPtr.Zero;
+ private const int MaxLength = 61;
+ private readonly HashSet<string> _resourceInterfaces = new HashSet<string>();
+ private bool _disposed = false;
+
+ /// <summary>
+ /// Constructor of ResourceInterfaces
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <seealso cref="Add()"/>
+ /// <seealso cref="Remove()"/>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory</exception>
+ /// <code>
+ /// ResourceInterfaces resourceInterfaces = new ResourceInterfaces();
+ /// </code>
+ public ResourceInterfaces()
+ {
+ int ret = Interop.IoTConnectivity.Common.ResourceInterfaces.Create(out _resourceInterfacesHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create interface");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Constructor of ResourceInterfaces using list of interfaces
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="ifaces">List of resource interfaces</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory</exception>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ /// <code>
+ /// ResourceInterfaces resourceInterfaces = new ResourceInterfaces(new List<string>()
+ /// { ResourceInterfaces.LinkInterface, ResourceInterfaces.ReadonlyInterface });
+ /// </code>
+ public ResourceInterfaces(IEnumerable<string> ifaces)
+ {
+ int ret = Interop.IoTConnectivity.Common.ResourceInterfaces.Create(out _resourceInterfacesHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create interface");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ foreach (string iface in ifaces)
+ {
+ Add(iface);
+ }
+ }
+
+ internal ResourceInterfaces(IntPtr ifacesHandleToClone)
+ {
+ int ret = Interop.IoTConnectivity.Common.ResourceInterfaces.Clone(ifacesHandleToClone, out _resourceInterfacesHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create interface");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+
+ Interop.IoTConnectivity.Common.ResourceInterfaces.ForeachCallback cb = (string iface, IntPtr data) =>
+ {
+ _resourceInterfaces.Add(iface);
+ return true;
+ };
+
+ ret = Interop.IoTConnectivity.Common.ResourceInterfaces.Foreach(ifacesHandleToClone, cb, IntPtr.Zero);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create type");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Destructor of the ResourceInterfaces class.
+ /// </summary>
+ ~ResourceInterfaces()
+ {
+ Dispose(false);
+ }
+
+ internal IntPtr ResourceInterfacesHandle
+ {
+ get
+ {
+ return _resourceInterfacesHandle;
+ }
+ }
+
+ /// <summary>
+ /// Indicates count of interfaces in the list
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Count of interfaces in the list.</value>
+ /// <code>
+ /// ResourceInterfaces resourceInterfaces = new ResourceInterfaces(new List<string>()
+ /// { ResourceInterfaces.LinkInterface, ResourceInterfaces.ReadonlyInterface });
+ /// Console.WriteLine("There are {0} interfaces", resourceInterfaces.Count);
+ /// </code>
+ public int Count
+ {
+ get
+ {
+ return _resourceInterfaces.Count;
+ }
+ }
+
+ /// <summary>
+ /// Adds a resource interface into the list.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>
+ /// @a item could be a value such as <see cref="DefaultInterface"/>
+ /// </remarks>
+ /// <param name="item">The string data to insert into the resource interfaces</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <seealso cref="Remove()"/>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ /// <code>
+ /// ResourceInterfaces resourceInterfaces = new ResourceInterfaces();
+ /// resourceInterfaces.Add(ResourceInterfaces.BatchInterface);
+ /// </code>
+ public void Add(string item)
+ {
+ if (IsValid(item))
+ {
+ int ret = Interop.IoTConnectivity.Common.ResourceInterfaces.Add(_resourceInterfacesHandle, item);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add interface");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ _resourceInterfaces.Add(item);
+ }
+ else
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Invalid interface");
+ throw IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.InvalidParameter);
+ }
+ }
+
+ /// <summary>
+ /// Removes a resource interface from the list
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="item">The string data to delete from the resource ifaces</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <seealso cref="Add()"/>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
+ /// <code>
+ /// ResourceInterfaces resourceInterfaces = new ResourceInterfaces(new List<string>(){ ResourceInterfaces.BatchInterface });
+ /// resourceInterfaces.Add(ResourceInterfaces.BatchInterface);
+ /// </code>
+ public void Remove(string item)
+ {
+ bool isRemoved = _resourceInterfaces.Remove(item);
+ if (isRemoved)
+ {
+ int ret = Interop.IoTConnectivity.Common.ResourceInterfaces.Remove(_resourceInterfacesHandle, item);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove interface");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ else
+ throw IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.InvalidParameter);
+ }
+
+ /// <summary>
+ /// Return enumerator for the list of interfaces
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <returns>The enumerator</returns>
+ /// <code>
+ /// ResourceInterfaces resourceInterfaces = new ResourceInterfaces(new List<string>()
+ /// { ResourceInterfaces.LinkInterface, ResourceInterfaces.ReadonlyInterface });
+ /// foreach(string item in resourceInterfaces)
+ /// {
+ /// Console.WriteLine("Interface : {0}", item);
+ /// }
+ /// </code>
+ public IEnumerator<string> GetEnumerator()
+ {
+ return _resourceInterfaces.GetEnumerator();
+ }
+
+ /// <summary>
+ /// Return enumerator for the list of interfaces
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <returns>The enumerator</returns>
+ /// <code>
+ /// ResourceInterfaces resourceInterfaces = new ResourceInterfaces(new List<string>()
+ /// { ResourceInterfaces.LinkInterface, ResourceInterfaces.ReadonlyInterface });
+ /// foreach(string item in resourceInterfaces)
+ /// {
+ /// Console.WriteLine("Interface : {0}", item);
+ /// }
+ /// </code>
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return _resourceInterfaces.GetEnumerator();
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ internal static bool IsValid(string type)
+ {
+ Regex r = new Regex("^[a-zA-Z0-9.-]+$");
+ return (type.Length <= MaxLength && type.Length > 0 && char.IsLower(type[0]) && r.IsMatch(type));
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects
+ }
+
+ Interop.IoTConnectivity.Common.ResourceInterfaces.Destroy(_resourceInterfacesHandle);
+ _disposed = true;
+ }
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResourceOptions.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResourceOptions.cs
new file mode 100755
index 0000000..37ee5e4
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResourceOptions.cs
@@ -0,0 +1,474 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// This class represents resource options. It provides APIs to manage them.\n
+ /// The iotcon options API provides methods for managing vendor specific options of coap packet.\n
+ /// See more about coap packet in http://tools.ietf.org/html/rfc7252.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class ResourceOptions : IDictionary<ushort, string>, IDisposable
+ {
+ internal const int MaxSize = 2;
+ internal const int IdMin = 2048;
+ internal const int IdMax = 3000;
+ internal const int DataMax = 15;
+
+ internal IntPtr _resourceOptionsHandle = IntPtr.Zero;
+ private readonly IDictionary<ushort, string> _options = new Dictionary<ushort, string>();
+ private bool _disposed = false;
+
+ /// <summary>
+ /// The resource options constructor
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <seealso cref="Add()"/>
+ /// <seealso cref="Remove()"/>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory</exception>
+ /// <code>
+ /// ResourceOptions options = new ResourceOptions();
+ /// </code>
+ public ResourceOptions()
+ {
+ int ret = Interop.IoTConnectivity.Common.Options.Create(out _resourceOptionsHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create options");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+
+ // internal constructor
+ internal ResourceOptions(IntPtr handleToClone)
+ {
+ int ret = Interop.IoTConnectivity.Common.Options.Create(out _resourceOptionsHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create options");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+
+ Interop.IoTConnectivity.Common.Options.OptionsCallback forEachCallback = (ushort id, string value, IntPtr userData) =>
+ {
+ Add(id, value);
+ return true;
+ };
+
+ ret = Interop.IoTConnectivity.Common.Options.ForEach(handleToClone, forEachCallback, IntPtr.Zero);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to iterate options");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Destructor of the ResourceOptions class.
+ /// </summary>
+ ~ResourceOptions()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Contains all the Option keys
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>All the Option keys.</value>
+ /// <code>
+ /// ResourceOptions options = new ResourceOptions();
+ /// options.Add(2050, "sample-data");
+ /// options.Add(2055, "sample value");
+ /// var keys = options.Keys;
+ /// Console.WriteLine("Resource options contains keys {0} and {1}", keys.ElementAt(0), keys.ElementAt(1));
+ /// </code>
+ public ICollection<ushort> Keys
+ {
+ get
+ {
+ return _options.Keys;
+ }
+ }
+
+ /// <summary>
+ /// Contains all the Option values
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>All the Option values.</value>
+ /// <code>
+ /// ResourceOptions options = new ResourceOptions();
+ /// options.Add(2050, "sample-data");
+ /// options.Add(2055, "sample value");
+ /// var values = options.Values;
+ /// Console.WriteLine("Resource options contains values {0} and {1}", values.ElementAt(0), values.ElementAt(1));
+ /// </code>
+ public ICollection<string> Values
+ {
+ get
+ {
+ return _options.Values;
+ }
+ }
+
+ /// <summary>
+ /// Gets the number of options
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The number of options.</value>
+ /// <code>
+ /// ResourceOptions options = new ResourceOptions();
+ /// options.Add(2050, "sample-data");
+ /// options.Add(2055, "sample value");
+ /// var count = options.Count;
+ /// Console.WriteLine("There are {0} keys in the options object", count);
+ /// </code>
+ public int Count
+ {
+ get
+ {
+ return _options.Count;
+ }
+ }
+
+ /// <summary>
+ /// Represents whether the collection is readonly
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Whether the collection is readonly.</value>
+ /// <code>
+ /// ResourceOptions options = new ResourceOptions();
+ /// if (options.IsReadOnly)
+ /// Console.WriteLine("Read only options");
+ /// </code>
+ public bool IsReadOnly
+ {
+ get
+ {
+ return _options.IsReadOnly;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the option data
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The option data.</value>
+ /// <param name="key">The option id to get or set.</param>
+ /// <returns>The option with the specified id.</returns>
+ /// <code>
+ /// ResourceOptions options = new ResourceOptions();
+ /// options[2055] = "sample-data";
+ /// Console.WriteLine("Option has : {0}", options[2055]);
+ /// </code>
+ public string this[ushort key]
+ {
+ get
+ {
+ return _options[key];
+ }
+ set
+ {
+ Add(key, value);
+ }
+ }
+
+ /// <summary>
+ /// Checks whether the given key exists in Options collection
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="key">The key to look for</param>
+ /// <returns>true if exists. Otherwise, false</returns>
+ /// <code>
+ /// ResourceOptions options = new ResourceOptions();
+ /// options.Add(2050, "sample-data");
+ /// if (options.ContainsKey(2050))
+ /// Console.WriteLine("options conatins key : 2050");
+ /// </code>
+ public bool ContainsKey(ushort key)
+ {
+ return _options.ContainsKey(key);
+ }
+
+ /// <summary>
+ /// Adds a new id and a correspoding data into the options.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>
+ /// ResourceOptions can have up to 2 options. \n
+ /// key is always situated between 2048 and 3000. \n
+ /// Length of option data is less than or equal to 15.
+ /// </remarks>
+ /// <param name="key">The id of the option to insert</param>
+ /// <param name="value">The string data to insert into the options</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <seealso cref="Remove()"/>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ /// <code>
+ /// ResourceOptions options = new ResourceOptions();
+ /// options.Add(2050, "sample-data");
+ /// </code>
+ public void Add(ushort key, string value)
+ {
+ int ret = (int)IoTConnectivityError.InvalidParameter;
+ if (IsValid(key, value))
+ {
+ ret = Interop.IoTConnectivity.Common.Options.Add(_resourceOptionsHandle, key, value);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add option");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ _options.Add(key, value);
+ }
+ else
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Invalid options");
+ throw IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.InvalidParameter);
+ }
+ }
+
+ /// <summary>
+ /// Removes the id and its associated data from the options.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="key">The id of the option to delete</param>
+ /// <returns>True if operation is successful. Otherwise, false</returns>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <seealso cref="Add()"/>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ /// <code>
+ /// ResourceOptions options = new ResourceOptions();
+ /// options.Add(2050, "12345");
+ /// var result = options.Remove(2050);
+ /// </code>
+ public bool Remove(ushort key)
+ {
+ int ret = Interop.IoTConnectivity.Common.Options.Remove(_resourceOptionsHandle, key);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove option");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+
+ bool isRemoved = _options.Remove(key);
+
+ return isRemoved;
+ }
+
+ /// <summary>
+ /// Gets the value associated with the specified key.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="key">The option id</param>
+ /// <param name="value">Value corresponding to option id</param>
+ /// <returns>True if the key exists, false otherwise</returns>
+ /// <code>
+ /// ResourceOptions options = new ResourceOptions();
+ /// options.Add(2050, "12345");
+ /// string value;
+ /// var isPresent = options.TryGetValue(2050, out value);
+ /// if (isPresent)
+ /// Console.WriteLine("value : {0}", value);
+ /// </code>
+ public bool TryGetValue(ushort key, out string value)
+ {
+ return _options.TryGetValue(key, out value);
+ }
+
+ /// <summary>
+ /// Adds options key and value as a key value pair
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="item">The key value pair</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <seealso cref="Remove()"/>
+ /// <code>
+ /// ResourceOptions options = new ResourceOptions();
+ /// options.Add(new KeyValuePair<ushort, string>(2050, "12345"));
+ /// </code>
+ public void Add(KeyValuePair<ushort, string> item)
+ {
+ Add(item.Key, item.Value);
+ }
+
+ /// <summary>
+ /// Clears the Options collection
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <code>
+ /// ResourceOptions options = new ResourceOptions();
+ /// options.Add(2050, "12345");
+ /// options.Add(2055, "sample");
+ /// options.Clear();
+ /// </code>
+ public void Clear()
+ {
+ foreach (ushort key in Keys)
+ {
+ int ret = Interop.IoTConnectivity.Common.Options.Remove(_resourceOptionsHandle, key);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove option");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ };
+ }
+ _options.Clear();
+ }
+
+ /// <summary>
+ /// Checks if the given option pair exists
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="item">The key value pair</param>
+ /// <returns>True if exists. Otherwise, false</returns>
+ /// <code>
+ /// ResourceOptions options = new ResourceOptions();
+ /// options.Add(new KeyValuePair<ushort, string>(2050, "12345"));
+ /// var isPresent = options.Contains(new KeyValuePair<ushort, string>(2050, "12345"));
+ /// if (isPresent)
+ /// Console.WriteLine("Key value pair is present");
+ /// </code>
+ public bool Contains(KeyValuePair<ushort, string> item)
+ {
+ return _options.Contains(item);
+ }
+
+ /// <summary>
+ /// Copies the elements of the options collection to an Array, starting at a particular index.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="array">The destination array</param>
+ /// <param name="arrayIndex">Index parameter</param>
+ /// <code>
+ /// ResourceOptions options = new ResourceOptions();
+ /// options.Add(new KeyValuePair<ushort, string>(2050, "12345"));
+ /// KeyValuePair<ushort, string>[] dest = new KeyValuePair<ushort, string>[options.Count];
+ /// options.CopyTo(dest, 0);
+ /// Console.WriteLine("Dest conatins ({0}, {1})", dest[0].Key, dest[0].Value);
+ /// </code>
+ public void CopyTo(KeyValuePair<ushort, string>[] array, int arrayIndex)
+ {
+ _options.CopyTo(array, arrayIndex);
+ }
+
+ /// <summary>
+ /// Remove the given key value pair from the options
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="item">The key value pair to remove</param>
+ /// <returns>True if operation is successful. Otherwise, false</returns>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <seealso cref="Add()"/>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ /// <code>
+ /// ResourceOptions options = new ResourceOptions();
+ /// options.Add(new KeyValuePair<ushort, string>(2050, "12345"));
+ /// var result = options.Remove(new KeyValuePair<ushort, string>(2050, "12345"));
+ /// </code>
+ public bool Remove(KeyValuePair<ushort, string> item)
+ {
+ return Remove(item.Key);
+ }
+
+ /// <summary>
+ /// Get the enumerator to options collection
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <returns>Enumerator to option pairs</returns>
+ /// <code>
+ /// ResourceOptions options = new ResourceOptions();
+ /// options.Add(new KeyValuePair<ushort, string>(2050, "sample1"));
+ /// options.Add(new KeyValuePair<ushort, string>(2055, "sample2"));
+ /// foreach (KeyValuePair<string, object> pair in options)
+ /// {
+ /// Console.WriteLine("key : {0}, value : {1}", pair.Key, pair.Value);
+ /// }
+ /// </code>
+ public IEnumerator<KeyValuePair<ushort, string>> GetEnumerator()
+ {
+ return _options.GetEnumerator();
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Get the enumerator to options collection
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <returns>Enumerator to option pairs</returns>
+ /// <code>
+ /// ResourceOptions options = new ResourceOptions();
+ /// options.Add(new KeyValuePair<ushort, string>(2050, "sample1"));
+ /// options.Add(new KeyValuePair<ushort, string>(2055, "sample2"));
+ /// foreach (KeyValuePair<string, object> pair in options)
+ /// {
+ /// Console.WriteLine("key : {0}, value : {1}", pair.Key, pair.Value);
+ /// }
+ /// </code>
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return _options.GetEnumerator();
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects
+ }
+
+ Interop.IoTConnectivity.Common.Options.Destroy(_resourceOptionsHandle);
+ _disposed = true;
+ }
+
+ private bool IsValid(ushort key, string value)
+ {
+ return (key > IdMin && key < IdMax && value.Length <= DataMax && _options.Count() < MaxSize);
+ }
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResourcePolicy.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResourcePolicy.cs
new file mode 100755
index 0000000..ca1082a
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResourcePolicy.cs
@@ -0,0 +1,64 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// Enumeration for policy which can be held in a resource.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum ResourcePolicy
+ {
+ /// <summary>
+ /// Indicates resource uninitialized
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ NoProperty = 0,
+ /// <summary>
+ /// Indicates resource that is allowed to be discovered
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ Discoverable = (1 << 0),
+ /// <summary>
+ /// Indicates resource that is allowed to be observed
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ Observable = (1 << 1),
+ /// <summary>
+ /// Indicates resource initialized and activated
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ Active = (1 << 2),
+ /// <summary>
+ /// Indicates resource which takes some delay to respond
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ Slow = (1 << 3),
+ /// <summary>
+ /// Indicates secure resource
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ Secure = (1 << 4),
+ /// <summary>
+ /// When this bit is set, the resource is allowed to be discovered only if discovery request contains an explicit querystring.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ ExplicitDiscoverable = (1 << 5),
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResourceQuery.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResourceQuery.cs
new file mode 100755
index 0000000..27a8135
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResourceQuery.cs
@@ -0,0 +1,563 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// This class provides APIs to manage query of request.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class ResourceQuery : IDictionary<string, string>, IDisposable
+ {
+ internal const int QueryMaxLenth = 64;
+ internal IntPtr _resourceQueryHandle = IntPtr.Zero;
+ private readonly IDictionary<string, string> _query = new Dictionary<string, string>();
+ private bool _disposed = false;
+
+ /// <summary>
+ /// The resource query constructor
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <seealso cref="Add()"/>
+ /// <seealso cref="Remove()"/>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory</exception>
+ /// <code>
+ /// ResourceQuery query = new ResourceQuery();
+ /// </code>
+ public ResourceQuery()
+ {
+ int ret = Interop.IoTConnectivity.Common.Query.Create(out _resourceQueryHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create query");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+
+ internal ResourceQuery(IntPtr resourceQueryHandleToClone)
+ {
+ int ret = Interop.IoTConnectivity.Common.Query.Create(out _resourceQueryHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create query");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+
+ Interop.IoTConnectivity.Common.Query.QueryCallback forEachCallback = (string key, string value, IntPtr userData) =>
+ {
+ Add(key, value);
+ return true;
+ };
+
+ ret = Interop.IoTConnectivity.Common.Query.Foreach(resourceQueryHandleToClone, forEachCallback, IntPtr.Zero);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to iterate query");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Destructor of the ResourceQuery class.
+ /// </summary>
+ ~ResourceQuery()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Gets and sets the resource type of the query
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The resource type of the query.</value>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
+ /// <code>
+ /// ResourceQuery query = new ResourceQuery();
+ /// query.Type = "org.tizen.light";
+ /// Console.WriteLine("Type of query : {0}", query.Type);
+ /// </code>
+ public string Type
+ {
+ get
+ {
+ IntPtr type;
+ int ret = Interop.IoTConnectivity.Common.Query.GetResourceType(_resourceQueryHandle, out type);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get type");
+ return "";
+ }
+ return (type != IntPtr.Zero) ? Marshal.PtrToStringAnsi(type) : string.Empty;
+ }
+ set
+ {
+ int ret = (int)IoTConnectivityError.InvalidParameter;
+ if (ResourceTypes.IsValid(value))
+ ret = Interop.IoTConnectivity.Common.Query.SetResourceType(_resourceQueryHandle, value);
+
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set type");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets and sets the resource interface of the query
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>
+ /// The resource interface of the query.
+ /// Setter value could be a value such as <see cref="ResourceInterfaces.DefaultInterface"/>
+ /// </value>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
+ /// <code>
+ /// ResourceQuery query = new ResourceQuery();
+ /// query.Interface = ResourceInterfaces.LinkInterface;
+ /// </code>
+ public string Interface
+ {
+ get
+ {
+ IntPtr iface;
+ int ret = Interop.IoTConnectivity.Common.Query.GetInterface(_resourceQueryHandle, out iface);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get interface");
+ return "";
+ }
+ return (iface != IntPtr.Zero) ? Marshal.PtrToStringAnsi(iface) : string.Empty;
+ }
+ set
+ {
+ int ret = (int)IoTConnectivityError.InvalidParameter;
+ if (ResourceInterfaces.IsValid(value))
+ ret = Interop.IoTConnectivity.Common.Query.SetInterface(_resourceQueryHandle, value);
+
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set interface");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Contains all the query keys
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>All the query keys.</value>
+ /// <code>
+ /// ResourceQuery query = new ResourceQuery();
+ /// query.Add("key", "value");
+ /// query.Add("newKey", "sample value");
+ /// var keys = query.Keys;
+ /// Console.WriteLine("Resource query contains keys {0} and {1}", keys.ElementAt(0), keys.ElementAt(1));
+ /// </code>
+ public ICollection<string> Keys
+ {
+ get
+ {
+ return _query.Keys;
+ }
+ }
+
+ /// <summary>
+ /// Contains all the query values
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>All the query values.</value>
+ /// <code>
+ /// ResourceQuery query = new ResourceQuery();
+ /// query.Add("key", "value");
+ /// query.Add("newKey", "sample value");
+ /// var values = query.Values;
+ /// Console.WriteLine("Resource query contains values {0} and {1}", values.ElementAt(0), values.ElementAt(1));
+ /// </code>
+ public ICollection<string> Values
+ {
+ get
+ {
+ return _query.Values;
+ }
+ }
+
+ /// <summary>
+ /// Gets the number of query elements
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The number of query elements.</value>
+ /// <code>
+ /// ResourceQuery query = new ResourceQuery();
+ /// query.Add("key", "value");
+ /// query.Add("newKey", "sample value");
+ /// var count = query.Count;
+ /// Console.WriteLine("There are {0} keys in the query object", count);
+ /// </code>
+ public int Count
+ {
+ get
+ {
+ return _query.Count;
+ }
+ }
+
+ /// <summary>
+ /// Represents whether the collection is readonly
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Whether the collection is readonly.</value>
+ /// <code>
+ /// ResourceQuery query = new ResourceQuery();
+ /// if (query.IsReadOnly)
+ /// Console.WriteLine("Read only query");
+ /// </code>
+ public bool IsReadOnly
+ {
+ get
+ {
+ return _query.IsReadOnly;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the query data
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The query data.</value>
+ /// <param name="key">The query key to get or set.</param>
+ /// <returns>The query with the specified key.</returns>
+ /// <code>
+ /// ResourceQuery query = new ResourceQuery();
+ /// query["key1"] = "sample-data";
+ /// Console.WriteLine("query has : {0}", query["key1"]);
+ /// </code>
+ public string this[string key]
+ {
+ get
+ {
+ return _query[key];
+ }
+
+ set
+ {
+ Add(key, value);
+ }
+ }
+
+ /// <summary>
+ /// Checks whether the given key exists in Query collection
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="key">The key to look for</param>
+ /// <returns>true if exists. Otherwise, false</returns>
+ /// <code>
+ /// ResourceQuery query = new ResourceQuery();
+ /// query.Add("key1", "value1");
+ /// if (query.ContainsKey("key1"))
+ /// Console.WriteLine("query conatins key : key1");
+ /// </code>
+ public bool ContainsKey(string key)
+ {
+ return _query.ContainsKey(key);
+ }
+
+ /// <summary>
+ /// Adds a new key and correspoding value into the query.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>
+ /// The full length of query should be less than or equal to 64.
+ /// </remarks>
+ /// <param name="key">The key of the query to insert</param>
+ /// <param name="value">The string data to insert into the query</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <seealso cref="Remove()"/>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
+ /// <code>
+ /// ResourceQuery query = new ResourceQuery();
+ /// query.Add("key1", "value1");
+ /// </code>
+ public void Add(string key, string value)
+ {
+ if (CanAddQuery(key, value))
+ {
+ int ret = Interop.IoTConnectivity.Common.Query.Add(_resourceQueryHandle, key, value);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add query");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ _query.Add(key, value);
+ }
+ else
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Query cannot be added");
+ throw IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.InvalidParameter);
+ }
+ }
+
+ /// <summary>
+ /// Removes the key and its associated value from the query.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="key">The id of the query to delete</param>
+ /// <returns>True if operation is successful. Otherwise, false</returns>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <seealso cref="Add()"/>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
+ /// <code>
+ /// ResourceQuery query = new ResourceQuery();
+ /// query.Add("key1", "value1");
+ /// var result = query.Remove("key1");
+ /// </code>
+ public bool Remove(string key)
+ {
+ int ret = Interop.IoTConnectivity.Common.Query.Remove(_resourceQueryHandle, key);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove query");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+
+ bool isRemoved = _query.Remove(key);
+
+ return isRemoved;
+ }
+
+ /// <summary>
+ /// Gets the value associated with the specified key.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="key">The query key</param>
+ /// <param name="value">Value corresponding to query key</param>
+ /// <returns>True if the key exists, false otherwise</returns>
+ /// <code>
+ /// ResourceQuery query = new ResourceQuery();
+ /// query.Add("key1", "value1");
+ /// string value;
+ /// var isPresent = query.TryGetValue("key1", out value);
+ /// if (isPresent)
+ /// Console.WriteLine("value : {0}", value);
+ /// </code>
+ public bool TryGetValue(string key, out string value)
+ {
+ return _query.TryGetValue(key, out value);
+ }
+
+ /// <summary>
+ /// Adds query key and value as a key value pair
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="item">The key value pair</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <seealso cref="Remove()"/>
+ /// <code>
+ /// ResourceQuery query = new ResourceQuery();
+ /// query.Add(new KeyValuePair<string, string>("key1", "value1"));
+ /// </code>
+ public void Add(KeyValuePair<string, string> item)
+ {
+ Add(item.Key, item.Value);
+ }
+
+ /// <summary>
+ /// Clears the Query collection
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
+ /// <code>
+ /// ResourceQuery query = new ResourceQuery();
+ /// query.Add("key1", "value1");
+ /// query.Add("key2", "value2");
+ /// query.Clear();
+ /// </code>
+ public void Clear()
+ {
+ foreach (string key in _query.Keys)
+ {
+ int ret = Interop.IoTConnectivity.Common.Query.Remove(_resourceQueryHandle, key);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to clear query");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+ _query.Clear();
+ }
+
+ /// <summary>
+ /// Checks if the given query pair exists
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="item">The key value pair</param>
+ /// <returns>True if exists. Otherwise, false</returns>
+ /// <code>
+ /// ResourceQuery query = new ResourceQuery();
+ /// query.Add(new KeyValuePair<string, string>("key1", "value1"));
+ /// var isPresent = query.Contains(new KeyValuePair<string, string>("key1", "value1"));
+ /// if (isPresent)
+ /// Console.WriteLine("Key value pair is present");
+ /// </code>
+ public bool Contains(KeyValuePair<string, string> item)
+ {
+ return _query.Contains(item);
+ }
+
+ /// <summary>
+ /// Copies the elements of the query collection to an Array, starting at a particular index.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="array">The destination array</param>
+ /// <param name="arrayIndex">Index parameter</param>
+ /// <code>
+ /// ResourceQuery query = new ResourceQuery();
+ /// query.Add(new KeyValuePair<string, string>("key1", "value1"));
+ /// KeyValuePair<string, string>[] dest = new KeyValuePair<string, string>[query.Count];
+ /// query.CopyTo(dest, 0);
+ /// Console.WriteLine("Dest conatins ({0}, {1})", dest[0].Key, dest[0].Value);
+ /// </code>
+ public void CopyTo(KeyValuePair<string, string>[] array, int arrayIndex)
+ {
+ _query.CopyTo(array, arrayIndex);
+ }
+
+ /// <summary>
+ /// Remove the given key value pair from the query
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="item">The key value pair to remove</param>
+ /// <returns>True if operation is successful. Otherwise, false</returns>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <seealso cref="Add()"/>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ /// <code>
+ /// ResourceQuery query = new ResourceQuery();
+ /// query.Add(new KeyValuePair<string, string>("key1", "value1"));
+ /// var result = query.Remove(new KeyValuePair<string, string>("key1", "value1"));
+ /// </code>
+ public bool Remove(KeyValuePair<string, string> item)
+ {
+ return Remove(item.Key);
+ }
+
+ /// <summary>
+ /// Get the enumerator to query collection
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <returns>Enumerator to query pairs</returns>
+ /// <code>
+ /// ResourceQuery query = new ResourceQuery();
+ /// query.Add(new KeyValuePair<string, string>("key1", "value1"));
+ /// query.Add(new KeyValuePair<string, string>("key2", "value2"));
+ /// foreach (KeyValuePair<string, string> pair in query)
+ /// {
+ /// Console.WriteLine("key : {0}, value : {1}", pair.Key, pair.Value);
+ /// }
+ /// </code>
+ public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
+ {
+ return _query.GetEnumerator();
+ }
+
+ /// <summary>
+ /// Get the enumerator to query collection
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <returns>Enumerator to query pairs</returns>
+ /// <code>
+ /// ResourceQuery query = new ResourceQuery();
+ /// query.Add(new KeyValuePair<string, string>("key1", "value1"));
+ /// query.Add(new KeyValuePair<string, string>("key2", "value2"));
+ /// foreach (KeyValuePair<string, string> pair in query)
+ /// {
+ /// Console.WriteLine("key : {0}, value : {1}", pair.Key, pair.Value);
+ /// }
+ /// </code>
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return _query.GetEnumerator();
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects
+ }
+
+ Interop.IoTConnectivity.Common.Query.Destroy(_resourceQueryHandle);
+ _disposed = true;
+ }
+
+ private bool CanAddQuery(string newKey, string newValue)
+ {
+ int queryLenth = 0;
+ foreach (string key in Keys)
+ {
+ queryLenth += key.Length + 2;
+ }
+ foreach (string value in Values)
+ {
+ queryLenth += value.Length;
+ }
+
+ if ((newKey.Length + newValue.Length + queryLenth + 2) < QueryMaxLenth)
+ return true;
+
+ return false;
+ }
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResourceState.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResourceState.cs
new file mode 100755
index 0000000..32eb72d
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResourceState.cs
@@ -0,0 +1,37 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// Enumeration for states of remote resource.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum ResourceState
+ {
+ /// <summary>
+ /// Indicates remote resource is alive
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ Alive = 0,
+ /// <summary>
+ /// Indicates remote resource is lost
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ LostSignal
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResourceTypes.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResourceTypes.cs
new file mode 100755
index 0000000..21bd1b3
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResourceTypes.cs
@@ -0,0 +1,268 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// This class contains resource types and provides APIs to manage, add, remove those types.
+ /// A resource type indicates a class or category of resources.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class ResourceTypes : IEnumerable<string>, IDisposable
+ {
+ internal const int MaxLength = 61;
+ internal IntPtr _resourceTypeHandle = IntPtr.Zero;
+ private readonly HashSet<string> _resourceTypes = new HashSet<string>();
+ private bool _disposed = false;
+
+ /// <summary>
+ /// Constructor of ResourceTypes
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <seealso cref="Add()"/>
+ /// <seealso cref="Remove()"/>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory</exception>
+ /// <code>
+ /// ResourceTypes types = new ResourceTypes();
+ /// </code>
+ public ResourceTypes()
+ {
+ int ret = Interop.IoTConnectivity.Common.ResourceTypes.Create(out _resourceTypeHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create type");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Constructor of ResourceTypes using list of types
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="types">List of resource types</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ /// <code>
+ /// ResourceTypes types = new ResourceTypes(new List<string>() { "org.tizen.light", "oic.if.room" });
+ /// </code>
+ public ResourceTypes(IEnumerable<string> types)
+ {
+ int ret = Interop.IoTConnectivity.Common.ResourceTypes.Create(out _resourceTypeHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create type");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+
+ foreach (string type in types)
+ {
+ Add(type);
+ }
+ }
+
+ internal ResourceTypes(IntPtr typesHandleToClone)
+ {
+ int ret = Interop.IoTConnectivity.Common.ResourceTypes.Clone(typesHandleToClone, out _resourceTypeHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create type");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+
+ Interop.IoTConnectivity.Common.ResourceTypes.ForeachCallback cb = (string type, IntPtr data) =>
+ {
+ _resourceTypes.Add(type);
+ return true;
+ };
+
+ ret = Interop.IoTConnectivity.Common.ResourceTypes.Foreach(typesHandleToClone, cb, IntPtr.Zero);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create type");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Destructor of the ResourceTypes class.
+ /// </summary>
+ ~ResourceTypes()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Indicates count of types in the list
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>Count of types in the list.</value>
+ /// <code>
+ /// ResourceTypes types = new ResourceTypes(new List<string>() { "org.tizen.light", "oic.if.room" });
+ /// Console.WriteLine("There are {0} items", types.Count);
+ /// </code>
+ public int Count
+ {
+ get
+ {
+ return _resourceTypes.Count;
+ }
+ }
+
+ /// <summary>
+ /// Adds a resource type into the list.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <remarks>
+ /// The length of @a item should be less than or equal to 61.\n
+ /// The @a item must start with a lowercase alphabetic character, followed by a sequence
+ /// of lowercase alphabetic, numeric, ".", or "-" characters, and contains no white space.\n
+ /// Duplicate strings are not allowed.
+ /// </remarks>
+ /// <param name="item">The string data to insert into the resource types</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <seealso cref="Remove()"/>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
+ /// <code>
+ /// ResourceTypes resourceTypes = new ResourceTypes();
+ /// resourceTypes.Add("org.tizen.light");
+ /// </code>
+ public void Add(string item)
+ {
+ if (IsValid(item))
+ {
+ int ret = Interop.IoTConnectivity.Common.ResourceTypes.Add(_resourceTypeHandle, item);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add type");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+ _resourceTypes.Add(item);
+ }
+ else
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Invalid type");
+ throw IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.InvalidParameter);
+ }
+ }
+
+ /// <summary>
+ /// Removes a resource type from the list
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="item">The string data to delete from the resource types</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ /// <seealso cref="Add()"/>
+ /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
+ /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
+ /// <code>
+ /// ResourceTypes resourceTypes = new ResourceTypes(new List<string>() { "org.tizen.light", "oic.if.room" });
+ /// resourceTypes.Remove("oic.if.room");
+ /// </code>
+ public void Remove(string item)
+ {
+ int ret = Interop.IoTConnectivity.Common.ResourceTypes.Remove(_resourceTypeHandle, item);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove type");
+ throw IoTConnectivityErrorFactory.GetException(ret);
+ }
+
+ _resourceTypes.Remove(item);
+ }
+
+ /// <summary>
+ /// Return enumerator for the list of types
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <returns>The enumerator</returns>
+ /// <code>
+ /// ResourceTypes resourceTypes = new ResourceTypes(new List<string>() { "org.tizen.light", "oic.if.room" });
+ /// foreach(string item in resourceTypes)
+ /// {
+ /// Console.WriteLine("Type : {0}", item);
+ /// }
+ /// </code>
+ public IEnumerator<string> GetEnumerator()
+ {
+ return _resourceTypes.GetEnumerator();
+ }
+
+ /// <summary>
+ /// Return enumerator for the list of types
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <returns>The enumerator</returns>
+ /// <code>
+ /// ResourceTypes resourceTypes = new ResourceTypes(new List<string>() { "org.tizen.light", "oic.if.room" });
+ /// foreach(string item in resourceTypes)
+ /// {
+ /// Console.WriteLine("Type : {0}", item);
+ /// }
+ /// </code>
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return _resourceTypes.GetEnumerator();
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ internal static bool IsValid(string type)
+ {
+ Regex r = new Regex("^[a-zA-Z0-9.-]+$");
+ return (type.Length <= MaxLength && type.Length > 0 && char.IsLower(type[0]) && r.IsMatch(type));
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
+ /// <feature>http://tizen.org/feature/iot.ocf</feature>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects
+ }
+
+ Interop.IoTConnectivity.Common.ResourceTypes.Destroy(_resourceTypeHandle);
+ _disposed = true;
+ }
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/Response.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/Response.cs
new file mode 100755
index 0000000..60e9e9d
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/Response.cs
@@ -0,0 +1,148 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// This class represents response from a resource.
+ /// It provides APIs to manage response.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class Response : IDisposable
+ {
+ private bool _disposed = false;
+
+ /// <summary>
+ /// Constructor of Response
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <code>
+ /// Response response = new Response();
+ /// </code>
+ public Response() { }
+
+ /// <summary>
+ /// Destructor of the Response class.
+ /// </summary>
+ ~Response()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Gets or sets the result from/into the reponse
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The result from/into the reponse.</value>
+ public ResponseCode Result { get; set; }
+
+ /// <summary>
+ /// Gets or sets the representation from/into the reponse
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The representation from/into the reponse.</value>
+ public Representation Representation { get; set; }
+
+ /// <summary>
+ /// Gets or sets the options from/into the reponse
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The options from/into the reponse.</value>
+ public ResourceOptions Options { get; set; }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ internal bool Send(IntPtr requestHandle)
+ {
+ IntPtr responseHandle = IntPtr.Zero;
+ int ret = Interop.IoTConnectivity.Server.Response.Create(requestHandle, out responseHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to send response");
+ return false;
+ }
+
+ ret = Interop.IoTConnectivity.Server.Response.SetResult(responseHandle, (int)Result);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to send response");
+ Interop.IoTConnectivity.Server.Response.Destroy(responseHandle);
+ return false;
+ }
+
+ if (Representation != null)
+ {
+ ret = Interop.IoTConnectivity.Server.Response.SetRepresentation(responseHandle, Representation._representationHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to send response");
+ Interop.IoTConnectivity.Server.Response.Destroy(responseHandle);
+ return false;
+ }
+ }
+
+ if (Options != null)
+ {
+ ret = Interop.IoTConnectivity.Server.Response.SetOptions(responseHandle, Options._resourceOptionsHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to send response");
+ Interop.IoTConnectivity.Server.Response.Destroy(responseHandle);
+ return false;
+ }
+ }
+
+ ret = Interop.IoTConnectivity.Server.Response.Send(responseHandle);
+ if (ret != (int)IoTConnectivityError.None)
+ {
+ Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to send response");
+ Interop.IoTConnectivity.Server.Response.Destroy(responseHandle);
+ return false;
+ }
+
+ Interop.IoTConnectivity.Server.Response.Destroy(responseHandle);
+ return true;
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_disposed)
+ return;
+
+ if (disposing)
+ {
+ }
+
+ _disposed = true;
+ }
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResponseCode.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResponseCode.cs
new file mode 100755
index 0000000..4e6ddfa
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/ResponseCode.cs
@@ -0,0 +1,62 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// Enumeration for result of response
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum ResponseCode
+ {
+ /// <summary>
+ /// Indicates result of response for success
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ Ok = 0,
+ /// <summary>
+ /// Indicates result of response for some error
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ Error,
+ /// <summary>
+ /// Indicates result of response for created resource
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ Created,
+ /// <summary>
+ /// Indicates result of response for deleted resource
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ Deleted,
+ /// <summary>
+ /// Indicates result of response for changed resource
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ Changed,
+ /// <summary>
+ /// Indicates result of response for slow resource
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ Slow,
+ /// <summary>
+ /// Indicates result of response for accessing unauthorized resource
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ Forbidden
+ }
+}
diff --git a/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/StateChangedEventArgs.cs b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/StateChangedEventArgs.cs
new file mode 100755
index 0000000..eefc47e
--- /dev/null
+++ b/src/Tizen.Network.IoTConnectivity/Tizen.Network.IoTConnectivity/StateChangedEventArgs.cs
@@ -0,0 +1,37 @@
+ /*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+using System;
+
+namespace Tizen.Network.IoTConnectivity
+{
+ /// <summary>
+ /// This class represents event arguments of the StateChanged event.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public class StateChangedEventArgs : EventArgs
+ {
+ internal StateChangedEventArgs() { }
+
+ /// <summary>
+ /// Indicates the new state of the resource
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <value>The new state of the resource.</value>
+ public ResourceState State { get; internal set; }
+ }
+}
diff --git a/src/Tizen.Network.Nfc/Interop/Interop.Glib.cs b/src/Tizen.Network.Nfc/Interop/Interop.Glib.cs
new file mode 100644
index 0000000..576a6e2
--- /dev/null
+++ b/src/Tizen.Network.Nfc/Interop/Interop.Glib.cs
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Glib
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool GSourceFunc(IntPtr userData);
+
+ [DllImport(Libraries.Glib, EntryPoint = "g_idle_add", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern uint IdleAdd(GSourceFunc d, IntPtr data);
+ }
+}
diff --git a/src/Tizen.Network.Nfc/Interop/Interop.Libc.cs b/src/Tizen.Network.Nfc/Interop/Interop.Libc.cs
new file mode 100644
index 0000000..825599e
--- /dev/null
+++ b/src/Tizen.Network.Nfc/Interop/Interop.Libc.cs
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Libc
+ {
+ [DllImport(Libraries.Libc, EntryPoint = "free", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int Free(IntPtr ptr);
+ }
+}
diff --git a/src/Tizen.Network.Nfc/Interop/Interop.Libraries.cs b/src/Tizen.Network.Nfc/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..8984d71
--- /dev/null
+++ b/src/Tizen.Network.Nfc/Interop/Interop.Libraries.cs
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string Nfc = "libcapi-network-nfc.so.0";
+ public const string Glib = "libglib-2.0.so.0";
+ public const string Libc = "libc.so.6";
+ }
+}
diff --git a/src/Tizen.Network.Nfc/Interop/Interop.Nfc.cs b/src/Tizen.Network.Nfc/Interop/Interop.Nfc.cs
new file mode 100644
index 0000000..d6ad84a
--- /dev/null
+++ b/src/Tizen.Network.Nfc/Interop/Interop.Nfc.cs
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Nfc
+ {
+ //Callback for async method
+ //nfc_activation_completed_cb
+ //nfc_tag_write_completed_cb
+ //nfc_tag_format_completed_cb
+ //nfc_mifare_authenticate_with_keyA_completed_cb
+ //nfc_mifare_authenticate_with_keyB_completed_cb
+ //nfc_mifare_write_block_completed_cb
+ //nfc_mifare_write_page_completed_cb
+ //nfc_mifare_increment_completed_cb
+ //nfc_mifare_decrement_completed_cb
+ //nfc_mifare_transfer_completed_cb
+ //nfc_mifare_restore_completed_cb
+ //nfc_p2p_send_completed_cb
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void VoidCallback(int result, IntPtr userData);
+ //nfc_tag_information_cb
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool TagInformationCallback(IntPtr key, IntPtr value, int valueSize, IntPtr userData);
+ //nfc_tag_transceive_completed_cb
+ //nfc_mifare_read_block_completed_cb
+ //nfc_mifare_read_page_completed_cb
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void TagTransceiveCompletedCallback(int result, IntPtr value, int bufferSize, IntPtr userData);
+ //nfc_tag_read_completed_cb
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool TagReadCompletedCallback(int result, IntPtr message, IntPtr userData);
+ //nfc_snep_event_cb
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void SnepEventCallback(IntPtr handle, int snepEvent, int result, IntPtr message, IntPtr userData);
+ //nfc_se_registered_aid_cb
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void SecureElementRegisteredAidCallback(int seType, IntPtr aid, bool readOnly, IntPtr userData);
+
+
+ //Callback for event
+ //nfc_activation_changed_cb
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ActivationChangedCallback(bool activated, IntPtr userData);
+ //nfc_tag_discovered_cb
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void TagDiscoveredCallback(int type, IntPtr tag, IntPtr userData);
+ //nfc_p2p_target_discovered_cb
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void P2pTargetDiscoveredCallback(int type, IntPtr p2pTaget, IntPtr userData);
+ //nfc_ndef_discovered_cb
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void NdefMessageDiscoveredCallback(IntPtr message, IntPtr userData);
+ //nfc_se_event_cb
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void SecureElementEventCallback(int eventType, IntPtr userData);
+ //nfc_se_transaction_event_cb
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void SecureElementTransactionEventCallback(int type, IntPtr aid, int aidSize, IntPtr param, int paramSize, IntPtr userData);
+ //nfc_p2p_data_received_cb
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void P2pDataReceivedCallback(IntPtr target, IntPtr message, IntPtr userData);
+ //nfc_hce_event_cb
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void HostCardEmulationEventCallback(IntPtr handle, int eventType, IntPtr apdu, uint apduLen, IntPtr userData);
+
+ //capi-network-nfc-0.2.5-6.1.armv7l
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_initialize")]
+ internal static extern int Initialize();
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_deinitialize")]
+ internal static extern int Deinitialize();
+
+ ////Nfc Manager
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_is_supported")]
+ internal static extern bool IsSupported();
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_set_activation")]
+ internal static extern int SetActivation(bool activation, VoidCallback callback, IntPtr userData);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_is_activated")]
+ internal static extern bool IsActivated();
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_set_activation_changed_cb")]
+ internal static extern int SetActivationChangedCallback(ActivationChangedCallback callback, IntPtr userData);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_unset_activation_changed_cb")]
+ internal static extern void UnsetActivationChangedCallback();
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_set_tag_discovered_cb")]
+ internal static extern int SetTagDiscoveredCallback(TagDiscoveredCallback callback, IntPtr userData);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_unset_tag_discovered_cb")]
+ internal static extern void UnsetTagDiscoveredCallback();
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_set_ndef_discovered_cb")]
+ internal static extern int SetNdefDiscoveredCallback(NdefMessageDiscoveredCallback callback, IntPtr userData);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_unset_ndef_discovered_cb")]
+ internal static extern void UnsetNdefDiscoveredCallback();
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_set_p2p_target_discovered_cb")]
+ internal static extern int SetP2pTargetDiscoveredCallback(P2pTargetDiscoveredCallback callback, IntPtr userData);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_unset_p2p_target_discovered_cb")]
+ internal static extern void UnsetP2pTargetDiscoveredCallback();
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_set_se_event_cb")]
+ internal static extern int SetSecureElementEventCallback(SecureElementEventCallback callback, IntPtr userData);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_unset_se_event_cb")]
+ internal static extern void UnsetSecureElementEventCallback();
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_set_se_transaction_event_cb")]
+ internal static extern int SetSecureElementTransactionEventCallback(int setype, SecureElementTransactionEventCallback callback, IntPtr userData);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_unset_se_transaction_event_cb")]
+ internal static extern int UnsetSecureElementTransactionEventCallback(int setype);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_set_hce_event_cb")]
+ internal static extern int SetHostCardEmulationEventCallback(HostCardEmulationEventCallback callback, IntPtr userData);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_unset_hce_event_cb")]
+ internal static extern void UnsetHostCardEmulationEventCallback();
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_enable_transaction_fg_dispatch")]
+ internal static extern int EnableTransactionForegroundDispatch();
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_disable_transaction_fg_dispatch")]
+ internal static extern int DisableTransactionForegroundDispatch();
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_get_cached_message")]
+ internal static extern int GetCachedMessage(out IntPtr ndefMessage);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_set_tag_filter")]
+ internal static extern void SetTagFilter(int filter);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_get_tag_filter")]
+ internal static extern int GetTagFilter();
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_get_connected_tag")]
+ internal static extern int GetConnectedTag(out IntPtr tag);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_get_connected_target")]
+ internal static extern int GetConnectedTarget(out IntPtr target);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_set_system_handler_enable")]
+ internal static extern int SetSystemHandlerEnable(bool enable);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_is_system_handler_enabled")]
+ internal static extern bool IsSystemHandlerEnabled();
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_set_se_type")]
+ internal static extern int SetSecureElementType(int type);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_manager_get_se_type")]
+ internal static extern int GetSecureElementType(out int type);
+
+ ////NDEF - NFC Data Exchange Format, TNF - Type Name Format
+ internal static class NdefRecord
+ {
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_ndef_record_create")]
+ internal static extern int Create(out IntPtr record, int tnf, byte[] type, int typeSize, byte[] id, int idSize, byte[] payload, uint payloadSize);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_ndef_record_create_text")]
+ internal static extern int CreateText(out IntPtr record, string text, string languageCode, int encode);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_ndef_record_create_uri")]
+ internal static extern int CreateUri(out IntPtr record, string uri);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_ndef_record_create_mime")]
+ internal static extern int CreateMime(out IntPtr record, string mimeType, byte[] data, uint dataSize);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_ndef_record_destroy")]
+ internal static extern int Destroy(IntPtr record);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_ndef_record_set_id")]
+ internal static extern int SetId(IntPtr record, byte[] id, int idSize);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_ndef_record_get_id")]
+ internal static extern int GetId(IntPtr record, out IntPtr id, out int size);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_ndef_record_get_payload")]
+ internal static extern int GetPayload(IntPtr record, out IntPtr payload, out uint size);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_ndef_record_get_type")]
+ internal static extern int GetType(IntPtr record, out IntPtr type, out int size);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_ndef_record_get_tnf")]
+ internal static extern int GetTnf(IntPtr record, out int tnf);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_ndef_record_get_text")]
+ internal static extern int GetText(IntPtr record, out string text);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_ndef_record_get_langcode")]
+ internal static extern int GetLanguageCode(IntPtr record, out string languageCode);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_ndef_record_get_encode_type")]
+ internal static extern int GetEncodeType(IntPtr record, out int encode);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_ndef_record_get_uri")]
+ internal static extern int GetUri(IntPtr record, out string uri);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_ndef_record_get_mime_type")]
+ internal static extern int GetMimeType(IntPtr record, out string mimeType);
+ }
+
+ internal static class NdefMessage
+ {
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_ndef_message_create")]
+ internal static extern int Create(out IntPtr ndefMessage);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_ndef_message_create_from_rawdata")]
+ internal static extern int CreateRawData(out IntPtr ndefMessage, byte[] rawData, uint rawDataSize);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_ndef_message_destroy")]
+ internal static extern int Destroy(IntPtr ndefMessage);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_ndef_message_get_record_count")]
+ internal static extern int GetRecordCount(IntPtr ndefMessage, out int count);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_ndef_message_get_rawdata")]
+ internal static extern int GetRawData(IntPtr ndefMessage, out IntPtr rawData, out uint rawDataSize);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_ndef_message_append_record")]
+ internal static extern int AppendRecord(IntPtr ndefMessage, IntPtr record);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_ndef_message_insert_record")]
+ internal static extern int InsertRecord(IntPtr ndefMessage, int index, IntPtr record);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_ndef_message_remove_record")]
+ internal static extern int RemoveRecord(IntPtr ndefMessage, int index);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_ndef_message_get_record")]
+ internal static extern int GetRecord(IntPtr ndefMessage, int index, out IntPtr record);
+ }
+
+ internal static class Tag
+ {
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_tag_get_type")]
+ internal static extern int GetType(IntPtr tag, out int type);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_tag_is_support_ndef")]
+ internal static extern int IsSupportNdef(IntPtr tag, out bool isSupported);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_tag_get_maximum_ndef_size")]
+ internal static extern int GetMaximumNdefSize(IntPtr tag, out uint maximunNdefBytesSize);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_tag_get_ndef_size")]
+ internal static extern int GetNdefSize(IntPtr tag, out uint ndefBytesSize);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_tag_foreach_information")]
+ internal static extern int ForeachInformation(IntPtr tag, TagInformationCallback callback, IntPtr userData);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_tag_transceive")]
+ internal static extern int Transceive(IntPtr tag, byte[] buffer, int bufferSize, TagTransceiveCompletedCallback callback, IntPtr userData);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_tag_read_ndef")]
+ internal static extern int ReadNdef(IntPtr tag, TagReadCompletedCallback callback, IntPtr userData);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_tag_write_ndef")]
+ internal static extern int WriteNdef(IntPtr tag, IntPtr ndefMessage, VoidCallback callback, IntPtr userData);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_tag_format_ndef")]
+ internal static extern int FormatNdef(IntPtr tag, byte[] key, int kyeSize, VoidCallback callback, IntPtr userData);
+
+ ////Mifare
+ }
+
+ ////SNEP - Simple NDEF Exchange Protocol
+ internal static class P2p
+ {
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_p2p_set_data_received_cb")]
+ internal static extern int SetDataReceivedCallback(IntPtr target, P2pDataReceivedCallback callback, IntPtr userData);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_p2p_unset_data_received_cb")]
+ internal static extern int UnsetDataReceivedCallback(IntPtr target);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_p2p_send")]
+ internal static extern int Send(IntPtr target, IntPtr ndefMessage, VoidCallback callback, IntPtr userData);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_snep_start_server")]
+ internal static extern int SnepStartServer(IntPtr target, string san, int sap, SnepEventCallback callback, IntPtr userData);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_snep_start_client")]
+ internal static extern int SnepStartClient(IntPtr target, string san, int sap, SnepEventCallback callback, IntPtr userData);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_snep_send_client_request")]
+ internal static extern int SnepSendClientRequest(IntPtr snepHandle, int type, IntPtr ndefMessage, SnepEventCallback callback, IntPtr userData);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_snep_stop_service")]
+ internal static extern int SnepStopService(IntPtr target, IntPtr snepHandle);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_snep_register_server")]
+ internal static extern int SnepRegisterServer(string san, int sap, SnepEventCallback callback, IntPtr userData);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_snep_unregister_server")]
+ internal static extern int SnepUnregisterServer(string sam, int sap);
+ }
+
+ ////SE - Secure Element, HCE - Host Card Emulation, APDU - Application Protocol Data Unit, AID - Application Identifier
+ internal static class CardEmulation
+ {
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_se_enable_card_emulation")]
+ internal static extern int EnableCardEmulation();
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_se_disable_card_emulation")]
+ internal static extern int DisableCardEmulatiion();
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_se_get_card_emulation_mode")]
+ internal static extern int GetCardEmulationMode(out int type);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_hce_send_apdu_response")]
+ internal static extern int HceSendApduRespondse(IntPtr seHandle, byte[] response, uint responseLength);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_se_set_default_route")]
+ internal static extern int SetDefaultRoute(int poweredOnStatus, int poweredOffStatus, int lowBatteryStatus);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_se_is_activated_handler_for_aid")]
+ internal static extern int IsActivatedHandlerForAid(int seType, string aid, out bool isActivatedHandler);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_se_is_activated_handler_for_category")]
+ internal static extern int IsActivatedHandlerForCategory(int seType, int category, out bool isActivatedHandler);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_se_register_aid")]
+ internal static extern int RegisterAid(int seType, int category, string aid);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_se_unregister_aid")]
+ internal static extern int UnregisterAid(int seType, int category, string aid);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_se_foreach_registered_aids")]
+ internal static extern int ForeachRegisterdAids(int seType, int category, SecureElementRegisteredAidCallback callback, IntPtr userData);
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_se_set_preferred_handler")]
+ internal static extern int SetPreferredHandler();
+ [DllImport(Libraries.Nfc, EntryPoint = "nfc_se_unset_preferred_handler")]
+ internal static extern int UnsetPreferredHandler();
+ }
+ }
+}
diff --git a/src/Tizen.Network.Nfc/Tizen.Network.Nfc.csproj b/src/Tizen.Network.Nfc/Tizen.Network.Nfc.csproj
new file mode 100644
index 0000000..60809fb
--- /dev/null
+++ b/src/Tizen.Network.Nfc/Tizen.Network.Nfc.csproj
@@ -0,0 +1,15 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ <ProjectReference Include="..\Tizen.System.Information\Tizen.System.Information.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcCallbackData.cs b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcCallbackData.cs
new file mode 100755
index 0000000..ba7c595
--- /dev/null
+++ b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcCallbackData.cs
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Network.Nfc
+{
+ /// <summary>
+ /// Structure containing the information of Tag data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class NfcTagInformation
+ {
+ private string _key;
+ private byte[] _informationValue;
+
+ internal NfcTagInformation(string key, byte[] informationValue)
+ {
+ _key = key;
+ _informationValue = informationValue;
+ }
+
+ /// <summary>
+ /// Key value.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Key
+ {
+ get
+ {
+ return _key;
+ }
+ }
+ /// <summary>
+ /// Information value.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public byte[] InformationValue
+ {
+ get
+ {
+ return _informationValue;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Structure containing the information of Secure element Aid(Application Identifier).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class NfcRegisteredAidInformation
+ {
+ private NfcSecureElementType _seType;
+ private string _aid;
+ private bool _readOnly;
+
+ internal NfcRegisteredAidInformation(NfcSecureElementType seType, string aid, bool readOnly)
+ {
+ _seType = seType;
+ _aid = aid;
+ _readOnly = readOnly;
+ }
+
+ /// <summary>
+ /// Secure Element Type value.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public NfcSecureElementType SeType
+ {
+ get
+ {
+ return _seType;
+ }
+ }
+
+ /// <summary>
+ /// The targeted Aid (Application Identifier) value.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Aid
+ {
+ get
+ {
+ return _aid;
+ }
+ }
+
+ /// <summary>
+ /// Read-only value. If this value is false, there are restrictions to the operation on this Aid.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool ReadOnly
+ {
+ get
+ {
+ return _readOnly;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcCardEmulationAdapter.cs b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcCardEmulationAdapter.cs
new file mode 100755
index 0000000..d74be00
--- /dev/null
+++ b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcCardEmulationAdapter.cs
@@ -0,0 +1,464 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+
+namespace Tizen.Network.Nfc
+{
+ /// <summary>
+ /// A class for NFC CardEmulation mode. It allows applications to handle Card Emulation informations.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
+ public class NfcCardEmulationAdapter : IDisposable
+ {
+ private bool disposed = false;
+
+ private event EventHandler<SecureElementEventArgs> _secureElementEvent;
+ private event EventHandler<SecureElementTranscationEventArgs> _secureElementTransactionEvent;
+ private event EventHandler<HostCardEmulationEventArgs> _hostCardEmulationEvent;
+
+ private Interop.Nfc.SecureElementEventCallback _secureElementEventCallback;
+ private Interop.Nfc.SecureElementTransactionEventCallback _secureElementTransactionEventCallback;
+ private Interop.Nfc.HostCardEmulationEventCallback _hostCardEmulationEventCallback;
+
+ /// <summary>
+ /// Event that is called when receiving Secure Element (SIM/UICC(Universal Integrated Circuit Card)) event.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<SecureElementEventArgs> SecureElementEvent
+ {
+ add
+ {
+ if (_secureElementEvent == null)
+ {
+ RegisterSecureElementEvent();
+ }
+ _secureElementEvent += value;
+ }
+ remove
+ {
+ _secureElementEvent -= value;
+ if (_secureElementEvent == null)
+ {
+ UnregisterSecureElementEvent();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Event that is called when receiving Secure Element(SIM/UICC(Universal Integrated Circuit Card)) transaction event for 'ESE(SmartMX)' type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<SecureElementTranscationEventArgs> EseSecureElementTransactionEvent
+ {
+ add
+ {
+ if (_secureElementTransactionEvent == null)
+ {
+ RegisterSecureElementTransactionEvent(NfcSecureElementType.EmbeddedSE);
+ }
+ _secureElementTransactionEvent += value;
+ }
+ remove
+ {
+ _secureElementTransactionEvent -= value;
+ if (_secureElementTransactionEvent == null)
+ {
+ UnregisterSecureElementTransactionEvent(NfcSecureElementType.EmbeddedSE);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Event that is called when receiving Secure Element(SIM/UICC(Universal Integrated Circuit Card)) transaction event for 'UICC' type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<SecureElementTranscationEventArgs> UiccSecureElementTransactionEvent
+ {
+ add
+ {
+ if (_secureElementTransactionEvent == null)
+ {
+ RegisterSecureElementTransactionEvent(NfcSecureElementType.Uicc);
+ }
+ _secureElementTransactionEvent += value;
+ }
+ remove
+ {
+ _secureElementTransactionEvent -= value;
+ if (_secureElementTransactionEvent == null)
+ {
+ UnregisterSecureElementTransactionEvent(NfcSecureElementType.Uicc);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Event that is called when when receiving HCE(Host Card Emulation) event.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<HostCardEmulationEventArgs> HostCardEmulationEvent
+ {
+ add
+ {
+ if (_hostCardEmulationEvent == null)
+ {
+ RegisterHostCardEmulationEvent();
+ }
+ _hostCardEmulationEvent += value;
+ }
+ remove
+ {
+ _hostCardEmulationEvent -= value;
+ if (_hostCardEmulationEvent == null)
+ {
+ UnregisterHostCardEmulationEvent();
+ }
+ }
+ }
+
+ internal NfcCardEmulationAdapter()
+ {
+ }
+
+ ~NfcCardEmulationAdapter()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects.
+ }
+ //Free unmanaged objects
+ disposed = true;
+ }
+
+ /// <summary>
+ /// Enable card emulation mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public void EnableCardEmulation()
+ {
+ int ret = Interop.Nfc.CardEmulation.EnableCardEmulation();
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to enable card emulation mode, Error - " + (NfcError)ret);
+ NfcErrorFactory.ThrowNfcException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Disable card emulation mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public void DisableCardEmulation()
+ {
+ int ret = Interop.Nfc.CardEmulation.DisableCardEmulatiion();
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to disable card emulation mode, Error - " + (NfcError)ret);
+ NfcErrorFactory.ThrowNfcException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Get the current card emulation mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>Enumeration value of NfcSecureElementCardEmulationMode.</returns>
+ public NfcSecureElementCardEmulationMode GetCardEmulationMode()
+ {
+ int mode = 0;
+ int ret = Interop.Nfc.CardEmulation.GetCardEmulationMode(out mode);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get card emulation mode, Error - " + (NfcError)ret);
+ }
+
+ return (NfcSecureElementCardEmulationMode)mode;
+ }
+
+ /// <summary>
+ /// Give the priority to the foreground application when dispatching transaction event.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public void EnableTransactionForegroundDispatch()
+ {
+ int ret = Interop.Nfc.EnableTransactionForegroundDispatch();
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to enable foreground dispatch, Error - " + (NfcError)ret);
+ NfcErrorFactory.ThrowNfcException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Disable foreground dispatch for "EVT_TRANSACTION" to the givin application.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public void DisableTransactionForegroundDispatch()
+ {
+ int ret = Interop.Nfc.DisableTransactionForegroundDispatch();
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to disable foreground dispatch, Error - " + (NfcError)ret);
+ NfcErrorFactory.ThrowNfcException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Gets the state whether an application to call this api is currently the activated handler for specific AID.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>'True' when application is currently the activated handler, otherwise 'False'.</returns>
+ /// <param name="seType">The type of Secure Element.</param>
+ /// <param name="aid">Application Id, specified in ISO/IEC 7816-4.</param>
+ /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public bool IsActivatedHandlerForAid(NfcSecureElementType seType, string aid)
+ {
+ bool isActivatedHandle = false;
+ int ret = Interop.Nfc.CardEmulation.IsActivatedHandlerForAid((int)seType, aid, out isActivatedHandle);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to check activated handle for aid, Error - " + (NfcError)ret);
+ NfcErrorFactory.ThrowNfcException(ret);
+ }
+
+ return isActivatedHandle;
+ }
+
+ /// <summary>
+ /// Gets the state whether an application to call this api is currently the activated handler for category.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>'True' when application is currently the activated handler, otherwise 'False'.</returns>
+ /// <param name="seType">The type of Secure Element.</param>
+ /// <param name="category">Enumeration value of category.</param>
+ /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public bool IsActivatedHandlerForCategory(NfcSecureElementType seType, NfcCardEmulationCategoryType category)
+ {
+ bool isActivatedHandle = false;
+ int ret = Interop.Nfc.CardEmulation.IsActivatedHandlerForCategory((int)seType, (int)category, out isActivatedHandle);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to check activated handle for category, Error - " + (NfcError)ret);
+ NfcErrorFactory.ThrowNfcException(ret);
+ }
+
+ return isActivatedHandle;
+ }
+
+ /// <summary>
+ /// Registers a AID for a specific category.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="seType">The type of Secure Element.</param>
+ /// <param name="category">Enumeration value of category.</param>
+ /// <param name="aid">Application Id, specified in ISO/IEC 7816-4.</param>
+ /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public void RegisterAid(NfcSecureElementType seType, NfcCardEmulationCategoryType category, string aid)
+ {
+ int ret = Interop.Nfc.CardEmulation.RegisterAid((int)seType, (int)category, aid);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to register aid, Error - " + (NfcError)ret);
+ NfcErrorFactory.ThrowNfcException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Unregisters a previously registered AID for the specified category.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="seType">The type of Secure Element.</param>
+ /// <param name="category">Enumeration value of category.</param>
+ /// <param name="aid">Application Id, specified in ISO/IEC 7816-4.</param>
+ /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public void UnregisterAid(NfcSecureElementType seType, NfcCardEmulationCategoryType category, string aid)
+ {
+ int ret = Interop.Nfc.CardEmulation.UnregisterAid((int)seType, (int)category, aid);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unregister aid, Error - " + (NfcError)ret);
+ NfcErrorFactory.ThrowNfcException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Sets the application as a preferred handler.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public void SetPreferredApplication()
+ {
+ int ret = Interop.Nfc.CardEmulation.SetPreferredHandler();
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set preferred handler, Error - " + (NfcError)ret);
+ NfcErrorFactory.ThrowNfcException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Unsets the application as a preferred handler.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public void UnsetPreferredApplication()
+ {
+ int ret = Interop.Nfc.CardEmulation.UnsetPreferredHandler();
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset preferred handler, Error - " + (NfcError)ret);
+ NfcErrorFactory.ThrowNfcException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Retrieves all registered AID.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>List of NfcRegisteredAidInformation objects.</returns>
+ /// <param name="seType">The type of Secure Element.</param>
+ /// <param name="category">Enumeration value of category.</param>
+ /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public IEnumerable<NfcRegisteredAidInformation> GetRegisteredAidInformation(NfcSecureElementType seType, NfcCardEmulationCategoryType category)
+ {
+ List<NfcRegisteredAidInformation> infoList = new List<NfcRegisteredAidInformation>();
+ Interop.Nfc.SecureElementRegisteredAidCallback callback = (int type, IntPtr aid, bool readOnly, IntPtr userData) =>
+ {
+ if (aid != IntPtr.Zero)
+ {
+ NfcRegisteredAidInformation aidInfo = new NfcRegisteredAidInformation((NfcSecureElementType)type, Marshal.PtrToStringAnsi(aid), readOnly);
+
+ infoList.Add(aidInfo);
+ }
+ };
+
+ int ret = Interop.Nfc.CardEmulation.ForeachRegisterdAids((int)seType, (int)category, callback, IntPtr.Zero);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get all registerd aid informations, Error - " + (NfcError)ret);
+ NfcErrorFactory.ThrowNfcException(ret);
+ }
+
+ return infoList;
+ }
+
+ private void RegisterSecureElementEvent()
+ {
+ _secureElementEventCallback = (int eventType, IntPtr userData) =>
+ {
+ NfcSecureElementEvent _eventType = (NfcSecureElementEvent)eventType;
+ SecureElementEventArgs e = new SecureElementEventArgs(_eventType);
+ _secureElementEvent.SafeInvoke(null, e);
+ };
+
+ int ret = Interop.Nfc.SetSecureElementEventCallback(_secureElementEventCallback, IntPtr.Zero);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set secure element event callback, Error - " + (NfcError)ret);
+ }
+ }
+
+ private void UnregisterSecureElementEvent()
+ {
+ Interop.Nfc.UnsetSecureElementEventCallback();
+ }
+
+ private void RegisterSecureElementTransactionEvent(NfcSecureElementType seType)
+ {
+ _secureElementTransactionEventCallback = (int type, IntPtr aid, int aidSize, IntPtr param, int paramSize, IntPtr userData) =>
+ {
+ NfcSecureElementType _secureElementType = (NfcSecureElementType)type;
+ byte[] _aid = NfcConvertUtil.IntLengthIntPtrToByteArray(aid, aidSize);
+ byte[] _param = NfcConvertUtil.IntLengthIntPtrToByteArray(param, paramSize);
+ SecureElementTranscationEventArgs e = new SecureElementTranscationEventArgs(_secureElementType, _aid, _param);
+ _secureElementTransactionEvent.SafeInvoke(null, e);
+ };
+
+ int ret = Interop.Nfc.SetSecureElementTransactionEventCallback((int)seType, _secureElementTransactionEventCallback, IntPtr.Zero);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set secure element transaction event callback, Error - " + (NfcError)ret);
+ }
+ }
+
+ private void UnregisterSecureElementTransactionEvent(NfcSecureElementType seType)
+ {
+ Interop.Nfc.UnsetSecureElementTransactionEventCallback((int)seType);
+ }
+
+ private void RegisterHostCardEmulationEvent()
+ {
+ _hostCardEmulationEventCallback = (IntPtr handle, int eventType, IntPtr apdu, uint apduLen, IntPtr userData) =>
+ {
+ IntPtr _seHandle = handle;
+ NfcHceEvent _hcdEventType = (NfcHceEvent)eventType;
+ byte[] _apdu = NfcConvertUtil.UintLengthIntPtrToByteArray(apdu, apduLen);
+ HostCardEmulationEventArgs e = new HostCardEmulationEventArgs(_seHandle, _hcdEventType, _apdu);
+ _hostCardEmulationEvent.SafeInvoke(null, e);
+ };
+
+ int ret = Interop.Nfc.SetHostCardEmulationEventCallback(_hostCardEmulationEventCallback, IntPtr.Zero);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set host card emulation event callback, Error - " + (NfcError)ret);
+ NfcErrorFactory.ThrowNfcException(ret);
+ }
+ }
+
+ private void UnregisterHostCardEmulationEvent()
+ {
+ Interop.Nfc.UnsetHostCardEmulationEventCallback();
+ }
+ }
+}
diff --git a/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcEnumerations.cs b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcEnumerations.cs
new file mode 100644
index 0000000..6a35053
--- /dev/null
+++ b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcEnumerations.cs
@@ -0,0 +1,441 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Network.Nfc
+{
+ /// <summary>
+ /// Enumeration for Nfc record TNF (Type Name Format).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum NfcRecordTypeNameFormat
+ {
+ /// <summary>
+ /// Empty
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Empty = 0,
+ /// <summary>
+ /// RTD(Record Type Definition) type format [NFC RTD]
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ WellKnown = 1,
+ /// <summary>
+ /// MIME Media types in RFC 2046 [RFC 2046]
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ MimeMedia = 2,
+ /// <summary>
+ /// Absolute URI as defined in RFC 3986 [RFC 3986]
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Uri = 3,
+ /// <summary>
+ /// NFC Forum external type [NFC RTD]
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ ExternalRtd = 4,
+ /// <summary>
+ /// The payload type is unknown
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Unknown = 5,
+ /// <summary>
+ /// final chunk of a chunked NDEF Record
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ UnChanged = 6
+ }
+
+ /// <summary>
+ /// Enumeration for Nfc Encode type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum NfcEncodeType
+ {
+ /// <summary>
+ /// UTF-8
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Utf8 = 0,
+ /// <summary>
+ /// UTF-16
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Utf16 = 1
+ }
+ /// <summary>
+ /// Enumeration for Nfc Tag type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum NfcTagType
+ {
+ /// <summary>
+ /// Unknown target
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ UnknownTarget = 0x00,
+ /// <summary>
+ /// Generic PICC
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ GenericPicc,
+ /// <summary>
+ /// ISO14443 A PICC
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Iso14443APicc,
+ /// <summary>
+ /// ISO14443 4A PICC
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Iso144434APicc,
+ /// <summary>
+ /// ISO14443 4A PICC
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Iso144433APicc,
+ /// <summary>
+ /// Mifare Mini PICC
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ MifareMiniPicc,
+ /// <summary>
+ /// Mifare 1k PICC
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Mifare1kPicc,
+ /// <summary>
+ /// Mifare 4k PICC
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Mifare4kPicc,
+ /// <summary>
+ /// Mifare Ultra PICC
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ MifareUltraPicc,
+ /// <summary>
+ /// Mifare Desfire PICC
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ MifareDesfirePicc,
+ /// <summary>
+ /// Iso14443 B PICC
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Iso14443BPicc,
+ /// <summary>
+ /// Iso14443 4B PICC
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Iso144434BPicc,
+ /// <summary>
+ /// ISO14443 B Prime PICC
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Iso14443BPrimePicc,
+ /// <summary>
+ /// Felica PICC
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ FelicaPicc,
+ /// <summary>
+ /// Jewel PICC
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ JewelPicc,
+ /// <summary>
+ /// ISO15693 PICC
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Iso15693Picc,
+ /// <summary>
+ /// Barcode 128 PICC
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Barcode128Picc,
+ /// <summary>
+ /// Barcode 256 PICC
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Barcode256Picc,
+ /// <summary>
+ /// NFCIP1 Target
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ NfcIp1Target,
+ /// <summary>
+ /// NFCIP1 Initiator
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ NfcIp1Initiator
+ }
+ /// <summary>
+ /// Enumeration for Nfc Tag Filter type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum NfcTagFilterType
+ {
+ /// <summary>
+ /// All disable
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ AllDisable = 0x0000,
+ /// <summary>
+ /// ISO14443A enable
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Iso14443AEnable = 0x0001,
+ /// <summary>
+ /// ISO14443B enable
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Iso14443BEnable = 0x0002,
+ /// <summary>
+ /// ISO15693 enable
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Iso15693Enable = 0x0004,
+ /// <summary>
+ /// FELICA enable
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ FelicaEnable = 0x0008,
+ /// <summary>
+ /// JEWEL enable
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ JewelEnable = 0x0010,
+ /// <summary>
+ /// IP enable
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ IpEnable = 0x0020,
+ /// <summary>
+ /// All enable
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ AllEnable = ~0
+ }
+ /// <summary>
+ /// Enumeration for Nfc discovered type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum NfcDiscoveredType
+ {
+ /// <summary>
+ /// Attached, discovered, activated event
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Attached,
+ /// <summary>
+ /// Detached, disappeared, deactivated event
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Detached
+ }
+ /// <summary>
+ /// Enumeration for Nfc Secure Element event.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum NfcSecureElementEvent
+ {
+ /// <summary>
+ /// Start transaction
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ StartTransaction,
+ /// <summary>
+ /// End transaction
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ EndTransaction,
+ /// <summary>
+ /// Ready signal
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Connectivity,
+ /// <summary>
+ /// CLF(Contactless Front-end) detects a RF field
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ FieldOn,
+ /// <summary>
+ /// CLF(Contactless Front-end) detects that the RF field is off
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ FieldOff,
+ /// <summary>
+ /// External reader trys to access secure element
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Transaction,
+ /// <summary>
+ /// Changing the emulated secure element type
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ TypeChanged,
+ /// <summary>
+ /// Changing the card emulation mode
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ CardEmulationChanged
+ }
+ /// <summary>
+ /// Enumeration for Nfc Filter type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum NfcSecureElementType
+ {
+ /// <summary>
+ /// Disable card emulation
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Disable = 0x00,
+ /// <summary>
+ /// SmartMX type card emulation (Embedded Secure Element)
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ EmbeddedSE = 0x01,
+ /// <summary>
+ /// UICC type card emulation (Universal IC Card)
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Uicc = 0x02,
+ /// <summary>
+ /// SDCARD card emulation
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Sdcard = 0x03,
+ /// <summary>
+ /// Host based card emulation
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Hce = 0x04
+ }
+ /// <summary>
+ /// Enumeration for Nfc discovered type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum NfcSecureElementCardEmulationMode
+ {
+ /// <summary>
+ /// Card Emulation mode OFF
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Off = 0x00,
+ /// <summary>
+ /// Card Emulation mode ON
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ On = 0x01
+ }
+ /// <summary>
+ /// Enumeration for SNEP(Simple NDEF Exchange Protocol) event.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum NfcSnepEvent
+ {
+ /// <summary>
+ /// server or client stopped
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Stop = 0x00,
+ /// <summary>
+ /// server started or client connected
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Start = 0x01,
+ /// <summary>
+ /// server received get request
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Get = 0x02,
+ /// <summary>
+ /// server received put request
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Put = 0x03,
+ /// <summary>
+ /// service registered
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Register = 0x04,
+ /// <summary>
+ /// service unregistered
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Unregister = 0x05
+ }
+ /// <summary>
+ /// Enumeration for SNEP request type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum NfcSnepRequestType
+ {
+ /// <summary>
+ /// get request
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Get = 0x01,
+ /// <summary>
+ /// put request
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Put = 0x02
+ }
+ /// <summary>
+ /// Enumeration for NFC Card Emulation Category type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum NfcCardEmulationCategoryType
+ {
+ /// <summary>
+ /// NFC payment services
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Payment = 0x01,
+ /// <summary>
+ /// all other card emulation services
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Other = 0x02
+ }
+ /// <summary>
+ /// Enumeration for NFC Card Emulation HCE(Host Card Emulation) event type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum NfcHceEvent
+ {
+ /// <summary>
+ /// HCE deactivated
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Deactivated = 0x00,
+ /// <summary>
+ /// HCE activated
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Activated = 0x01,
+ /// <summary>
+ /// HCE APDU(Application Protocol Data Unit) Received
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ ApduReceived = 0x02
+ }
+}
diff --git a/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcErrorFactory.cs b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcErrorFactory.cs
new file mode 100644
index 0000000..7af0af5
--- /dev/null
+++ b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcErrorFactory.cs
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Network.Nfc
+{
+ /// <summary>
+ /// Enumeration for Nfc Error.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum NfcError
+ {
+ None = ErrorCode.None,
+ IoError = ErrorCode.IoError,
+ InvalidParameterError = ErrorCode.InvalidParameter,
+ OutOfMemoryError = ErrorCode.OutOfMemory,
+ TimedOutError = ErrorCode.TimedOut,
+ DeviceBusyError = ErrorCode.ResourceBusy,
+ NotSupportedError = ErrorCode.NotSupported,
+ PermissionDeniedError = ErrorCode.PermissionDenied,
+ OperationFailedError = -0x01C20000 | 0x01,
+ InvalidNdefMessageError = -0x01C20000 | 0x02,
+ InvalidRecordTypeError = -0x01C20000 | 0x03,
+ NoDeviceError = -0x01C20000 | 0x04,
+ NotActivatedError = -0x01C20000 | 0x05,
+ AlreadyActivatedError = -0x01C20000 | 0x06,
+ AlreadyDeactivatedError = -0x01C20000 | 0x07,
+ ReadOnlyNdefError = -0x01C20000 | 0x08,
+ NoSpaceOnNdefError = -0x01C20000 | 0x09,
+ NoNdefMessageError = -0x01C20000 | 0x0a,
+ NotNdefFormatError = -0x01C20000 | 0x0b,
+ SecurityRestrictedError = -0x01C20000 | 0x0c,
+ IllegalStateError = -0x01C20000 | 0x0d,
+ NotInitializedError = -0x01C20000 | 0x0e,
+ TagNotSupportedError = -0x01C20000 | 0x0f,
+ AidAlreadyRegisteredError = -0x01C20000 | 0x10
+ }
+
+ internal static class NfcErrorFactory
+ {
+ static internal void ThrowNfcException(int e)
+ {
+ ThrowException(e, false);
+ }
+
+ static internal void ThrowNfcException(int e, int handle)
+ {
+ ThrowException(e, (handle < 0));
+ }
+
+ static private void ThrowException(int e, bool isHandleNull)
+ {
+ NfcError err = (NfcError)e;
+
+ if (isHandleNull)
+ {
+ throw new InvalidOperationException("Invalid instance (object may have been disposed or released)");
+ }
+
+ if (err == NfcError.InvalidParameterError)
+ {
+ throw new ArgumentException(err.ToString());
+ }
+ else if (err == NfcError.NotSupportedError)
+ {
+ throw new NotSupportedException();
+ }
+ else
+ {
+ throw new InvalidOperationException(err.ToString());
+ }
+ }
+
+ }
+}
diff --git a/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcEventArgs.cs b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcEventArgs.cs
new file mode 100644
index 0000000..37195ab
--- /dev/null
+++ b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcEventArgs.cs
@@ -0,0 +1,320 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Network.Nfc
+{
+ /// <summary>
+ /// An extended EventArgs class which contains changed Nfc activation state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class ActivationChangedEventArgs : EventArgs
+ {
+ private bool _activated = false;
+
+ internal ActivationChangedEventArgs(bool activated)
+ {
+ _activated = activated;
+ }
+
+ /// <summary>
+ /// The Nfc activation state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool Activated
+ {
+ get
+ {
+ return _activated;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains changed Nfc tag discovered.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class TagDiscoveredEventArgs : EventArgs
+ {
+ private NfcDiscoveredType _type = NfcDiscoveredType.Detached;
+ private NfcTag _tag;
+
+ internal TagDiscoveredEventArgs(NfcDiscoveredType _type, IntPtr tagHandle)
+ {
+ _tag = new NfcTag(tagHandle);
+ }
+
+ /// <summary>
+ /// The tag type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public NfcDiscoveredType Type
+ {
+ get
+ {
+ return _type;
+ }
+ }
+
+ /// <summary>
+ /// Tag object
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public NfcTag Tag
+ {
+ get
+ {
+ return _tag;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains changed Nfc p2p target discovered.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class P2pTargetDiscoveredEventArgs : EventArgs
+ {
+ private NfcDiscoveredType _type = NfcDiscoveredType.Detached;
+ private NfcP2p _p2pTarget;
+
+ internal P2pTargetDiscoveredEventArgs(NfcDiscoveredType _type, IntPtr p2pTargetHandle)
+ {
+ _p2pTarget = new NfcP2p(p2pTargetHandle);
+ }
+
+ /// <summary>
+ /// The p2p target type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public NfcDiscoveredType Type
+ {
+ get
+ {
+ return _type;
+ }
+ }
+
+ /// <summary>
+ /// P2p object
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public NfcP2p P2pTarget
+ {
+ get
+ {
+ return _p2pTarget;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains changed Nfc ndef discovered.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class NdefMessageDiscoveredEventArgs : EventArgs
+ {
+ private NfcNdefMessage _ndef;
+
+ internal NdefMessageDiscoveredEventArgs(IntPtr messageHandle)
+ {
+ _ndef = new NfcNdefMessage(messageHandle);
+ }
+
+ /// <summary>
+ /// The NdefMessage object that is most recently received via NFC p2p mode or tag mode
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public NfcNdefMessage NdefMessage
+ {
+ get
+ {
+ return _ndef;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains changed Secure element event.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class SecureElementEventArgs : EventArgs
+ {
+ private NfcSecureElementEvent _eventType = NfcSecureElementEvent.StartTransaction;
+
+ internal SecureElementEventArgs(NfcSecureElementEvent eventType)
+ {
+ _eventType = eventType;
+ }
+
+ /// <summary>
+ /// The Nfc secure element event.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public NfcSecureElementEvent EventType
+ {
+ get
+ {
+ return _eventType;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains changed Secure element trasaction event.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class SecureElementTranscationEventArgs : EventArgs
+ {
+ private NfcSecureElementType _secureElementType = NfcSecureElementType.Disable;
+ byte[] _aid;
+ byte[] _param;
+
+ internal SecureElementTranscationEventArgs(NfcSecureElementType secureElementType, byte[] aid, byte[] param)
+ {
+ _secureElementType = secureElementType;
+ _aid = aid;
+ _param = param;
+ }
+
+ /// <summary>
+ /// The Nfc secure element type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public NfcSecureElementType SecureElementType
+ {
+ get
+ {
+ return _secureElementType;
+ }
+ }
+ /// <summary>
+ /// The Nfc secure element aid.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public byte[] ApplicationID
+ {
+ get
+ {
+ return _aid;
+ }
+ }
+ /// <summary>
+ /// The Nfc secure element param.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public byte[] Param
+ {
+ get
+ {
+ return _param;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains changed HCE(Host Card Emulation) event.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class HostCardEmulationEventArgs : EventArgs
+ {
+ private NfcSecureElement _se;
+ private NfcHceEvent _hceEvent = NfcHceEvent.Deactivated;
+ private byte[] _apdu;
+
+ internal HostCardEmulationEventArgs(IntPtr seHandle, NfcHceEvent hcdEvent, byte[] apdu)
+ {
+ _se = new NfcSecureElement(seHandle);
+ _hceEvent = hcdEvent;
+ _apdu = apdu;
+ }
+
+ /// <summary>
+ /// The Nfc secure element.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public NfcSecureElement SecureElement
+ {
+ get
+ {
+ return _se;
+ }
+ }
+ /// <summary>
+ /// The Nfc hce event.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public NfcHceEvent HceEvent
+ {
+ get
+ {
+ return _hceEvent;
+ }
+ }
+ /// <summary>
+ /// The Nfc apdu(Application Protocol Data Unit)
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public byte[] Apdu
+ {
+ get
+ {
+ return _apdu;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains changed HCE(Host Card Emulation) event.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class P2pDataReceivedEventArgs : EventArgs
+ {
+ private NfcP2p _p2pTarget;
+ private NfcNdefMessage _ndefMessage;
+
+ internal P2pDataReceivedEventArgs(IntPtr p2pHandle, IntPtr ndefHandle)
+ {
+ _p2pTarget = new NfcP2p(p2pHandle);
+ _ndefMessage = new NfcNdefMessage(ndefHandle);
+ }
+
+ /// <summary>
+ /// The Nfc p2p target.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public NfcP2p P2pTarget
+ {
+ get
+ {
+ return _p2pTarget;
+ }
+ }
+ /// <summary>
+ /// The Nfc ndef message.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public NfcNdefMessage NdefMessage
+ {
+ get
+ {
+ return _ndefMessage;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcManager.cs b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcManager.cs
new file mode 100755
index 0000000..439fec7
--- /dev/null
+++ b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcManager.cs
@@ -0,0 +1,429 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Tizen.System;
+
+namespace Tizen.Network.Nfc
+{
+ /// <summary>
+ /// A class for NFC management. It allows applications to use NFC service.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/nfc</privilege>
+ static public class NfcManager
+ {
+ /// <summary>
+ /// Whether NFC is supported.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ static public bool IsSupported
+ {
+ get
+ {
+ bool isNfcSupported = SystemInfo.TryGetValue("http://tizen.org/feature/network.nfc", out isNfcSupported);
+
+ if (!isNfcSupported)
+ {
+ throw new NotSupportedException();
+ }
+
+ try
+ {
+ return NfcManagerImpl.Instance.IsSupported;
+ }
+ catch (TypeInitializationException e)
+ {
+ throw e.InnerException;
+ }
+ }
+ }
+
+ /// <summary>
+ /// NFC Activation state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ static public bool IsActivated
+ {
+ get
+ {
+ bool isNfcSupported = SystemInfo.TryGetValue("http://tizen.org/feature/network.nfc", out isNfcSupported);
+
+ if (!isNfcSupported)
+ {
+ throw new NotSupportedException();
+ }
+
+ try
+ {
+ return NfcManagerImpl.Instance.IsActivated;
+ }
+ catch (TypeInitializationException e)
+ {
+ throw e.InnerException;
+ }
+ }
+ }
+
+ /// <summary>
+ /// The Tag Filter type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ static public NfcTagFilterType TagFilterType
+ {
+ get
+ {
+ bool isNfcSupported = SystemInfo.TryGetValue("http://tizen.org/feature/network.nfc", out isNfcSupported);
+ bool isTagSupported = SystemInfo.TryGetValue("http://tizen.org/feature/network.nfc.tag", out isTagSupported);
+
+ if (!isNfcSupported || !isTagSupported)
+ {
+ throw new NotSupportedException();
+ }
+
+ try
+ {
+ return NfcManagerImpl.Instance.TagFilterType;
+ }
+ catch (TypeInitializationException e)
+ {
+ throw e.InnerException;
+ }
+ }
+ set
+ {
+ bool isNfcSupported = SystemInfo.TryGetValue("http://tizen.org/feature/network.nfc", out isNfcSupported);
+ bool isTagSupported = SystemInfo.TryGetValue("http://tizen.org/feature/network.nfc.tag", out isTagSupported);
+
+ if (!isNfcSupported || !isTagSupported)
+ {
+ throw new NotSupportedException();
+ }
+
+ try
+ {
+ NfcManagerImpl.Instance.TagFilterType = value;
+ }
+ catch (TypeInitializationException e)
+ {
+ throw e.InnerException;
+ }
+ }
+ }
+
+ /// <summary>
+ /// The Secure Element type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ static public NfcSecureElementType SecureElementType
+ {
+ get
+ {
+ bool isNfcSupported = SystemInfo.TryGetValue("http://tizen.org/feature/network.nfc", out isNfcSupported);
+ bool isCeSupported = SystemInfo.TryGetValue("http://tizen.org/feature/network.nfc.cardemulation", out isCeSupported);
+
+ if (!isNfcSupported || !isCeSupported)
+ {
+ throw new NotSupportedException();
+ }
+
+ try
+ {
+ return NfcManagerImpl.Instance.SecureElementType;
+ }
+ catch (TypeInitializationException e)
+ {
+ throw e.InnerException;
+ }
+ }
+ set
+ {
+ bool isNfcSupported = SystemInfo.TryGetValue("http://tizen.org/feature/network.nfc", out isNfcSupported);
+ bool isCeSupported = SystemInfo.TryGetValue("http://tizen.org/feature/network.nfc.cardemulation", out isCeSupported);
+
+ if (!isNfcSupported || !isCeSupported)
+ {
+ throw new NotSupportedException();
+ }
+
+ try
+ {
+ NfcManagerImpl.Instance.SecureElementType = value;
+ }
+ catch (TypeInitializationException e)
+ {
+ throw e.InnerException;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Enable or disable the system handling for tag and target discovered event.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ static public bool SystemHandlerEnabled
+ {
+ get
+ {
+ bool isNfcSupported = SystemInfo.TryGetValue("http://tizen.org/feature/network.nfc", out isNfcSupported);
+
+ if (!isNfcSupported)
+ {
+ throw new NotSupportedException();
+ }
+
+ try
+ {
+ return NfcManagerImpl.Instance.SystemHandlerEnabled;
+ }
+ catch (TypeInitializationException e)
+ {
+ throw e.InnerException;
+ }
+ }
+ set
+ {
+ bool isNfcSupported = SystemInfo.TryGetValue("http://tizen.org/feature/network.nfc", out isNfcSupported);
+
+ if (!isNfcSupported)
+ {
+ throw new NotSupportedException();
+ }
+
+ try
+ {
+ NfcManagerImpl.Instance.SystemHandlerEnabled = value;
+ }
+ catch (TypeInitializationException e)
+ {
+ throw e.InnerException;
+ }
+ }
+ }
+
+ /// <summary>
+ /// The cached Ndef Message.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ static public NfcNdefMessage CachedNdefMessage
+ {
+ get
+ {
+ bool isNfcSupported = SystemInfo.TryGetValue("http://tizen.org/feature/network.nfc", out isNfcSupported);
+
+ if (!isNfcSupported)
+ {
+ throw new NotSupportedException();
+ }
+
+ try
+ {
+ return NfcManagerImpl.Instance.CachedNdefMessage;
+ }
+ catch (TypeInitializationException e)
+ {
+ throw e.InnerException;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets Tag adapter object.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ static public NfcTagAdapter GetTagAdapter()
+ {
+ bool isNfcSupported = SystemInfo.TryGetValue("http://tizen.org/feature/network.nfc", out isNfcSupported);
+ bool isTagSupported = SystemInfo.TryGetValue("http://tizen.org/feature/network.nfc.tag", out isTagSupported);
+
+ if (!isNfcSupported || !isTagSupported)
+ {
+ throw new NotSupportedException();
+ }
+
+ try
+ {
+ return NfcManagerImpl.Instance.TagAdapter;
+ }
+ catch (TypeInitializationException e)
+ {
+ throw e.InnerException;
+ }
+ }
+
+ /// <summary>
+ /// Gets P2p adapter object.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ static public NfcP2pAdapter GetP2pAdapter()
+ {
+ bool isNfcSupported = SystemInfo.TryGetValue("http://tizen.org/feature/network.nfc", out isNfcSupported);
+ bool isP2pSupported = SystemInfo.TryGetValue("http://tizen.org/feature/network.nfc.p2p", out isP2pSupported);
+
+ if (!isNfcSupported || !isP2pSupported)
+ {
+ throw new NotSupportedException();
+ }
+
+ try
+ {
+ return NfcManagerImpl.Instance.P2pAdapter;
+ }
+ catch (TypeInitializationException e)
+ {
+ throw e.InnerException;
+ }
+ }
+
+ /// <summary>
+ /// Gets Card Emulation adepter object.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ static public NfcCardEmulationAdapter GetCardEmulationAdapter()
+ {
+ bool isNfcSupported = SystemInfo.TryGetValue("http://tizen.org/feature/network.nfc", out isNfcSupported);
+ bool isCeSupported = SystemInfo.TryGetValue("http://tizen.org/feature/network.nfc.cardemulation", out isCeSupported);
+
+ if (!isNfcSupported || !isCeSupported)
+ {
+ throw new NotSupportedException();
+ }
+
+ try
+ {
+ return NfcManagerImpl.Instance.CardEmulationAdapter;
+ }
+ catch (TypeInitializationException e)
+ {
+ throw e.InnerException;
+ }
+ }
+
+ /// <summary>
+ /// Activates Nfc asynchronously.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>A task indicates whether the Activate method is done or not.</returns>
+ static public Task SetActivationAsync(bool activation)
+ {
+ bool isNfcSupported = SystemInfo.TryGetValue("http://tizen.org/feature/network.nfc", out isNfcSupported);
+
+ if (!isNfcSupported)
+ {
+ throw new NotSupportedException();
+ }
+
+ try
+ {
+ return NfcManagerImpl.Instance.SetActivationAsync(activation);
+ }
+ catch (TypeInitializationException e)
+ {
+ throw e.InnerException;
+ }
+ }
+
+ /// <summary>
+ /// The Activation changed event.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ static public event EventHandler<ActivationChangedEventArgs> ActivationChanged
+ {
+ add
+ {
+ bool isNfcSupported = SystemInfo.TryGetValue("http://tizen.org/feature/network.nfc", out isNfcSupported);
+
+ if (!isNfcSupported)
+ {
+ throw new NotSupportedException();
+ }
+
+ try
+ {
+ NfcManagerImpl.Instance.ActivationChanged += value;
+ }
+ catch (TypeInitializationException e)
+ {
+ throw e.InnerException;
+ }
+ }
+ remove
+ {
+ bool isNfcSupported = SystemInfo.TryGetValue("http://tizen.org/feature/network.nfc", out isNfcSupported);
+
+ if (!isNfcSupported)
+ {
+ throw new NotSupportedException();
+ }
+
+ try
+ {
+ NfcManagerImpl.Instance.ActivationChanged -= value;
+ }
+ catch (TypeInitializationException e)
+ {
+ throw e.InnerException;
+ }
+ }
+ }
+
+ /// <summary>
+ /// The Ndef discovered event.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ static public event EventHandler<NdefMessageDiscoveredEventArgs> NdefMessageDiscovered
+ {
+ add
+ {
+ bool isNfcSupported = SystemInfo.TryGetValue("http://tizen.org/feature/network.nfc", out isNfcSupported);
+
+ if (!isNfcSupported)
+ {
+ throw new NotSupportedException();
+ }
+
+ try
+ {
+ NfcManagerImpl.Instance.NdefMessageDiscovered += value;
+ }
+ catch (TypeInitializationException e)
+ {
+ throw e.InnerException;
+ }
+ }
+ remove
+ {
+ bool isNfcSupported = SystemInfo.TryGetValue("http://tizen.org/feature/network.nfc", out isNfcSupported);
+
+ if (!isNfcSupported)
+ {
+ throw new NotSupportedException();
+ }
+
+ try
+ {
+ NfcManagerImpl.Instance.NdefMessageDiscovered -= value;
+ }
+ catch (TypeInitializationException e)
+ {
+ throw e.InnerException;
+ }
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcManagerEvent.cs b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcManagerEvent.cs
new file mode 100644
index 0000000..7150daa
--- /dev/null
+++ b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcManagerEvent.cs
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Threading.Tasks;
+
+namespace Tizen.Network.Nfc
+{
+ internal static class EventHandlerExtension
+ {
+ internal static void SafeInvoke(this EventHandler evt, object sender, EventArgs e)
+ {
+ var handler = evt;
+ if (handler != null)
+ {
+ handler(sender, e);
+ }
+ }
+ internal static void SafeInvoke<T>(this EventHandler<T> evt, object sender, T e) where T : EventArgs
+ {
+ var handler = evt;
+ if (handler != null)
+ {
+ handler(sender, e);
+ }
+ }
+ }
+
+ internal partial class NfcManagerImpl
+ {
+ private event EventHandler<ActivationChangedEventArgs> _activationChanged;
+ private event EventHandler<NdefMessageDiscoveredEventArgs> _ndefMessageDiscovered;
+
+ private Interop.Nfc.ActivationChangedCallback _activationChangedCallback;
+ private Interop.Nfc.NdefMessageDiscoveredCallback _ndefMessageDiscoveredCallback;
+
+ internal event EventHandler<ActivationChangedEventArgs> ActivationChanged
+ {
+ add
+ {
+ if (_activationChanged == null)
+ {
+ RegisterActivationChangedEvent();
+ }
+ _activationChanged += value;
+ }
+ remove
+ {
+ _activationChanged -= value;
+ if (_activationChanged == null)
+ {
+ UnregisterActivationChangedEvent();
+ }
+ }
+ }
+
+ internal event EventHandler<NdefMessageDiscoveredEventArgs> NdefMessageDiscovered
+ {
+ add
+ {
+ if (_ndefMessageDiscovered == null)
+ {
+ RegisterNdefMessageDiscoveredEvent();
+ }
+ _ndefMessageDiscovered += value;
+ }
+ remove
+ {
+ _ndefMessageDiscovered -= value;
+ if (_ndefMessageDiscovered == null)
+ {
+ UnregisterNdefMessageDiscoveredEvent();
+ }
+ }
+ }
+
+ internal void RemoveAllRegisteredEvent()
+ {
+ //unregister all remaining events when this object is released.
+ if (_activationChanged != null)
+ {
+ UnregisterActivationChangedEvent();
+ }
+ }
+
+ private void RegisterActivationChangedEvent()
+ {
+ _activationChangedCallback = (bool activated, IntPtr userData) =>
+ {
+ bool isActivated = activated;
+ ActivationChangedEventArgs e = new ActivationChangedEventArgs(isActivated);
+ _activationChanged.SafeInvoke(null, e);
+ };
+ int ret = Interop.Nfc.SetActivationChangedCallback(_activationChangedCallback, IntPtr.Zero);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set activation changed callback, Error - " + (NfcError)ret);
+ }
+ }
+
+ private void UnregisterActivationChangedEvent()
+ {
+ Interop.Nfc.UnsetActivationChangedCallback();
+ }
+
+ private void RegisterNdefMessageDiscoveredEvent()
+ {
+ _ndefMessageDiscoveredCallback = (IntPtr ndefMessageHandle, IntPtr userData) =>
+ {
+ NdefMessageDiscoveredEventArgs e = new NdefMessageDiscoveredEventArgs(ndefMessageHandle);
+ _ndefMessageDiscovered.SafeInvoke(null, e);
+ };
+
+ int ret = Interop.Nfc.SetNdefDiscoveredCallback(_ndefMessageDiscoveredCallback, IntPtr.Zero);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set ndef message discovered callback, Error - " + (NfcError)ret);
+ }
+ }
+
+ private void UnregisterNdefMessageDiscoveredEvent()
+ {
+ Interop.Nfc.UnsetNdefDiscoveredCallback();
+ }
+ }
+}
diff --git a/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcManagerImpl.cs b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcManagerImpl.cs
new file mode 100755
index 0000000..702f1b2
--- /dev/null
+++ b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcManagerImpl.cs
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+
+namespace Tizen.Network.Nfc
+{
+ static internal class Globals
+ {
+ internal const string LogTag = "Tizen.Network.Nfc";
+ }
+
+ internal static class NfcConvertUtil
+ {
+ internal static byte[] IntLengthIntPtrToByteArray(IntPtr nativeValue, int length)
+ {
+ byte[] value = new byte[length];
+ if (nativeValue != IntPtr.Zero)
+ {
+ Marshal.Copy(nativeValue, value, 0, length);
+ }
+ return value;
+ }
+
+ internal static byte[] UintLengthIntPtrToByteArray(IntPtr nativeValue, uint length)
+ {
+ byte[] value = new byte[length];
+
+ if (nativeValue != IntPtr.Zero)
+ {
+ for (int i = 0; i < length; i++)
+ {
+ value[i] = Marshal.ReadByte(nativeValue);
+ nativeValue += sizeof(byte);
+ }
+ }
+ return value;
+ }
+ }
+
+ internal partial class NfcManagerImpl : IDisposable
+ {
+ private static readonly NfcManagerImpl _instance = new NfcManagerImpl();
+ private static readonly NfcTagAdapter _instanceTagAdapter = new NfcTagAdapter();
+ private static readonly NfcP2pAdapter _instanceP2pAdapter = new NfcP2pAdapter();
+ private static readonly NfcCardEmulationAdapter _instanceCardEmulationAdapter = new NfcCardEmulationAdapter();
+
+ private Dictionary<IntPtr, Interop.Nfc.VoidCallback> _callback_map = new Dictionary<IntPtr, Interop.Nfc.VoidCallback>();
+ private int _requestId = 0;
+ private bool disposed = false;
+
+ internal static NfcManagerImpl Instance
+ {
+ get
+ {
+ return _instance;
+ }
+ }
+
+ internal NfcTagAdapter TagAdapter
+ {
+ get
+ {
+ return _instanceTagAdapter;
+ }
+ }
+
+ internal NfcP2pAdapter P2pAdapter
+ {
+ get
+ {
+ return _instanceP2pAdapter;
+ }
+ }
+
+ internal NfcCardEmulationAdapter CardEmulationAdapter
+ {
+ get
+ {
+ return _instanceCardEmulationAdapter;
+ }
+ }
+
+ internal bool IsSupported
+ {
+ get
+ {
+ bool support = Interop.Nfc.IsSupported();
+
+ return support;
+ }
+ }
+
+ internal bool IsActivated
+ {
+ get
+ {
+ bool active = Interop.Nfc.IsActivated();
+
+ return active;
+ }
+ }
+
+ internal NfcNdefMessage CachedNdefMessage
+ {
+ get
+ {
+ IntPtr ndef = IntPtr.Zero; ;
+ int ret = Interop.Nfc.GetCachedMessage(out ndef);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get cached ndef message, Error - " + (NfcError)ret);
+ }
+
+ NfcNdefMessage ndefMessage = new NfcNdefMessage(ndef);
+ return ndefMessage;
+ }
+ }
+
+ internal NfcTagFilterType TagFilterType
+ {
+ get
+ {
+ int type = Interop.Nfc.GetTagFilter();
+
+ return (NfcTagFilterType)type;
+ }
+ set
+ {
+ Interop.Nfc.SetTagFilter((int)value);
+ }
+ }
+
+ internal NfcSecureElementType SecureElementType
+ {
+ get
+ {
+ int type;
+ int ret = Interop.Nfc.GetSecureElementType(out type);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get secure element type, Error - " + (NfcError)ret);
+ }
+ return (NfcSecureElementType)type;
+ }
+ set
+ {
+ int ret = Interop.Nfc.SetSecureElementType((int)value);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set secure element type, Error - " + (NfcError)ret);
+ }
+ }
+ }
+
+ internal bool SystemHandlerEnabled
+ {
+ get
+ {
+ bool systemhandler = Interop.Nfc.IsSystemHandlerEnabled();
+
+ return systemhandler;
+ }
+ set
+ {
+ int ret = Interop.Nfc.SetSystemHandlerEnable(value);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to enable system handler, Error - " + (NfcError)ret);
+ }
+ }
+ }
+
+ private NfcManagerImpl()
+ {
+ Initialize();
+ }
+
+ ~NfcManagerImpl()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects.
+ }
+ //Free unmanaged objects
+ Deinitialize();
+ disposed = true;
+ }
+
+ private void Initialize()
+ {
+ int ret = Interop.Nfc.Initialize();
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to Initialize Nfc, Error - " + (NfcError)ret);
+ NfcErrorFactory.ThrowNfcException(ret);
+ }
+ }
+
+ private void Deinitialize()
+ {
+ int ret = Interop.Nfc.Deinitialize();
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to Deinitialize Nfc, Error - " + (NfcError)ret);
+ }
+ }
+
+ internal Task SetActivationAsync(bool activation)
+ {
+ TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
+ IntPtr id = IntPtr.Zero;
+ lock (_callback_map)
+ {
+ id = (IntPtr)_requestId++;
+ _callback_map[id] = (error, key) =>
+ {
+ Log.Debug(Globals.LogTag, "nfc activated");
+ if (error != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Error occurs during Nfc activating, " + (NfcError)error);
+ task.SetException(new InvalidOperationException("Error occurs during Nfc activating, " + (NfcError)error));
+ }
+ task.SetResult(true);
+ lock (_callback_map)
+ {
+ _callback_map.Remove(key);
+ }
+ };
+
+ int ret = Interop.Nfc.SetActivation(activation, _callback_map[id], id);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to activate nfc, Error - " + (NfcError)ret);
+ NfcErrorFactory.ThrowNfcException(ret);
+ }
+ }
+ return task.Task;
+ }
+ }
+}
diff --git a/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcNdefMessage.cs b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcNdefMessage.cs
new file mode 100755
index 0000000..80d1574
--- /dev/null
+++ b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcNdefMessage.cs
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+
+namespace Tizen.Network.Nfc
+{
+ /// <summary>
+ /// A class for Ndef Message information. It allows applications to use Ndef Message information.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class NfcNdefMessage : IDisposable
+ {
+ private bool disposed = false;
+ private IntPtr _messageHandle = IntPtr.Zero;
+ private List<NfcNdefRecord> _recordList = new List<NfcNdefRecord>();
+
+ /// <summary>
+ /// The number of record in NDEF message.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int RecordCount
+ {
+ get
+ {
+ int recordCount;
+ int ret = Interop.Nfc.NdefMessage.GetRecordCount(_messageHandle, out recordCount);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get record count, Error - " + (NfcError)ret);
+ }
+ return recordCount;
+ }
+ }
+
+ /// <summary>
+ /// Creates a object for the access point.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public NfcNdefMessage()
+ {
+ int ret = Interop.Nfc.NdefMessage.Create(out _messageHandle);
+
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to create Ndef message, Error - " + (NfcError)ret);
+ NfcErrorFactory.ThrowNfcException(ret);
+ }
+ }
+
+ internal NfcNdefMessage(IntPtr messageHandle)
+ {
+ _messageHandle = messageHandle;
+ }
+
+ ~NfcNdefMessage()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects.
+ int ret = Interop.Nfc.NdefMessage.Destroy(_messageHandle);
+
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to destroy ndef message, Error - " + (NfcError)ret);
+ }
+ }
+ //Free unmanaged objects
+ disposed = true;
+ }
+
+ /// <summary>
+ /// Appends a record into NDEF message.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>Whether appending the record succeeded.</returns>
+ /// <param name="record">The NfcNdefRecord object that will be appended into NDEF message.</param>
+ public bool AppendRecord(NfcNdefRecord record)
+ {
+ bool isSuccess = true;
+
+ int ret = Interop.Nfc.NdefMessage.AppendRecord(_messageHandle, record.GetHandle());
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to append record, Error - " + (NfcError)ret);
+ isSuccess = false;
+ }
+ else
+ {
+ _recordList.Add(record);
+ }
+
+ return isSuccess;
+ }
+
+ /// <summary>
+ /// Inserts a record at index into NDEF message.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>Whether insterting the record succeeded.</returns>
+ /// <param name="index">The index of record ( starts from 0 ).</param>
+ /// <param name="record">The NfcNdefRecord object that will be appended into NDEF message.</param>
+ public bool InsertRecord(int index, NfcNdefRecord record)
+ {
+ bool isSuccess = true;
+
+ int ret = Interop.Nfc.NdefMessage.InsertRecord(_messageHandle, index, record.GetHandle());
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to insert record, Error - " + (NfcError)ret);
+ isSuccess = false;
+ }
+ else
+ {
+ _recordList.Add(record);
+ }
+
+ return isSuccess;
+ }
+
+ /// <summary>
+ /// Inserts a record at index into NDEF message.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>Whether removing the record succeeded.</returns>
+ /// <param name="index">The index of record ( starts from 0 ).</param>
+ public bool RemoveRecord(int index)
+ {
+ bool isSuccess = true;
+
+ int ret = Interop.Nfc.NdefMessage.RemoveRecord(_messageHandle, index);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to remove record, Error - " + (NfcError)ret);
+ isSuccess = false;
+ }
+
+ return isSuccess;
+ }
+
+ /// <summary>
+ /// Gets record by index.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>The NfcNdefRecord object.</returns>
+ /// <param name="index">The index of record ( starts from 0 ).</param>
+ public NfcNdefRecord GetRecord(int index)
+ {
+ IntPtr recordHandle;
+ NfcNdefRecord recordObject = null;
+
+ int ret = Interop.Nfc.NdefMessage.GetRecord(_messageHandle, index, out recordHandle);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to remove record, Error - " + (NfcError)ret);
+ }
+
+ foreach (NfcNdefRecord recordElement in _recordList)
+ {
+ if(recordElement.GetHandle() == recordHandle)
+ {
+ Log.Debug(Globals.LogTag, "Find record handle");
+ recordObject = recordElement;
+ break;
+ }
+ }
+
+ return recordObject;
+ }
+
+ internal IntPtr GetHandle()
+ {
+ return _messageHandle;
+ }
+ }
+}
diff --git a/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcNdefRecord.cs b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcNdefRecord.cs
new file mode 100755
index 0000000..6387c79
--- /dev/null
+++ b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcNdefRecord.cs
@@ -0,0 +1,322 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+
+namespace Tizen.Network.Nfc
+{
+ /// <summary>
+ /// A class for Ndef Record information. It allows applications to use Ndef Record information.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class NfcNdefRecord : IDisposable
+ {
+ private bool disposed = false;
+ private IntPtr _recordHandle = IntPtr.Zero;
+
+ /// <summary>
+ /// The record ID.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public byte[] Id
+ {
+ get
+ {
+ IntPtr id;
+ int idLength;
+ int ret = Interop.Nfc.NdefRecord.GetId(_recordHandle, out id, out idLength);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get id, Error - " + (NfcError)ret);
+ return null;
+ }
+
+ return NfcConvertUtil.IntLengthIntPtrToByteArray(id, idLength);
+ }
+ }
+
+ /// <summary>
+ /// The record payload.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public byte[] Payload
+ {
+ get
+ {
+ IntPtr payload;
+ uint payloadLength;
+ int ret = Interop.Nfc.NdefRecord.GetPayload(_recordHandle, out payload, out payloadLength);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get payload, Error - " + (NfcError)ret);
+ return null;
+ }
+
+ return NfcConvertUtil.UintLengthIntPtrToByteArray(payload, payloadLength);
+ }
+ }
+
+ /// <summary>
+ /// The record type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public byte[] Type
+ {
+ get
+ {
+ IntPtr type;
+ int typeSize;
+ int ret = Interop.Nfc.NdefRecord.GetType(_recordHandle, out type, out typeSize);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get payload, Error - " + (NfcError)ret);
+ return null;
+ }
+
+ return NfcConvertUtil.IntLengthIntPtrToByteArray(type, typeSize);
+ }
+ }
+
+ /// <summary>
+ /// The record TNF(Type Name Format) value.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public NfcRecordTypeNameFormat Tnf
+ {
+ get
+ {
+ int tnf;
+ int ret = Interop.Nfc.NdefRecord.GetTnf(_recordHandle, out tnf);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get tnf, Error - " + (NfcError)ret);
+ }
+ return (NfcRecordTypeNameFormat)tnf;
+ }
+ }
+
+ /// <summary>
+ /// The text of text type Ndef record.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Text
+ {
+ get
+ {
+ string text;
+ int ret = Interop.Nfc.NdefRecord.GetText(_recordHandle, out text);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get text, Error - " + (NfcError)ret);
+ }
+ return text;
+ }
+ }
+
+ /// <summary>
+ /// The language code of text type Ndef record.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string LanguageCode
+ {
+ get
+ {
+ string languageCode;
+ int ret = Interop.Nfc.NdefRecord.GetLanguageCode(_recordHandle, out languageCode);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get language code, Error - " + (NfcError)ret);
+ }
+ return languageCode;
+ }
+ }
+
+ /// <summary>
+ /// The encoding type of text type Ndef record.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public NfcEncodeType EncodeType
+ {
+ get
+ {
+ int encodeType;
+ int ret = Interop.Nfc.NdefRecord.GetEncodeType(_recordHandle, out encodeType);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get encode type, Error - " + (NfcError)ret);
+ }
+ return (NfcEncodeType)encodeType;
+ }
+ }
+
+ /// <summary>
+ /// The URI of uri type Ndef record.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Uri
+ {
+ get
+ {
+ string uri;
+ int ret = Interop.Nfc.NdefRecord.GetUri(_recordHandle, out uri);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get uri, Error - " + (NfcError)ret);
+ }
+ return uri;
+ }
+ }
+
+ /// <summary>
+ /// The mime type of mime type Ndef record.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string MimeType
+ {
+ get
+ {
+ string mimeType;
+ int ret = Interop.Nfc.NdefRecord.GetMimeType(_recordHandle, out mimeType);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get mime type, Error - " + (NfcError)ret);
+ }
+ return mimeType;
+ }
+ }
+
+ /// <summary>
+ /// Creates a record with given parameter value.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="format">The type name format.</param>
+ /// <param name="type">The specified type name.</param>
+ /// <param name="id">The record ID.</param>
+ /// <param name="payload">The payload of this record.</param>
+ /// <param name="paloadLength">The byte size of payload.</param>
+ /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public NfcNdefRecord(NfcRecordTypeNameFormat format, byte[] type, byte[] id, byte[] payload, uint paloadLength)
+ {
+ int ret = Interop.Nfc.NdefRecord.Create(out _recordHandle, (int)format, type, type.Length, id, id.Length, payload, paloadLength);
+
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to create Ndef record, Error - " + (NfcError)ret);
+ NfcErrorFactory.ThrowNfcException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Creates a record with text type payload.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="text">The encoded text.</param>
+ /// <param name="languageCode">The language code string value followed by IANA[RFC 3066] (ex: en-US, ko-KR).</param>
+ /// <param name="encode">The encoding type.</param>
+ /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public NfcNdefRecord(string text, string languageCode, NfcEncodeType encode)
+ {
+ int ret = Interop.Nfc.NdefRecord.CreateText(out _recordHandle, text, languageCode, (int)encode);
+
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to create ndef Text record, Error - " + (NfcError)ret);
+ NfcErrorFactory.ThrowNfcException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Creates a record with text type payload.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="uri">The URI string that will be stored in the payload.</param>
+ /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public NfcNdefRecord(string uri)
+ {
+ int ret = Interop.Nfc.NdefRecord.CreateUri(out _recordHandle, uri);
+
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to create ndef Uri record, Error - " + (NfcError)ret);
+ NfcErrorFactory.ThrowNfcException(ret);
+ }
+ }
+
+ /// <summary>
+ /// Creates a record with text type payload.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="mimeType">The mime type [RFC 2046] (ex. text/plain, image/jpeg ) This value is stored in type field.</param>
+ /// <param name="data">The data in form of bytes array.</param>
+ /// <param name="dataSize">The size of data.</param>
+ /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public NfcNdefRecord(string mimeType, byte[] data, uint dataSize)
+ {
+ int ret = Interop.Nfc.NdefRecord.CreateMime(out _recordHandle, mimeType, data, dataSize);
+
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to create ndef Mime record, Error - " + (NfcError)ret);
+ NfcErrorFactory.ThrowNfcException(ret);
+ }
+ }
+
+ ~NfcNdefRecord()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects.
+ int ret = Interop.Nfc.NdefRecord.Destroy(_recordHandle);
+
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to destroy ndef record, Error - " + (NfcError)ret);
+ }
+ }
+ //Free unmanaged objects
+ disposed = true;
+ }
+
+ internal IntPtr GetHandle()
+ {
+ return _recordHandle;
+ }
+ }
+}
diff --git a/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcP2p.cs b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcP2p.cs
new file mode 100755
index 0000000..a1a5308
--- /dev/null
+++ b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcP2p.cs
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Tizen.Network.Nfc
+{
+ /// <summary>
+ /// A class for managing the p2p target information.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class NfcP2p : IDisposable
+ {
+ private IntPtr _p2pTargetHandle = IntPtr.Zero;
+ private bool disposed = false;
+
+ private event EventHandler<P2pDataReceivedEventArgs> _p2pDataReceived;
+
+ private Interop.Nfc.P2pDataReceivedCallback _p2pDataReceivedCallback;
+
+ /// <summary>
+ /// The event for receiving data from NFC peer-to-peer target.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<P2pDataReceivedEventArgs> P2pDataReceived
+ {
+ add
+ {
+ _p2pDataReceived += value;
+ }
+ remove
+ {
+ _p2pDataReceived -= value;
+ }
+ }
+
+ internal NfcP2p(IntPtr handle)
+ {
+ _p2pTargetHandle = handle;
+ RegisterP2pDataReceivedEvent();
+ }
+
+ ~NfcP2p()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects.
+ UnregisterP2pDataReceivedEvent();
+ }
+ //Free unmanaged objects
+ disposed = true;
+ }
+
+ internal IntPtr GetHandle()
+ {
+ return _p2pTargetHandle;
+ }
+
+ /// <summary>
+ /// Sends data to NFC peer-to-peer target.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="ndefMessage">NfcNdefMessage object.</param>
+ /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public Task<NfcError> SendNdefMessageAsync(NfcNdefMessage ndefMessage)
+ {
+ var task = new TaskCompletionSource<NfcError>();
+
+ Interop.Nfc.VoidCallback callback = (int result, IntPtr userData) =>
+ {
+ task.SetResult((NfcError)result);
+ return;
+ };
+
+ int ret = Interop.Nfc.P2p.Send(_p2pTargetHandle, ndefMessage.GetHandle(), callback, IntPtr.Zero);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to write ndef message, Error - " + (NfcError)ret);
+ NfcErrorFactory.ThrowNfcException(ret);
+ }
+
+ return task.Task;
+ }
+
+ private void RegisterP2pDataReceivedEvent()
+ {
+ _p2pDataReceivedCallback = (IntPtr p2pTargetHandle, IntPtr ndefMessageHandle, IntPtr userData) =>
+ {
+ P2pDataReceivedEventArgs e = new P2pDataReceivedEventArgs(p2pTargetHandle, ndefMessageHandle);
+ _p2pDataReceived.SafeInvoke(null, e);
+ };
+
+ int ret = Interop.Nfc.P2p.SetDataReceivedCallback(_p2pTargetHandle, _p2pDataReceivedCallback, IntPtr.Zero);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set p2p target discovered callback, Error - " + (NfcError)ret);
+ }
+ }
+
+ private void UnregisterP2pDataReceivedEvent()
+ {
+ Interop.Nfc.P2p.UnsetDataReceivedCallback(_p2pTargetHandle);
+ }
+ }
+
+ /// <summary>
+ /// A class for managing the snep(Simple NDEF Exchange Protocol) information.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class NfcSnep : IDisposable
+ {
+ private IntPtr _snepHandle = IntPtr.Zero;
+ private bool disposed = false;
+
+ internal NfcSnep(IntPtr handle)
+ {
+ _snepHandle = handle;
+ }
+
+ ~NfcSnep()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects.
+ }
+ //Free unmanaged objects
+ disposed = true;
+ }
+
+ internal IntPtr GetHandle()
+ {
+ return _snepHandle;
+ }
+ }
+}
diff --git a/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcP2pAdapter.cs b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcP2pAdapter.cs
new file mode 100755
index 0000000..ac3c693
--- /dev/null
+++ b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcP2pAdapter.cs
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+
+namespace Tizen.Network.Nfc
+{
+ /// <summary>
+ /// A class for NFC P2P(Peer to Peer) mode. It allows applications to handle P2P informations.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/nfc</privilege>
+ public class NfcP2pAdapter : IDisposable
+ {
+ private NfcP2p _p2pTarget;
+ private bool disposed = false;
+
+ private event EventHandler<P2pTargetDiscoveredEventArgs> _p2pTargetDiscovered;
+
+ private Interop.Nfc.P2pTargetDiscoveredCallback _p2pTargetDiscoveredCallback;
+
+ /// <summary>
+ /// The event for receiving NFC peer-to-peer target discovered notification.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<P2pTargetDiscoveredEventArgs> P2pTargetDiscovered
+ {
+ add
+ {
+ _p2pTargetDiscovered += value;
+ }
+ remove
+ {
+ _p2pTargetDiscovered -= value;
+ }
+ }
+
+ internal NfcP2pAdapter()
+ {
+ RegisterP2pTargetDiscoveredEvent();
+ }
+
+ ~NfcP2pAdapter()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects.
+ UnregisterP2pTargetDiscoveredEvent();
+ }
+ //Free unmanaged objects
+ disposed = true;
+ }
+
+ /// <summary>
+ /// Gets current connected p2p target.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>NfcP2p object.</returns>
+ /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public NfcP2p GetConnectedTarget()
+ {
+ IntPtr targetHandle = IntPtr.Zero;
+ int ret = Interop.Nfc.GetConnectedTarget(out targetHandle);
+
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get connected p2p target, Error - " + (NfcError)ret);
+ NfcErrorFactory.ThrowNfcException(ret);
+ }
+ _p2pTarget = new NfcP2p(targetHandle);
+
+ return _p2pTarget;
+ }
+
+ private void RegisterP2pTargetDiscoveredEvent()
+ {
+ _p2pTargetDiscoveredCallback = (int type, IntPtr p2pTargetHandle, IntPtr userData) =>
+ {
+ NfcDiscoveredType tagType = (NfcDiscoveredType)type;
+ P2pTargetDiscoveredEventArgs e = new P2pTargetDiscoveredEventArgs(tagType, p2pTargetHandle);
+ _p2pTargetDiscovered.SafeInvoke(null, e);
+ };
+
+ int ret = Interop.Nfc.SetP2pTargetDiscoveredCallback(_p2pTargetDiscoveredCallback, IntPtr.Zero);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set p2p target discovered callback, Error - " + (NfcError)ret);
+ }
+ }
+
+ private void UnregisterP2pTargetDiscoveredEvent()
+ {
+ Interop.Nfc.UnsetP2pTargetDiscoveredCallback();
+ }
+ }
+}
diff --git a/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcSecureElement.cs b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcSecureElement.cs
new file mode 100644
index 0000000..e882ba7
--- /dev/null
+++ b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcSecureElement.cs
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+
+namespace Tizen.Network.Nfc
+{
+ /// <summary>
+ /// A class for managing the Secure Element information.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class NfcSecureElement : IDisposable
+ {
+ private IntPtr _secureElementHandle = IntPtr.Zero;
+ private bool disposed = false;
+
+ internal NfcSecureElement(IntPtr handle)
+ {
+ _secureElementHandle = handle;
+ }
+
+ ~NfcSecureElement()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects.
+ }
+ //Free unmanaged objects
+ disposed = true;
+ }
+
+ /// <summary>
+ /// Send APDU(Application Protocol Data Unit) response to CLF(Contactless Front-end).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="response">The bytes array of response data.</param>
+ /// <param name="responseLength">The size of response bytes array.</param>
+ /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public void HceSendApduResponse(byte[] response, uint responseLength)
+ {
+ int ret = Interop.Nfc.CardEmulation.HceSendApduRespondse(_secureElementHandle, response, responseLength);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to hcd send apdu response, Error - " + (NfcError)ret);
+ NfcErrorFactory.ThrowNfcException(ret);
+ }
+ }
+
+ internal IntPtr GetHandle()
+ {
+ return _secureElementHandle;
+ }
+ }
+}
diff --git a/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcTag.cs b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcTag.cs
new file mode 100755
index 0000000..7643171
--- /dev/null
+++ b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcTag.cs
@@ -0,0 +1,293 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Tizen.Network.Nfc
+{
+ /// <summary>
+ /// A class for managing the Tag information.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class NfcTag : IDisposable
+ {
+ private bool disposed = false;
+ private IntPtr _tagHandle = IntPtr.Zero;
+
+ /// <summary>
+ /// The type of NFC tag.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public NfcTagType Type
+ {
+ get
+ {
+ int type;
+ int ret = Interop.Nfc.Tag.GetType(_tagHandle, out type);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get tag type, Error - " + (NfcError)ret);
+ }
+ return (NfcTagType)type;
+ }
+ }
+
+ /// <summary>
+ /// Whether the given NFC tag supports NDEF messages.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool IsSupportNdef
+ {
+ get
+ {
+ bool isSupport;
+ int ret = Interop.Nfc.Tag.IsSupportNdef(_tagHandle, out isSupport);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get support state, Error - " + (NfcError)ret);
+ }
+ return isSupport;
+
+ }
+ }
+
+ /// <summary>
+ /// The maximum NDEF message size that can be stored in NFC tag.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public uint MaximumNdefSize
+ {
+ get
+ {
+ uint maxSize;
+ int ret = Interop.Nfc.Tag.GetMaximumNdefSize(_tagHandle, out maxSize);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get max ndef size, Error - " + (NfcError)ret);
+ }
+ return maxSize;
+ }
+ }
+
+ /// <summary>
+ /// The size of NDEF message that stored in the tag.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public uint NdefSize
+ {
+ get
+ {
+ uint ndefSize;
+ int ret = Interop.Nfc.Tag.GetNdefSize(_tagHandle, out ndefSize);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get ndef size, Error - " + (NfcError)ret);
+ }
+ return ndefSize;
+ }
+ }
+
+ internal NfcTag(IntPtr handle)
+ {
+ _tagHandle = handle;
+ }
+
+ ~NfcTag()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects.
+ }
+ //Free unmanaged objects
+ disposed = true;
+ }
+
+ /// <summary>
+ /// Retrieves all tag information.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>List of NfcTagInformation objects.</returns>
+ /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public IEnumerable<NfcTagInformation> ForeachInformation()
+ {
+ List<NfcTagInformation> infoList = new List<NfcTagInformation>();
+ Interop.Nfc.TagInformationCallback callback = (IntPtr key, IntPtr infoValue, int valueSize, IntPtr userData) =>
+ {
+ if (key != IntPtr.Zero && infoValue != IntPtr.Zero)
+ {
+ NfcTagInformation tagInfo = new NfcTagInformation(Marshal.PtrToStringAnsi(key), new byte[valueSize]);
+
+ Marshal.Copy(infoValue, tagInfo.InformationValue, 0, valueSize);
+
+ infoList.Add(tagInfo);
+
+ return true;
+ }
+ return false;
+ };
+
+ int ret = Interop.Nfc.Tag.ForeachInformation(_tagHandle, callback, IntPtr.Zero);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get all Tag information, Error - " + (NfcError)ret);
+ NfcErrorFactory.ThrowNfcException(ret);
+ }
+
+ return infoList;
+ }
+
+ /// <summary>
+ /// Transceives the data of the raw format card.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="buffer">The binary data for parameter or additional commands.</param>
+ /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public Task<byte[]> TransceiveAsync(byte[] buffer)
+ {
+ var task = new TaskCompletionSource<byte[]>();
+
+ byte[] resultBuffer = null;
+ Interop.Nfc.TagTransceiveCompletedCallback callback = (int result, IntPtr resultData, int dataSize, IntPtr userData) =>
+ {
+ if (result == (int)NfcError.None)
+ {
+ resultBuffer = new byte[dataSize];
+ Marshal.Copy(resultData, resultBuffer, 0, dataSize);
+ task.SetResult(resultBuffer);
+ }
+ return;
+ };
+
+ int ret = Interop.Nfc.Tag.Transceive(_tagHandle, buffer, buffer.Length, callback, IntPtr.Zero);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to transceive data, Error - " + (NfcError)ret);
+ NfcErrorFactory.ThrowNfcException(ret);
+ }
+
+ return task.Task;
+ }
+
+ /// <summary>
+ /// Reads NDEF formatted data from NFC tag.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public Task<NfcNdefMessage> ReadNdefMessageAsync()
+ {
+ var task = new TaskCompletionSource<NfcNdefMessage>();
+
+ NfcNdefMessage ndefMsg = null;
+ Interop.Nfc.TagReadCompletedCallback callback = (int result, IntPtr ndefMessage, IntPtr userData) =>
+ {
+ if (result == (int)NfcError.None)
+ {
+ ndefMsg = new NfcNdefMessage(ndefMessage);
+ task.SetResult(ndefMsg);
+
+ return true;
+ }
+ return false;
+ };
+
+ int ret = Interop.Nfc.Tag.ReadNdef(_tagHandle, callback, IntPtr.Zero);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to read ndef message, Error - " + (NfcError)ret);
+ NfcErrorFactory.ThrowNfcException(ret);
+ }
+
+ return task.Task;
+ }
+
+ /// <summary>
+ /// Writes NDEF formatted data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="ndefMessage">The NfcNdefMessage object.</param>
+ /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public Task<NfcError> WriteNdefMessageAsync(NfcNdefMessage ndefMessage)
+ {
+ var task = new TaskCompletionSource<NfcError>();
+
+ Interop.Nfc.VoidCallback callback = (int result, IntPtr userData) =>
+ {
+ task.SetResult((NfcError)result);
+ return;
+ };
+
+ int ret = Interop.Nfc.Tag.WriteNdef(_tagHandle, ndefMessage.GetHandle(), callback, IntPtr.Zero);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to write ndef message, Error - " + (NfcError)ret);
+ NfcErrorFactory.ThrowNfcException(ret);
+ }
+
+ return task.Task;
+ }
+
+ /// <summary>
+ /// Formats the detected tag that can store NDEF message.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="keyValue">The key value that may need to format the tag.</param>
+ /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public Task<NfcError> FormatNdefMessageAsync(byte[] keyValue)
+ {
+ var task = new TaskCompletionSource<NfcError>();
+
+ Interop.Nfc.VoidCallback callback = (int result, IntPtr userData) =>
+ {
+ task.SetResult((NfcError)result);
+ return;
+ };
+
+ int ret = Interop.Nfc.Tag.FormatNdef(_tagHandle, keyValue, keyValue.Length, callback, IntPtr.Zero);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to format ndef message, Error - " + (NfcError)ret);
+ NfcErrorFactory.ThrowNfcException(ret);
+ }
+
+ return task.Task;
+ }
+ }
+}
diff --git a/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcTagAdapter.cs b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcTagAdapter.cs
new file mode 100755
index 0000000..61c6c1b
--- /dev/null
+++ b/src/Tizen.Network.Nfc/Tizen.Network.Nfc/NfcTagAdapter.cs
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+
+namespace Tizen.Network.Nfc
+{
+ /// <summary>
+ /// A class for NFC Tag mode. It allows applications to handle Tag informations.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/nfc</privilege>
+ public class NfcTagAdapter : IDisposable
+ {
+ private NfcTag _tag;
+ private bool disposed = false;
+
+ private event EventHandler<TagDiscoveredEventArgs> _tagDiscovered;
+
+ private Interop.Nfc.TagDiscoveredCallback _tagDiscoveredCallback;
+
+ /// <summary>
+ /// The event for receiving tag discovered notification.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<TagDiscoveredEventArgs> TagDiscovered
+ {
+ add
+ {
+ _tagDiscovered += value;
+ }
+ remove
+ {
+ _tagDiscovered -= value;
+ }
+ }
+
+ internal NfcTagAdapter()
+ {
+ RegisterTagDiscoveredEvent();
+ }
+
+ ~NfcTagAdapter()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects.
+ UnregisterTagDiscoveredEvent();
+ }
+ //Free unmanaged objects
+ disposed = true;
+ }
+
+ /// <summary>
+ /// Gets current connected tag.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>NfcTag object.</returns>
+ /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public NfcTag GetConnectedTag()
+ {
+ IntPtr tagHandle = IntPtr.Zero;
+ int ret = Interop.Nfc.GetConnectedTag(out tagHandle);
+
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get connected tag, Error - " + (NfcError)ret);
+ NfcErrorFactory.ThrowNfcException(ret);
+ }
+ _tag = new NfcTag(tagHandle);
+
+ return _tag;
+ }
+
+ private void RegisterTagDiscoveredEvent()
+ {
+ _tagDiscoveredCallback = (int type, IntPtr tagHandle, IntPtr userData) =>
+ {
+ NfcDiscoveredType tagType = (NfcDiscoveredType)type;
+ TagDiscoveredEventArgs e = new TagDiscoveredEventArgs(tagType, tagHandle);
+ _tagDiscovered.SafeInvoke(null, e);
+ };
+
+ int ret = Interop.Nfc.SetTagDiscoveredCallback(_tagDiscoveredCallback, IntPtr.Zero);
+ if (ret != (int)NfcError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set tag discovered callback, Error - " + (NfcError)ret);
+ }
+ }
+
+ private void UnregisterTagDiscoveredEvent()
+ {
+ Interop.Nfc.UnsetTagDiscoveredCallback();
+ }
+ }
+}
diff --git a/src/Tizen.Network.Smartcard/Interop/Interop.Glib.cs b/src/Tizen.Network.Smartcard/Interop/Interop.Glib.cs
new file mode 100644
index 0000000..576a6e2
--- /dev/null
+++ b/src/Tizen.Network.Smartcard/Interop/Interop.Glib.cs
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Glib
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool GSourceFunc(IntPtr userData);
+
+ [DllImport(Libraries.Glib, EntryPoint = "g_idle_add", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern uint IdleAdd(GSourceFunc d, IntPtr data);
+ }
+}
diff --git a/src/Tizen.Network.Smartcard/Interop/Interop.Libc.cs b/src/Tizen.Network.Smartcard/Interop/Interop.Libc.cs
new file mode 100644
index 0000000..825599e
--- /dev/null
+++ b/src/Tizen.Network.Smartcard/Interop/Interop.Libc.cs
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Libc
+ {
+ [DllImport(Libraries.Libc, EntryPoint = "free", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int Free(IntPtr ptr);
+ }
+}
diff --git a/src/Tizen.Network.Smartcard/Interop/Interop.Libraries.cs b/src/Tizen.Network.Smartcard/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..f231ed1
--- /dev/null
+++ b/src/Tizen.Network.Smartcard/Interop/Interop.Libraries.cs
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string Smartcard = "libcapi-network-smartcard.so.0";
+ public const string Glib = "libglib-2.0.so.0";
+ public const string Libc = "libc.so.6";
+ }
+}
diff --git a/src/Tizen.Network.Smartcard/Interop/Interop.Smartcard.cs b/src/Tizen.Network.Smartcard/Interop/Interop.Smartcard.cs
new file mode 100644
index 0000000..234de80
--- /dev/null
+++ b/src/Tizen.Network.Smartcard/Interop/Interop.Smartcard.cs
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Smartcard
+ {
+ //capi-network-smartcard-0.0.6-2.1.armv7l.rpm
+ //Smartcard Manager
+ [DllImport(Libraries.Smartcard, EntryPoint = "smartcard_initialize")]
+ internal static extern int Initialize();
+ [DllImport(Libraries.Smartcard, EntryPoint = "smartcard_deinitialize")]
+ internal static extern int Deinitialize();
+ [DllImport(Libraries.Smartcard, EntryPoint = "smartcard_get_readers")]
+ internal static extern int GetReaders(out IntPtr readers, out int len);
+
+ internal static class Reader
+ {
+ [DllImport(Libraries.Smartcard, EntryPoint = "smartcard_reader_get_name")]
+ internal static extern int ReaderGetName(int reader, out IntPtr readerName);
+ [DllImport(Libraries.Smartcard, EntryPoint = "smartcard_reader_is_secure_element_present")]
+ internal static extern int ReaderIsSecureElementPresent(int reader, out bool present);
+ [DllImport(Libraries.Smartcard, EntryPoint = "smartcard_reader_open_session")]
+ internal static extern int ReaderOpenSession(int reader, out int session);
+ [DllImport(Libraries.Smartcard, EntryPoint = "smartcard_reader_close_sessions")]
+ internal static extern int ReaderCloseSessions(int reader);
+ }
+
+ internal static class Session
+ {
+ [DllImport(Libraries.Smartcard, EntryPoint = "smartcard_session_get_reader")]
+ internal static extern int SessionGetReader(int session, out int reader);
+ [DllImport(Libraries.Smartcard, EntryPoint = "smartcard_session_get_atr")]
+ internal static extern int SessionGetAtr(int session, out IntPtr atr, out int len);
+ [DllImport(Libraries.Smartcard, EntryPoint = "smartcard_session_close")]
+ internal static extern int SessionClose(int session);
+ [DllImport(Libraries.Smartcard, EntryPoint = "smartcard_session_is_closed")]
+ internal static extern int SessionIsClosed(int session, out bool closed);
+ [DllImport(Libraries.Smartcard, EntryPoint = "smartcard_session_close_channels")]
+ internal static extern int SessionCloseChannels(int session);
+ [DllImport(Libraries.Smartcard, EntryPoint = "smartcard_session_open_basic_channel")]
+ internal static extern int SessionOpenBasicChannel(int session, byte[] aid, int aidLen, byte p2, out int channel);
+ [DllImport(Libraries.Smartcard, EntryPoint = "smartcard_session_open_logical_channel")]
+ internal static extern int SessionOpenLogicalChannel(int session, byte[] aid, int aidLen, byte p2, out int channel);
+ }
+
+ internal static class Channel
+ {
+ [DllImport(Libraries.Smartcard, EntryPoint = "smartcard_channel_close")]
+ internal static extern int ChannelClose(int channel);
+ [DllImport(Libraries.Smartcard, EntryPoint = "smartcard_channel_is_basic_channel")]
+ internal static extern int ChannelIsBasicChannel(int channel, out bool basicChannel);
+ [DllImport(Libraries.Smartcard, EntryPoint = "smartcard_channel_is_closed")]
+ internal static extern int ChannelIsClosed(int channel, out bool closed);
+ [DllImport(Libraries.Smartcard, EntryPoint = "smartcard_channel_get_select_response")]
+ internal static extern int ChannelGetSelectResponse(int channel, out IntPtr selectResp, out int len);
+ [DllImport(Libraries.Smartcard, EntryPoint = "smartcard_channel_get_session")]
+ internal static extern int ChannelGetSession(int channel, out int session);
+ [DllImport(Libraries.Smartcard, EntryPoint = "smartcard_channel_transmit")]
+ internal static extern int ChannelTransmit(int channel, byte[] cmd, int cmdLen, out IntPtr resp, out int len);
+ [DllImport(Libraries.Smartcard, EntryPoint = "smartcard_channel_transmit_retrieve_response")]
+ internal static extern int ChannelTransmitRetrieveResponse(int channel, out IntPtr name, out int len);
+ [DllImport(Libraries.Smartcard, EntryPoint = "smartcard_channel_select_next")]
+ internal static extern int ChannelSelectNext(int channel, out bool success);
+ }
+ }
+}
diff --git a/src/Tizen.Network.Smartcard/Tizen.Network.Smartcard.csproj b/src/Tizen.Network.Smartcard/Tizen.Network.Smartcard.csproj
new file mode 100644
index 0000000..d5717a4
--- /dev/null
+++ b/src/Tizen.Network.Smartcard/Tizen.Network.Smartcard.csproj
@@ -0,0 +1,15 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
+
diff --git a/src/Tizen.Network.Smartcard/Tizen.Network.Smartcard/SmartcardChannel.cs b/src/Tizen.Network.Smartcard/Tizen.Network.Smartcard/SmartcardChannel.cs
new file mode 100644
index 0000000..f77df6e
--- /dev/null
+++ b/src/Tizen.Network.Smartcard/Tizen.Network.Smartcard/SmartcardChannel.cs
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+
+namespace Tizen.Network.Smartcard
+{
+ /// <summary>
+ /// A class for Smartcard channel informations. It allows applications to handle channel informations.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/secureelement</privilege>
+ public class SmartcardChannel : IDisposable
+ {
+ private int _channelHandle = -1;
+ private bool disposed = false;
+ private SmartcardSession _sessionObject;
+
+ /// <summary>
+ /// Whether the kind of channel is basic.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool IsBasicChannel
+ {
+ get
+ {
+ bool isBasicChannel;
+ int ret = Interop.Smartcard.Channel.ChannelIsBasicChannel(_channelHandle, out isBasicChannel);
+ if (ret != (int)SmartcardError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get basic channel, Error - " + (SmartcardError)ret);
+ }
+ return isBasicChannel;
+ }
+ }
+
+ /// <summary>
+ /// Whether the kind of channel is logical.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool IsLogicalChannel
+ {
+ get
+ {
+ bool isBasicChannel;
+ int ret = Interop.Smartcard.Channel.ChannelIsBasicChannel(_channelHandle, out isBasicChannel);
+ if (ret != (int)SmartcardError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get logical channel, Error - " + (SmartcardError)ret);
+ }
+ return !isBasicChannel;
+ }
+ }
+
+ /// <summary>
+ /// Whether the channel is closed.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool IsClosed
+ {
+ get
+ {
+ bool isClosed;
+ int ret = Interop.Smartcard.Channel.ChannelIsClosed(_channelHandle, out isClosed);
+ if (ret != (int)SmartcardError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get closed, Error - " + (SmartcardError)ret);
+ }
+ return isClosed;
+ }
+ }
+
+ /// <summary>
+ /// The session that has opened the given channel.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public SmartcardSession Session
+ {
+ get
+ {
+ int session;
+ int ret = Interop.Smartcard.Channel.ChannelGetSession(_channelHandle, out session);
+ if (ret != (int)SmartcardError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get session, Error - " + (SmartcardError)ret);
+ }
+
+ if (_sessionObject.GetHandle() != session)
+ {
+ Log.Error(Globals.LogTag, "Does not correspond with session, Error - " + _sessionObject.GetHandle() + " " + session);
+ }
+
+ return _sessionObject;
+ }
+ }
+
+ internal SmartcardChannel(SmartcardSession sessionHandle, int channelHandle)
+ {
+ _sessionObject = sessionHandle;
+ _channelHandle = channelHandle;
+ }
+
+ ~SmartcardChannel()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects.
+ }
+ //Free unmanaged objects
+ disposed = true;
+ }
+
+ /// <summary>
+ /// Closes the given channel to the Secure Element.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="NotSupportedException">Thrown when Smartcard is not supported.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public void Close()
+ {
+ int ret = Interop.Smartcard.Channel.ChannelClose(_channelHandle);
+ if (ret != (int)SmartcardError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to channel close, Error - " + (SmartcardError)ret);
+ SmartcardErrorFactory.ThrowSmartcardException(ret);
+ }
+ Dispose(true);
+ }
+
+ /// <summary>
+ /// Gets the response to the select command.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>Byte array to retrieve the SELECT response.</returns>
+ public byte[] GetSelectedResponse()
+ {
+ byte[] respList;
+ IntPtr strAtr;
+ int len;
+ int ret = Interop.Smartcard.Channel.ChannelGetSelectResponse(_channelHandle, out strAtr, out len);
+ if (ret != (int)SmartcardError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get select response, Error - " + (SmartcardError)ret);
+ }
+
+ respList = new byte[len];
+ for (int i = 0; i < len; i++)
+ {
+ respList[i] = Marshal.ReadByte(strAtr);
+ strAtr += sizeof(byte);
+ }
+ return respList;
+ }
+
+ /// <summary>
+ /// Transmits an APDU command (as per ISO/IEC 7816-4) to the Secure Element.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>Byte array for the response APDU plus status words.</returns>
+ /// <param name="cmd">Command APDU to be send to the secure element.</param>
+ public byte[] Transmit(byte[] cmd)
+ {
+ byte[] atrList;
+ IntPtr strAtr;
+ int len;
+ int ret = Interop.Smartcard.Channel.ChannelTransmit(_channelHandle, cmd, cmd.Length, out strAtr, out len);
+ if (ret != (int)SmartcardError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to transmit, Error - " + (SmartcardError)ret);
+ }
+
+ atrList = new byte[len];
+ for (int i = 0; i < len; i++)
+ {
+ atrList[i] = Marshal.ReadByte(strAtr);
+ strAtr += sizeof(byte);
+ }
+
+ return atrList;
+ }
+
+ /// <summary>
+ /// Helper function to retrieves the response APDU of the previous transmit() call.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>Byte array for the response APDU plus status words.</returns>
+ public byte[] GetTransmittedResponse()
+ {
+ byte[] respList;
+ IntPtr strAtr;
+ int len;
+ int ret = Interop.Smartcard.Channel.ChannelTransmitRetrieveResponse(_channelHandle, out strAtr, out len);
+ if (ret != (int)SmartcardError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get trasmit retrieve response, Error - " + (SmartcardError)ret);
+ }
+
+ respList = new byte[len];
+ for (int i = 0; i < len; i++)
+ {
+ respList[i] = Marshal.ReadByte(strAtr);
+ strAtr += sizeof(byte);
+ }
+ return respList;
+ }
+
+ /// <summary>
+ /// Performs a selection of the next Applet on the given channel that matches to the partial Application ID(AID).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>True or false depending whether another applet with the partial Application ID(AID).</returns>
+ public bool SelectNext()
+ {
+ bool selectNext;
+ int ret = Interop.Smartcard.Channel.ChannelSelectNext(_channelHandle, out selectNext);
+ if (ret != (int)SmartcardError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to select next, Error - " + (SmartcardError)ret);
+ }
+ return selectNext;
+ }
+ }
+}
diff --git a/src/Tizen.Network.Smartcard/Tizen.Network.Smartcard/SmartcardErrorFactory.cs b/src/Tizen.Network.Smartcard/Tizen.Network.Smartcard/SmartcardErrorFactory.cs
new file mode 100644
index 0000000..a562a2f
--- /dev/null
+++ b/src/Tizen.Network.Smartcard/Tizen.Network.Smartcard/SmartcardErrorFactory.cs
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Network.Smartcard
+{
+ internal enum SmartcardError
+ {
+ None = ErrorCode.None,
+ IoError = ErrorCode.IoError,
+ InvalidParameterError = ErrorCode.InvalidParameter,
+ PermissionDeniedError = ErrorCode.PermissionDenied,
+ NotSupportedError = ErrorCode.NotSupported,
+ GeneralError = -0x01C70000 | 0x01,
+ NoSuchElementError = -0x01C70000 | 0x02,
+ IllegalStateError = -0x01C70000 | 0x03,
+ IllegalReferenceError = -0x01C70000 | 0x04,
+ OperationNotSupportError = -0x01C70000 | 0x05,
+ ChannelNotAvailableError = -0x01C70000 | 0x06,
+ NotInitializedError = -0x01C70000 | 0x07
+ }
+
+ internal static class SmartcardErrorFactory
+ {
+ static internal void ThrowSmartcardException(int e)
+ {
+ ThrowException(e, false);
+ }
+
+ static internal void ThrowSmartcardException(int e, int handle)
+ {
+ ThrowException(e, (handle < 0));
+ }
+
+ static private void ThrowException(int e, bool isHandleNull)
+ {
+ SmartcardError err = (SmartcardError)e;
+
+ if (isHandleNull)
+ {
+ throw new InvalidOperationException("Invalid instance (object may have been disposed or released)");
+ }
+
+ if (err == SmartcardError.InvalidParameterError)
+ {
+ throw new ArgumentException(err.ToString());
+ }
+ else if (err == SmartcardError.NotSupportedError)
+ {
+ throw new NotSupportedException(err.ToString());
+ }
+ else
+ {
+ throw new InvalidOperationException(err.ToString());
+ }
+ }
+
+ }
+}
diff --git a/src/Tizen.Network.Smartcard/Tizen.Network.Smartcard/SmartcardManager.cs b/src/Tizen.Network.Smartcard/Tizen.Network.Smartcard/SmartcardManager.cs
new file mode 100755
index 0000000..7edf663
--- /dev/null
+++ b/src/Tizen.Network.Smartcard/Tizen.Network.Smartcard/SmartcardManager.cs
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Tizen.Network.Smartcard
+{
+ /// <summary>
+ /// A class for Smartcard management. It allows applications to use Smartcard service.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/secureelement</privilege>
+ static public class SmartcardManager
+ {
+ /// <summary>
+ /// Gets the list of available Secure Element readers.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>List of SmartcardReader objects.</returns>
+ static public IEnumerable<SmartcardReader> GetReaders()
+ {
+ try
+ {
+ return SmartcardManagerImpl.Instance.GetReaders();
+ }
+ catch (TypeInitializationException e)
+ {
+ throw e.InnerException;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.Smartcard/Tizen.Network.Smartcard/SmartcardManagerImpl.cs b/src/Tizen.Network.Smartcard/Tizen.Network.Smartcard/SmartcardManagerImpl.cs
new file mode 100755
index 0000000..5e4db7f
--- /dev/null
+++ b/src/Tizen.Network.Smartcard/Tizen.Network.Smartcard/SmartcardManagerImpl.cs
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+
+namespace Tizen.Network.Smartcard
+{
+ static internal class Globals
+ {
+ internal const string LogTag = "Tizen.Network.Smartcard";
+ }
+
+ internal class SmartcardManagerImpl : IDisposable
+ {
+ private static readonly SmartcardManagerImpl _instance = new SmartcardManagerImpl();
+ private List<SmartcardReader> _readerList = new List<SmartcardReader>();
+ private bool disposed = false;
+
+ internal static SmartcardManagerImpl Instance
+ {
+ get
+ {
+ return _instance;
+ }
+ }
+
+ private SmartcardManagerImpl()
+ {
+ initialize();
+ }
+
+ ~SmartcardManagerImpl()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects.
+ foreach (SmartcardReader reader in _readerList)
+ {
+ reader.Dispose();
+ _readerList.Remove(reader);
+ }
+ }
+ //Free unmanaged objects
+ deinitialize();
+ disposed = true;
+ }
+
+ private void initialize()
+ {
+ int ret = Interop.Smartcard.Initialize();
+ if (ret != (int)SmartcardError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to initialize smartcard, Error - " + (SmartcardError)ret);
+ SmartcardErrorFactory.ThrowSmartcardException(ret);
+ }
+ }
+
+ private void deinitialize()
+ {
+ int ret = Interop.Smartcard.Deinitialize();
+ if (ret != (int)SmartcardError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to deinitialize smartcard, Error - " + (SmartcardError)ret);
+ }
+ }
+
+ internal IEnumerable<SmartcardReader> GetReaders()
+ {
+ IntPtr readerPtr;
+ int len = 0;
+
+ int ret = Interop.Smartcard.GetReaders(out readerPtr, out len);
+ if (ret != (int)SmartcardError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to remove with AP, Error - " + (SmartcardError)ret);
+ SmartcardErrorFactory.ThrowSmartcardException(ret);
+ }
+
+ for (int i = 0; i < len; i++)
+ {
+ int readerID = Marshal.ReadInt32(readerPtr);
+
+ SmartcardReader readerItem = new SmartcardReader(readerID);
+ _readerList.Add(readerItem);
+ readerPtr += sizeof(int);
+ }
+
+ return _readerList;
+ }
+ }
+}
diff --git a/src/Tizen.Network.Smartcard/Tizen.Network.Smartcard/SmartcardReader.cs b/src/Tizen.Network.Smartcard/Tizen.Network.Smartcard/SmartcardReader.cs
new file mode 100644
index 0000000..2aa6f07
--- /dev/null
+++ b/src/Tizen.Network.Smartcard/Tizen.Network.Smartcard/SmartcardReader.cs
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+
+namespace Tizen.Network.Smartcard
+{
+ /// <summary>
+ /// A class for Smartcard reader informations. It allows applications to handle reader informations.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/secureelement</privilege>
+ public class SmartcardReader : IDisposable
+ {
+ private int _readerHandle = -1;
+ private int _session;
+ private bool disposed = false;
+ private List<SmartcardSession> _sessionList = new List<SmartcardSession>();
+
+ /// <summary>
+ /// The name of reader.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Name
+ {
+ get
+ {
+ IntPtr strPtr;
+ int ret = Interop.Smartcard.Reader.ReaderGetName(_readerHandle, out strPtr);
+ if (ret != (int)SmartcardError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get reader name, Error - " + (SmartcardError)ret);
+ return "";
+ }
+ return Marshal.PtrToStringAnsi(strPtr);
+ }
+ }
+
+ /// <summary>
+ /// The existence of secure element.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool IsSecureElementPresent
+ {
+ get
+ {
+ bool isPresent;
+ int ret = Interop.Smartcard.Reader.ReaderIsSecureElementPresent(_readerHandle, out isPresent);
+ if (ret != (int)SmartcardError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get present, Error - " + (SmartcardError)ret);
+ }
+ return isPresent;
+ }
+ }
+
+ internal SmartcardReader(int handle)
+ {
+ _readerHandle = handle;
+ }
+
+ ~SmartcardReader()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects.
+ foreach (SmartcardSession session in _sessionList)
+ {
+ session.Dispose();
+ _sessionList.Remove(session);
+ }
+ }
+ //Free unmanaged objects
+ disposed = true;
+ }
+
+ internal int GetHandle()
+ {
+ return _readerHandle;
+ }
+
+ internal int GetSession()
+ {
+ return _session;
+ }
+
+ /// <summary>
+ /// Connects to a Secure Element in the given reader.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>The SmartcardSession object.</returns>
+ public SmartcardSession OpenSession()
+ {
+ int ret = Interop.Smartcard.Reader.ReaderOpenSession(_readerHandle, out _session);
+ if (ret != (int)SmartcardError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get session handle, Error - " + (SmartcardError)ret);
+ }
+
+ SmartcardSession session = new SmartcardSession(this, _session);
+ _sessionList.Add(session);
+ return session;
+ }
+
+ /// <summary>
+ /// Closes all the sessions opened on the given reader.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="NotSupportedException">Thrown when Smartcard is not supported.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public void CloseSessions()
+ {
+ int ret = Interop.Smartcard.Reader.ReaderCloseSessions(_readerHandle);
+ if (ret != (int)SmartcardError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to close sessions, Error - " + (SmartcardError)ret);
+ SmartcardErrorFactory.ThrowSmartcardException(ret);
+ }
+
+ foreach (SmartcardSession session in _sessionList)
+ {
+ session.Close();
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.Smartcard/Tizen.Network.Smartcard/SmartcardSession.cs b/src/Tizen.Network.Smartcard/Tizen.Network.Smartcard/SmartcardSession.cs
new file mode 100644
index 0000000..107181e
--- /dev/null
+++ b/src/Tizen.Network.Smartcard/Tizen.Network.Smartcard/SmartcardSession.cs
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+
+namespace Tizen.Network.Smartcard
+{
+ /// <summary>
+ /// A class for Smartcard session informations. It allows applications to handle session informations.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/secureelement</privilege>
+ public class SmartcardSession : IDisposable
+ {
+ private int _sessionHandle = -1;
+ private bool disposed = false;
+ private List<SmartcardChannel> _basicChannelList = new List<SmartcardChannel>();
+ private List<SmartcardChannel> _logicalChannelList = new List<SmartcardChannel>();
+ private SmartcardReader _readerObject;
+ private int _basicChannel = 0;
+ private int _logicalChannel = 0;
+
+ /// <summary>
+ /// The reader object that provides the given session.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public SmartcardReader Reader
+ {
+ get
+ {
+ int reader;
+ int ret = Interop.Smartcard.Session.SessionGetReader(_sessionHandle, out reader);
+ if (ret != (int)SmartcardError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get reader, Error - " + (SmartcardError)ret);
+ }
+
+ if (_readerObject.GetHandle() != reader)
+ {
+ Log.Error(Globals.LogTag, "Does not correspond with reader, Error - " + _readerObject.GetHandle() + " " + reader);
+ }
+
+ return _readerObject;
+ }
+ }
+
+ /// <summary>
+ /// The Answer to Reset(ATR) of this Secure Element.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public byte[] Atr
+ {
+ get
+ {
+ byte[] atrList;
+ IntPtr strAtr;
+ int len;
+ int ret = Interop.Smartcard.Session.SessionGetAtr(_sessionHandle, out strAtr, out len);
+ if (ret != (int)SmartcardError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get atr, Error - " + (SmartcardError)ret);
+ }
+
+ atrList = new byte[len];
+ for (int i = 0; i < len; i++)
+ {
+ atrList[i] = Marshal.ReadByte(strAtr);
+ strAtr += sizeof(byte);
+ }
+ return atrList;
+ }
+ }
+
+ /// <summary>
+ /// Whether the session is closed.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool IsClosed
+ {
+ get
+ {
+ bool isClosed;
+ int ret = Interop.Smartcard.Session.SessionIsClosed(_sessionHandle, out isClosed);
+ if (ret != (int)SmartcardError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get present, Error - " + (SmartcardError)ret);
+ }
+ return isClosed;
+ }
+ }
+
+ internal SmartcardSession(SmartcardReader readerHandle, int sessionHandle)
+ {
+ _readerObject = readerHandle;
+ _sessionHandle = sessionHandle;
+ }
+
+ ~SmartcardSession()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ if (disposing)
+ {
+ // Free managed objects.
+ foreach (SmartcardChannel channel in _basicChannelList)
+ {
+ channel.Dispose();
+ _basicChannelList.Remove(channel);
+ }
+
+ foreach (SmartcardChannel channel in _logicalChannelList)
+ {
+ channel.Dispose();
+ _logicalChannelList.Remove(channel);
+ }
+ }
+ //Free unmanaged objects
+ disposed = true;
+ }
+
+ internal int GetHandle()
+ {
+ return _sessionHandle;
+ }
+
+ /// <summary>
+ /// Closes the connection with the Secure Element.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="NotSupportedException">Thrown when Smartcard is not supported.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public void Close()
+ {
+ int ret = Interop.Smartcard.Session.SessionClose(_sessionHandle);
+ if (ret != (int)SmartcardError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to close, Error - " + (SmartcardError)ret);
+ SmartcardErrorFactory.ThrowSmartcardException(ret);
+ }
+ Dispose(true);
+ }
+
+ /// <summary>
+ /// Closes any channel opened on the given session.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="NotSupportedException">Thrown when Smartcard is not supported.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public void CloseChannels()
+ {
+ int ret = Interop.Smartcard.Session.SessionCloseChannels(_sessionHandle);
+ if (ret != (int)SmartcardError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to close, Error - " + (SmartcardError)ret);
+ SmartcardErrorFactory.ThrowSmartcardException(ret);
+ }
+
+ foreach (SmartcardChannel channel in _basicChannelList)
+ {
+ channel.Close();
+ }
+
+ foreach (SmartcardChannel channel in _logicalChannelList)
+ {
+ channel.Close();
+ }
+ }
+
+ /// <summary>
+ /// Gets an access to the basic channel, as defined in the ISO/IEC 7816-4 specification (the one that has number 0).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>The SmartcardChannel object for basic channel.</returns>
+ /// <param name="aid">Byte array containing the Application ID(AID) to be selected on the given channel.</param>
+ /// <param name="p2">P2 byte of the SELECT command if executed.</param>
+ /// <exception cref="NotSupportedException">Thrown when Smartcard is not supported.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public SmartcardChannel OpenBasicChannel(byte[] aid, byte p2)
+ {
+ int ret = Interop.Smartcard.Session.SessionOpenBasicChannel(_sessionHandle, aid, aid.Length, p2, out _basicChannel);
+ if (ret != (int)SmartcardError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to open basic channel, Error - " + (SmartcardError)ret);
+ SmartcardErrorFactory.ThrowSmartcardException(ret);
+ }
+ SmartcardChannel basicChannel = new SmartcardChannel(this, _basicChannel);
+ _basicChannelList.Add(basicChannel);
+
+ return basicChannel;
+ }
+
+ /// <summary>
+ /// Open a logical channel with the Secure Element, selecting the Applet represented by the given Application ID(AID).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>The SmartcardChannel object for logical channel.</returns>
+ /// <param name="aid">Byte array containing the Application ID(AID) to be selected on the given channel.</param>
+ /// <param name="p2">P2 byte of the SELECT command if executed.</param>
+ /// <exception cref="NotSupportedException">Thrown when Smartcard is not supported.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public SmartcardChannel OpenLogicalChannel(byte[] aid, byte p2)
+ {
+ int ret = Interop.Smartcard.Session.SessionOpenLogicalChannel(_sessionHandle, aid, aid.Length, p2, out _logicalChannel);
+ if (ret != (int)SmartcardError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to open logical channel, Error - " + (SmartcardError)ret);
+ SmartcardErrorFactory.ThrowSmartcardException(ret);
+ }
+ SmartcardChannel logicalChannel = new SmartcardChannel(this, _logicalChannel);
+ _logicalChannelList.Add(logicalChannel);
+
+ return logicalChannel;
+ }
+ }
+}
diff --git a/src/Tizen.Network.WiFi/Interop/Interop.Libraries.cs b/src/Tizen.Network.WiFi/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..d966df6
--- /dev/null
+++ b/src/Tizen.Network.WiFi/Interop/Interop.Libraries.cs
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string WiFi = "libcapi-network-wifi-manager.so.1";
+ public const string Glib = "libglib-2.0.so.0";
+ public const string Libc = "libc.so.6";
+ }
+}
diff --git a/src/Tizen.Network.WiFi/Interop/Interop.WiFi.cs b/src/Tizen.Network.WiFi/Interop/Interop.WiFi.cs
new file mode 100755
index 0000000..bc2fd1d
--- /dev/null
+++ b/src/Tizen.Network.WiFi/Interop/Interop.WiFi.cs
@@ -0,0 +1,331 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Network.WiFi;
+using Tizen.Network.Connection;
+
+internal static partial class Interop
+{
+ internal static partial class WiFi
+ {
+ //Callback for async method
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void VoidCallback(int result, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool HandleCallback(IntPtr handle, IntPtr userData);
+
+ //Callback for event
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void DeviceStateChangedCallback(int deviceState, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ConnectionStateChangedCallback(int connectionState, IntPtr ap, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void RssiLevelChangedCallback(int level, IntPtr userData);
+
+ //capi-network-wifi-1.0.65-19.23.armv7l
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_initialize")]
+ internal static extern int Initialize(out SafeWiFiManagerHandle wifi);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_deinitialize")]
+ internal static extern int Deinitialize(IntPtr wifi);
+
+ ////Wi-Fi Manager
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_activate")]
+ internal static extern int Activate(SafeWiFiManagerHandle wifi, VoidCallback callback, IntPtr userData);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_activate_with_wifi_picker_tested")]
+ internal static extern int ActivateWithWiFiPickerTested(SafeWiFiManagerHandle wifi, VoidCallback callback, IntPtr userData);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_deactivate")]
+ internal static extern int Deactivate(SafeWiFiManagerHandle wifi, VoidCallback callback, IntPtr userData);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_is_activated")]
+ internal static extern int IsActive(SafeWiFiManagerHandle wifi, out bool activated);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_get_mac_address")]
+ internal static extern int GetMacAddress(SafeWiFiManagerHandle wifi, out string macAddress);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_get_network_interface_name")]
+ internal static extern int GetNetworkInterfaceName(SafeWiFiManagerHandle wifi, out string interfaceName);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_scan")]
+ internal static extern int Scan(SafeWiFiManagerHandle wifi, VoidCallback callback, IntPtr userData);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_scan_specific_ap")]
+ internal static extern int ScanSpecificAP(SafeWiFiManagerHandle wifi, string essid, VoidCallback callback, IntPtr userData);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_get_connected_ap")]
+ internal static extern int GetConnectedAP(SafeWiFiManagerHandle wifi, out IntPtr ap);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_foreach_found_ap")]
+ internal static extern int GetForeachFoundAPs(SafeWiFiManagerHandle wifi, HandleCallback callback, IntPtr userData);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_foreach_found_specific_ap")]
+ internal static extern int GetForeachFoundSpecificAPs(SafeWiFiManagerHandle wifi, HandleCallback callback, IntPtr userData);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_connect")]
+ internal static extern int Connect(SafeWiFiManagerHandle wifi, IntPtr ap, VoidCallback callback, IntPtr userData);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_disconnect")]
+ internal static extern int Disconnect(SafeWiFiManagerHandle wifi, IntPtr ap, VoidCallback callback, IntPtr userData);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_connect_by_wps_pbc")]
+ internal static extern int ConnectByWpsPbc(SafeWiFiManagerHandle wifi, IntPtr ap, VoidCallback callback, IntPtr userData);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_connect_by_wps_pin")]
+ internal static extern int ConnectByWpsPin(SafeWiFiManagerHandle wifi, IntPtr ap, string pin, VoidCallback callback, IntPtr userData);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_connect_by_wps_pbc_without_ssid")]
+ internal static extern int ConnectByWpsPbcWithoutSsid(SafeWiFiManagerHandle wifi, VoidCallback callback, IntPtr userData);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_connect_by_wps_pin_without_ssid")]
+ internal static extern int ConnectByWpsPinWithoutSsid(SafeWiFiManagerHandle wifi, string pin, VoidCallback callback, IntPtr userData);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_forget_ap")]
+ internal static extern int RemoveAP(SafeWiFiManagerHandle wifi, IntPtr ap);
+
+ //Wi-Fi Monitor
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_get_connection_state")]
+ internal static extern int GetConnectionState(SafeWiFiManagerHandle wifi, out int connectionState);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_set_device_state_changed_cb")]
+ internal static extern int SetDeviceStateChangedCallback(SafeWiFiManagerHandle wifi, DeviceStateChangedCallback callback, IntPtr userData);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_unset_device_state_changed_cb")]
+ internal static extern int UnsetDeviceStateChangedCallback(SafeWiFiManagerHandle wifi);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_set_background_scan_cb")]
+ internal static extern int SetBackgroundScanCallback(SafeWiFiManagerHandle wifi, VoidCallback callback, IntPtr userData);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_unset_background_scan_cb")]
+ internal static extern int UnsetBackgroundScanCallback(SafeWiFiManagerHandle wifi);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_set_connection_state_changed_cb")]
+ internal static extern int SetConnectionStateChangedCallback(SafeWiFiManagerHandle wifi, ConnectionStateChangedCallback callback, IntPtr userData);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_unset_connection_state_changed_cb")]
+ internal static extern int UnsetConnectionStateChangedCallback(SafeWiFiManagerHandle wifi);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_set_rssi_level_changed_cb")]
+ internal static extern int SetRssiLevelchangedCallback(SafeWiFiManagerHandle wifi, RssiLevelChangedCallback callback, IntPtr userData);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_unset_rssi_level_changed_cb")]
+ internal static extern int UnsetRssiLevelchangedCallback(SafeWiFiManagerHandle wifi);
+
+ internal static class AP
+ {
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_create")]
+ internal static extern int Create(SafeWiFiManagerHandle wifi, string essid, out IntPtr ap);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_hidden_create")]
+ internal static extern int CreateHiddenAP(SafeWiFiManagerHandle wifi, string essid, out IntPtr ap);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_destroy")]
+ internal static extern int Destroy(IntPtr ap);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_clone")]
+ internal static extern int Clone(out IntPtr cloned, IntPtr original);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_refresh")]
+ internal static extern int Refresh(IntPtr ap);
+
+ ////Network Information
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_get_essid")]
+ internal static extern int GetEssid(SafeWiFiAPHandle ap, out IntPtr essid);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_get_bssid")]
+ internal static extern int GetBssid(SafeWiFiAPHandle ap, out IntPtr bssid);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_get_rssi")]
+ internal static extern int GetRssi(SafeWiFiAPHandle ap, out int rssi);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_get_frequency")]
+ internal static extern int GetFrequency(SafeWiFiAPHandle ap, out int frequency);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_get_max_speed")]
+ internal static extern int GetMaxSpeed(SafeWiFiAPHandle ap, out int maxSpeed);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_is_favorite")]
+ internal static extern int IsFavorite(SafeWiFiAPHandle ap, out bool isFavorite);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_is_passpoint")]
+ internal static extern int IsPasspoint(SafeWiFiAPHandle ap, out bool isPasspoint);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_get_connection_state")]
+ internal static extern int GetConnectionState(SafeWiFiAPHandle ap, out int connectionState);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_get_ip_config_type")]
+ internal static extern int GetIPConfigType(SafeWiFiAPHandle ap, int addressFamily, out int ipConfigType);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_set_ip_config_type")]
+ internal static extern int SetIPConfigType(SafeWiFiAPHandle ap, int addressFamily, int ipConfigType);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_get_ip_address")]
+ internal static extern int GetIPAddress(SafeWiFiAPHandle ap, int addressFamily, out IntPtr ipAddress);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_foreach_ipv6_address")]
+ internal static extern int GetAllIPv6Addresses(SafeWiFiAPHandle ap, HandleCallback callback, IntPtr userData);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_set_ip_address")]
+ internal static extern int SetIPAddress(SafeWiFiAPHandle ap, int addressFamily, string ipAddress);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_get_subnet_mask")]
+ internal static extern int GetSubnetMask(SafeWiFiAPHandle ap, int addressFamily, out IntPtr subnetMask);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_set_subnet_mask")]
+ internal static extern int SetSubnetMask(SafeWiFiAPHandle ap, int addressFamily, string subnetMask);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_get_gateway_address")]
+ internal static extern int GetGatewayAddress(SafeWiFiAPHandle ap, int addressFamily, out IntPtr gatewayAddress);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_set_gateway_address")]
+ internal static extern int SetGatewayAddress(SafeWiFiAPHandle ap, int addressFamily, string gatewayAddress);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_get_dhcp_server_address")]
+ internal static extern int GetDhcpServerAddress(SafeWiFiAPHandle ap, AddressFamily addressFamily, out string dhcpServer);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_get_proxy_address")]
+ internal static extern int GetProxyAddress(SafeWiFiAPHandle ap, int addressFamily, out IntPtr proxyAddress);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_set_proxy_address")]
+ internal static extern int SetProxyAddress(SafeWiFiAPHandle ap, int addressFamily, string proxyAddress);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_get_proxy_type")]
+ internal static extern int GetProxyType(SafeWiFiAPHandle ap, out int proxyType);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_set_proxy_type")]
+ internal static extern int SetProxyType(SafeWiFiAPHandle ap, int proxyType);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_get_dns_address")]
+ internal static extern int GetDnsAddress(SafeWiFiAPHandle ap, int order, int addressFamily, out IntPtr dnsAddress);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_set_dns_address")]
+ internal static extern int SetDnsAddress(SafeWiFiAPHandle ap, int order, int addressFamily, string dnsAddress);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_get_prefix_length")]
+ internal static extern int GetPrefixLength(SafeWiFiAPHandle ap, int addressFamily, out int length);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_set_prefix_length")]
+ internal static extern int SetPrefixLength(SafeWiFiAPHandle ap, int addressFamily, int length);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_get_dns_config_type")]
+ internal static extern int GetDnsConfigType(SafeWiFiAPHandle ap, int addressFamily, out int type);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_set_dns_config_type")]
+ internal static extern int SetDnsConfigType(SafeWiFiAPHandle ap, int addressFamily, int type);
+
+ ////Security Information
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_get_security_type")]
+ internal static extern int GetSecurityType(SafeWiFiAPHandle ap, out int securityType);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_set_security_type")]
+ internal static extern int SetSecurityType(SafeWiFiAPHandle ap, int securityType);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_get_encryption_type")]
+ internal static extern int GetEncryptionType(SafeWiFiAPHandle ap, out int encryptionType);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_set_encryption_type")]
+ internal static extern int SetEncryptionType(SafeWiFiAPHandle ap, int encryptionType);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_is_passphrase_required")]
+ internal static extern int IsPassphraseRequired(SafeWiFiAPHandle ap, out bool required);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_set_passphrase")]
+ internal static extern int SetPassphrase(SafeWiFiAPHandle ap, string passphrase);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_is_wps_supported")]
+ internal static extern int IsWpsSupported(SafeWiFiAPHandle ap, out bool supported);
+
+ ////EAP
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_set_eap_passphrase")]
+ internal static extern int SetEapPassphrase(SafeWiFiAPHandle ap, string userName, string password);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_get_eap_passphrase")]
+ internal static extern int GetEapPassphrase(SafeWiFiAPHandle ap, out IntPtr userName, out bool isPasswordSet);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_get_eap_ca_cert_file")]
+ internal static extern int GetEapCaCertFile(SafeWiFiAPHandle ap, out IntPtr file);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_set_eap_ca_cert_file")]
+ internal static extern int SetEapCaCertFile(SafeWiFiAPHandle ap, string file);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_get_eap_client_cert_file")]
+ internal static extern int GetEapClientCertFile(SafeWiFiAPHandle ap, out IntPtr file);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_set_eap_client_cert_file")]
+ internal static extern int SetEapClientCertFile(SafeWiFiAPHandle ap, string file);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_get_eap_private_key_file")]
+ internal static extern int GetEapPrivateKeyFile(SafeWiFiAPHandle ap, out IntPtr file);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_set_eap_private_key_info")]
+ internal static extern int SetEapPrivateKeyFile(SafeWiFiAPHandle ap, string file, string password);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_get_eap_type")]
+ internal static extern int GetEapType(SafeWiFiAPHandle ap, out int eapType);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_set_eap_type")]
+ internal static extern int SetEapType(SafeWiFiAPHandle ap, int eapType);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_get_eap_auth_type")]
+ internal static extern int GetEapAuthType(SafeWiFiAPHandle ap, out int file);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_ap_set_eap_auth_type")]
+ internal static extern int SetEapAuthType(SafeWiFiAPHandle ap, int file);
+ }
+
+ internal static class Config
+ {
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_config_create")]
+ internal static extern int Create(SafeWiFiManagerHandle wifi, string name, string passPhrase, int securityType, out IntPtr config);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_config_clone")]
+ internal static extern int Clone(IntPtr origin, out IntPtr cloned);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_config_destroy")]
+ internal static extern int Destroy(IntPtr config);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_config_save")]
+ internal static extern int SaveConfiguration(SafeWiFiManagerHandle wifi, IntPtr config);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_config_foreach_configuration")]
+ internal static extern int GetForeachConfiguration(SafeWiFiManagerHandle wifi, HandleCallback callback, IntPtr userData);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_config_get_name")]
+ internal static extern int GetName(IntPtr config, out IntPtr name);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_config_get_security_type")]
+ internal static extern int GetSecurityType(IntPtr config, out int securityType);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_config_set_proxy_address")]
+ internal static extern int SetProxyAddress(IntPtr config, int addressFamily, string proxyAddress);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_config_get_proxy_address")]
+ internal static extern int GetProxyAddress(IntPtr config, out int addressFamily, out IntPtr proxyAddress);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_config_set_hidden_ap_property")]
+ internal static extern int SetHiddenAPProperty(IntPtr config, bool isHidden);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_config_get_hidden_ap_property")]
+ internal static extern int GetHiddenAPProperty(IntPtr config, out bool isHidden);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_config_get_eap_anonymous_identity")]
+ internal static extern int GetEapAnonymousIdentity(SafeWiFiConfigHandle config, out IntPtr anonymousIdentify);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_config_set_eap_anonymous_identity")]
+ internal static extern int SetEapAnonymousIdentity(SafeWiFiConfigHandle config, string anonymousIdentify);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_config_get_eap_ca_cert_file")]
+ internal static extern int GetEapCaCertFile(SafeWiFiConfigHandle config, out IntPtr caCert);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_config_set_eap_ca_cert_file")]
+ internal static extern int SetEapCaCertFile(SafeWiFiConfigHandle config, string caCert);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_config_get_eap_client_cert_file")]
+ internal static extern int GetEapClientCertFile(SafeWiFiConfigHandle config, out IntPtr clientCert);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_config_set_eap_client_cert_file")]
+ internal static extern int SetEapClientCertFile(SafeWiFiConfigHandle config, string privateKey, string clientCert);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_config_get_eap_identity")]
+ internal static extern int GetEapIdentity(SafeWiFiConfigHandle config, out IntPtr identify);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_config_set_eap_identity")]
+ internal static extern int SetEapIdentity(SafeWiFiConfigHandle config, string identify);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_config_get_eap_type")]
+ internal static extern int GetEapType(SafeWiFiConfigHandle config, out int eapType);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_config_set_eap_type")]
+ internal static extern int SetEapType(SafeWiFiConfigHandle config, int eapType);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_config_get_eap_auth_type")]
+ internal static extern int GetEapAuthType(SafeWiFiConfigHandle config, out int eapAuthType);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_config_set_eap_auth_type")]
+ internal static extern int SetEapAuthType(SafeWiFiConfigHandle config, int eapAuthType);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_config_get_eap_subject_match")]
+ internal static extern int GetEapSubjectMatch(SafeWiFiConfigHandle config, out IntPtr subjectMatch);
+ [DllImport(Libraries.WiFi, EntryPoint = "wifi_manager_config_set_eap_subject_match")]
+ internal static extern int SetEapSubjectMatch(SafeWiFiConfigHandle config, string subjectMatch);
+ }
+
+ internal sealed class SafeWiFiAPHandle : SafeHandle
+ {
+ public SafeWiFiAPHandle() : base(IntPtr.Zero, true)
+ {
+ }
+
+ public SafeWiFiAPHandle(IntPtr handle) : base(handle, true)
+ {
+ }
+
+ public override bool IsInvalid
+ {
+ get
+ {
+ return this.handle == IntPtr.Zero;
+ }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ WiFi.AP.Destroy(this.handle);
+ this.SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+
+ internal sealed class SafeWiFiConfigHandle : SafeHandle
+ {
+ public SafeWiFiConfigHandle() : base(IntPtr.Zero, true)
+ {
+ }
+
+ public SafeWiFiConfigHandle(IntPtr handle) : base(handle, true)
+ {
+ }
+
+ public override bool IsInvalid
+ {
+ get
+ {
+ return this.handle == IntPtr.Zero;
+ }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ WiFi.Config.Destroy(this.handle);
+ this.SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+
+ }
+
+ internal static partial class Libc
+ {
+ [DllImport(Libraries.Libc, EntryPoint = "free")]
+ public static extern void Free(IntPtr userData);
+ }
+}
diff --git a/src/Tizen.Network.WiFi/Tizen.Network.WiFi.csproj b/src/Tizen.Network.WiFi/Tizen.Network.WiFi.csproj
new file mode 100644
index 0000000..9b73f3a
--- /dev/null
+++ b/src/Tizen.Network.WiFi/Tizen.Network.WiFi.csproj
@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen.Network.Connection\Tizen.Network.Connection.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
+
diff --git a/src/Tizen.Network.WiFi/Tizen.Network.WiFi/ConnectionStateChangedEventArgs.cs b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/ConnectionStateChangedEventArgs.cs
new file mode 100755
index 0000000..352a777
--- /dev/null
+++ b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/ConnectionStateChangedEventArgs.cs
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Network.WiFi
+{
+ /// <summary>
+ /// An extended EventArgs class which contains changed connection state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class ConnectionStateChangedEventArgs : EventArgs
+ {
+ private WiFiConnectionState _state = WiFiConnectionState.Disconnected;
+ private WiFiAP _ap;
+
+ internal ConnectionStateChangedEventArgs(WiFiConnectionState s, IntPtr apHandle)
+ {
+ _state = s;
+ _ap = new WiFiAP(apHandle);
+ }
+
+ /// <summary>
+ /// The wifi connection state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public WiFiConnectionState State
+ {
+ get
+ {
+ return _state;
+ }
+ }
+
+ /// <summary>
+ /// The access point
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public WiFiAP AP
+ {
+ get
+ {
+ return _ap;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.WiFi/Tizen.Network.WiFi/DeviceStateChangedEventArgs.cs b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/DeviceStateChangedEventArgs.cs
new file mode 100644
index 0000000..f3e45ba
--- /dev/null
+++ b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/DeviceStateChangedEventArgs.cs
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Network.WiFi
+{
+ /// <summary>
+ /// An extended EventArgs class which contains changed device state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class DeviceStateChangedEventArgs : EventArgs
+ {
+ private WiFiDeviceState _state = WiFiDeviceState.Deactivated;
+
+ internal DeviceStateChangedEventArgs(WiFiDeviceState s)
+ {
+ _state = s;
+ }
+
+ /// <summary>
+ /// The wifi device state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public WiFiDeviceState State
+ {
+ get
+ {
+ return _state;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.WiFi/Tizen.Network.WiFi/IWiFiEap.cs b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/IWiFiEap.cs
new file mode 100755
index 0000000..1a12f74
--- /dev/null
+++ b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/IWiFiEap.cs
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Network.WiFi
+{
+ /// <summary>
+ /// An abstract class for WiFi EAP information.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ internal interface IWiFiEap
+ {
+ /// <summary>
+ /// The file path of CA Certificate of EAP.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ string CaCertificationFile { get; set; }
+
+ /// <summary>
+ /// The EAP type of wifi.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ WiFiEapType EapType { get; set; }
+
+ /// <summary>
+ /// The type of EAP phase2 authentication of Wi-Fi.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ WiFiAuthenticationType AuthenticationType { get; set; }
+ } //WiFiEap
+}
diff --git a/src/Tizen.Network.WiFi/Tizen.Network.WiFi/RssiLevelChangedEventArgs.cs b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/RssiLevelChangedEventArgs.cs
new file mode 100755
index 0000000..374c9c8
--- /dev/null
+++ b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/RssiLevelChangedEventArgs.cs
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Network.WiFi
+{
+ /// <summary>
+ /// An extended EventArgs class which contains changed RSSI level.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class RssiLevelChangedEventArgs : EventArgs
+ {
+ private WiFiRssiLevel _level = WiFiRssiLevel.Level0;
+
+ internal RssiLevelChangedEventArgs(WiFiRssiLevel l)
+ {
+ _level = l;
+ }
+
+ /// <summary>
+ /// The wifi RSSI level.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public WiFiRssiLevel Level
+ {
+ get
+ {
+ return _level;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiAP.cs b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiAP.cs
new file mode 100755
index 0000000..6877e75
--- /dev/null
+++ b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiAP.cs
@@ -0,0 +1,524 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Threading.Tasks;
+using System.Collections.Generic;
+
+namespace Tizen.Network.WiFi
+{
+ /// <summary>
+ /// A class for managing the network information of the access point(AP).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class WiFiAP : IDisposable
+ {
+ private IntPtr _apHandle = IntPtr.Zero;
+ private Dictionary<IntPtr, Interop.WiFi.VoidCallback> _callback_map = new Dictionary<IntPtr, Interop.WiFi.VoidCallback>();
+ private static Dictionary<IntPtr, Interop.WiFi.VoidCallback> s_callbackMap = new Dictionary<IntPtr, Interop.WiFi.VoidCallback>();
+ private int _requestId = 0;
+ private static int s_requestId = 0;
+ private WiFiNetwork _network;
+ private WiFiSecurity _security;
+ private bool _disposed = false;
+
+ /// <summary>
+ /// The network information of the access point(AP).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>WiFiNetwork instance containing network information of AP.</value>
+ public WiFiNetwork NetworkInformation
+ {
+ get
+ {
+ return _network;
+ }
+ }
+
+ /// <summary>
+ /// The security information of the access point(AP).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>WiFiSecurity instance containing security information of AP.</value>
+ public WiFiSecurity SecurityInformation
+ {
+ get
+ {
+ return _security;
+ }
+ }
+
+ internal WiFiAP(IntPtr handle)
+ {
+ Log.Debug(Globals.LogTag, "New WiFiAP. Handle: " + handle);
+ _apHandle = handle;
+ Initialize();
+ }
+
+ /// <summary>
+ /// Creates an object for the access point.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="essid">The Extended Service Set Identifier of the access point.</param>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="ArgumentNullException">Thrown when Essid is passed as null.</exception>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation.</exception>
+ public WiFiAP(string essid)
+ {
+ Log.Debug(Globals.LogTag, "New WiFiAP. Essid: " + essid);
+ createHandle(essid, true);
+ Initialize();
+ }
+
+ /// <summary>
+ /// Creates an object for the hidden access point.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="essid">The Extended Service Set Identifier of the access point.</param>
+ /// <param name="hidden">The value to set hidden AP</param>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="ArgumentNullException">Thrown when Essid is passed as null.</exception>
+ /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation.</exception>
+ public WiFiAP(string essid, bool hidden)
+ {
+ createHandle(essid, hidden);
+ Initialize();
+ }
+
+ ~WiFiAP()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// A method to destroy the managed WiFiAP objects.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (_disposed)
+ return;
+
+ if (disposing)
+ {
+ Interop.WiFi.AP.Destroy(_apHandle);
+ _apHandle = IntPtr.Zero;
+ }
+ _disposed = true;
+ }
+
+ private void createHandle(string id, bool hidden)
+ {
+ int ret = -1;
+ if (id == null)
+ {
+ throw new ArgumentNullException("Essid is null");
+ }
+
+ if (hidden)
+ {
+ ret = Interop.WiFi.AP.CreateHiddenAP(WiFiManagerImpl.Instance.GetSafeHandle(), id, out _apHandle);
+ }
+
+ else
+ {
+ ret = Interop.WiFi.AP.Create(WiFiManagerImpl.Instance.GetSafeHandle(), id, out _apHandle);
+ }
+
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to create handle, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle());
+ }
+ }
+
+ private void Initialize()
+ {
+ Interop.WiFi.SafeWiFiAPHandle apHandle = new Interop.WiFi.SafeWiFiAPHandle(_apHandle);
+ _network = new WiFiNetwork(apHandle);
+ _security = new WiFiSecurity(apHandle);
+ }
+
+ /// <summary>
+ /// Refreshes the access point information.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="ObjectDisposedException">Thrown when object instance is disposed or released.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public void Refresh()
+ {
+ Log.Debug(Globals.LogTag, "Refresh");
+ if (_disposed)
+ {
+ throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
+ }
+ int ret = Interop.WiFi.AP.Refresh(_apHandle);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to refresh ap handle, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _apHandle, "http://tizen.org/privilege/network.get");
+ }
+ }
+
+ /// <summary>
+ /// Connects the access point asynchronously.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns> A task indicating whether the Connect method is done or not.</returns>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <privilege>http://tizen.org/privilege/network.set</privilege>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="ObjectDisposedException">Thrown when object instance is disposed or released.</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public Task ConnectAsync()
+ {
+ Log.Debug(Globals.LogTag, "ConnectAsync");
+ if (_disposed)
+ {
+ throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
+ }
+ TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
+ IntPtr id;
+ lock (_callback_map)
+ {
+ id = (IntPtr)_requestId++;
+ _callback_map[id] = (error, key) =>
+ {
+ Log.Debug(Globals.LogTag, "Connecting finished : " + (WiFiError)error);
+ if (error != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
+ task.SetException(new InvalidOperationException("Error occurs during WiFi connecting, " + (WiFiError)error));
+ }
+ task.SetResult(true);
+ lock (_callback_map)
+ {
+ _callback_map.Remove(key);
+ }
+ };
+ }
+
+ int ret = Interop.WiFi.Connect(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, _callback_map[id], id);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
+ }
+
+ return task.Task;
+ }
+
+ /// <summary>
+ /// Connects the access point with WPS asynchronously.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="info">A WpsInfo instance which is of type WpsPbcInfo or WpsPinInfo.</param>
+ /// <returns>A task indicating whether the ConnectWps method is done or not.</returns>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <privilege>http://tizen.org/privilege/network.profile</privilege>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="ObjectDisposedException">Thrown when object instance is disposed or released.</exception>
+ /// <exception cref="ArgumentNullException">Thrown when WpsPinInfo object is constructed with null pin.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">Thrown when WpsPinInfo object is constructed with pin which is an empty string or more than 7 characters.</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public Task ConnectWpsAsync(WpsInfo info)
+ {
+ Log.Debug(Globals.LogTag, "ConnectWpsAsync");
+ if (_disposed)
+ {
+ throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
+ }
+ TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
+ IntPtr id;
+ lock (_callback_map)
+ {
+ id = (IntPtr)_requestId++;
+ _callback_map[id] = (error, key) =>
+ {
+ Log.Debug(Globals.LogTag, "Connecting by WPS finished");
+ if (error != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
+ task.SetException(new InvalidOperationException("Error occurs during WiFi connecting, " + (WiFiError)error));
+ }
+ task.SetResult(true);
+ lock (_callback_map)
+ {
+ _callback_map.Remove(key);
+ }
+ };
+ }
+
+ int ret = -1;
+ if (info.GetType() == typeof(WpsPbcInfo))
+ {
+ ret = Interop.WiFi.ConnectByWpsPbc(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, _callback_map[id], id);
+ }
+
+ else if (info.GetType() == typeof(WpsPinInfo))
+ {
+ WpsPinInfo pinInfo = (WpsPinInfo)info;
+ if (pinInfo.GetWpsPin() == null)
+ {
+ throw new ArgumentNullException("Wps pin should not be null");
+ }
+
+ if (pinInfo.GetWpsPin().Length == 0 || pinInfo.GetWpsPin().Length > 8)
+ {
+ throw new ArgumentOutOfRangeException("Wps pin should not be empty or more than 7 characters");
+ }
+
+ ret = Interop.WiFi.ConnectByWpsPin(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, pinInfo.GetWpsPin(), _callback_map[id], id);
+ }
+
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
+ }
+
+ return task.Task;
+ }
+
+ /// <summary>
+ /// Connects the access point with WPS without ssid asynchronously.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="info">A WpsInfo instance which is of type WpsPbcInfo or WpsPinInfo.</param>
+ /// <returns>A task which contains Connected access point information.</returns>
+ /// <remarks>
+ /// If WpsPinInfo is used, its object has to be constructed with a pin which must be 4 or 8 characters long.
+ /// </remarks>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <privilege>http://tizen.org/privilege/network.set</privilege>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <privilege>http://tizen.org/privilege/network.profile</privilege>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="ArgumentNullException">Thrown when WpsPinInfo object is constructed with null pin.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">Thrown when WpsPinInfo object is constructed with pin which is not of 4 or 8 characters long.</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public static Task<WiFiAP> ConnectWpsWithoutSsidAsync(WpsInfo info)
+ {
+ TaskCompletionSource<WiFiAP> task = new TaskCompletionSource<WiFiAP>();
+ IntPtr id;
+ lock (s_callbackMap)
+ {
+ id = (IntPtr)s_requestId++;
+ s_callbackMap[id] = (error, key) =>
+ {
+ Log.Debug(Globals.LogTag, "Connecting by WPS finished");
+ if (error != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
+ task.SetException(new InvalidOperationException("Error occurs during WiFi connecting, " + (WiFiError)error));
+ }
+ WiFiAP ap = WiFiManagerImpl.Instance.GetConnectedAP();
+ task.SetResult(ap);
+ lock (s_callbackMap)
+ {
+ s_callbackMap.Remove(key);
+ }
+ };
+ }
+
+ int ret = -1;
+ if (info.GetType() == typeof(WpsPbcInfo))
+ {
+ ret = Interop.WiFi.ConnectByWpsPbcWithoutSsid(WiFiManagerImpl.Instance.GetSafeHandle(), s_callbackMap[id], id);
+ }
+
+ else if (info.GetType() == typeof(WpsPinInfo))
+ {
+ WpsPinInfo pinInfo = (WpsPinInfo)info;
+ if (pinInfo.GetWpsPin() == null)
+ {
+ throw new ArgumentNullException("Wps pin should not be null");
+ }
+
+ if (pinInfo.GetWpsPin().Length != 4 && pinInfo.GetWpsPin().Length != 8)
+ {
+ throw new ArgumentOutOfRangeException("Wps pin should be of 4 or 8 characters long");
+ }
+
+ ret = Interop.WiFi.ConnectByWpsPinWithoutSsid(WiFiManagerImpl.Instance.GetSafeHandle(), pinInfo.GetWpsPin(), s_callbackMap[id], id);
+ }
+
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle());
+ }
+
+ return task.Task;
+ }
+
+ /// <summary>
+ /// Disconnects the access point asynchronously.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns> A task indicating whether the Disconnect method is done or not.</returns>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <privilege>http://tizen.org/privilege/network.set</privilege>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="ObjectDisposedException">Thrown when object instance is disposed or released.</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public Task DisconnectAsync()
+ {
+ Log.Debug(Globals.LogTag, "DisconnectAsync");
+ if (_disposed)
+ {
+ throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
+ }
+ TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
+ IntPtr id;
+ lock (_callback_map)
+ {
+ id = (IntPtr)_requestId++;
+ _callback_map[id] = (error, key) =>
+ {
+ Log.Debug(Globals.LogTag, "Disconnecting finished");
+ if (error != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Error occurs during WiFi disconnecting, " + (WiFiError)error);
+ task.SetException(new InvalidOperationException("Error occurs during WiFi disconnecting, " + (WiFiError)error));
+ }
+ task.SetResult(true);
+ lock (_callback_map)
+ {
+ _callback_map.Remove(key);
+ }
+ };
+ }
+ int ret = Interop.WiFi.Disconnect(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, _callback_map[id], id);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to disconnect wifi, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
+ }
+ return task.Task;
+ }
+
+ /// <summary>
+ /// Deletes the information of stored access point and disconnects it when it is connected.<br>
+ /// If an AP is connected, then connection information will be stored. This information is used when a connection to that AP is established automatically.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <privilege>http://tizen.org/privilege/network.profile</privilege>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="ObjectDisposedException">Thrown when object instance is disposed or released.</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public void ForgetAP()
+ {
+ Log.Debug(Globals.LogTag, "ForgetAP");
+ if (_disposed)
+ {
+ throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
+ }
+ int ret = Interop.WiFi.RemoveAP(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to forget AP, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
+ }
+ }
+ }
+
+ /// <summary>
+ /// An abstract class which is used to represent WPS information of access point.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public abstract class WpsInfo
+ {
+ }
+
+ /// <summary>
+ /// A class which is used to represent WPS PBC information of access point.
+ /// </summary>
+ public class WpsPbcInfo : WpsInfo
+ {
+ }
+
+ /// <summary>
+ /// A class which is used to represent WPS PIN information of access point.
+ /// </summary>
+ public class WpsPinInfo : WpsInfo
+ {
+ private string _pin;
+
+ private WpsPinInfo()
+ {
+ }
+
+ /// <summary>
+ /// A public constructor which instantiates WpsPinInfo class with the given pin.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="pin">WPS Pin of the access point.</param>
+ /// <remarks>
+ /// Pin should not be null or empty. It should be of less than 8 characters.
+ /// </remarks>
+ public WpsPinInfo(string pin)
+ {
+ _pin = pin;
+ }
+
+ internal string GetWpsPin()
+ {
+ return _pin;
+ }
+ }
+}
diff --git a/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiAddressInformation.cs b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiAddressInformation.cs
new file mode 100755
index 0000000..03e8d37
--- /dev/null
+++ b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiAddressInformation.cs
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using System.Net;
+using Tizen.Network.Connection;
+
+namespace Tizen.Network.WiFi
+{
+ internal class WiFiAddressInformation : IAddressInformation
+ {
+ private Interop.WiFi.SafeWiFiAPHandle _handle;
+ private AddressFamily _family;
+
+ internal WiFiAddressInformation(Interop.WiFi.SafeWiFiAPHandle handle, AddressFamily family)
+ {
+ _handle = handle;
+ _family = family;
+ }
+
+ public System.Net.IPAddress Dns1
+ {
+ get
+ {
+ IntPtr addrPtr;
+ int ret = Interop.WiFi.AP.GetDnsAddress(_handle, 1, (int)_family, out addrPtr);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get first dns address, Error - " + (WiFiError)ret);
+ return System.Net.IPAddress.Parse("0.0.0.0");
+ }
+ string addrStr = Marshal.PtrToStringAnsi(addrPtr);
+ Interop.Libc.Free(addrPtr);
+ if (addrStr == null)
+ return System.Net.IPAddress.Parse("0.0.0.0");
+ return System.Net.IPAddress.Parse(addrStr);
+ }
+ set
+ {
+ int ret = Interop.WiFi.AP.SetDnsAddress(_handle, 1, (int)_family, value.ToString());
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set first dns address, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _handle.DangerousGetHandle());
+ }
+ }
+ }
+
+ public System.Net.IPAddress Dns2
+ {
+ get
+ {
+ IntPtr addrPtr;
+ int ret = Interop.WiFi.AP.GetDnsAddress(_handle, 2, (int)_family, out addrPtr);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get second dns address, Error - " + (WiFiError)ret);
+ return System.Net.IPAddress.Parse("0.0.0.0");
+ }
+ string addrStr = Marshal.PtrToStringAnsi(addrPtr);
+ Interop.Libc.Free(addrPtr);
+ if (addrStr == null)
+ return System.Net.IPAddress.Parse("0.0.0.0");
+ return System.Net.IPAddress.Parse(addrStr);
+ }
+ set
+ {
+ int ret = Interop.WiFi.AP.SetDnsAddress(_handle, 2, (int)_family, value.ToString());
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set second dns address, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _handle.DangerousGetHandle());
+ }
+ }
+ }
+
+ public System.Net.IPAddress Gateway
+ {
+ get
+ {
+ IntPtr addrPtr;
+ int ret = Interop.WiFi.AP.GetGatewayAddress(_handle, (int)_family, out addrPtr);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get gateway address, Error - " + (WiFiError)ret);
+ return System.Net.IPAddress.Parse("0.0.0.0");
+ }
+ string addrStr = Marshal.PtrToStringAnsi(addrPtr);
+ Interop.Libc.Free(addrPtr);
+ if (addrStr == null)
+ return System.Net.IPAddress.Parse("0.0.0.0");
+ return System.Net.IPAddress.Parse(addrStr);
+ }
+ set
+ {
+ int ret = Interop.WiFi.AP.SetGatewayAddress(_handle, (int)_family, value.ToString());
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set gateway address, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _handle.DangerousGetHandle());
+ }
+ }
+ }
+
+ public System.Net.IPAddress SubnetMask
+ {
+ get
+ {
+ IntPtr addrPtr;
+ int ret = Interop.WiFi.AP.GetSubnetMask(_handle, (int)_family, out addrPtr);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get subnet mask, Error - " + (WiFiError)ret);
+ return System.Net.IPAddress.Parse("0.0.0.0");
+ }
+ string addrStr = Marshal.PtrToStringAnsi(addrPtr);
+ Interop.Libc.Free(addrPtr);
+ if (addrStr == null)
+ return System.Net.IPAddress.Parse("0.0.0.0");
+ return System.Net.IPAddress.Parse(addrStr);
+ }
+ set
+ {
+ int ret = Interop.WiFi.AP.SetSubnetMask(_handle, (int)_family, value.ToString());
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set subnet mask, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _handle.DangerousGetHandle());
+ }
+ }
+ }
+
+ public System.Net.IPAddress IP
+ {
+ get
+ {
+ IntPtr addrPtr;
+ int ret = Interop.WiFi.AP.GetIPAddress(_handle, (int)_family, out addrPtr);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get ip address, Error - " + (WiFiError)ret);
+ return System.Net.IPAddress.Parse("0.0.0.0");
+ }
+ string addrStr = Marshal.PtrToStringAnsi(addrPtr);
+ Interop.Libc.Free(addrPtr);
+ if (addrStr == null)
+ return System.Net.IPAddress.Parse("0.0.0.0");
+ return System.Net.IPAddress.Parse(addrStr);
+ }
+ set
+ {
+ int ret = Interop.WiFi.AP.SetIPAddress(_handle, (int)_family, value.ToString());
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set ip address, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _handle.DangerousGetHandle());
+ }
+ }
+ }
+
+ public IPConfigType IPConfigType
+ {
+ get
+ {
+ int type;
+ int ret = Interop.WiFi.AP.GetIPConfigType(_handle, (int)_family, out type);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get ip config type, Error - " + (WiFiError)ret);
+ }
+ return (IPConfigType)type;
+ }
+ set
+ {
+ int ret = Interop.WiFi.AP.SetIPConfigType(_handle, (int)_family, (int)value);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set ip config type, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _handle.DangerousGetHandle());
+ }
+ }
+ }
+
+ public int PrefixLength
+ {
+ get
+ {
+ int Value;
+ int ret = Interop.WiFi.AP.GetPrefixLength(_handle, (int)_family, out Value);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get prefix length, " + (WiFiError)ret);
+ return -1;
+ }
+ return Value;
+ }
+
+ set
+ {
+ int ret = Interop.WiFi.AP.SetPrefixLength(_handle, (int)_family, value);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to set prefix length, " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _handle.DangerousGetHandle());
+ }
+ }
+ }
+
+ public DnsConfigType DnsConfigType
+ {
+ get
+ {
+ int Value;
+ int ret = Interop.WiFi.AP.GetDnsConfigType(_handle, (int)_family, out Value);
+ if ((WiFiError)ret != WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to get DNS config type, " + (WiFiError)ret);
+ }
+ return (DnsConfigType)Value;
+ }
+ set
+ {
+ int ret = Interop.WiFi.AP.SetDnsConfigType(_handle, (int)_family, (int)value);
+ if ((WiFiError)ret != WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "It failed to set DNS config type, " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _handle.DangerousGetHandle());
+ }
+ }
+ }
+
+ /// <summary>
+ /// DHCP server address. It is only supported for IPv4 address family.
+ /// </summary>
+ /// <value>Represents DHCP server address.</value>
+ public System.Net.IPAddress DhcpServerAddress
+ {
+ get
+ {
+ string dhcpServer;
+ int ret = Interop.WiFi.AP.GetDhcpServerAddress(_handle, AddressFamily.IPv4, out dhcpServer);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get DHCP server address, Error - " + (WiFiError)ret);
+ }
+
+ if (dhcpServer == null)
+ {
+ return IPAddress.Parse("0.0.0.0");
+ }
+
+ return IPAddress.Parse(dhcpServer);
+ }
+ }
+
+ }
+}
diff --git a/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiConfiguration.cs b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiConfiguration.cs
new file mode 100755
index 0000000..dabfb31
--- /dev/null
+++ b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiConfiguration.cs
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Net;
+using System.Threading.Tasks;
+using System.Runtime.InteropServices;
+using Tizen.Network.Connection;
+
+namespace Tizen.Network.WiFi
+{
+ /// <summary>
+ /// A class for managing the configuration of Wi-Fi.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class WiFiConfiguration : IDisposable
+ {
+ private IntPtr _configHandle = IntPtr.Zero;
+ private bool _disposed = false;
+ private WiFiEapConfiguration _eapConfig;
+
+ /// <summary>
+ /// The name of access point(AP).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Name assigned to AP in WiFi configuration.</value>
+ public string Name
+ {
+ get
+ {
+ IntPtr strPtr;
+ int ret = Interop.WiFi.Config.GetName(_configHandle, out strPtr);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get name, Error - " + (WiFiError)ret);
+ return "";
+ }
+ return Marshal.PtrToStringAnsi(strPtr);
+ }
+ }
+
+ /// <summary>
+ /// The security type of access point(AP).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Security type of AP in WiFi configuration.</value>
+ public WiFiSecurityType SecurityType
+ {
+ get
+ {
+ int type;
+ int ret = Interop.WiFi.Config.GetSecurityType(_configHandle, out type);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get security type, Error - " + (WiFiError)ret);
+ }
+ return (WiFiSecurityType)type;
+ }
+ }
+
+ /// <summary>
+ /// The proxy address.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Proxy address of the access point.</value>
+ /// <exception cref="NotSupportedException">Thrown while setting this property when WiFi is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown while setting this property due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown while setting this value due to invalid operation.</exception>
+ public string ProxyAddress
+ {
+ get
+ {
+ IntPtr strPtr;
+ int addressFamily;
+ int ret = Interop.WiFi.Config.GetProxyAddress(_configHandle, out addressFamily, out strPtr);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get proxy address, Error - " + (WiFiError)ret);
+ return "";
+ }
+ return Marshal.PtrToStringAnsi(strPtr);
+ }
+ set
+ {
+ if (_disposed)
+ {
+ throw new ObjectDisposedException("Invalid WiFiConfiguration instance (Object may have been disposed or released)");
+ }
+ int ret = Interop.WiFi.Config.SetProxyAddress(_configHandle, (int)AddressFamily.IPv4, value);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set proxy address, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _configHandle);
+ }
+ }
+ }
+
+ /// <summary>
+ /// A property check whether the access point(AP) is hidden or not.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Boolean value indicating whether AP is hidden or not.</value>
+ /// <exception cref="NotSupportedException">Thrown while setting this property when WiFi is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown while setting this property due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown while setting this value due to invalid operation.</exception>
+ public bool IsHidden
+ {
+ get
+ {
+ bool hidden;
+ int ret = Interop.WiFi.Config.GetHiddenAPProperty(_configHandle, out hidden);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get isHidden, Error - " + (WiFiError)ret);
+ }
+ return hidden;
+ }
+ set
+ {
+ if (_disposed)
+ {
+ throw new ObjectDisposedException("Invalid WiFiConfiguration instance (Object may have been disposed or released)");
+ }
+ int ret = Interop.WiFi.Config.SetHiddenAPProperty(_configHandle, value);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set IsHidden, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _configHandle);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The EAP Configuration.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>EAP configuration assigned to WiFi.</value>
+ public WiFiEapConfiguration EapConfiguration
+ {
+ get
+ {
+ return _eapConfig;
+ }
+ }
+
+ internal WiFiConfiguration(IntPtr handle)
+ {
+ _configHandle = handle;
+ Interop.WiFi.SafeWiFiConfigHandle configHandle = new Interop.WiFi.SafeWiFiConfigHandle(handle);
+ _eapConfig = new WiFiEapConfiguration(configHandle);
+ }
+
+ /// <summary>
+ /// Creates a WiFiConfiguration object with the given name, passphrase and securetype.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="name">Name of the WiFi.</param>
+ /// <param name="passPhrase">Password to access the WiFi.</param>
+ /// <param name="type">Security type of the WiFi.</param>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="ArgumentNullException">Thrown when the object is constructed with name as null.</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when it is failed due to invalid operation.</exception>
+ public WiFiConfiguration(string name, string passPhrase, WiFiSecurityType type)
+ {
+ if (name == null)
+ {
+ throw new ArgumentNullException("Name of the WiFi is null");
+ }
+
+ int ret = Interop.WiFi.Config.Create(WiFiManagerImpl.Instance.GetSafeHandle(), name, passPhrase, (int)type, out _configHandle);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to create config handle, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle());
+ }
+
+ Interop.WiFi.SafeWiFiConfigHandle configHandle = new Interop.WiFi.SafeWiFiConfigHandle(_configHandle);
+ _eapConfig = new WiFiEapConfiguration(configHandle);
+ }
+
+ ~WiFiConfiguration()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// A method to destroy the managed objects in WiFiConfiguration.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (_disposed)
+ return;
+
+ if (disposing)
+ {
+ Interop.WiFi.Config.Destroy(_configHandle);
+ _configHandle = IntPtr.Zero;
+ }
+ _disposed = true;
+ }
+
+ internal IntPtr GetHandle()
+ {
+ return _configHandle;
+ }
+ } //WiFiNetworkConfiguratin
+}
diff --git a/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiEap.cs b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiEap.cs
new file mode 100755
index 0000000..dd89ccd
--- /dev/null
+++ b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiEap.cs
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Network.WiFi
+{
+ /// <summary>
+ /// A class for managing the EAP information of access point(AP).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class WiFiEap : IWiFiEap
+ {
+ private Interop.WiFi.SafeWiFiAPHandle _apHandle;
+
+ /// <summary>
+ /// The file path of CA Certificate of EAP.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>CA certification file of EAP.</value>
+ /// <exception cref="NotSupportedException">Thrown while setting this value when WiFi is not supported.</exception>
+ /// <exception cref="ArgumentNullException">Thrown while setting this value when file value is null.</exception>
+ /// <exception cref="ArgumentException">Thrown while setting this property due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown while setting this value due to invalid operation.</exception>
+ public string CaCertificationFile
+ {
+ get
+ {
+ IntPtr strPtr;
+ int ret = Interop.WiFi.AP.GetEapCaCertFile(_apHandle, out strPtr);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get caCertFile, Error - " + (WiFiError)ret);
+ return "";
+ }
+ return Marshal.PtrToStringAnsi(strPtr);
+ }
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("File value is null");
+ }
+ int ret = Interop.WiFi.AP.SetEapCaCertFile(_apHandle, value);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set caCertFile, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _apHandle.DangerousGetHandle());
+ }
+ }
+ }
+
+ /// <summary>
+ /// The EAP type of wifi.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Type of EAP.</value>
+ /// <exception cref="NotSupportedException">Thrown while setting this value when WiFi is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown while setting this property due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown while setting this value due to invalid operation.</exception>
+ public WiFiEapType EapType
+ {
+ get
+ {
+ int type;
+ int ret = Interop.WiFi.AP.GetEapType(_apHandle, out type);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get eap type, Error - " + (WiFiError)ret);
+ }
+ return (WiFiEapType)type;
+ }
+ set
+ {
+ int ret = Interop.WiFi.AP.SetEapType(_apHandle, (int)value);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set eap type, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _apHandle.DangerousGetHandle());
+ }
+ }
+ }
+
+ /// <summary>
+ /// The type of EAP phase2 authentication of Wi-Fi.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Authentication type of WiFi.</value>
+ /// <exception cref="NotSupportedException">Thrown while setting this value when WiFi is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown while setting this property due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown while setting this value due to invalid operation.</exception>
+ public WiFiAuthenticationType AuthenticationType
+ {
+ get
+ {
+ int type;
+ int ret = Interop.WiFi.AP.GetEapAuthType(_apHandle, out type);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get auth type, Error - " + (WiFiError)ret);
+ }
+ return (WiFiAuthenticationType)type;
+ }
+ set
+ {
+ int ret = Interop.WiFi.AP.SetEapAuthType(_apHandle, (int)value);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set eap auth type, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _apHandle.DangerousGetHandle());
+ }
+ }
+ }
+
+ internal WiFiEap(Interop.WiFi.SafeWiFiAPHandle apHandle)
+ {
+ _apHandle = apHandle;
+ }
+
+ /// <summary>
+ /// Gets the private key file of EAP.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>The file path of private key.</returns>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory. </exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public string GetPrivateKeyFile()
+ {
+ IntPtr strPtr;
+ int ret = Interop.WiFi.AP.GetEapPrivateKeyFile(_apHandle, out strPtr);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get private key file, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _apHandle.DangerousGetHandle());
+ }
+ return Marshal.PtrToStringAnsi(strPtr);
+ }
+
+ /// <summary>
+ /// Sets the private key information of EAP.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="privateKeyFile">The file path of private key.</param>
+ /// <param name="password">The password.</param>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="ArgumentNullException">Thrown when file path of private key is null.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public void SetPrivateKeyFile(string privateKeyFile, string password)
+ {
+ if (privateKeyFile == null)
+ {
+ throw new ArgumentNullException("File path of private key is null");
+ }
+ int ret = Interop.WiFi.AP.SetEapPrivateKeyFile(_apHandle, privateKeyFile, password);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set private key file, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _apHandle.DangerousGetHandle());
+ }
+ }
+
+ /// <summary>
+ /// Gets the Client Certificate of EAP.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>The file path of Client Certificate.</returns>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory. </exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public string GetClientCertFile()
+ {
+ IntPtr strPtr;
+ int ret = Interop.WiFi.AP.GetEapClientCertFile(_apHandle, out strPtr);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get client cert file, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _apHandle.DangerousGetHandle());
+ }
+ return Marshal.PtrToStringAnsi(strPtr);
+ }
+
+ /// <summary>
+ /// Sets the CA Certificate of EAP.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="clientCertFile">The file path of Client Certificate.</param>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="ArgumentNullException">Thrown when file path of Client Certificate is null.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public void SetClientCertFile(string clientCertFile)
+ {
+ if (clientCertFile == null)
+ {
+ throw new ArgumentNullException("File path of Client certificate is null");
+ }
+ int ret = Interop.WiFi.AP.SetEapClientCertFile(_apHandle, clientCertFile);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set client cert file, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _apHandle.DangerousGetHandle());
+ }
+ }
+
+ /// <summary>
+ /// Gets the username of EAP passphrase.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>The user name</returns>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory. </exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public string GetUserName()
+ {
+ IntPtr strptr;
+ bool passwordSet;
+ int ret = Interop.WiFi.AP.GetEapPassphrase(_apHandle, out strptr, out passwordSet);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get user name in eap passphrase, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _apHandle.DangerousGetHandle());
+ }
+ return Marshal.PtrToStringAnsi(strptr);
+ }
+
+ /// <summary>
+ /// Returns whether the password is set or not.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>True if password is set, false if password is not set.</returns>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory. </exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public bool IsPasswordSet()
+ {
+ IntPtr strptr;
+ bool passwordSet;
+ int ret = Interop.WiFi.AP.GetEapPassphrase(_apHandle, out strptr, out passwordSet);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get IsPasswordSet in passphrase, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _apHandle.DangerousGetHandle());
+ }
+ return passwordSet;
+ }
+
+ /// <summary>
+ /// Sets the user name of EAP.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="userName">The user name</param>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="ArgumentNullException">Thrown when the user name is passed as null. </exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public void SetUserName(string userName)
+ {
+ if (userName == null)
+ {
+ throw new ArgumentNullException("User name is null");
+ }
+ int ret = Interop.WiFi.AP.SetEapPassphrase(_apHandle, userName, null);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set username, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _apHandle.DangerousGetHandle());
+ }
+ }
+
+ /// <summary>
+ /// Sets the password of EAP.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="password">The password</param>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="ArgumentNullException">Thrown when the password is passed as null. </exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ public void SetPassword(string password)
+ {
+ if (password == null)
+ {
+ throw new ArgumentNullException("Password is null");
+ }
+ int ret = Interop.WiFi.AP.SetEapPassphrase(_apHandle, null, password);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set password, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _apHandle.DangerousGetHandle());
+ }
+ }
+ } //WiFiEapInformation
+}
diff --git a/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiEapConfiguration.cs b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiEapConfiguration.cs
new file mode 100755
index 0000000..387bb23
--- /dev/null
+++ b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiEapConfiguration.cs
@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Network.WiFi
+{
+ /// <summary>
+ /// A class for managing the EAP configuration.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class WiFiEapConfiguration : IWiFiEap
+ {
+ private Interop.WiFi.SafeWiFiConfigHandle _configHandle;
+
+ /// <summary>
+ /// The file path of CA Certificate of EAP.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>CA certification file of EAP.</value>
+ /// <exception cref="NotSupportedException">Thrown while setting this value when WiFi is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown while setting this property due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown while setting this value due to invalid operation.</exception>
+ public string CaCertificationFile
+ {
+ get
+ {
+ IntPtr strPtr;
+ int ret = Interop.WiFi.Config.GetEapCaCertFile(_configHandle, out strPtr);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get caCertFile Error - " + (WiFiError)ret);
+ return "";
+ }
+ return Marshal.PtrToStringAnsi(strPtr);
+ }
+ set
+ {
+ int ret = Interop.WiFi.Config.SetEapCaCertFile(_configHandle, value);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set caCertFile, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _configHandle.DangerousGetHandle());
+ }
+ }
+ }
+
+ /// <summary>
+ /// The EAP type of wifi.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Type of EAP.</value>
+ /// <exception cref="NotSupportedException">Thrown while setting this value when WiFi is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown while setting this property due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown while setting this value due to invalid operation.</exception>
+ public WiFiEapType EapType
+ {
+ get
+ {
+ int type;
+ int ret = Interop.WiFi.Config.GetEapType(_configHandle, out type);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to eap type Error - " + (WiFiError)ret);
+ }
+ return (WiFiEapType)type;
+ }
+ set
+ {
+ int ret = Interop.WiFi.Config.SetEapType(_configHandle, (int)value);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set eap type, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _configHandle.DangerousGetHandle());
+ }
+ }
+ }
+
+ /// <summary>
+ /// The type of EAP phase2 authentication of Wi-Fi.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Authentication type of WiFi.</value>
+ /// <exception cref="NotSupportedException">Thrown while setting this value when WiFi is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown while setting this property due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown while setting this value due to invalid operation.</exception>
+ public WiFiAuthenticationType AuthenticationType
+ {
+ get
+ {
+ int type;
+ int ret = Interop.WiFi.Config.GetEapAuthType(_configHandle, out type);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get auth type Error - " + (WiFiError)ret);
+ }
+ return (WiFiAuthenticationType)type;
+ }
+ set
+ {
+ int ret = Interop.WiFi.Config.SetEapAuthType(_configHandle, (int)value);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set eap auth type, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _configHandle.DangerousGetHandle());
+ }
+ }
+ }
+
+ /// <summary>
+ /// The anonymous identity of access point(AP).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Represents the anonymous identity of the access point.</value>
+ /// <exception cref="NotSupportedException">Thrown while setting this value when WiFi is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown while setting this property due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown while setting this value due to invalid operation.</exception>
+ public string AnonymousIdentify
+ {
+ get
+ {
+ IntPtr strPtr;
+ int ret = Interop.WiFi.Config.GetEapAnonymousIdentity(_configHandle, out strPtr);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get anonymous identify Error - " + (WiFiError)ret);
+ return "";
+ }
+ return Marshal.PtrToStringAnsi(strPtr);
+ }
+ set
+ {
+ int ret = Interop.WiFi.Config.SetEapAnonymousIdentity(_configHandle, value);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set anonymous identify, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _configHandle.DangerousGetHandle());
+ }
+ }
+ }
+
+ /// <summary>
+ /// The identity of access point(AP).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Represents the identity of the access point.</value>
+ /// <exception cref="NotSupportedException">Thrown while setting this value when WiFi is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown while setting this property due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown while setting this value due to invalid operation.</exception>
+ public string Identity
+ {
+ get
+ {
+ IntPtr strPtr;
+ int ret = Interop.WiFi.Config.GetEapIdentity(_configHandle, out strPtr);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get identify Error - " + (WiFiError)ret);
+ return "";
+ }
+ return Marshal.PtrToStringAnsi(strPtr);
+ }
+ set
+ {
+ int ret = Interop.WiFi.Config.SetEapIdentity(_configHandle, value);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set identify, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _configHandle.DangerousGetHandle());
+ }
+ }
+ }
+
+ /// <summary>
+ /// The subject match of access point(AP).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Represents the subject match of AP.</value>
+ /// <exception cref="NotSupportedException">Thrown while setting this value when WiFi is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown while setting this property due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown while setting this value due to invalid operation.</exception>
+ public string SubjectMatch
+ {
+ get
+ {
+ IntPtr strPtr;
+ int ret = Interop.WiFi.Config.GetEapSubjectMatch(_configHandle, out strPtr);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get subject match Error - " + (WiFiError)ret);
+ return "";
+ }
+ return Marshal.PtrToStringAnsi(strPtr);
+ }
+ set
+ {
+ int ret = Interop.WiFi.Config.SetEapSubjectMatch(_configHandle, value);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set subject match, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _configHandle.DangerousGetHandle());
+ }
+ }
+ }
+
+ internal WiFiEapConfiguration(Interop.WiFi.SafeWiFiConfigHandle handle)
+ {
+ _configHandle = handle;
+ }
+
+ /// <summary>
+ /// Gets access point client cert file from configuration.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>The certification authority(CA) certificates file of access point.</returns>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
+ public string GetClientCertFile()
+ {
+ IntPtr strPtr;
+ int ret = Interop.WiFi.Config.GetEapClientCertFile(_configHandle, out strPtr);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get client cert file, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _configHandle.DangerousGetHandle());
+ }
+ return Marshal.PtrToStringAnsi(strPtr);
+ }
+
+ /// <summary>
+ /// Sets access point client cert file to configuration.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="privateKey">The private key file.</param>
+ /// <param name="clientCert">The certification authority(CA) certificates file of access point.</param>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
+ public void SetClientCertFile(string privateKey, string clientCert)
+ {
+ int ret = Interop.WiFi.Config.SetEapClientCertFile(_configHandle, privateKey, clientCert);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set client cert file, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _configHandle.DangerousGetHandle());
+ }
+ }
+ } //WiFiEapConfiguration
+}
diff --git a/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiEnumerations.cs b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiEnumerations.cs
new file mode 100755
index 0000000..8627d03
--- /dev/null
+++ b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiEnumerations.cs
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Network.WiFi
+{
+ /// <summary>
+ /// Enumeration for Wi-Fi EAP type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum WiFiEapType
+ {
+ /// <summary>
+ /// EAP PEAP type
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Peap = 0,
+ /// <summary>
+ /// EAP TLS type
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Tls = 1,
+ /// <summary>
+ /// EAP TTLS type
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Ttls = 2,
+ /// <summary>
+ /// EAP SIM type
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Sim = 3,
+ /// <summary>
+ /// EAP AKA type
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Aka = 4
+ }
+
+ /// <summary>
+ /// Enumeration for Wi-Fi RSSI level.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum WiFiRssiLevel
+ {
+ /// <summary>
+ /// Level 0
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Level0 = 0,
+ /// <summary>
+ /// Level 1
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Level1 = 1,
+ /// <summary>
+ /// Level 2
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Level2 = 2,
+ /// <summary>
+ /// Level 3
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Level3 = 3,
+ /// <summary>
+ /// Level 4
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Level4 = 4
+ }
+
+ /// <summary>
+ /// Enumeration for Wi-Fi connection state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum WiFiConnectionState
+ {
+ /// <summary>
+ /// Connection failed state
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Failure = -1,
+ /// <summary>
+ /// Disconnected state
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Disconnected = 0,
+ /// <summary>
+ /// Association state
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Association = 1,
+ /// <summary>
+ /// Configuration state
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Congfiguration = 2,
+ /// <summary>
+ /// Connected state
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Connected = 3
+ }
+
+ /// <summary>
+ /// Enumeration for Wi-Fi device state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum WiFiDeviceState
+ {
+ /// <summary>
+ /// Wi-Fi is Deactivated
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Deactivated = 0,
+ /// <summary>
+ /// Wi-Fi is activated
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Activated = 1
+ }
+
+ /// <summary>
+ /// Enumeration for Wi-Fi proxy type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum WiFiProxyType
+ {
+ /// <summary>
+ /// Direct connection
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Direct = 0,
+ /// <summary>
+ /// Auto configuration(Use PAC file). If URL property is not set, DHCP/WPAD auto-discover will be tried
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Auto = 1,
+ /// <summary>
+ /// Manual configuration
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Manual = 2
+ }
+
+ /// <summary>
+ /// Enumeration for Wi-Fi authentication type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum WiFiAuthenticationType
+ {
+ /// <summary>
+ /// EAP phase2 authentication none
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ None = 0,
+ /// <summary>
+ /// EAP phase2 authentication PAP
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Pap = 1,
+ /// <summary>
+ /// EAP phase2 authentication MSCHAP
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Mschap = 2,
+ /// <summary>
+ /// EAP phase2 authentication MSCHAPv2
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Mschapv2 = 3,
+ /// <summary>
+ /// EAP phase2 authentication GTC
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Gtc = 4,
+ /// <summary>
+ /// EAP phase2 authentication MD5
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Md5 = 5
+ }
+}
diff --git a/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiErrorFactory.cs b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiErrorFactory.cs
new file mode 100755
index 0000000..1b43a1d
--- /dev/null
+++ b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiErrorFactory.cs
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Network.WiFi
+{
+ internal enum WiFiError
+ {
+ None = ErrorCode.None,
+ InvalidParameterError = ErrorCode.InvalidParameter,
+ OutOfMemoryError = ErrorCode.OutOfMemory,
+ InvalidOperationError = ErrorCode.InvalidOperation,
+ AddressFamilyNotSupportedError = ErrorCode.AddressFamilyNotSupported,
+ OperationFailedError = -0x01C50000 | 0x0301,
+ NoConnectionError = -0x01C50000 | 0x0302,
+ NowInProgressError = ErrorCode.NowInProgress,
+ AlreadyExistsError = -0x01C50000 | 0x0303,
+ OperationAbortedError = -0x01C50000 | 0x0304,
+ DhcpFailedError = -0x01C50000 | 0x0306,
+ InvalidKeyError = -0x01C50000 | 0x0307,
+ NoReplyError = -0x01C50000 | 0x0308,
+ SecurityRestrictedError = -0x01C50000 | 0x0309,
+ PermissionDeniedError = ErrorCode.PermissionDenied,
+ NotSupportedError = ErrorCode.NotSupported
+ }
+
+ internal static class WiFiErrorFactory
+ {
+ static internal void ThrowWiFiException(int e, IntPtr handle)
+ {
+ ThrowExcption(e, (handle == IntPtr.Zero), false, "");
+ }
+
+ static internal void ThrowWiFiException(int e, IntPtr handle1, IntPtr handle2)
+ {
+ ThrowExcption(e, (handle1 == IntPtr.Zero), (handle2 == IntPtr.Zero), "");
+ }
+
+ static internal void ThrowWiFiException(int e, string message)
+ {
+ ThrowExcption(e, false, false, message);
+ }
+
+ static internal void ThrowWiFiException(int e, IntPtr handle, string message)
+ {
+ ThrowExcption(e, (handle == IntPtr.Zero), false, message);
+ }
+
+ static internal void ThrowWiFiException(int e, IntPtr handle1, IntPtr handle2, string message)
+ {
+ ThrowExcption(e, (handle1 == IntPtr.Zero), (handle2 == IntPtr.Zero), message);
+ }
+
+ static private void ThrowExcption(int e, bool isHandle1Null, bool isHandle2Null, string message)
+ {
+ WiFiError err = (WiFiError)e;
+ if (err == WiFiError.NotSupportedError)
+ {
+ throw new NotSupportedException("Unsupported feature http://tizen.org/feature/network.wifi");
+ }
+
+ if (err == WiFiError.PermissionDeniedError)
+ {
+ throw new UnauthorizedAccessException("Permission denied " + message);
+ }
+
+ if (err == WiFiError.OutOfMemoryError)
+ {
+ throw new OutOfMemoryException("Out of memory");
+ }
+
+ if (err == WiFiError.InvalidParameterError || err == WiFiError.InvalidKeyError)
+ {
+ if (isHandle1Null || isHandle2Null)
+ {
+ throw new InvalidOperationException("Invalid instance (object may have been disposed or released)");
+ }
+
+ throw new ArgumentException("Invalid parameter");
+ }
+
+ throw new InvalidOperationException(err.ToString());
+ }
+ }
+}
diff --git a/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiManager.cs b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiManager.cs
new file mode 100755
index 0000000..ed06c62
--- /dev/null
+++ b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiManager.cs
@@ -0,0 +1,378 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+using System.ComponentModel;
+
+namespace Tizen.Network.WiFi
+{
+ /// <summary>
+ /// A class for managing WiFiManager handle.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public sealed class SafeWiFiManagerHandle : SafeHandle
+ {
+ internal SafeWiFiManagerHandle() : base(IntPtr.Zero, true)
+ {
+ }
+
+ /// <summary>
+ /// Checks the validity of the handle.
+ /// </summary>
+ /// <value>Represents the validity of the handle.</value>
+ public override bool IsInvalid
+ {
+ get
+ {
+ return this.handle == IntPtr.Zero;
+ }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ Interop.WiFi.Deinitialize(this.handle);
+ this.SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+
+ /// <summary>
+ /// A manager class which allows applications to connect to a Wireless Local Area Network (WLAN) and to transfer data over the network.<br>
+ /// The Wi-Fi Manager enables your application to activate and deactivate a local Wi-Fi device, and to connect to a WLAN network in the infrastructure mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ static public class WiFiManager
+ {
+ /// <summary>
+ /// The local MAC address.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Represents the mac address of the WiFi.</value>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ static public string MacAddress
+ {
+ get
+ {
+ return WiFiManagerImpl.Instance.MacAddress;
+ }
+ }
+
+ /// <summary>
+ /// The name of the network interface.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Interface name of WiFi.</value>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ static public string InterfaceName
+ {
+ get
+ {
+ return WiFiManagerImpl.Instance.InterfaceName;
+ }
+ }
+
+ /// <summary>
+ /// The network connection state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Represents the connection state of WiFi.</value>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ static public WiFiConnectionState ConnectionState
+ {
+ get
+ {
+ return WiFiManagerImpl.Instance.ConnectionState;
+ }
+ }
+
+ /// <summary>
+ /// A property to Check whether Wi-Fi is activated.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Boolean value to check whether WiFi is activated or not.</value>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ static public bool IsActive
+ {
+ get
+ {
+ return WiFiManagerImpl.Instance.IsActive;
+ }
+ }
+
+ /// <summary>
+ /// DeviceStateChanged is raised when the device state is changed.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ static public event EventHandler<DeviceStateChangedEventArgs> DeviceStateChanged
+ {
+ add
+ {
+ WiFiManagerImpl.Instance.DeviceStateChanged += value;
+ }
+ remove
+ {
+ WiFiManagerImpl.Instance.DeviceStateChanged -= value;
+ }
+ }
+
+ /// <summary>
+ /// ConnectionStateChanged is raised when the connection state is changed.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ static public event EventHandler<ConnectionStateChangedEventArgs> ConnectionStateChanged
+ {
+ add
+ {
+ WiFiManagerImpl.Instance.ConnectionStateChanged += value;
+ }
+ remove
+ {
+ WiFiManagerImpl.Instance.ConnectionStateChanged -= value;
+ }
+ }
+
+ /// <summary>
+ /// RssiLevelChanged is raised when the RSSI of connected Wi-Fi is changed.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ static public event EventHandler<RssiLevelChangedEventArgs> RssiLevelChanged
+ {
+ add
+ {
+ WiFiManagerImpl.Instance.RssiLevelChanged += value;
+ }
+ remove
+ {
+ WiFiManagerImpl.Instance.RssiLevelChanged -= value;
+ }
+ }
+
+ /// <summary>
+ /// BackgroundScanFinished is raised when the background scan is finished.
+ /// The background scan starts automatically when wifi is activated. The callback will be invoked periodically.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ static public event EventHandler BackgroundScanFinished
+ {
+ add
+ {
+ WiFiManagerImpl.Instance.BackgroundScanFinished += value;
+ }
+ remove
+ {
+ WiFiManagerImpl.Instance.BackgroundScanFinished -= value;
+ }
+ }
+
+ /// <summary>
+ /// Gets the WiFi safe handle.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>The instance of SafeWiFiManagerHandle</returns>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static SafeWiFiManagerHandle GetWiFiHandle()
+ {
+ return WiFiManagerImpl.Instance.GetSafeHandle();
+ }
+
+ /// <summary>
+ /// Gets the result of the scan.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns> A list of WiFiAP objects.</returns>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ static public IEnumerable<WiFiAP> GetFoundAPs()
+ {
+ return WiFiManagerImpl.Instance.GetFoundAPs();
+ }
+
+ /// <summary>
+ /// Gets the result of specific AP scan.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns> A list contains the WiFiAP objects.</returns>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ static public IEnumerable<WiFiAP> GetFoundSpecificAPs()
+ {
+ return WiFiManagerImpl.Instance.GetFoundSpecificAPs();
+ }
+
+ /// <summary>
+ /// Gets the list of wifi configurations.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>A list contains the WiFiConfiguration objects.</returns>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <privilege>http://tizen.org/privilege/network.profile</privilege>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when system is out of memory.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ static public IEnumerable<WiFiConfiguration> GetWiFiConfigurations()
+ {
+ return WiFiManagerImpl.Instance.GetWiFiConfigurations();
+ }
+
+ /// <summary>
+ /// Saves Wi-Fi configuration of access point.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="configuration">The configuration to be stored</param>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <privilege>http://tizen.org/privilege/network.profile</privilege>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="ArgumentNullException">Thrown when WiFiConfiguration is passed as null.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ static public void SaveWiFiConfiguration(WiFiConfiguration configuration)
+ {
+ WiFiManagerImpl.Instance.SaveWiFiNetworkConfiguration(configuration);
+ }
+
+ /// <summary>
+ /// Gets the object of the connected WiFiAP.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns> The connected wifi access point(AP) information.</returns>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when system is out of memory.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ static public WiFiAP GetConnectedAP()
+ {
+ return WiFiManagerImpl.Instance.GetConnectedAP();
+ }
+
+ /// <summary>
+ /// Activates Wi-Fi asynchronously.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns> A task indicating whether the Activate method is done or not.</returns>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <privilege>http://tizen.org/privilege/network.set</privilege>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ static public Task ActivateAsync()
+ {
+ return WiFiManagerImpl.Instance.ActivateAsync();
+ }
+
+ /// <summary>
+ /// Activates Wi-Fi asynchronously and displays Wi-Fi picker (popup) when Wi-Fi is not automatically connected.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns> A task indicating whether the ActivateWithPicker method is done or not.</returns>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <privilege>http://tizen.org/privilege/network.set</privilege>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ static public Task ActivateWithPickerAsync()
+ {
+ return WiFiManagerImpl.Instance.ActivateWithWiFiPickerTestedAsync();
+ }
+
+ /// <summary>
+ /// Deactivates Wi-Fi asynchronously.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns> A task indicating whether the Deactivate method is done or not.</returns>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <privilege>http://tizen.org/privilege/network.set</privilege>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ static public Task DeactivateAsync()
+ {
+ return WiFiManagerImpl.Instance.DeactivateAsync();
+ }
+
+ /// <summary>
+ /// Starts scan asynchronously.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns> A task indicating whether the Scan method is done or not.</returns>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <privilege>http://tizen.org/privilege/network.set</privilege>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ static public Task ScanAsync()
+ {
+ return WiFiManagerImpl.Instance.ScanAsync();
+ }
+
+ /// <summary>
+ /// Starts specific access point scan, asynchronously.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns> A task indicating whether the ScanSpecificAP method is done or not.</returns>
+ /// <param name="essid">The essid of hidden ap</param>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <privilege>http://tizen.org/privilege/network.set</privilege>
+ /// <privilege>http://tizen.org/privilege/network.get</privilege>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
+ static public Task ScanSpecificAPAsync(string essid)
+ {
+ return WiFiManagerImpl.Instance.ScanSpecificAPAsync(essid);
+ }
+ }
+}
diff --git a/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiManagerImpl.cs b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiManagerImpl.cs
new file mode 100755
index 0000000..10865c4
--- /dev/null
+++ b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiManagerImpl.cs
@@ -0,0 +1,434 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Network.WiFi
+{
+ static internal class Globals
+ {
+ internal const string LogTag = "Tizen.Network.WiFi";
+ }
+
+ internal class HandleHolder
+ {
+ private SafeWiFiManagerHandle _handle;
+
+ internal HandleHolder()
+ {
+ _handle = WiFiManagerImpl.Instance.Initialize();
+ Log.Debug(Globals.LogTag, "Handle: " + _handle);
+ }
+
+ internal SafeWiFiManagerHandle GetSafeHandle()
+ {
+ Log.Debug(Globals.LogTag, "Handleholder safehandle = " + _handle);
+ return _handle;
+ }
+ }
+
+ internal partial class WiFiManagerImpl
+ {
+ private static WiFiManagerImpl _instance = null;
+ private Dictionary<IntPtr, Interop.WiFi.VoidCallback> _callback_map = new Dictionary<IntPtr, Interop.WiFi.VoidCallback>();
+ private int _requestId = 0;
+ private string _macAddress;
+
+ internal string MacAddress
+ {
+ get
+ {
+ if (String.IsNullOrEmpty(_macAddress))
+ {
+ string address;
+ int ret = Interop.WiFi.GetMacAddress(GetSafeHandle(), out address);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get mac address, Error - " + (WiFiError)ret);
+ _macAddress = "";
+ }
+ else
+ {
+ _macAddress = address;
+ }
+ }
+ return _macAddress;
+ }
+ }
+
+ internal string InterfaceName
+ {
+ get
+ {
+ string name;
+ int ret = Interop.WiFi.GetNetworkInterfaceName(GetSafeHandle(), out name);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get interface name, Error - " + (WiFiError)ret);
+ return "";
+ }
+ return name;
+ }
+ }
+
+ internal WiFiConnectionState ConnectionState
+ {
+ get
+ {
+ int state;
+ int ret = Interop.WiFi.GetConnectionState(GetSafeHandle(), out state);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get connection state, Error - " + (WiFiError)ret);
+ return WiFiConnectionState.Failure;
+ }
+ return (WiFiConnectionState)state;
+ }
+ }
+
+ internal bool IsActive
+ {
+ get
+ {
+ bool active;
+ int ret = Interop.WiFi.IsActive(GetSafeHandle(), out active);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get isActive, Error - " + (WiFiError)ret);
+ }
+ return active;
+ }
+ }
+
+ internal static WiFiManagerImpl Instance
+ {
+ get
+ {
+ if (_instance == null)
+ {
+ Log.Debug(Globals.LogTag, "Instance is null");
+ _instance = new WiFiManagerImpl();
+ }
+
+ return _instance;
+ }
+ }
+
+ private static ThreadLocal<HandleHolder> s_threadName = new ThreadLocal<HandleHolder>(() =>
+ {
+ Log.Info(Globals.LogTag, "In threadlocal delegate");
+ return new HandleHolder();
+ });
+
+ private WiFiManagerImpl()
+ {
+ }
+
+ internal SafeWiFiManagerHandle GetSafeHandle()
+ {
+ return s_threadName.Value.GetSafeHandle();
+ }
+
+ internal SafeWiFiManagerHandle Initialize()
+ {
+ SafeWiFiManagerHandle handle;
+ int ret = Interop.WiFi.Initialize(out handle);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to initialize wifi, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, "http://tizen.org/privilege/network.get");
+ }
+ return handle;
+ }
+
+ internal IEnumerable<WiFiAP> GetFoundAPs()
+ {
+ Log.Debug(Globals.LogTag, "GetFoundAPs");
+ List<WiFiAP> apList = new List<WiFiAP>();
+ Interop.WiFi.HandleCallback callback = (IntPtr apHandle, IntPtr userData) =>
+ {
+ if (apHandle != IntPtr.Zero)
+ {
+ IntPtr clonedHandle;
+ Interop.WiFi.AP.Clone(out clonedHandle, apHandle);
+ WiFiAP apItem = new WiFiAP(clonedHandle);
+ apList.Add(apItem);
+ return true;
+ }
+ return false;
+ };
+
+ int ret = Interop.WiFi.GetForeachFoundAPs(GetSafeHandle(), callback, IntPtr.Zero);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get all APs, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle(), "http://tizen.org/privilege/network.get");
+ }
+
+ return apList;
+ }
+
+ internal IEnumerable<WiFiAP> GetFoundSpecificAPs()
+ {
+ Log.Debug(Globals.LogTag, "GetFoundSpecificAPs");
+ List<WiFiAP> apList = new List<WiFiAP>();
+ Interop.WiFi.HandleCallback callback = (IntPtr apHandle, IntPtr userData) =>
+ {
+ if (apHandle != IntPtr.Zero)
+ {
+ IntPtr clonedHandle;
+ Interop.WiFi.AP.Clone(out clonedHandle, apHandle);
+ WiFiAP apItem = new WiFiAP(clonedHandle);
+ apList.Add(apItem);
+ return true;
+ }
+ return false;
+
+ };
+
+ int ret = Interop.WiFi.GetForeachFoundSpecificAPs(GetSafeHandle(), callback, IntPtr.Zero);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get specific APs, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle(), "http://tizen.org/privilege/network.get");
+ }
+
+ return apList;
+ }
+
+ internal IEnumerable<WiFiConfiguration> GetWiFiConfigurations()
+ {
+ Log.Debug(Globals.LogTag, "GetWiFiConfigurations");
+ List<WiFiConfiguration> configList = new List<WiFiConfiguration>();
+ Interop.WiFi.HandleCallback callback = (IntPtr configHandle, IntPtr userData) =>
+ {
+ if (configHandle != IntPtr.Zero)
+ {
+ IntPtr clonedConfig;
+ Interop.WiFi.Config.Clone(configHandle, out clonedConfig);
+ WiFiConfiguration configItem = new WiFiConfiguration(clonedConfig);
+ configList.Add(configItem);
+ return true;
+ }
+ return false;
+ };
+
+ int ret = Interop.WiFi.Config.GetForeachConfiguration(GetSafeHandle(), callback, IntPtr.Zero);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get configurations, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle(), "http://tizen.org/privilege/network.profile");
+ }
+
+ return configList;
+ }
+
+ internal void SaveWiFiNetworkConfiguration(WiFiConfiguration config)
+ {
+ Log.Debug(Globals.LogTag, "SaveWiFiNetworkConfiguration");
+ if (config == null)
+ {
+ throw new ArgumentNullException("WiFi configuration is null");
+ }
+
+ IntPtr configHandle = config.GetHandle();
+ int ret = Interop.WiFi.Config.SaveConfiguration(GetSafeHandle(), configHandle);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to save configuration, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle(), "http://tizen.org/privilege/network.profile");
+ }
+ }
+
+ internal WiFiAP GetConnectedAP()
+ {
+ Log.Debug(Globals.LogTag, "GetConnectedAP");
+ IntPtr apHandle;
+ int ret = Interop.WiFi.GetConnectedAP(GetSafeHandle(), out apHandle);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to connect with AP, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle(), "http://tizen.org/privilege/network.get");
+ }
+ WiFiAP ap = new WiFiAP(apHandle);
+ return ap;
+ }
+
+ internal Task ActivateAsync()
+ {
+ Log.Debug(Globals.LogTag, "ActivateAsync");
+ TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
+ IntPtr id;
+ lock (_callback_map)
+ {
+ id = (IntPtr)_requestId++;
+ _callback_map[id] = (error, key) =>
+ {
+ Log.Debug(Globals.LogTag, "wifi activated");
+ if (error != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Error occurs during WiFi activating, " + (WiFiError)error);
+ task.SetException(new InvalidOperationException("Error occurs during WiFi activating, " + (WiFiError)error));
+ }
+ task.SetResult(true);
+ lock (_callback_map)
+ {
+ _callback_map.Remove(key);
+ }
+ };
+ }
+ int ret = Interop.WiFi.Activate(GetSafeHandle(), _callback_map[id], id);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to activate wifi, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle());
+ }
+ return task.Task;
+ }
+
+ internal Task ActivateWithWiFiPickerTestedAsync()
+ {
+ Log.Debug(Globals.LogTag, "ActivateWithWiFiPickerTestedAsync");
+ TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
+ IntPtr id;
+ lock (_callback_map)
+ {
+ id = (IntPtr)_requestId++;
+ _callback_map[id] = (error, key) =>
+ {
+ Log.Debug(Globals.LogTag, "Activation finished");
+ if (error != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Error occurs during WiFi activating, " + (WiFiError)error);
+ task.SetException(new InvalidOperationException("Error occurs during WiFi activating, " + (WiFiError)error));
+ }
+ task.SetResult(true);
+ lock (_callback_map)
+ {
+ _callback_map.Remove(key);
+ }
+ };
+ }
+ int ret = Interop.WiFi.ActivateWithWiFiPickerTested(GetSafeHandle(), _callback_map[id], id);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to activate wifi, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle());
+ }
+ return task.Task;
+ }
+
+ internal Task DeactivateAsync()
+ {
+ Log.Debug(Globals.LogTag, "DeactivateAsync");
+ TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
+ IntPtr id;
+ lock (_callback_map)
+ {
+ id = (IntPtr)_requestId++;
+ _callback_map[id] = (error, key) =>
+ {
+ Log.Debug(Globals.LogTag, "Deactivation finished");
+ if (error != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Error occurs during WiFi deactivating, " + (WiFiError)error);
+ task.SetException(new InvalidOperationException("Error occurs during WiFi deactivating, " + (WiFiError)error));
+ }
+ task.SetResult(true);
+ lock (_callback_map)
+ {
+ _callback_map.Remove(key);
+ }
+ };
+ }
+ int ret = Interop.WiFi.Deactivate(GetSafeHandle(), _callback_map[id], id);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to deactivate wifi, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle());
+ }
+ return task.Task;
+ }
+
+ internal Task ScanAsync()
+ {
+ Log.Debug(Globals.LogTag, "ScanAsync");
+ TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
+ IntPtr id;
+ lock (_callback_map)
+ {
+ id = (IntPtr)_requestId++;
+ _callback_map[id] = (error, key) =>
+ {
+ Log.Debug(Globals.LogTag, "Scanning finished");
+ if (error != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Error occurs during WiFi scanning, " + (WiFiError)error);
+ task.SetException(new InvalidOperationException("Error occurs during WiFi scanning, " + (WiFiError)error));
+ }
+ task.SetResult(true);
+ lock (_callback_map)
+ {
+ _callback_map.Remove(key);
+ }
+ };
+ }
+ int ret = Interop.WiFi.Scan(GetSafeHandle(), _callback_map[id], id);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to scan all AP, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle());
+ }
+ return task.Task;
+ }
+
+ internal Task ScanSpecificAPAsync(string essid)
+ {
+ Log.Debug(Globals.LogTag, "ScanSpecificAPAsync " + essid);
+ TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
+ IntPtr id;
+ lock (_callback_map)
+ {
+ id = (IntPtr)_requestId++;
+ _callback_map[id] = (error, key) =>
+ {
+ Log.Debug(Globals.LogTag, "Scanning with specific AP finished");
+ if (error != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Error occurs during WiFi scanning, " + (WiFiError)error);
+ task.SetException(new InvalidOperationException("Error occurs during WiFi scanning, " + (WiFiError)error));
+ }
+ task.SetResult(true);
+ lock (_callback_map)
+ {
+ _callback_map.Remove(key);
+ }
+ };
+ }
+ int ret = Interop.WiFi.ScanSpecificAP(GetSafeHandle(), essid, _callback_map[id], id);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to scan with specific AP, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle());
+ }
+ return task.Task;
+ }
+ }
+}
diff --git a/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiNetwork.cs b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiNetwork.cs
new file mode 100755
index 0000000..8027835
--- /dev/null
+++ b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiNetwork.cs
@@ -0,0 +1,336 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Runtime.InteropServices;
+using Tizen.Network.Connection;
+
+namespace Tizen.Network.WiFi
+{
+ /// <summary>
+ /// A class for managing the Wi-Fi network information.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class WiFiNetwork
+ {
+ private Interop.WiFi.SafeWiFiAPHandle _apHandle;
+ private IAddressInformation _ipv4;
+ private IAddressInformation _ipv6;
+ private string _essid;
+
+ /// <summary>
+ /// The Extended Service Set Identifier(ESSID).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Essid of the WiFi.</value>
+ public string Essid
+ {
+ get
+ {
+ if (string.IsNullOrEmpty(_essid))
+ {
+ IntPtr strPtr;
+ int ret = Interop.WiFi.AP.GetEssid(_apHandle, out strPtr);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get essid, Error - " + (WiFiError)ret);
+ _essid = "";
+ }
+ else
+ {
+ _essid = Marshal.PtrToStringAnsi(strPtr);
+ }
+ }
+ return _essid;
+ }
+ }
+
+ /// <summary>
+ /// The Basic Service Set Identifier(BSSID).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Bssid of the WiFi.</value>
+ public string Bssid
+ {
+ get
+ {
+ IntPtr strPtr;
+ int ret = Interop.WiFi.AP.GetBssid(_apHandle, out strPtr);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get bssid, Error - " + (WiFiError)ret);
+ return "";
+ }
+ return Marshal.PtrToStringAnsi(strPtr);
+ }
+ }
+
+ /// <summary>
+ /// The address informaiton for IPv4.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>IP address information for IPv4 type.</value>
+ public IAddressInformation IPv4Setting
+ {
+ get
+ {
+ return _ipv4;
+ }
+ }
+
+ /// <summary>
+ /// The address ainformation for IPv6.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>IP address information for IPv6 type.</value>
+ public IAddressInformation IPv6Setting
+ {
+ get
+ {
+ return _ipv6;
+ }
+ }
+
+ /// <summary>
+ /// The proxy address.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Represents proxy address of WiFi.</value>
+ /// <exception cref="NotSupportedException">Thrown while setting this property when WiFi is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown while setting this property due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown while setting this value due to invalid operation.</exception>
+ public string ProxyAddress
+ {
+ get
+ {
+ IntPtr strPtr;
+ int ret = Interop.WiFi.AP.GetProxyAddress(_apHandle, (int)AddressFamily.IPv4, out strPtr);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get proxy address, Error - " + (WiFiError)ret);
+ return "";
+ }
+ return Marshal.PtrToStringAnsi(strPtr);
+ }
+ set
+ {
+ int ret = Interop.WiFi.AP.SetProxyAddress(_apHandle, (int)AddressFamily.IPv4, value);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set proxy address, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _apHandle.DangerousGetHandle());
+ }
+ }
+ }
+
+ /// <summary>
+ /// The proxy type(IPv6).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Represents proxy type of WiFi.</value>
+ /// <exception cref="NotSupportedException">Thrown while setting this property when WiFi is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown while setting this property due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown while setting this value due to invalid operation.</exception>
+ public WiFiProxyType ProxyType
+ {
+ get
+ {
+ int type;
+ int ret = Interop.WiFi.AP.GetProxyType(_apHandle, out type);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get proxy type, Error - " + (WiFiError)ret);
+ }
+ return (WiFiProxyType)type;
+ }
+ set
+ {
+ int ret = Interop.WiFi.AP.SetProxyType(_apHandle, (int)value);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set proxy type, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _apHandle.DangerousGetHandle());
+ }
+ }
+ }
+
+ /// <summary>
+ /// The frequency band(MHz).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Represents the frequency band value.</value>
+ public int Frequency
+ {
+ get
+ {
+ int freq;
+ int ret = Interop.WiFi.AP.GetFrequency(_apHandle, out freq);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get frequency, Error - " + (WiFiError)ret);
+ }
+ return freq;
+ }
+ }
+
+ /// <summary>
+ /// The Received signal strength indication(RSSI).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Represents Rssi level of WiFi.</value>
+ public WiFiRssiLevel Rssi
+ {
+ get
+ {
+ int rssi;
+ int ret = Interop.WiFi.AP.GetRssi(_apHandle, out rssi);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get rssi, Error - " + (WiFiError)ret);
+ }
+ return (WiFiRssiLevel)rssi;
+ }
+ }
+
+ /// <summary>
+ /// The max speed (Mbps).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Represents max speed value.</value>
+ public int MaxSpeed
+ {
+ get
+ {
+ int maxSpeed;
+ int ret = Interop.WiFi.AP.GetMaxSpeed(_apHandle, out maxSpeed);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get max speed, Error - " + (WiFiError)ret);
+ }
+ return maxSpeed;
+ }
+ }
+
+ /// <summary>
+ /// A property to check whether the access point is favorite or not.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Boolean value to check if the access point is favorite or not.</value>
+ public bool IsFavorite
+ {
+ get
+ {
+ bool isFavorite;
+ int ret = Interop.WiFi.AP.IsFavorite(_apHandle, out isFavorite);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get favorite, Error - " + (WiFiError)ret);
+ }
+ return isFavorite;
+ }
+ }
+
+ /// <summary>
+ /// A property to check whether the access point is passpoint or not.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Boolean value to check if the access point is passpoint or not.</value>
+ public bool IsPasspoint
+ {
+ get
+ {
+ bool isPasspoint;
+ Log.Debug(Globals.LogTag, "Handle: " + _apHandle);
+ int ret = Interop.WiFi.AP.IsPasspoint(_apHandle, out isPasspoint);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get isPassport, Error - " + (WiFiError)ret);
+ }
+ return isPasspoint;
+ }
+ }
+
+ /// <summary>
+ /// The connection state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Represents the connection state of WiFi.</value>
+ public WiFiConnectionState ConnectionState
+ {
+ get
+ {
+ int state;
+ int ret = Interop.WiFi.AP.GetConnectionState(_apHandle, out state);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get connection state, Error - " + (WiFiError)ret);
+ }
+ return (WiFiConnectionState)state;
+ }
+ }
+
+ /// <summary>
+ /// Gets the all IPv6 addresses of the access point
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>A list of IPv6 addresses of the access point.</returns>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
+ public IEnumerable<System.Net.IPAddress> GetAllIPv6Addresses()
+ {
+ Log.Debug(Globals.LogTag, "GetAllIPv6Addresses");
+ List<System.Net.IPAddress> ipList = new List<System.Net.IPAddress>();
+ Interop.WiFi.HandleCallback callback = (IntPtr ipv6Address, IntPtr userData) =>
+ {
+ if (ipv6Address != IntPtr.Zero)
+ {
+ string ipv6 = Marshal.PtrToStringAnsi(ipv6Address);
+ ipList.Add(System.Net.IPAddress.Parse(ipv6));
+ return true;
+ }
+ return false;
+ };
+
+ int ret = Interop.WiFi.AP.GetAllIPv6Addresses(_apHandle, callback, IntPtr.Zero);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get all IPv6 addresses, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _apHandle.DangerousGetHandle());
+ }
+
+ return ipList;
+ }
+
+ internal WiFiNetwork(Interop.WiFi.SafeWiFiAPHandle apHandle)
+ {
+ _apHandle = apHandle;
+ _ipv4 = new WiFiAddressInformation(apHandle, AddressFamily.IPv4);
+ _ipv6 = new WiFiAddressInformation(apHandle, AddressFamily.IPv6);
+
+ IntPtr strPtr;
+ int ret = Interop.WiFi.AP.GetEssid(_apHandle, out strPtr);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get essid, Error - " + (WiFiError)ret);
+ }
+ _essid = Marshal.PtrToStringAnsi(strPtr);
+ }
+ } //WiFiNetworkInformation
+}
diff --git a/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiNetworkChange.cs b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiNetworkChange.cs
new file mode 100755
index 0000000..ac1eabf
--- /dev/null
+++ b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiNetworkChange.cs
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Threading.Tasks;
+
+namespace Tizen.Network.WiFi
+{
+ internal static class EventHandlerExtension
+ {
+ internal static void SafeInvoke(this EventHandler evt, object sender, EventArgs e)
+ {
+ var handler = evt;
+ if (handler != null)
+ {
+ handler(sender, e);
+ }
+ }
+
+ internal static void SafeInvoke<T>(this EventHandler<T> evt, object sender, T e) where T : EventArgs
+ {
+ var handler = evt;
+ if (handler != null)
+ {
+ handler(sender, e);
+ }
+ }
+ }
+
+ internal partial class WiFiManagerImpl
+ {
+ private event EventHandler<DeviceStateChangedEventArgs> _deviceStateChanged;
+ private event EventHandler<ConnectionStateChangedEventArgs> _connectionStateChanged;
+ private event EventHandler<RssiLevelChangedEventArgs> _rssiLevelChanged;
+ private event EventHandler _backgroundScanFinished;
+
+ private Interop.WiFi.DeviceStateChangedCallback _deviceChangedCallback;
+ private Interop.WiFi.ConnectionStateChangedCallback _connectionChangedCallback;
+ private Interop.WiFi.RssiLevelChangedCallback _rssiChangedCallback;
+ private Interop.WiFi.VoidCallback _backgroundScanFinishedCallback;
+
+ internal event EventHandler<DeviceStateChangedEventArgs> DeviceStateChanged
+ {
+ add
+ {
+ if (_deviceStateChanged == null)
+ {
+ RegisterDeviceStateChangedEvent();
+ }
+ _deviceStateChanged += value;
+ }
+ remove
+ {
+ _deviceStateChanged -= value;
+ if (_deviceStateChanged == null)
+ {
+ UnregisterDeviceStateChangedEvent();
+ }
+ }
+ }
+
+ internal event EventHandler<ConnectionStateChangedEventArgs> ConnectionStateChanged
+ {
+ add
+ {
+ if (_connectionStateChanged == null)
+ {
+ RegisterConnectionStateChangedEvent();
+ }
+ _connectionStateChanged += value;
+ }
+ remove
+ {
+ _connectionStateChanged -= value;
+ if (_connectionStateChanged == null)
+ {
+ UnregisterConnectionStateChangedEvent();
+ }
+ }
+ }
+
+ internal event EventHandler<RssiLevelChangedEventArgs> RssiLevelChanged
+ {
+ add
+ {
+ if (_rssiLevelChanged == null)
+ {
+ RegisterRssiLevelChangedEvent();
+ }
+ _rssiLevelChanged += value;
+ }
+ remove
+ {
+ _rssiLevelChanged -= value;
+ if (_rssiLevelChanged == null)
+ {
+ UnregisterRssiLevelChangedEvent();
+ }
+ }
+ }
+
+ internal event EventHandler BackgroundScanFinished
+ {
+ add
+ {
+ if (_backgroundScanFinished == null)
+ {
+ RegisterBackgroundScanFinishedEvent();
+ }
+ _backgroundScanFinished += value;
+ }
+ remove
+ {
+ _backgroundScanFinished -= value;
+ if (_backgroundScanFinished == null)
+ {
+ UnregisterBackgroundScanFinishedEvent();
+ }
+ }
+ }
+
+ private void RegisterDeviceStateChangedEvent()
+ {
+ _deviceChangedCallback = (int deviceState, IntPtr userDate) =>
+ {
+ WiFiDeviceState state = (WiFiDeviceState)deviceState;
+ DeviceStateChangedEventArgs e = new DeviceStateChangedEventArgs(state);
+ _deviceStateChanged.SafeInvoke(null, e);
+ };
+ int ret = Interop.WiFi.SetDeviceStateChangedCallback(GetSafeHandle(), _deviceChangedCallback, IntPtr.Zero);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set device state changed callback, Error - " + (WiFiError)ret);
+ }
+ }
+
+ private void UnregisterDeviceStateChangedEvent()
+ {
+ int ret = Interop.WiFi.UnsetDeviceStateChangedCallback(GetSafeHandle());
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset device state changed callback, Error - " + (WiFiError)ret);
+ }
+ }
+
+ private void RegisterConnectionStateChangedEvent()
+ {
+ _connectionChangedCallback = (int connectionState, IntPtr ap, IntPtr userData) =>
+ {
+ if (ap != IntPtr.Zero)
+ {
+ WiFiConnectionState state = (WiFiConnectionState)connectionState;
+ ConnectionStateChangedEventArgs e = new ConnectionStateChangedEventArgs(state, ap);
+ _connectionStateChanged.SafeInvoke(null, e);
+ }
+ };
+ int ret = Interop.WiFi.SetConnectionStateChangedCallback(GetSafeHandle(), _connectionChangedCallback, IntPtr.Zero);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set copnnection state changed callback, Error - " + (WiFiError)ret);
+ }
+ }
+
+ private void UnregisterConnectionStateChangedEvent()
+ {
+ int ret = Interop.WiFi.UnsetConnectionStateChangedCallback(GetSafeHandle());
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset device state changed callback, Error - " + (WiFiError)ret);
+ }
+ }
+
+ private void RegisterRssiLevelChangedEvent()
+ {
+
+ _rssiChangedCallback = (int rssiLevel, IntPtr userDate) =>
+ {
+ WiFiRssiLevel level = (WiFiRssiLevel)rssiLevel;
+ RssiLevelChangedEventArgs e = new RssiLevelChangedEventArgs(level);
+ _rssiLevelChanged.SafeInvoke(null, e);
+ };
+ int ret = Interop.WiFi.SetRssiLevelchangedCallback(GetSafeHandle(), _rssiChangedCallback, IntPtr.Zero);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set rssi level changed callback, Error - " + (WiFiError)ret);
+ }
+ }
+
+ private void UnregisterRssiLevelChangedEvent()
+ {
+ int ret = Interop.WiFi.UnsetRssiLevelchangedCallback(GetSafeHandle());
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset rssi level changed callback, Error - " + (WiFiError)ret);
+ }
+ }
+
+ private void RegisterBackgroundScanFinishedEvent()
+ {
+ _backgroundScanFinishedCallback = (int result, IntPtr userDate) =>
+ {
+ EventArgs e = new EventArgs();
+ _backgroundScanFinished.SafeInvoke(null, e);
+ };
+ int ret = Interop.WiFi.SetBackgroundScanCallback(GetSafeHandle(), _backgroundScanFinishedCallback, IntPtr.Zero);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set background scan callback, Error - " + (WiFiError)ret);
+ }
+ }
+
+ private void UnregisterBackgroundScanFinishedEvent()
+ {
+ int ret = Interop.WiFi.UnsetBackgroundScanCallback(GetSafeHandle());
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset background scan callback, Error - " + (WiFiError)ret);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiSecurity.cs b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiSecurity.cs
new file mode 100755
index 0000000..9f3451c
--- /dev/null
+++ b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiSecurity.cs
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Tizen.Network.Connection;
+
+namespace Tizen.Network.WiFi
+{
+ /// <summary>
+ /// A class for managing the WiFi security information.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class WiFiSecurity
+ {
+ private Interop.WiFi.SafeWiFiAPHandle _apHandle;
+ private WiFiEap _eap;
+
+ /// <summary>
+ /// The type of Wi-Fi security.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Represents the security type of WiFi.</value>
+ /// <exception cref="NotSupportedException">Thrown while setting this property when WiFi is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown while setting this property due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown while setting this value due to invalid operation.</exception>
+ public WiFiSecurityType SecurityType
+ {
+ get
+ {
+ int type;
+ int ret = Interop.WiFi.AP.GetSecurityType(_apHandle, out type);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get security type, Error - " + (WiFiError)ret);
+ }
+ return (WiFiSecurityType)type;
+ }
+ set
+ {
+ int ret = Interop.WiFi.AP.SetSecurityType(_apHandle, (int)value);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set security type, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _apHandle.DangerousGetHandle());
+ }
+ }
+ }
+
+ /// <summary>
+ /// The type of Wi-Fi encryption
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Represents the encryption type of WiFi.</value>
+ /// <exception cref="NotSupportedException">Thrown while setting this property when WiFi is not supported.</exception>
+ /// <exception cref="ArgumentException">Thrown while setting this property due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown while setting this value due to invalid operation.</exception>
+ public WiFiEncryptionType EncryptionType
+ {
+ get
+ {
+ int type;
+ int ret = Interop.WiFi.AP.GetEncryptionType(_apHandle, out type);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get encryption type, Error - " + (WiFiError)ret);
+ }
+ return (WiFiEncryptionType)type;
+ }
+ set
+ {
+ int ret = Interop.WiFi.AP.SetEncryptionType(_apHandle, (int)value);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set encryption type, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _apHandle.DangerousGetHandle());
+ }
+ }
+ }
+
+ /// <summary>
+ /// The EAP information
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Eap information of WiFi.</value>
+ public WiFiEap EapInformation
+ {
+ get
+ {
+ return _eap;
+ }
+ }
+
+ /// <summary>
+ /// A property to check whether the passphrase is required or not.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Boolean value to check if passphrase is required or not.</value>
+ public bool IsPassphraseRequired
+ {
+ get
+ {
+ bool required;
+ int ret = Interop.WiFi.AP.IsPassphraseRequired(_apHandle, out required);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get isPassportRequired, Error - " + (WiFiError)ret);
+ }
+ return required;
+ }
+ }
+
+ /// <summary>
+ /// A property to check whether the Wi-Fi Protected Setup(WPS) is supported or not.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>Boolean value to check if wps is supported or not.</value>
+ public bool IsWpsSupported
+ {
+ get
+ {
+ bool supported;
+ int ret = Interop.WiFi.AP.IsWpsSupported(_apHandle, out supported);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get isWapSupported, Error - " + (WiFiError)ret);
+ }
+ return supported;
+ }
+ }
+
+ internal WiFiSecurity(Interop.WiFi.SafeWiFiAPHandle apHandle)
+ {
+ _apHandle = apHandle;
+ _eap = new WiFiEap(apHandle);
+ }
+
+ /// <summary>
+ /// Sets the passphrase.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="passphrase">The passphrase of the access point.</param>
+ /// <feature>http://tizen.org/feature/network.wifi</feature>
+ /// <exception cref="NotSupportedException">Thrown when WiFi is not supported.</exception>
+ /// <exception cref="ArgumentNullException">Thrown when passphrase is passed as null.</exception>
+ /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
+ public void SetPassphrase(string passphrase)
+ {
+ if (passphrase == null)
+ {
+ throw new ArgumentNullException("Passphrase is null");
+ }
+ int ret = Interop.WiFi.AP.SetPassphrase(_apHandle, passphrase);
+ if (ret != (int)WiFiError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set passphrase, Error - " + (WiFiError)ret);
+ WiFiErrorFactory.ThrowWiFiException(ret, _apHandle.DangerousGetHandle());
+ }
+ }
+ } //WiFiSecurityInformation
+}
diff --git a/src/Tizen.Network.WiFiDirect/Interop/Interop.Libraries.cs b/src/Tizen.Network.WiFiDirect/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..c036d47
--- /dev/null
+++ b/src/Tizen.Network.WiFiDirect/Interop/Interop.Libraries.cs
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string WiFiDirect = "libwifi-direct.so.1";
+ public const string Glib = "libglib-2.0.so.0";
+ public const string Libc = "libc.so.6";
+ }
+}
diff --git a/src/Tizen.Network.WiFiDirect/Interop/Interop.WiFiDirect.cs b/src/Tizen.Network.WiFiDirect/Interop/Interop.WiFiDirect.cs
new file mode 100644
index 0000000..3f68798
--- /dev/null
+++ b/src/Tizen.Network.WiFiDirect/Interop/Interop.WiFiDirect.cs
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Tizen.Network.WiFiDirect;
+using System.Runtime.InteropServices;
+
+/// <summary>
+/// Interop class for Wi-Fi Direct
+/// </summary>
+internal static partial class Interop
+{
+ /// <summary>
+ /// Wi-Fi Direct Native Apis
+ /// </summary>
+ internal static partial class WiFiDirect
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void DiscoveryStateChangedCallback(int result, WiFiDirectDiscoveryState state, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void PeerFoundCallback(int result, WiFiDirectDiscoveryState state, string address, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void DeviceStateChangedCallback(int result, WiFiDirectDeviceState state, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ConnectionStateChangedCallback(int result, WiFiDirectConnectionState state, string address, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ClientIpAddressAssignedCallback(string macAddress, string ipAddress, string interfaceAddress, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ServiceStateChangedCallback(int result, WiFiDirectServiceDiscoveryState state, WiFiDirectServiceType type, IntPtr responseData, string address, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void StateChangedCallback(WiFiDirectState state, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool DiscoveredPeerCallback(ref DiscoveredPeerStruct peer, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool ConnectedPeerCallback(ref ConnectedPeerStruct peer, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool WpsTypeCallback(WiFiDirectWpsType type, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool PersistentGroupCallback(string address, string ssid, IntPtr userData);
+
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_set_state_changed_cb")]
+ internal static extern int SetStateChangedCallback(StateChangedCallback stateChangedCb, IntPtr userData);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_unset_state_changed_cb")]
+ internal static extern int UnsetStateChangedCallback();
+
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_set_device_state_changed_cb")]
+ internal static extern int SetDeviceStateChangedCallback(DeviceStateChangedCallback deviceChangedCb, IntPtr userData);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_unset_device_state_changed_cb")]
+ internal static extern int UnsetDeviceStateChangedCallback();
+
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_set_discovery_state_changed_cb")]
+ internal static extern int SetDiscoveryStateChangedCallback(DiscoveryStateChangedCallback discoveryStateChangedCb, IntPtr userData);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_unset_discovery_state_changed_cb")]
+ internal static extern int UnsetDiscoveryStateChangedCallback();
+
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_set_peer_found_cb")]
+ internal static extern int SetPeerFoundCallback(PeerFoundCallback peerFoundCb, IntPtr userData);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_unset_peer_found_cb")]
+ internal static extern int UnsetPeerFoundCallback();
+
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_set_connection_state_changed_cb")]
+ internal static extern int SetConnectionChangedCallback(ConnectionStateChangedCallback connectionCb, IntPtr userData);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_unset_connection_state_changed_cb")]
+ internal static extern int UnsetConnectionChangedCallback();
+
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_set_client_ip_address_assigned_cb")]
+ internal static extern int SetIpAddressAssignedCallback(ClientIpAddressAssignedCallback callback, IntPtr userData);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_unset_client_ip_address_assigned_cb")]
+ internal static extern int UnsetIpAddressAssignedCallback();
+
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_set_service_state_changed_cb")]
+ internal static extern int SetServiceStateChangedCallback(ServiceStateChangedCallback serviceStateChangedCb, IntPtr userData);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_unset_service_state_changed_cb")]
+ internal static extern int UnsetServiceStateChangedCallback();
+
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_initialize")]
+ internal static extern int Initialize();
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_deinitialize")]
+ internal static extern int Deinitialize();
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_activate")]
+ internal static extern int Activate();
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_deactivate")]
+ internal static extern int Deactivate();
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_start_discovery_specific_channel")]
+ internal static extern int StartDiscoveryInChannel(bool listenOnly, int timeout, WiFiDirectDiscoveryChannel channel);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_cancel_discovery")]
+ internal static extern int StopDiscovery();
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_foreach_discovered_peers")]
+ internal static extern int GetDiscoveredPeers(DiscoveredPeerCallback callback, IntPtr userData);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_connect")]
+ internal static extern int Connect(string address);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_cancel_connection")]
+ internal static extern int CancelConnection(string address);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_disconnect_all")]
+ internal static extern int DisconnectAll();
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_disconnect")]
+ internal static extern int Disconnect(string address);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_foreach_connected_peers")]
+ internal static extern int GetConnectedPeers(ConnectedPeerCallback callback, IntPtr userData);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_create_group")]
+ internal static extern int CreateGroup();
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_destroy_group")]
+ internal static extern int DestroyGroup();
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_is_group_owner")]
+ internal static extern int IsGroupOwner(out bool isGroupOwner);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_is_autonomous_group")]
+ internal static extern int IsAutonomousGroup(out bool isAutonomous);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_set_device_name")]
+ internal static extern int SetName(string name);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_get_device_name")]
+ internal static extern int GetName(out string name);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_get_ssid")]
+ internal static extern int GetSsid(out string ssid);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_get_network_interface_name")]
+ internal static extern int GetInterfaceName(out string name);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_get_ip_address")]
+ internal static extern int GetIpAddress(out string address);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_get_subnet_mask")]
+ internal static extern int GetSubnetMask(out string mask);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_get_gateway_address")]
+ internal static extern int GetGatewayAddress(out string address);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_get_mac_address")]
+ internal static extern int GetMacAddress(out string address);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_get_state")]
+ internal static extern int GetState(out WiFiDirectState state);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_is_discoverable")]
+ internal static extern int IsDiscoverable(out bool isDiscoverable);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_is_listening_only")]
+ internal static extern int IsListeningOnly(out bool listenOnly);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_get_primary_device_type")]
+ internal static extern int GetPrimaryType(out WiFiDirectPrimaryDeviceType type);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_get_secondary_device_type")]
+ internal static extern int GetSecondaryType(out WiFiDirectSecondaryDeviceType type);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_activate_pushbutton")]
+ internal static extern int ActivatePushButton();
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_set_wps_pin")]
+ internal static extern int SetWpsPin(string pin);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_get_wps_pin")]
+ internal static extern int GetWpsPin(out string pin);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_get_supported_wps_mode")]
+ internal static extern int GetWpsMode(out int mode);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_foreach_supported_wps_types")]
+ internal static extern int GetWpsTypes(WpsTypeCallback callback, IntPtr userData);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_get_local_wps_type")]
+ internal static extern int GetLocalWpsType(out WiFiDirectWpsType type);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_set_req_wps_type")]
+ internal static extern int SetReqWpsType(WiFiDirectWpsType type);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_get_req_wps_type")]
+ internal static extern int GetReqWpsType(out WiFiDirectWpsType type);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_set_group_owner_intent")]
+ internal static extern int SetIntent(int intent);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_get_group_owner_intent")]
+ internal static extern int GetIntent(out int intent);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_set_max_clients")]
+ internal static extern int SetMaxClients(int max);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_get_max_clients")]
+ internal static extern int GetMaxClients(out int max);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_set_passphrase")]
+ internal static extern int SetPassPhrase(string passphrase);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_get_passphrase")]
+ internal static extern int GetPassPhrase(out string passphrase);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_get_operating_channel")]
+ internal static extern int GetChannel(out int channel);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_set_autoconnection_mode")]
+ internal static extern int SetAutoConnectionMode(bool mode);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_is_autoconnection_mode")]
+ internal static extern int GetAutoConnectionMode(out bool mode);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_set_autoconnection_peer")]
+ internal static extern int SetAutoConnectionPeer(string address);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_set_persistent_group_enabled")]
+ internal static extern int SetPersistentGroupState(bool enabled);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_is_persistent_group_enabled")]
+ internal static extern int GetPersistentGroupState(out bool enabled);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_foreach_persistent_groups")]
+ internal static extern int GetPersistentGroups(PersistentGroupCallback callback, IntPtr userData);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_remove_persistent_group")]
+ internal static extern int RemovePersistentGroup(string address, string ssid);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_start_service_discovery")]
+ internal static extern int StartServiceDiscovery(string address, WiFiDirectServiceType type);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_cancel_service_discovery")]
+ internal static extern int StopServiceDiscovery(string address, WiFiDirectServiceType type);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_register_service")]
+ internal static extern int RegisterService(WiFiDirectServiceType type, string info1, string info2, out uint serviceId);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_deregister_service")]
+ internal static extern int DeregisterService(uint serviceId);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_init_miracast")]
+ internal static extern int InitMiracast(bool enable);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_get_peer_info")]
+ internal static extern int GetDiscoveredPeerInfo(string address, out IntPtr peer);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_init_display")]
+ internal static extern int InitDisplay();
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_deinit_display")]
+ internal static extern int DeinitDisplay();
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_set_display")]
+ internal static extern int SetDisplay(WiFiDirectDisplayType type, int port, int hdcp);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_set_display_availability")]
+ internal static extern int SetDisplayAvailability(bool availability);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_get_peer_display_type")]
+ internal static extern int GetDisplayType(string address, out WiFiDirectDisplayType type);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_get_peer_display_availability")]
+ internal static extern int GetDisplayAvailability(string address, out bool availability);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_get_peer_display_hdcp")]
+ internal static extern int GetDisplayHdcp(string address, out int hdcp);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_get_peer_display_port")]
+ internal static extern int GetDisplayPort(string address, out int port);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_get_peer_display_throughput")]
+ internal static extern int GetDisplayThroughput(string address, out int throughput);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_get_peer_rssi")]
+ internal static extern int GetRssi(string address, out int rssi);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_get_session_timer")]
+ internal static extern int GetSessionTimer(out int seconds);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_set_session_timer")]
+ internal static extern int SetSessionTimer(int seconds);
+ [DllImport(Libraries.WiFiDirect,EntryPoint = "wifi_direct_set_auto_group_removal")]
+ internal static extern int SetAutoGroupRemoval(bool enable);
+ }
+}
diff --git a/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect.csproj b/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect.csproj
new file mode 100644
index 0000000..24940b4
--- /dev/null
+++ b/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect.csproj
@@ -0,0 +1,19 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <PackageReference Include="System.Threading.Thread" Version="$(SystemPackageVersion)" PrivateAssets="All" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
+
diff --git a/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/NamespaceDoc.cs b/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/NamespaceDoc.cs
new file mode 100644
index 0000000..3052502
--- /dev/null
+++ b/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/NamespaceDoc.cs
@@ -0,0 +1,7 @@
+/**
+<summary>
+The Tizen.Network.WiFiDirect namespace provides classes to manage the settings of Wi-Fi Direct.
+In addition, this namespace provides classes to connect and disconnect remote devices using Wi-Fi Direct.
+</summary>
+*/
+namespace Tizen.Network.WiFiDirect {}
diff --git a/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectData.cs b/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectData.cs
new file mode 100644
index 0000000..a40a808
--- /dev/null
+++ b/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectData.cs
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.ObjectModel;
+
+namespace Tizen.Network.WiFiDirect
+{
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct DiscoveredPeerStruct
+ {
+ [MarshalAsAttribute(UnmanagedType.LPStr)]
+ internal string _name;
+
+ [MarshalAsAttribute(UnmanagedType.LPStr)]
+ internal string _macAddress;
+
+ [MarshalAsAttribute(UnmanagedType.LPStr)]
+ internal string _interfaceAddress;
+
+ internal int _channel;
+
+ [MarshalAsAttribute(UnmanagedType.I1)]
+ internal bool _isConnected;
+
+ [MarshalAsAttribute(UnmanagedType.I1)]
+ internal bool _isGroupOwner;
+
+ internal WiFiDirectPrimaryDeviceType _primaryType;
+
+ internal WiFiDirectSecondaryDeviceType _secondaryType;
+
+ internal int _wpsTypes;
+
+ [MarshalAsAttribute(UnmanagedType.I1)]
+ internal bool _isP2PInvitationSupported;
+
+ internal uint _serviceCount;
+
+ internal IntPtr _serviceList;
+
+ [MarshalAsAttribute(UnmanagedType.I1)]
+ internal bool _isMiracast;
+ }
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct ConnectedPeerStruct
+ {
+ [MarshalAsAttribute(UnmanagedType.LPStr)]
+ internal string _name;
+
+ [MarshalAsAttribute(UnmanagedType.LPStr)]
+ internal string _ipAddress;
+
+ [MarshalAsAttribute(UnmanagedType.LPStr)]
+ internal string _macAddress;
+
+ [MarshalAsAttribute(UnmanagedType.LPStr)]
+ internal string _interfaceAddress;
+
+ internal int _channel;
+
+ [MarshalAsAttribute(UnmanagedType.I1)]
+ internal bool _isP2PSupport;
+
+ internal WiFiDirectPrimaryDeviceType _primaryType;
+
+ internal WiFiDirectSecondaryDeviceType _secondaryType;
+
+ internal uint _serviceCount;
+
+ internal IntPtr _serviceList;
+
+ [MarshalAsAttribute(UnmanagedType.I1)]
+ internal bool _isMiracast;
+ }
+
+ internal static class WiFiDirectUtils
+ {
+ internal static WiFiDirectPeer ConvertStructToDiscoveredPeer(DiscoveredPeerStruct peer)
+ {
+ WiFiDirectPeer resultPeer = new WiFiDirectPeer();
+ resultPeer._peerDeviceName = peer._name;
+ resultPeer._peerMacAddress = peer._macAddress;
+ resultPeer._peerInterfaceAddress = peer._interfaceAddress;
+ resultPeer._peerChannel = peer._channel;
+ resultPeer._isPeerConnected = peer._isConnected;
+ resultPeer._isPeerGroupOwner = peer._isGroupOwner;
+ resultPeer._peerPrimaryType = peer._primaryType;
+ resultPeer._peerSecondaryType = peer._secondaryType;
+ resultPeer._peerWpsTypes = peer._wpsTypes;
+ resultPeer._p2PInvitationSupported = peer._isP2PInvitationSupported;
+ Collection<string> uuidList = null;
+
+ if (peer._serviceCount > 0)
+ {
+ IntPtr[] serviceList = new IntPtr[peer._serviceCount];
+ Marshal.Copy(peer._serviceList, serviceList, 0, (int)peer._serviceCount);
+ uuidList = new Collection<string>();
+ foreach (IntPtr service in serviceList)
+ {
+ string registeredService = Marshal.PtrToStringAnsi(service);
+ uuidList.Add(registeredService);
+ }
+
+ resultPeer._peerServiceCount = peer._serviceCount;
+ resultPeer._peerServiceList = uuidList;
+ }
+
+ resultPeer._isPeerMiracastDevice = peer._isMiracast;
+ return resultPeer;
+ }
+
+ internal static WiFiDirectPeer ConvertStructToConnectedPeer(ConnectedPeerStruct peer)
+ {
+ WiFiDirectPeer resultPeer = new WiFiDirectPeer();
+ resultPeer._peerDeviceName = peer._name;
+ resultPeer._peerIpAddress = peer._ipAddress;
+ resultPeer._peerMacAddress = peer._macAddress;
+ resultPeer._peerInterfaceAddress = peer._interfaceAddress;
+ resultPeer._peerChannel = peer._channel;
+ resultPeer._peerP2PSupport = peer._isP2PSupport;
+ resultPeer._peerPrimaryType = peer._primaryType;
+ resultPeer._peerSecondaryType = peer._secondaryType;
+ Collection<string> uuidList = null;
+
+ if (peer._serviceCount > 0)
+ {
+ IntPtr[] serviceList = new IntPtr[peer._serviceCount];
+ Marshal.Copy(peer._serviceList, serviceList, 0, (int)peer._serviceCount);
+ uuidList = new Collection<string>();
+ foreach (IntPtr service in serviceList)
+ {
+ string registeredService = Marshal.PtrToStringAnsi(service);
+ uuidList.Add(registeredService);
+ }
+
+ resultPeer._peerServiceCount = peer._serviceCount;
+ resultPeer._peerServiceList = uuidList;
+ }
+
+ resultPeer._isPeerMiracastDevice = peer._isMiracast;
+ return resultPeer;
+ }
+ }
+
+}
diff --git a/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectEnumerations.cs b/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectEnumerations.cs
new file mode 100644
index 0000000..12461d2
--- /dev/null
+++ b/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectEnumerations.cs
@@ -0,0 +1,649 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Network.WiFiDirect
+{
+ /// <summary>
+ /// Enumeration for Wi-Fi Direct discovery state.
+ /// </summary>
+ public enum WiFiDirectDiscoveryState
+ {
+ /// <summary>
+ /// Only listen has started.
+ /// </summary>
+ OnlyListenStarted = 0,
+ /// <summary>
+ /// Discovery started.
+ /// </summary>
+ Started,
+ /// <summary>
+ /// A remote peer is found.
+ /// </summary>
+ Found,
+ /// <summary>
+ /// Discovery finished.
+ /// </summary>
+ Finished,
+ /// <summary>
+ /// A remote peer is lost.
+ /// </summary>
+ Lost
+ }
+
+ /// <summary>
+ /// Enumeration for Wi-Fi Direct display device type.
+ /// </summary>
+ public enum WiFiDirectDisplayType
+ {
+ /// <summary>
+ /// Configure as WFD source.
+ /// </summary>
+ Source = 0,
+ /// <summary>
+ /// Configure as WFD primary sink.
+ /// </summary>
+ Prisink,
+ /// <summary>
+ /// Configure as WFD secondary sink.
+ /// </summary>
+ Secsink,
+ /// <summary>
+ /// Configure as WFD dual role.
+ /// </summary>
+ Dual
+ }
+
+ /// <summary>
+ /// Enumeration for Wi-Fi Discovery channel.
+ /// </summary>
+ public enum WiFiDirectDiscoveryChannel
+ {
+ /// <summary>
+ /// Scan full channel.
+ /// </summary>
+ FullScan = 0,
+ /// <summary>
+ /// The social channel.
+ /// </summary>
+ SocialChannel = 1611,
+ /// <summary>
+ /// Scan channel 1.
+ /// </summary>
+ Channel1 = 1,
+ /// <summary>
+ /// Scan channel 6.
+ /// </summary>
+ Channel6 = 6,
+ /// <summary>
+ /// Scan channel 11.
+ /// </summary>
+ Channel11 = 11
+ }
+
+ /// <summary>
+ /// Enumeration for Wi-Fi Direct connection state.
+ /// </summary>
+ public enum WiFiDirectConnectionState
+ {
+ /// <summary>
+ /// Connection is requested.
+ /// </summary>
+ ConnectionRequest,
+ /// <summary>
+ /// Wps is requested.
+ /// </summary>
+ ConnectionWpsRequest,
+ /// <summary>
+ /// Connection in progress.
+ /// </summary>
+ ConnectionInProgress,
+ /// <summary>
+ /// Connected .
+ /// </summary>
+ ConnectionRsp,
+ /// <summary>
+ /// Disconnected by remote group client.
+ /// </summary>
+ DisassociationInd,
+ /// <summary>
+ /// Disconnected by local device.
+ /// </summary>
+ DisconnectRsp,
+ /// <summary>
+ /// Disconnected by remote group owner.
+ /// </summary>
+ DisconnectInd,
+ /// <summary>
+ /// Group is created.
+ /// </summary>
+ GroupCreated,
+ /// <summary>
+ /// Group is destroyed.
+ /// </summary>
+ GroupDestroyed
+ }
+
+ /// <summary>
+ /// Enumeration for Wi-Fi Direct primary device type.
+ /// </summary>
+ public enum WiFiDirectPrimaryDeviceType
+ {
+ /// <summary>
+ /// Computer.
+ /// </summary>
+ Computer = 1,
+ /// <summary>
+ /// Input device.
+ /// </summary>
+ InputDevice = 2,
+ /// <summary>
+ /// Printer.
+ /// </summary>
+ Printer = 3,
+ /// <summary>
+ /// Camera.
+ /// </summary>
+ Camera = 4,
+ /// <summary>
+ /// Storage.
+ /// </summary>
+ Storage = 5,
+ /// <summary>
+ /// Network Infrastructure.
+ /// </summary>
+ NetworkInfrastructure = 6,
+ /// <summary>
+ /// Display.
+ /// </summary>
+ Display = 7,
+ /// <summary>
+ /// Multimedia device.
+ /// </summary>
+ MultimediaDevice = 8,
+ /// <summary>
+ /// Game device.
+ /// </summary>
+ GameDevice = 9,
+ /// <summary>
+ /// Telephone.
+ /// </summary>
+ Telephone = 10,
+ /// <summary>
+ /// Audio.
+ /// </summary>
+ Audio = 11,
+ /// <summary>
+ /// Others.
+ /// </summary>
+ Other = 255
+ }
+
+ /// <summary>
+ /// Enumeration for Wi-Fi Direct secondary device type.
+ /// </summary>
+ public enum WiFiDirectSecondaryDeviceType
+ {
+ /// <summary>
+ /// Computer PC.
+ /// </summary>
+ ComputerPc = 1,
+ /// <summary>
+ /// Computer server.
+ /// </summary>
+ ComputerServer = 2,
+ /// <summary>
+ /// Computer media center.
+ /// </summary>
+ ComputerMediaCenter = 3,
+ /// <summary>
+ /// Computer UMPC.
+ /// </summary>
+ ComputerUmpc = 4,
+ /// <summary>
+ /// Computer notebook.
+ /// </summary>
+ ComputerNotebook = 5,
+ /// <summary>
+ /// Computer desktop
+ /// </summary>
+ ComputerDesktop = 6,
+ /// <summary>
+ /// Computer MID.
+ /// </summary>
+ ComputerMid = 7,
+ /// <summary>
+ /// Computer netbook.
+ /// </summary>
+ ComputerNetbook = 8,
+ /// <summary>
+ /// Input keyboard.
+ /// </summary>
+ InputKeyboard = 1,
+ /// <summary>
+ /// Input mouse.
+ /// </summary>
+ InputMouse = 2,
+ /// <summary>
+ /// Input joystick.
+ /// </summary>
+ InputJoystick = 3,
+ /// <summary>
+ /// Input trackball.
+ /// </summary>
+ InputTrackball = 4,
+ /// <summary>
+ /// Input controller.
+ /// </summary>
+ InputController = 5,
+ /// <summary>
+ /// Inpute remote.
+ /// </summary>
+ InputRemote = 6,
+ /// <summary>
+ /// Input touch screen.
+ /// </summary>
+ InputTouchScreen = 7,
+ /// <summary>
+ /// Input biometric reader.
+ /// </summary>
+ InputBiometricReader = 8,
+ /// <summary>
+ /// Input barcode reader.
+ /// </summary>
+ InputBarcodeReader = 9,
+ /// <summary>
+ /// Printer.
+ /// </summary>
+ Printer = 1,
+ /// <summary>
+ /// Printer scanner.
+ /// </summary>
+ PrinterScanner = 2,
+ /// <summary>
+ /// Printer fax.
+ /// </summary>
+ PrinterFax = 3,
+ /// <summary>
+ /// Printer copier.
+ /// </summary>
+ PrinterCopier = 4,
+ /// <summary>
+ /// Printer all-in-one.
+ /// </summary>
+ PrinterAllInOne = 5,
+ /// <summary>
+ /// Digital still camera.
+ /// </summary>
+ CameraDigital = 1,
+ /// <summary>
+ /// Video camera.
+ /// </summary>
+ CameraVideo = 2,
+ /// <summary>
+ /// Webcam.
+ /// </summary>
+ CameraWebcam = 3,
+ /// <summary>
+ /// Security camera.
+ /// </summary>
+ CameraSecurity = 4,
+ /// <summary>
+ /// Storage NAS.
+ /// </summary>
+ StorageNas = 1,
+ /// <summary>
+ /// Network ap.
+ /// </summary>
+ NetworkAp = 1,
+ /// <summary>
+ /// Network router.
+ /// </summary>
+ NetworkRouter = 2,
+ /// <summary>
+ /// Network switch.
+ /// </summary>
+ NetworkSwitch = 3,
+ /// <summary>
+ /// Network gateway.
+ /// </summary>
+ NetworkGateway = 4,
+ /// <summary>
+ /// Display tv.
+ /// </summary>
+ DisplayTv = 1,
+ /// <summary>
+ /// Display picture frame.
+ /// </summary>
+ DisplayPicFrame = 2,
+ /// <summary>
+ /// Display projector.
+ /// </summary>
+ DisplayProjector = 3,
+ /// <summary>
+ /// Display monitor.
+ /// </summary>
+ DisplayMonitor = 4,
+ /// <summary>
+ /// Multimedia DAR.
+ /// </summary>
+ MultimediaDar = 1,
+ /// <summary>
+ /// Multimedia PVR.
+ /// </summary>
+ MultimediaPvr = 2,
+ /// <summary>
+ /// Multimedia MCX.
+ /// </summary>
+ MultimediaMcx = 3,
+ /// <summary>
+ /// Multimedia set-top box.
+ /// </summary>
+ MultimediaStb = 4,
+ /// <summary>
+ /// Media Server / Media Adapter / Media Extender.
+ /// </summary>
+ MultimediaMsMaMe = 5,
+ /// <summary>
+ /// Multimedia portable video player.
+ /// </summary>
+ MultimediaPvp = 6,
+ /// <summary>
+ /// Game xbox.
+ /// </summary>
+ GameXbox = 1,
+ /// <summary>
+ /// The game xbox 360.
+ /// </summary>
+ GameXbox360,
+ /// <summary>
+ /// Game play station.
+ /// </summary>
+ GamePlayStation = 2,
+ /// <summary>
+ /// Game console.
+ /// </summary>
+ GameConsole = 3,
+ /// <summary>
+ /// Game portable.
+ /// </summary>
+ GamePortable = 4,
+ /// <summary>
+ /// Windows mobile.
+ /// </summary>
+ TelephoneWindowsMobile = 1,
+ /// <summary>
+ /// Phone - single mode.
+ /// </summary>
+ TelephonePhoneSingle = 2,
+ /// <summary>
+ /// Phone - dual mode.
+ /// </summary>
+ TelephonePhoneDual = 3,
+ /// <summary>
+ /// Smart Phone - single mode.
+ /// </summary>
+ TelephoneSmartphoneSingle = 4,
+ /// <summary>
+ /// Smart Phone - dual mode.
+ /// </summary>
+ TelephoneSmartphoneDual = 5,
+ /// <summary>
+ /// Audio tuner.
+ /// </summary>
+ AudioTuner = 1,
+ /// <summary>
+ /// Audio speaker.
+ /// </summary>
+ AudioSpeaker = 2,
+ /// <summary>
+ /// Audio pmp.
+ /// </summary>
+ AudioPmp = 3,
+ /// <summary>
+ /// Audio headset.
+ /// </summary>
+ AudioHeadset = 4,
+ /// <summary>
+ /// Audio headphone.
+ /// </summary>
+ AudioHeadphone = 5,
+ /// <summary>
+ /// Audio microphone.
+ /// </summary>
+ AudioMic = 6
+ }
+
+ /// <summary>
+ /// Enumeration for Wi-Fi Direct link status.
+ /// </summary>
+ public enum WiFiDirectState
+ {
+ /// <summary>
+ /// Deactivated.
+ /// </summary>
+ Deactivated = 0,
+ /// <summary>
+ /// Deactivating.
+ /// </summary>
+ Deactivating,
+ /// <summary>
+ /// Activating.
+ /// </summary>
+ Activating,
+ /// <summary>
+ /// Activated.
+ /// </summary>
+ Activated,
+ /// <summary>
+ /// Discovering.
+ /// </summary>
+ Discovering,
+ /// <summary>
+ /// Connecting.
+ /// </summary>
+ Connecting,
+ /// <summary>
+ /// Disconnecting.
+ /// </summary>
+ Disconnecting,
+ /// <summary>
+ /// Connected.
+ /// </summary>
+ Connected,
+ /// <summary>
+ /// Group owner.
+ /// </summary>
+ GroupOwner
+ }
+
+ /// <summary>
+ /// Enumeration for Wi-Fi WPS type.
+ /// </summary>
+ public enum WiFiDirectWpsType
+ {
+ /// <summary>
+ /// No WPS type.
+ /// </summary>
+ None = 0x00,
+ /// <summary>
+ /// Push button configuration.
+ /// </summary>
+ Pbc = 0x01,
+ /// <summary>
+ /// Display pin code.
+ /// </summary>
+ PinDisplay = 0x02,
+ /// <summary>
+ /// Provide the keypad to input the pin.
+ /// </summary>
+ PinKeypad = 0x04
+ }
+
+ /// <summary>
+ /// Enumeration for Service Discovery type.
+ /// </summary>
+ public enum WiFiDirectServiceType
+ {
+ /// <summary>
+ /// Service discovery Type all.
+ /// </summary>
+ All,
+ /// <summary>
+ /// Service discovery Type bonjour.
+ /// </summary>
+ Bonjour,
+ /// <summary>
+ /// Service discovery Type UPNP.
+ /// </summary>
+ Upnp,
+ /// <summary>
+ /// Service discovery Type ws discovery.
+ /// </summary>
+ WsDiscovery,
+ /// <summary>
+ /// Service discovery Type wifi-display.
+ /// </summary>
+ WiFiDisplay,
+ /// <summary>
+ /// Service discovery Type bt address.
+ /// </summary>
+ BtAddress,
+ /// <summary>
+ /// Service discovery Type contact info.
+ /// </summary>
+ ContactInfo,
+ /// <summary>
+ /// Service discovery Type vendor-specific.
+ /// </summary>
+ Vendor
+ }
+
+ /// <summary>
+ /// Enumeration for Wi-Fi Direct service Discovery state.
+ /// </summary>
+ public enum WiFiDirectServiceDiscoveryState
+ {
+ /// <summary>
+ /// Service discovery started.
+ /// </summary>
+ Started,
+ /// <summary>
+ /// Service discovery found.
+ /// </summary>
+ Found,
+ /// <summary>
+ /// Service discovery finished.
+ /// </summary>
+ Finished
+ }
+
+ /// <summary>
+ /// Enumeration for Wi-Fi Direct device state.
+ /// </summary>
+ public enum WiFiDirectDeviceState
+ {
+ /// <summary>
+ /// Activated.
+ /// </summary>
+ Activated,
+ /// <summary>
+ /// Deactivated.
+ /// </summary>
+ Deactivated
+ }
+
+ /// <summary>
+ /// Enumeration for Wi-Fi Direct error code.
+ /// </summary>
+ public enum WiFiDirectError
+ {
+ /// <summary>
+ /// Successful.
+ /// </summary>
+ None = ErrorCode.None,
+ /// <summary>
+ /// Operation not permitted.
+ /// </summary>
+ NotPermitted = ErrorCode.NotPermitted,
+ /// <summary>
+ /// Out of memory.
+ /// </summary>
+ OutOfMemory = ErrorCode.OutOfMemory,
+ /// <summary>
+ /// Permission denied.
+ /// </summary>
+ PermissionDenied = ErrorCode.PermissionDenied,
+ /// <summary>
+ /// Device or resource busy.
+ /// </summary>
+ ResourceBusy = ErrorCode.ResourceBusy,
+ /// <summary>
+ /// Invalid function parameter.
+ /// </summary>
+ InvalidParameter = ErrorCode.InvalidParameter,
+ /// <summary>
+ /// Connection timed out.
+ /// </summary>
+ ConnectionTimeOut = ErrorCode.ConnectionTimeout,
+ /// <summary>
+ /// Not supported.
+ /// </summary>
+ NotSupported = ErrorCode.NotSupported,
+ /// <summary>
+ /// Not initialized.
+ /// </summary>
+ NotInitialized = -0x01C60000 | 0x01,
+ /// <summary>
+ /// I/O error.
+ /// </summary>
+ CommunicationFailed = -0x01C60000 | 0x02,
+ /// <summary>
+ /// WiFi is being used.
+ /// </summary>
+ WiFiUsed = -0x01C60000 | 0x03,
+ /// <summary>
+ /// Mobile AP is being used.
+ /// </summary>
+ MobileApUsed = -0x01C60000 | 0x04,
+ /// <summary>
+ /// Connection failed.
+ /// </summary>
+ ConnectionFailed = -0x01C60000 | 0x05,
+ /// <summary>
+ /// Authentication failed.
+ /// </summary>
+ AuthFailed = -0x01C60000 | 0x06,
+ /// <summary>
+ /// Operation failed.
+ /// </summary>
+ OperationFailed = -0x01C60000 | 0x07,
+ /// <summary>
+ /// Too many client.
+ /// </summary>
+ TooManyClient = -0x01C60000 | 0x08,
+ /// <summary>
+ /// Already initialized client.
+ /// </summary>
+ AlreadyInitialized = -0x01C60000 | 0x09,
+ /// <summary>
+ /// Connection cancelled by local device.
+ /// </summary>
+ ConnectionCancelled = -0x01C60000 | 0x10
+ }
+}
diff --git a/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectError.cs b/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectError.cs
new file mode 100644
index 0000000..80e929e
--- /dev/null
+++ b/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectError.cs
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Network.WiFiDirect
+{
+ internal static class WiFiDirectErrorFactory
+ {
+ internal static void ThrowWiFiDirectException(int exception)
+ {
+ WiFiDirectError _error = (WiFiDirectError)exception;
+ switch (_error)
+ {
+ case WiFiDirectError.InvalidParameter:
+ throw new InvalidOperationException("Invalid parameter");
+ case WiFiDirectError.AlreadyInitialized:
+ throw new InvalidOperationException("Already initialized");
+ case WiFiDirectError.AuthFailed:
+ throw new InvalidOperationException("Authentication failed");
+ case WiFiDirectError.CommunicationFailed:
+ throw new InvalidOperationException("Communication failed");
+ case WiFiDirectError.ConnectionCancelled:
+ throw new InvalidOperationException("Connection cancelled");
+ case WiFiDirectError.ConnectionFailed:
+ throw new InvalidOperationException("Connection failed");
+ case WiFiDirectError.ConnectionTimeOut:
+ throw new InvalidOperationException("Connection timed out");
+ case WiFiDirectError.MobileApUsed:
+ throw new InvalidOperationException("Mobile Ap is being used");
+ case WiFiDirectError.NotInitialized:
+ throw new InvalidOperationException("Not initialized");
+ case WiFiDirectError.NotPermitted:
+ throw new InvalidOperationException("Not permitted");
+ case WiFiDirectError.NotSupported:
+ throw new NotSupportedException("Not supported");
+ case WiFiDirectError.OperationFailed:
+ throw new InvalidOperationException("Operation failed");
+ case WiFiDirectError.OutOfMemory:
+ throw new InvalidOperationException("Out of memory");
+ case WiFiDirectError.PermissionDenied:
+ throw new UnauthorizedAccessException("Permission denied (http://tizen.org/privilege/wifidirect)");
+ case WiFiDirectError.ResourceBusy:
+ throw new InvalidOperationException("Resource is busy");
+ case WiFiDirectError.TooManyClient:
+ throw new InvalidOperationException("Too many client");
+ case WiFiDirectError.WiFiUsed:
+ throw new InvalidOperationException("Wi-fi is being used");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectEventArgs.cs b/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectEventArgs.cs
new file mode 100644
index 0000000..b87af3b
--- /dev/null
+++ b/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectEventArgs.cs
@@ -0,0 +1,382 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Network.WiFiDirect
+{
+ /// <summary>
+ /// An extended EventArgs class which contains changed connection state during connecting or disconnecting peer device.
+ /// </summary>
+ public class ConnectionStateChangedEventArgs : EventArgs
+ {
+ private WiFiDirectError _error;
+ private WiFiDirectConnectionState _state;
+ private string _macAddress;
+
+ internal ConnectionStateChangedEventArgs(WiFiDirectError error, WiFiDirectConnectionState state, string macAddress)
+ {
+ _error = error;
+ _state = state;
+ _macAddress = macAddress;
+ }
+
+ /// <summary>
+ /// Wi-Fi Direct result.
+ /// </summary>
+ public WiFiDirectError Error
+ {
+ get
+ {
+ return _error;
+ }
+ }
+
+ /// <summary>
+ /// Wi-Fi Direct connection state of peer.
+ /// </summary>
+ public WiFiDirectConnectionState State
+ {
+ get
+ {
+ return _state;
+ }
+ }
+
+ /// <summary>
+ /// MacAddress of peer.
+ /// </summary>
+ public string MacAddress
+ {
+ get
+ {
+ return _macAddress;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains address properties of the peer when it connects to a group owner.
+ /// </summary>
+ public class IpAddressAssignedEventArgs : EventArgs
+ {
+ private string _macAddress;
+ private string _ipAddress;
+ private string _interfaceAddress;
+
+ internal IpAddressAssignedEventArgs(string macAddress, string ipAddress, string interfaceAddress)
+ {
+ _macAddress = macAddress;
+ _ipAddress = ipAddress;
+ _interfaceAddress = interfaceAddress;
+ }
+
+ /// <summary>
+ /// MacAddress of connected peer.
+ /// </summary>
+ public string MacAddress
+ {
+ get
+ {
+ return _macAddress;
+ }
+ }
+
+ /// <summary>
+ /// IpAddress of connected peer.
+ /// </summary>
+ public string IpAddress
+ {
+ get
+ {
+ return _ipAddress;
+ }
+ }
+
+ /// <summary>
+ /// InterfaceAddress of connected peer.
+ /// </summary>
+ public string InterfaceAddress
+ {
+ get
+ {
+ return _interfaceAddress;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains changed Wi-Fi Direct state of local device.
+ /// </summary>
+ public class StateChangedEventArgs : EventArgs
+ {
+ private WiFiDirectState _state;
+
+ internal StateChangedEventArgs(WiFiDirectState state)
+ {
+ _state = state;
+ }
+
+ /// <summary>
+ /// Wi-Fi Direct state.
+ /// </summary>
+ public WiFiDirectState State
+ {
+ get
+ {
+ return _state;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains changed Wi-Fi Direct discovery state during Wi-Fi Direct scan operation.
+ /// </summary>
+ public class DiscoveryStateChangedEventArgs : EventArgs
+ {
+ private WiFiDirectError _error;
+ private WiFiDirectDiscoveryState _state;
+
+ internal DiscoveryStateChangedEventArgs(WiFiDirectError error, WiFiDirectDiscoveryState state)
+ {
+ _error = error;
+ _state = state;
+ }
+
+ /// <summary>
+ /// Wi-Fi Direct result.
+ /// </summary>
+ public WiFiDirectError Error
+ {
+ get
+ {
+ return _error;
+ }
+ }
+
+ /// <summary>
+ /// Wi-Fi Direct Discovery state.
+ /// </summary>
+ public WiFiDirectDiscoveryState DiscoveryState
+ {
+ get
+ {
+ return _state;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains found peer information during Wi-Fi Direct scan operation.
+ /// </summary>
+ public class PeerFoundEventArgs : EventArgs
+ {
+ private WiFiDirectError _error;
+ private WiFiDirectDiscoveryState _state;
+ private WiFiDirectPeer _peer;
+
+ internal PeerFoundEventArgs(WiFiDirectError error, WiFiDirectDiscoveryState state, WiFiDirectPeer peer)
+ {
+ _error = error;
+ _state = state;
+ _peer = peer;
+ }
+
+ /// <summary>
+ /// Wi-Fi Direct result.
+ /// </summary>
+ public WiFiDirectError Error
+ {
+ get
+ {
+ return _error;
+ }
+ }
+
+ /// <summary>
+ /// Wi-Fi Direct Discovery state.
+ /// </summary>
+ public WiFiDirectDiscoveryState DiscoveryState
+ {
+ get
+ {
+ return _state;
+ }
+ }
+
+ /// <summary>
+ /// Found peer.
+ /// </summary>
+ public WiFiDirectPeer Peer
+ {
+ get
+ {
+ return _peer;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains changed device state during activation or deactivation.
+ /// </summary>
+ public class DeviceStateChangedEventArgs : EventArgs
+ {
+ private WiFiDirectError _error;
+ private WiFiDirectDeviceState _state;
+
+ internal DeviceStateChangedEventArgs(WiFiDirectError error, WiFiDirectDeviceState state)
+ {
+ _error = error;
+ _state = state;
+ }
+
+ /// <summary>
+ /// Wi-Fi Direct result.
+ /// </summary>
+ public WiFiDirectError Error
+ {
+ get
+ {
+ return _error;
+ }
+ }
+
+ /// <summary>
+ /// State of the device.
+ /// </summary>
+ public WiFiDirectDeviceState DeviceState
+ {
+ get
+ {
+ return _state;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains changed service information during service discovery.
+ /// </summary>
+ public class ServiceStateChangedEventArgs : EventArgs
+ {
+ private WiFiDirectError _error;
+ private WiFiDirectServiceDiscoveryState _state;
+ private WiFiDirectServiceType _type;
+ private string _response;
+ private WiFiDirectPeer _peer;
+
+ internal ServiceStateChangedEventArgs(WiFiDirectError error, WiFiDirectServiceDiscoveryState state, WiFiDirectServiceType type, string response, WiFiDirectPeer peer)
+ {
+ _error = error;
+ _state = state;
+ _type = type;
+ _response = response;
+ _peer = peer;
+ }
+
+ /// <summary>
+ /// Wi-Fi Direct result.
+ /// </summary>
+ public WiFiDirectError Error
+ {
+ get
+ {
+ return _error;
+ }
+ }
+
+ /// <summary>
+ /// Service discovery state.
+ /// </summary>
+ public WiFiDirectServiceDiscoveryState ServiceDiscoveryState
+ {
+ get
+ {
+ return _state;
+ }
+ }
+
+ /// <summary>
+ /// Types of service.
+ /// </summary>
+ public WiFiDirectServiceType ServiceType
+ {
+ get
+ {
+ return _type;
+ }
+ }
+
+ /// <summary>
+ /// Received response.
+ /// </summary>
+ public string Response
+ {
+ get
+ {
+ return _response;
+ }
+ }
+
+ /// <summary>
+ /// Peer servicing device.
+ /// </summary>
+ public WiFiDirectPeer Peer
+ {
+ get
+ {
+ return _peer;
+ }
+ }
+ }
+
+ /// <summary>
+ /// An extended EventArgs class which contains changed connection state during disconnect all peers or group related operations.
+ /// </summary>
+ public class ConnectionStatusChangedEventArgs : EventArgs
+ {
+ private WiFiDirectError _error;
+ private WiFiDirectConnectionState _state;
+
+ internal ConnectionStatusChangedEventArgs(WiFiDirectError error, WiFiDirectConnectionState state)
+ {
+ _error = error;
+ _state = state;
+ }
+
+ /// <summary>
+ /// Wi-Fi Direct result.
+ /// </summary>
+ public WiFiDirectError Error
+ {
+ get
+ {
+ return _error;
+ }
+ }
+
+ /// <summary>
+ /// Connection state.
+ /// </summary>
+ public WiFiDirectConnectionState ConnectionState
+ {
+ get
+ {
+ return _state;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectManager.cs b/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectManager.cs
new file mode 100644
index 0000000..2a1bf99
--- /dev/null
+++ b/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectManager.cs
@@ -0,0 +1,1628 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.ComponentModel;
+using System.Collections.Generic;
+
+namespace Tizen.Network.WiFiDirect
+{
+ /// <summary>
+ /// A class which is used to manage settings of Wi-Fi Direct.<br/>
+ /// This class is used to discover peer devices and manage settings of Wi-Fi Direct.
+ /// </summary>
+ public static class WiFiDirectManager
+ {
+ /// <summary>
+ /// Gets the IsInitialized.
+ /// </summary>
+ /// <value>
+ /// A property to check whether the Wifidirect is initialized or not.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <remarks>
+ /// If it is not initialized, false will be returned.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static bool IsInitialized
+ {
+ get
+ {
+ return WiFiDirectManagerImpl.Instance.IsInitialize;
+ }
+ }
+ /// <summary>
+ /// Gets the IsGroupOwner.
+ /// </summary>
+ /// <value>
+ /// A property to check whether the device is group owner or not.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// If it is deactivated, false will be returned.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static bool IsGroupOwner
+ {
+ get
+ {
+ if (Globals.IsActivated)
+ {
+ return WiFiDirectManagerImpl.Instance.IsGroupOwner;
+ }
+
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the IsAutonomousGroup.
+ /// </summary>
+ /// <value>
+ /// A property to check whether the current group is the autonomous group or not.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// If it is deactivated, false will be returned.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static bool IsAutonomousGroup
+ {
+ get
+ {
+ if (Globals.IsActivated)
+ {
+ return WiFiDirectManagerImpl.Instance.IsAutonomousGroup;
+ }
+
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the Ssid.
+ /// </summary>
+ /// <value>
+ /// SSID of local device.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <remarks>
+ /// If there is any error, null will be returned.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static string Ssid
+ {
+ get
+ {
+ if (Globals.IsInitialize)
+ {
+ return WiFiDirectManagerImpl.Instance.Ssid;
+ }
+
+ else
+ {
+ return null;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the NetworkInterface.
+ /// </summary>
+ /// <value>
+ /// Name of network interface.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// If it is deactivated, null will be returned.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static string NetworkInterface
+ {
+ get
+ {
+ if (Globals.IsActivated)
+ {
+ return WiFiDirectManagerImpl.Instance.NetworkInterface;
+ }
+
+ else
+ {
+ return null;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the IpAddress.
+ /// </summary>
+ /// <value>
+ /// IP address of a local device.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// If it is deactivated, null will be returned.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static string IpAddress
+ {
+ get
+ {
+ if (Globals.IsActivated)
+ {
+ return WiFiDirectManagerImpl.Instance.IpAddress;
+ }
+
+ else
+ {
+ return null;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the SubnetMask.
+ /// </summary>
+ /// <value>
+ /// Subnet mask.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// If it is deactivated, null will be returned.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static string SubnetMask
+ {
+ get
+ {
+ if (Globals.IsActivated)
+ {
+ return WiFiDirectManagerImpl.Instance.SubnetMask;
+ }
+
+ else
+ {
+ return null;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the GatewayAddress.
+ /// </summary>
+ /// <value>
+ /// Gateway address.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// If it is deactivated, null will be returned.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static string GatewayAddress
+ {
+ get
+ {
+ if (Globals.IsActivated)
+ {
+ return WiFiDirectManagerImpl.Instance.GatewayAddress;
+ }
+
+ else
+ {
+ return null;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the MacAddress.
+ /// </summary>
+ /// <value>
+ /// Mac address of a local device.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <remarks>
+ /// If there is any error, null will be returned.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static string MacAddress
+ {
+ get
+ {
+ if (Globals.IsInitialize)
+ {
+ return WiFiDirectManagerImpl.Instance.MacAddress;
+ }
+
+ else
+ {
+ return null;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the State.
+ /// </summary>
+ /// <value>
+ /// State of Wi-Fi direct service.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static WiFiDirectState State
+ {
+ get
+ {
+ return WiFiDirectManagerImpl.Instance.State;
+ }
+ }
+
+ /// <summary>
+ /// A property to check whether the device is discoverable or not by P2P discovery.
+ /// </summary>
+ /// <value>
+ ///
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static bool IsDiscoverable
+ {
+ get
+ {
+ if (Globals.IsInitialize)
+ {
+ return WiFiDirectManagerImpl.Instance.IsDiscoverable;
+ }
+
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the IsListenOnly.
+ /// </summary>
+ /// <value>
+ /// A property to check whether the local device is listening only.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// If it is deactivated, false will be returned.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static bool IsListenOnly
+ {
+ get
+ {
+ if (Globals.IsActivated)
+ {
+ return WiFiDirectManagerImpl.Instance.IsListenOnly;
+ }
+
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the PrimaryType.
+ /// </summary>
+ /// <value>
+ /// Primary device type of local device.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <remarks>
+ /// If there is any error, 0 will be returned.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static WiFiDirectPrimaryDeviceType PrimaryType
+ {
+ get
+ {
+ if (Globals.IsInitialize)
+ {
+ return WiFiDirectManagerImpl.Instance.PrimaryType;
+ }
+
+ else
+ {
+ return default(WiFiDirectPrimaryDeviceType);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the SecondaryType.
+ /// </summary>
+ /// <value>
+ /// Secondary device type of local device.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <remarks>
+ /// If there is any error, 0 will be returned.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static WiFiDirectSecondaryDeviceType SecondaryType
+ {
+ get
+ {
+ if (Globals.IsInitialize)
+ {
+ return WiFiDirectManagerImpl.Instance.SecondaryType;
+ }
+
+ else
+ {
+ return default(WiFiDirectSecondaryDeviceType);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the WpsMode.
+ /// </summary>
+ /// <value>
+ /// Supported WPS (Wi-Fi Protected Setup) types at local device.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <remarks>
+ /// If there is any error, -1 will be returned.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static int WpsMode
+ {
+ get
+ {
+ if (Globals.IsInitialize)
+ {
+ return WiFiDirectManagerImpl.Instance.WpsMode;
+ }
+
+ else
+ {
+ return -1;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the Wps.
+ /// </summary>
+ /// <value>
+ /// WPS (Wi-Fi Protected Setup) type.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static WiFiDirectWpsType Wps
+ {
+ get
+ {
+ if (Globals.IsInitialize)
+ {
+ return WiFiDirectManagerImpl.Instance.WpsType;
+ }
+
+ else
+ {
+ return default(WiFiDirectWpsType);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the OperatingChannel.
+ /// </summary>
+ /// <value>
+ /// Channel number on which the P2P Device is operating as the P2P Group.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <remarks>
+ /// If there is any error, -1 will be returned.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static int OperatingChannel
+ {
+ get
+ {
+ if (Globals.IsInitialize)
+ {
+ return WiFiDirectManagerImpl.Instance.OperatingChannel;
+ }
+
+ else
+ {
+ return -1;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets and sets the PersistentGroupEnabled.
+ /// </summary>
+ /// <value>
+ /// A property to check whether persistent group is enabled.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static bool PersistentGroupEnabled
+ {
+ get
+ {
+ if (Globals.IsInitialize)
+ {
+ return WiFiDirectManagerImpl.Instance.PersistentGroupEnabled;
+ }
+
+ else
+ {
+ return false;
+ }
+ }
+
+ set
+ {
+ if (Globals.IsInitialize)
+ {
+ WiFiDirectManagerImpl.Instance.PersistentGroupEnabled = value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets and sets the AutoConnect.
+ /// </summary>
+ /// <value>
+ /// Autoconnection mode status.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static bool AutoConnect
+ {
+ get
+ {
+ if (Globals.IsInitialize)
+ {
+ return WiFiDirectManagerImpl.Instance.AutoConnect;
+ }
+
+ else
+ {
+ return false;
+ }
+ }
+
+ set
+ {
+ if (Globals.IsInitialize)
+ {
+ WiFiDirectManagerImpl.Instance.AutoConnect = value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets and sets the WpsPin.
+ /// </summary>
+ /// <value>
+ /// WPS PIN number.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// If it is deactivated, null will be returned during get and Not permitted exception message will be returned during set.
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static string WpsPin
+ {
+ get
+ {
+ if (Globals.IsActivated)
+ {
+ return WiFiDirectManagerImpl.Instance.WpsPin;
+ }
+
+ else
+ {
+ return null;
+ }
+ }
+
+ set
+ {
+ if (Globals.IsActivated)
+ {
+ WiFiDirectManagerImpl.Instance.WpsPin = value;
+ }
+
+ else
+ {
+ Log.Error(Globals.LogTag, "Wifi-direct is not activated");
+ WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets and sets the Name.
+ /// </summary>
+ /// <value>
+ /// Name of local device.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static string Name
+ {
+ get
+ {
+ if (Globals.IsInitialize)
+ {
+ return WiFiDirectManagerImpl.Instance.Name;
+ }
+
+ else
+ {
+ return null;
+ }
+ }
+
+ set
+ {
+ if (Globals.IsInitialize)
+ {
+ WiFiDirectManagerImpl.Instance.Name = value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets and sets the RequestedWps.
+ /// </summary>
+ /// <value>
+ /// Requested WPS (Wi-Fi Protected Setup) type.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static WiFiDirectWpsType RequestedWps
+ {
+ get
+ {
+ if (Globals.IsInitialize)
+ {
+ return WiFiDirectManagerImpl.Instance.RequestedWps;
+ }
+
+ else
+ {
+ return default(WiFiDirectWpsType);
+ }
+ }
+
+ set
+ {
+ if (Globals.IsInitialize)
+ {
+ WiFiDirectManagerImpl.Instance.RequestedWps = value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets and sets the GroupOwnerIntent.
+ /// </summary>
+ /// <value>
+ /// Intent of the group owner.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static int GroupOwnerIntent
+ {
+ get
+ {
+ if (Globals.IsInitialize)
+ {
+ return WiFiDirectManagerImpl.Instance.GroupOwnerIntent;
+ }
+
+ else
+ {
+ return -1;
+ }
+ }
+
+ set
+ {
+ if (Globals.IsInitialize)
+ {
+ WiFiDirectManagerImpl.Instance.GroupOwnerIntent = value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets and sets the MaxClients.
+ /// </summary>
+ /// <value>
+ /// Max number of clients.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static int MaxClients
+ {
+ get
+ {
+ if (Globals.IsInitialize)
+ {
+ return WiFiDirectManagerImpl.Instance.MaxClients;
+ }
+
+ else
+ {
+ return -1;
+ }
+ }
+
+ set
+ {
+ if (Globals.IsInitialize)
+ {
+ WiFiDirectManagerImpl.Instance.MaxClients = value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets and sets the Passphrase.
+ /// It is used during Wi-Fi Direct Group creation.
+ /// </summary>
+ /// <value>
+ /// Wi-Fi Protected Access (WPA) password.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// If it is deactivated, null will be returned during get and Not permitted exception message will be returned during set.
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static string Passphrase
+ {
+ get
+ {
+ if (Globals.IsActivated)
+ {
+ return WiFiDirectManagerImpl.Instance.Passphrase;
+ }
+
+ else
+ {
+ return null;
+ }
+ }
+
+ set
+ {
+ if (Globals.IsActivated)
+ {
+ WiFiDirectManagerImpl.Instance.Passphrase = value;
+ }
+
+ else
+ {
+ Log.Error(Globals.LogTag, "Wi-Fi direct is not activated");
+ WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets and sets the SessionTimer.
+ /// </summary>
+ /// <value>
+ /// Connection session timer value in second.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// If it is deactivated, -1 will be returned during get and Not permitted exception message will be returned during set.
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static int SessionTimer
+ {
+ get
+ {
+ if (Globals.IsActivated)
+ {
+ return WiFiDirectManagerImpl.Instance.SessionTimer;
+ }
+
+ else
+ {
+ return -1;
+ }
+ }
+
+ set
+ {
+ if (Globals.IsActivated)
+ {
+ WiFiDirectManagerImpl.Instance.SessionTimer = value;
+ }
+
+ else
+ {
+ Log.Error(Globals.LogTag, "Wi-Fi direct is not activated");
+ WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
+ }
+ }
+ }
+
+ /// <summary>
+ /// (event) StateChanged is raised when Wi-Fi Direct state is changed.
+ /// </summary>
+ public static event EventHandler<StateChangedEventArgs> StateChanged
+ {
+ add
+ {
+ WiFiDirectManagerImpl.Instance.StateChanged += value;
+ }
+
+ remove
+ {
+ WiFiDirectManagerImpl.Instance.StateChanged -= value;
+ }
+ }
+
+ /// <summary>
+ /// (event) DiscoveryStateChanged is raised when Wi-Fi Direct discovery state is changed.
+ /// </summary>
+ public static event EventHandler<DiscoveryStateChangedEventArgs> DiscoveryStateChanged
+ {
+ add
+ {
+ if (Globals.IsInitialize)
+ {
+ WiFiDirectManagerImpl.Instance.DiscoveryStateChanged += value;
+ }
+ }
+
+ remove
+ {
+ if (Globals.IsInitialize)
+ {
+ WiFiDirectManagerImpl.Instance.DiscoveryStateChanged -= value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// (event) DeviceStateChanged is raised when device state is changed.
+ /// </summary>
+ public static event EventHandler<DeviceStateChangedEventArgs> DeviceStateChanged
+ {
+ add
+ {
+ if (Globals.IsInitialize)
+ {
+ WiFiDirectManagerImpl.Instance.DeviceStateChanged += value;
+ }
+ }
+
+ remove
+ {
+ if (Globals.IsInitialize)
+ {
+ WiFiDirectManagerImpl.Instance.DeviceStateChanged -= value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// (event) PeerFound is raised when peer is found.
+ /// </summary>
+ public static event EventHandler<PeerFoundEventArgs> PeerFound
+ {
+ add
+ {
+ if (Globals.IsInitialize)
+ {
+ WiFiDirectManagerImpl.Instance.PeerFound += value;
+ }
+ }
+
+ remove
+ {
+ if (Globals.IsInitialize)
+ {
+ WiFiDirectManagerImpl.Instance.PeerFound -= value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// (event) ConnectionStatusChanged is raised when status of connection is changed.
+ /// </summary>
+ public static event EventHandler<ConnectionStatusChangedEventArgs> ConnectionStatusChanged
+ {
+ add
+ {
+ if (Globals.IsInitialize)
+ {
+ WiFiDirectManagerImpl.Instance.ConnectionStatusChanged += value;
+ }
+ }
+
+ remove
+ {
+ if (Globals.IsInitialize)
+ {
+ WiFiDirectManagerImpl.Instance.ConnectionStatusChanged -= value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Activates the Wi-Fi Direct service.
+ /// </summary>
+ /// <remarks>
+ /// If this succeeds, DeviceStateChanged event will be invoked.
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static void Activate()
+ {
+ if (Globals.IsInitialize)
+ {
+ WiFiDirectManagerImpl.Instance.Activate();
+ }
+
+ else
+ {
+ Log.Error(Globals.LogTag, "Wi-Fi direct is not initialized");
+ WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotInitialized);
+ }
+ }
+
+ /// <summary>
+ /// Deactivates the Wi-Fi Direct service.
+ /// </summary>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/network.wifidirect
+ /// </feature>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// If this succeeds, DeviceStateChanged event will be invoked.
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static void Deactivate()
+ {
+ if (Globals.IsActivated)
+ {
+ WiFiDirectManagerImpl.Instance.Deactivate();
+ }
+
+ else
+ {
+ Log.Error(Globals.LogTag, "Wi-Fi direct is not activated");
+ WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
+ }
+ }
+
+ /// <summary>
+ /// Starts discovery to find all P2P capable devices.
+ /// </summary>
+ /// <param name="listenOnly">Listen status.If False, then cycle between Scan and Listen.If True, then skip the initial 802.11 Scan and enter Listen state.</param>
+ /// <param name="duration">Duration of discovery period, in seconds.</param>
+ /// <param name="channel">Discovery channel.It is optional, default enum value FullScan is assigned.</param>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/network.wifidirect
+ /// </feature>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// If this succeeds, DiscoveryStateChanged and PeerFound event will be invoked.
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static void StartDiscovery(bool listenOnly, int duration, WiFiDirectDiscoveryChannel channel = WiFiDirectDiscoveryChannel.FullScan)
+ {
+ if (Globals.IsActivated)
+ {
+ WiFiDirectManagerImpl.Instance.StartDiscovery(listenOnly, duration, channel);
+ }
+
+ else
+ {
+ Log.Error(Globals.LogTag, "Wi-Fi direct is not activated");
+ WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
+ }
+ }
+
+ /// <summary>
+ /// Cancels discovery process.
+ /// </summary>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/network.wifidirect
+ /// </feature>
+ /// <remarks>
+ /// Discovery must be started by StartDiscovery.
+ /// If this succeeds, DiscoveryStateChanged and PeerFound event will be invoked.
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static void CancelDiscovery()
+ {
+ if (WiFiDirectManager.State == WiFiDirectState.Discovering)
+ {
+ WiFiDirectManagerImpl.Instance.CancelDiscovery();
+ }
+
+ else
+ {
+ Log.Error(Globals.LogTag, "Wi-Fi direct discovery is not started");
+ WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
+ }
+ }
+
+ /// <summary>
+ /// Gets the information of discovered peers.
+ /// </summary>
+ /// <returns> List of discovered peer objects.</returns>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/network.wifidirect
+ /// </feature>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static IEnumerable<WiFiDirectPeer> GetDiscoveredPeers()
+ {
+ if (Globals.IsActivated)
+ {
+ return WiFiDirectManagerImpl.Instance.GetDiscoveredPeers();
+ }
+
+ else
+ {
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Gets the information of connected peers.
+ /// </summary>
+ /// <returns> List of connected peer objects.</returns>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/network.wifidirect
+ /// </feature>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static IEnumerable<WiFiDirectPeer> GetConnectedPeers()
+ {
+ if (Globals.IsActivated)
+ {
+ return WiFiDirectManagerImpl.Instance.GetConnectedPeers();
+ }
+
+ else
+ {
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Disconnects all connected links to peers.
+ /// </summary>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/network.wifidirect
+ /// </feature>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// If this succeeds, ConnectionStatusChanged event will be invoked.
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static void DisconnectAll()
+ {
+ if (Globals.IsActivated)
+ {
+ WiFiDirectManagerImpl.Instance.DisconnectAll();
+ }
+
+ else
+ {
+ Log.Error(Globals.LogTag, "Wifi-direct is not activated");
+ WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
+ }
+ }
+
+ /// <summary>
+ /// Creates a Wi-Fi Direct group and sets up device as the group owner.
+ /// </summary>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/network.wifidirect
+ /// </feature>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// If this succeeds, ConnectionStatusChanged event will be invoked with GroupCreated.
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static void CreateGroup()
+ {
+ if (Globals.IsActivated)
+ {
+ WiFiDirectManagerImpl.Instance.CreateGroup();
+ }
+
+ else
+ {
+ Log.Error(Globals.LogTag, "Wifi-direct is not activated");
+ WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
+ }
+ }
+
+ /// <summary>
+ /// Destroys the Wi-Fi Direct group owned by a local device.If creating a group is in progress, this API cancels that process.
+ /// </summary>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/network.wifidirect
+ /// </feature>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// If this succeeds, ConnectionStatusChanged event will be invoked with GroupDestroyed.
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static void DestroyGroup()
+ {
+ if (Globals.IsActivated)
+ {
+ WiFiDirectManagerImpl.Instance.DestroyGroup();
+ }
+
+ else
+ {
+ Log.Error(Globals.LogTag, "Wifi-direct is not activated");
+ WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
+ }
+ }
+
+ /// <summary>
+ /// Set the WPS config PBC as preferred method for connection.
+ /// </summary>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/network.wifidirect
+ /// </feature>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static void ActivatePushButton()
+ {
+ if (Globals.IsActivated)
+ {
+ WiFiDirectManagerImpl.Instance.ActivatePushButton();
+ }
+
+ else
+ {
+ Log.Error(Globals.LogTag, "Wifi-direct is not activated");
+ WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
+ }
+ }
+
+ /// <summary>
+ /// Gets the supported WPS types.
+ /// </summary>
+ /// <returns>The list of supported wps types.</returns>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/network.wifidirect
+ /// </feature>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static IEnumerable<WiFiDirectWpsType> GetSupportedWpsTypes()
+ {
+ if (Globals.IsInitialize)
+ {
+ return WiFiDirectManagerImpl.Instance.GetSupportedWpsTypes();
+ }
+
+ else
+ {
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Gets the persistent groups.
+ /// </summary>
+ /// <returns>List of the persistent group objects.</returns>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/network.wifidirect
+ /// </feature>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static IEnumerable<WiFiDirectPersistentGroup> GetPersistentGroups()
+ {
+ if (Globals.IsInitialize)
+ {
+ return WiFiDirectManagerImpl.Instance.GetPersistentGroups();
+ }
+
+ else
+ {
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Removes a persistent group.
+ /// </summary>
+ /// <param name="group">Persistent group owner.</param>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/network.wifidirect
+ /// </feature>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static void RemovePersistentGroup(WiFiDirectPersistentGroup group)
+ {
+ if (Globals.IsInitialize)
+ {
+ WiFiDirectManagerImpl.Instance.RemovePersistentGroup(group);
+ }
+
+ else
+ {
+ Log.Error(Globals.LogTag, "Wifi-direct is not activated");
+ WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotInitialized);
+ }
+ }
+
+ /// <summary>
+ /// Initializes or Deintializes the WiFi-Direct Display(MIRACAST) service.
+ /// </summary>
+ /// <param name="enable">Enables/Disables service.</param>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/network.wifidirect
+ /// http://tizen.org/feature/network.wifi.direct.display
+ /// </feature>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">
+ /// Thrown during one of the following cases :
+ /// 1. When the wifidirect is not supported
+ /// 2. When the wifidirect display feature is not supported
+ /// </exception>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static void InitMiracast(bool enable)
+ {
+ if (Globals.IsActivated)
+ {
+ WiFiDirectManagerImpl.Instance.InitMiracast(enable);
+ }
+
+ else
+ {
+ Log.Error(Globals.LogTag, "Wifi-direct is not activated");
+ WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
+ }
+ }
+
+ /// <summary>
+ /// Enables Wi-Fi Display functionality.
+ /// </summary>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/network.wifidirect
+ /// http://tizen.org/feature/network.wifi.direct.display
+ /// </feature>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">
+ /// Thrown during one of the following cases :
+ /// 1. When the wifidirect is not supported
+ /// 2. When the wifidirect display feature is not supported
+ /// </exception>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static void InitDisplay()
+ {
+ if (Globals.IsActivated)
+ {
+ WiFiDirectManagerImpl.Instance.InitDisplay();
+ }
+
+ else
+ {
+ Log.Error(Globals.LogTag, "Wifi-direct is not activated");
+ WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
+ }
+ }
+
+ /// <summary>
+ /// Disable Wi-Fi Display(WFD) functionality and disable the support of WFD Information Element(IE).
+ /// </summary>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/network.wifidirect
+ /// http://tizen.org/feature/network.wifi.direct.display
+ /// </feature>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated and WFD must be enabled.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">
+ /// Thrown during one of the following cases :
+ /// 1. When the wifidirect is not supported
+ /// 2. When the wifidirect display feature is not supported
+ /// </exception>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static void DeinitDisplay()
+ {
+ if (Globals.IsActivated && Globals.s_isDisplay)
+ {
+ WiFiDirectManagerImpl.Instance.DeinitDisplay();
+ }
+
+ else
+ {
+ Log.Error(Globals.LogTag, "Wifi-direct is not activated and/or Wi-Fi display is not enabled");
+ WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
+ }
+ }
+
+ /// <summary>
+ /// Sets the Wi-Fi Display parameters for the WFD IE of local device.
+ /// </summary>
+ /// <param name="type">WFD Device Type: define the Role of WFD device like source or sink.</param>
+ /// <param name="port">Specifies Session Management Control Port number. It should be 2 bytes(0~65535).</param>
+ /// <param name="hdcp">CP support bit: (1 = enable the hdcp support, 0 = disable the hdcp support).</param>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/network.wifidirect
+ /// http://tizen.org/feature/network.wifi.direct.display
+ /// </feature>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated and WFD must be enabled.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">
+ /// Thrown during one of the following cases :
+ /// 1. When the wifidirect is not supported
+ /// 2. When the wifidirect display feature is not supported
+ /// </exception>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static void SetDisplay(WiFiDirectDisplayType type, int port, int hdcp)
+ {
+ if (Globals.IsActivated && Globals.s_isDisplay)
+ {
+ WiFiDirectManagerImpl.Instance.SetDisplay(type, port, hdcp);
+ }
+
+ else
+ {
+ Log.Error(Globals.LogTag, "Wifi-direct is not activated and/or Wi-Fi display is not enabled");
+ WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
+ }
+ }
+
+ /// <summary>
+ /// Sets the Wi-Fi Display session availability.
+ /// </summary>
+ /// <param name="availability">Wi-Fi Display session availability.</param>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/network.wifidirect
+ /// http://tizen.org/feature/network.wifi.direct.display
+ /// </feature>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated and WFD must be enabled.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">
+ /// Thrown during one of the following cases :
+ /// 1. When the wifidirect is not supported
+ /// 2. When the wifidirect display feature is not supported
+ /// </exception>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static void SetDisplayAvailability(bool availability)
+ {
+ if (Globals.IsActivated && Globals.s_isDisplay)
+ {
+ WiFiDirectManagerImpl.Instance.SetDisplayAvailability(availability);
+ }
+
+ else
+ {
+ Log.Error(Globals.LogTag, "Wifi-direct is not activated and/or Wi-Fi display is not enabled");
+ WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
+ }
+ }
+
+ /// <summary>
+ /// Sets the automatic group removal feature when all peers are disconnected.
+ /// </summary>
+ /// <param name="enable">Enables/Disables group removal feature.</param>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/network.wifidirect
+ /// </feature>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// ConnectionStatusChanged event will be invoked with GroupDestroyed when this feature is enabled and there's no connected group client and if device is group owner.
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static void SetAutoGroupRemove(bool enable)
+ {
+ if (Globals.IsActivated)
+ {
+ WiFiDirectManagerImpl.Instance.SetAutoGroupRemove(enable);
+ }
+
+ else
+ {
+ Log.Error(Globals.LogTag, "Wifi-direct is not activated");
+ WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
+ }
+ }
+
+ /// <summary>
+ /// Registers the service.
+ /// </summary>
+ /// <returns>The service Id of service getting registered.</returns>
+ /// <param name="type">Type of Wi-Fi Direct Service.</param>
+ /// <param name="info">Service specific information.</param>
+ /// <param name="serviceInfo">Service information.</param>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/network.wifidirect
+ /// http://tizen.org/feature/network.wifi.direct.service_discovery
+ /// </feature>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// If there is any error while registering service, 0 will be returned.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">
+ /// Thrown during one of the following cases :
+ /// 1. When the wifidirect is not supported
+ /// 2. When the wifidirect service discovery is not supported
+ /// </exception>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static uint RegisterService(WiFiDirectServiceType type, string info, string serviceInfo)
+ {
+ if (Globals.IsActivated)
+ {
+ return WiFiDirectManagerImpl.Instance.RegisterService(type, info, serviceInfo);
+ }
+
+ else
+ {
+ return 0;
+ }
+ }
+
+ /// <summary>
+ /// Deregisters for a service used for WiFi Direct Service Discovery.
+ /// </summary>
+ /// <param name="serviceId"> Service ID for which service has to be deregistered.</param>
+ /// <privilege>
+ /// http://tizen.org/privilege/wifidirect
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/network.wifidirect
+ /// http://tizen.org/feature/network.wifi.direct.service_discovery
+ /// </feature>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">
+ /// Thrown during one of the following cases :
+ /// 1. When the wifidirect is not supported
+ /// 2. When the wifidirect service discovery is not supported
+ /// </exception>
+ /// <exception cref="InvalidOperationException">The object is in invalid state.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ public static void DeregisterService(uint serviceId)
+ {
+ if (Globals.IsActivated)
+ {
+ WiFiDirectManagerImpl.Instance.DeregisterService(serviceId);
+ }
+
+ else
+ {
+ Log.Error(Globals.LogTag, "Wifi-direct is not activated");
+ WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectManagerImpl.cs b/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectManagerImpl.cs
new file mode 100644
index 0000000..9c06edc
--- /dev/null
+++ b/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectManagerImpl.cs
@@ -0,0 +1,1248 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading;
+
+namespace Tizen.Network.WiFiDirect
+{
+ internal class WiFiDirectThreadLocal
+ {
+ private int _threadId;
+ internal WiFiDirectThreadLocal(int id)
+ {
+ _threadId = id;
+ }
+
+ public int ThreadId
+ {
+ get
+ {
+ return _threadId;
+ }
+ }
+
+ ~WiFiDirectThreadLocal()
+ {
+ Log.Info(Globals.LogTag, "Deinitializing Wi-Fi direct");
+ int ret = Interop.WiFiDirect.Deinitialize();
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to deinitialize Wi-Fi direct, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+
+ else
+ {
+ Globals.s_isInitialize = false;
+ }
+ }
+ }
+
+ internal static class Globals
+ {
+ internal const string LogTag = "Tizen.Network.WiFiDirect";
+ internal static bool s_isInitialize = false;
+ internal static bool s_isDisplay = false;
+ private static ThreadLocal<WiFiDirectThreadLocal> s_threadName = new ThreadLocal<WiFiDirectThreadLocal>(() =>
+ {
+ Log.Info(Globals.LogTag, "In threadlocal delegate");
+ return new WiFiDirectThreadLocal(Thread.CurrentThread.ManagedThreadId);
+ });
+ internal static bool IsActivated
+ {
+ get
+ {
+ WiFiDirectState _state = WiFiDirectManager.State;
+ if (IsInitialize)
+ {
+ if (_state == WiFiDirectState.Deactivated || _state == WiFiDirectState.Deactivating)
+ {
+ return false;
+ }
+
+ else
+ {
+ return true;
+ }
+ }
+
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ private static bool IsUniqueThread()
+ {
+ if (s_threadName.IsValueCreated)
+ {
+ Log.Info(Globals.LogTag, "This thread is old");
+ return false;
+ }
+
+ else
+ {
+ WiFiDirectThreadLocal obj = s_threadName.Value;
+ Log.Info(Globals.LogTag, "This thread is new , Id = " + obj.ThreadId);
+ return true;
+ }
+ }
+
+ internal static bool IsInitialize
+ {
+ get
+ {
+ if(Globals.IsUniqueThread() || !Globals.s_isInitialize)
+ {
+ WiFiDirectManagerImpl.Instance.Initialize();
+ }
+
+ return (Globals.s_isInitialize);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Implementation of Wi-Fi Direct Apis
+ /// </summary>
+ internal partial class WiFiDirectManagerImpl : IDisposable
+ {
+ private event EventHandler<StateChangedEventArgs> _stateChanged;
+ private event EventHandler<DiscoveryStateChangedEventArgs > _discoveryStateChanged;
+ private event EventHandler<PeerFoundEventArgs > _peerFound;
+ private event EventHandler<DeviceStateChangedEventArgs > _deviceStateChanged;
+ private event EventHandler<ConnectionStatusChangedEventArgs > _connectionStatusChanged;
+
+ private Interop.WiFiDirect.StateChangedCallback _stateChangedCallback;
+ private Interop.WiFiDirect.DiscoveryStateChangedCallback _discoveryStateChangedCallback;
+ private Interop.WiFiDirect.PeerFoundCallback _peerFoundCallback;
+ private Interop.WiFiDirect.DeviceStateChangedCallback _deviceStateChangedCallback;
+ private Interop.WiFiDirect.ConnectionStateChangedCallback _connectionChangedCallback;
+
+ internal event EventHandler<StateChangedEventArgs> StateChanged
+ {
+ add
+ {
+ if (_stateChanged == null)
+ {
+ RegisterStateChangedEvent();
+ }
+
+ _stateChanged += value;
+ }
+
+ remove
+ {
+ _stateChanged -= value;
+ if (_stateChanged == null)
+ {
+ UnregisterStateChangedEvent();
+ }
+ }
+ }
+
+ internal event EventHandler<DiscoveryStateChangedEventArgs> DiscoveryStateChanged
+ {
+ add
+ {
+ if (_discoveryStateChanged == null)
+ {
+ RegisterDiscoveryStateChangedEvent();
+ }
+
+ _discoveryStateChanged += value;
+ }
+
+ remove
+ {
+ _discoveryStateChanged -= value;
+ if (_discoveryStateChanged == null)
+ {
+ UnregisterDiscoveryStateChangedEvent();
+ }
+ }
+ }
+
+ internal event EventHandler<PeerFoundEventArgs> PeerFound
+ {
+ add
+ {
+ if (_peerFound == null)
+ {
+ RegisterPeerFoundEvent();
+ }
+
+ _peerFound += value;
+ }
+
+ remove
+ {
+ _peerFound -= value;
+ if (_peerFound == null)
+ {
+ UnregisterPeerFoundEvent();
+ }
+ }
+ }
+
+ internal event EventHandler<DeviceStateChangedEventArgs> DeviceStateChanged
+ {
+ add
+ {
+ if (_deviceStateChanged == null)
+ {
+ RegisterDeviceStateChangedEvent();
+ }
+
+ _deviceStateChanged += value;
+ }
+
+ remove
+ {
+ _deviceStateChanged -= value;
+ if (_deviceStateChanged == null)
+ {
+ UnregisterDeviceStateChangedEvent();
+ }
+ }
+ }
+
+ internal event EventHandler<ConnectionStatusChangedEventArgs> ConnectionStatusChanged
+ {
+ add
+ {
+ if (_connectionStatusChanged == null)
+ {
+ RegisterConnectionStatusChangedEvent();
+ }
+
+ _connectionStatusChanged += value;
+ }
+
+ remove
+ {
+ _connectionStatusChanged -= value;
+ if (_connectionStatusChanged == null)
+ {
+ UnregisterConnectionStatusChangedEvent();
+ }
+ }
+ }
+
+ private bool _disposed = false;
+ private static WiFiDirectManagerImpl _instance;
+
+ private void RegisterStateChangedEvent()
+ {
+ _stateChangedCallback = (WiFiDirectState stateInfo, IntPtr userData) =>
+ {
+ if (_stateChanged != null)
+ {
+ WiFiDirectState state = stateInfo;
+ _stateChanged(null, new StateChangedEventArgs(state));
+ }
+ };
+ int ret = Interop.WiFiDirect.SetStateChangedCallback(_stateChangedCallback, IntPtr.Zero);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set Wi-Fi Direct state changed callback, Error - " + (WiFiDirectError)ret);
+ }
+ }
+
+ private void UnregisterStateChangedEvent()
+ {
+ int ret = Interop.WiFiDirect.UnsetStateChangedCallback();
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset Wi-Fi Direct state changed callback, Error - " + (WiFiDirectError)ret);
+ }
+ }
+
+ private void RegisterDiscoveryStateChangedEvent()
+ {
+ _discoveryStateChangedCallback = (int result, WiFiDirectDiscoveryState stateInfo, IntPtr userData) =>
+ {
+ if (_discoveryStateChanged != null)
+ {
+ WiFiDirectError error = (WiFiDirectError)result;
+ WiFiDirectDiscoveryState state = stateInfo;
+ _discoveryStateChanged(null, new DiscoveryStateChangedEventArgs(error, state));
+ }
+ };
+ int ret = Interop.WiFiDirect.SetDiscoveryStateChangedCallback(_discoveryStateChangedCallback, IntPtr.Zero);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set Wi-Fi Direct discovery state changed callback, Error - " + (WiFiDirectError)ret);
+ }
+ }
+
+ private void UnregisterDiscoveryStateChangedEvent()
+ {
+ int ret = Interop.WiFiDirect.UnsetDiscoveryStateChangedCallback();
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset Wi-Fi Direct discovery state changed callback, Error - " + (WiFiDirectError)ret);
+ }
+ }
+
+ private void RegisterPeerFoundEvent()
+ {
+ _peerFoundCallback = (int result, WiFiDirectDiscoveryState stateInfo, string address, IntPtr userData) =>
+ {
+ if (_peerFound != null)
+ {
+ WiFiDirectError error = (WiFiDirectError)result;
+ WiFiDirectDiscoveryState state = stateInfo;
+ IntPtr peer;
+ Interop.WiFiDirect.GetDiscoveredPeerInfo(address, out peer);
+ DiscoveredPeerStruct peerStruct = (DiscoveredPeerStruct)Marshal.PtrToStructure(peer, typeof(DiscoveredPeerStruct));
+ _peerFound(null, new PeerFoundEventArgs(error, state, WiFiDirectUtils.ConvertStructToDiscoveredPeer(peerStruct)));
+ }
+ };
+ int ret = Interop.WiFiDirect.SetPeerFoundCallback(_peerFoundCallback, IntPtr.Zero);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set Wi-Fi Direct discovery state changed callback, Error - " + (WiFiDirectError)ret);
+ }
+ }
+
+ private void UnregisterPeerFoundEvent()
+ {
+ int ret = Interop.WiFiDirect.UnsetPeerFoundCallback();
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset Wi-Fi Direct discovery state changed callback, Error - " + (WiFiDirectError)ret);
+ }
+ }
+
+ private void RegisterDeviceStateChangedEvent()
+ {
+ _deviceStateChangedCallback = (int result, WiFiDirectDeviceState stateInfo, IntPtr userData) =>
+ {
+ if (_deviceStateChanged != null)
+ {
+ WiFiDirectError error = (WiFiDirectError)result;
+ WiFiDirectDeviceState state = stateInfo;
+ _deviceStateChanged(null, new DeviceStateChangedEventArgs(error, state));
+ }
+ };
+ int ret = Interop.WiFiDirect.SetDeviceStateChangedCallback(_deviceStateChangedCallback, IntPtr.Zero);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set device state changed callback, Error - " + (WiFiDirectError)ret);
+ }
+ }
+
+ private void UnregisterDeviceStateChangedEvent()
+ {
+ int ret = Interop.WiFiDirect.UnsetDeviceStateChangedCallback();
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset device state changed callback, Error - " + (WiFiDirectError)ret);
+ }
+ }
+
+ private void RegisterConnectionStatusChangedEvent()
+ {
+ _connectionChangedCallback = (int result, WiFiDirectConnectionState stateInfo, string address, IntPtr userData) =>
+ {
+ if (_connectionStatusChanged != null)
+ {
+ WiFiDirectError error = (WiFiDirectError)result;
+ WiFiDirectConnectionState state = stateInfo;
+
+ _connectionStatusChanged(null, new ConnectionStatusChangedEventArgs(error, state));
+ }
+ };
+ int ret = Interop.WiFiDirect.SetConnectionChangedCallback(_connectionChangedCallback, IntPtr.Zero);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set connection status changed callback, Error - " + (WiFiDirectError)ret);
+ }
+ }
+
+ private void UnregisterConnectionStatusChangedEvent()
+ {
+ int ret = Interop.WiFiDirect.UnsetConnectionChangedCallback();
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset connection status changed callback, Error - " + (WiFiDirectError)ret);
+ }
+ }
+
+ internal bool IsInitialize
+ {
+ get
+ {
+ return Globals.IsInitialize;
+ }
+ }
+ internal bool IsGroupOwner
+ {
+ get
+ {
+ bool isGroupOwner;
+ int ret = Interop.WiFiDirect.IsGroupOwner(out isGroupOwner);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get whether this device is the group owner or not, Error - " + (WiFiDirectError)ret);
+ }
+
+ return isGroupOwner;
+ }
+ }
+
+ internal bool IsAutonomousGroup
+ {
+ get
+ {
+ bool isAutonomousGroup;
+ int ret = Interop.WiFiDirect.IsAutonomousGroup(out isAutonomousGroup);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to check whether the current group is autonomous or not, Error - " + (WiFiDirectError)ret);
+ }
+
+ return isAutonomousGroup;
+ }
+ }
+
+ internal string Ssid
+ {
+ get
+ {
+ string ssid;
+ int ret = Interop.WiFiDirect.GetSsid(out ssid);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get SSID of local device, Error - " + (WiFiDirectError)ret);
+ return null;
+ }
+
+ return ssid;
+ }
+ }
+
+ internal string NetworkInterface
+ {
+ get
+ {
+ string networkInterface;
+ int ret = Interop.WiFiDirect.GetInterfaceName(out networkInterface);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get name of network interface, Error - " + (WiFiDirectError)ret);
+ return "";
+ }
+
+ return networkInterface;
+ }
+ }
+
+ internal string IpAddress
+ {
+ get
+ {
+ string ipAddress;
+ int ret = Interop.WiFiDirect.GetIpAddress(out ipAddress);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get IP address of local device, Error - " + (WiFiDirectError)ret);
+ return "";
+ }
+
+ return ipAddress;
+ }
+ }
+
+ internal string SubnetMask
+ {
+ get
+ {
+ string subnetMask;
+ int ret = Interop.WiFiDirect.GetSubnetMask(out subnetMask);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get subnet mask, Error - " + (WiFiDirectError)ret);
+ return "";
+ }
+
+ return subnetMask;
+ }
+ }
+
+ internal string GatewayAddress
+ {
+ get
+ {
+ string gatewayAddress;
+ int ret = Interop.WiFiDirect.GetGatewayAddress(out gatewayAddress);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get gateway address, Error - " + (WiFiDirectError)ret);
+ return "";
+ }
+
+ return gatewayAddress;
+ }
+ }
+
+ internal string MacAddress
+ {
+ get
+ {
+ string macAddress;
+ int ret = Interop.WiFiDirect.GetMacAddress(out macAddress);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get mac address, Error - " + (WiFiDirectError)ret);
+ return null;
+ }
+
+ return macAddress;
+ }
+ }
+
+ internal WiFiDirectState State
+ {
+ get
+ {
+ WiFiDirectState state;
+ int ret = Interop.WiFiDirect.GetState(out state);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get state of Wi-Fi direct service, Error - " + (WiFiDirectError)ret);
+ }
+
+ return state;
+ }
+ }
+
+ internal bool IsDiscoverable
+ {
+ get
+ {
+ bool isDiscoverable;
+ int ret = Interop.WiFiDirect.IsDiscoverable(out isDiscoverable);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to check whether the device is discoverable, Error - " + (WiFiDirectError)ret);
+ }
+
+ return isDiscoverable;
+ }
+ }
+
+ internal bool IsListenOnly
+ {
+ get
+ {
+ bool isListenOnly;
+ int ret = Interop.WiFiDirect.IsListeningOnly(out isListenOnly);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to check whether the local device is listening only, Error - " + (WiFiDirectError)ret);
+ }
+
+ return isListenOnly;
+ }
+ }
+
+ internal WiFiDirectPrimaryDeviceType PrimaryType
+ {
+ get
+ {
+ WiFiDirectPrimaryDeviceType primaryType;
+ int ret = Interop.WiFiDirect.GetPrimaryType(out primaryType);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get the primary device type of local device, Error - " + (WiFiDirectError)ret);
+ }
+
+ return primaryType;
+ }
+ }
+
+ internal WiFiDirectSecondaryDeviceType SecondaryType
+ {
+ get
+ {
+ WiFiDirectSecondaryDeviceType secondaryType;
+ int ret = Interop.WiFiDirect.GetSecondaryType(out secondaryType);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get the secondary device type of local device, Error - " + (WiFiDirectError)ret);
+ }
+
+ return secondaryType;
+ }
+ }
+
+ internal int WpsMode
+ {
+ get
+ {
+ int mode;
+ int ret = Interop.WiFiDirect.GetWpsMode(out mode);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get supproted wps modes at local device, Error - " + (WiFiDirectError)ret);
+ return -1;
+ }
+
+ return mode;
+ }
+ }
+
+ internal WiFiDirectWpsType WpsType
+ {
+ get
+ {
+ WiFiDirectWpsType wpsType;
+ int ret = Interop.WiFiDirect.GetLocalWpsType(out wpsType);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get the WPS type, Error - " + (WiFiDirectError)ret);
+ }
+
+ return wpsType;
+ }
+ }
+
+ internal int OperatingChannel
+ {
+ get
+ {
+ int channel;
+ int ret = Interop.WiFiDirect.GetChannel(out channel);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get operating channel, Error - " + (WiFiDirectError)ret);
+ return -1;
+ }
+
+ return channel;
+ }
+ }
+
+ internal bool PersistentGroupEnabled
+ {
+ get
+ {
+ bool isEnabled;
+ int ret = Interop.WiFiDirect.GetPersistentGroupState(out isEnabled);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to check persistent group state, Error - " + (WiFiDirectError)ret);
+ }
+
+ return isEnabled;
+ }
+
+ set
+ {
+ int ret = Interop.WiFiDirect.SetPersistentGroupState(value);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set the persistent group state, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+ }
+ }
+
+ internal bool AutoConnect
+ {
+ get
+ {
+ bool isAutoConnect;
+ int ret = Interop.WiFiDirect.GetAutoConnectionMode(out isAutoConnect);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get autoconnection mode status, Error - " + (WiFiDirectError)ret);
+ }
+
+ return isAutoConnect;
+ }
+
+ set
+ {
+ int ret = Interop.WiFiDirect.SetAutoConnectionMode(value);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set the autoconnection mode, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+ }
+ }
+
+ internal string WpsPin
+ {
+ get
+ {
+ string pin;
+ int ret = Interop.WiFiDirect.GetWpsPin(out pin);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get WPS pin, Error - " + (WiFiDirectError)ret);
+ }
+
+ return pin;
+ }
+
+ set
+ {
+ int ret = Interop.WiFiDirect.SetWpsPin(value.ToString());
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set or update WPS pin, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+ }
+ }
+
+ internal string Name
+ {
+ get
+ {
+ string name;
+ int ret = Interop.WiFiDirect.GetName(out name);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get name of local device, Error - " + (WiFiDirectError)ret);
+ return null;
+ }
+
+ return name;
+ }
+
+ set
+ {
+ int ret = Interop.WiFiDirect.SetName(value.ToString());
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set name of local device, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+ }
+ }
+
+ internal WiFiDirectWpsType RequestedWps
+ {
+ get
+ {
+ WiFiDirectWpsType wpsType;
+ int ret = Interop.WiFiDirect.GetReqWpsType(out wpsType);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get the requested WPS type, Error - " + (WiFiDirectError)ret);
+ }
+
+ return wpsType;
+ }
+
+ set
+ {
+ int ret = Interop.WiFiDirect.SetReqWpsType(value);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set the requested WPS type, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+ }
+ }
+
+ internal int GroupOwnerIntent
+ {
+ get
+ {
+ int intent;
+ int ret = Interop.WiFiDirect.GetIntent(out intent);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get the intent of the group owner, Error - " + (WiFiDirectError)ret);
+ }
+
+ return intent;
+ }
+
+ set
+ {
+ int ret = Interop.WiFiDirect.SetIntent(value);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set the intent of the group owner, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+ }
+ }
+
+ internal int MaxClients
+ {
+ get
+ {
+ int maxClients;
+ int ret = Interop.WiFiDirect.GetMaxClients(out maxClients);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get the max number of clients, Error - " + (WiFiDirectError)ret);
+ }
+
+ return maxClients;
+ }
+
+ set
+ {
+ int ret = Interop.WiFiDirect.SetMaxClients(value);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set the max number of clients, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+ }
+ }
+
+ internal string Passphrase
+ {
+ get
+ {
+ string passphrase;
+ int ret = Interop.WiFiDirect.GetPassPhrase(out passphrase);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get Wi-Fi Protected Access password, Error - " + (WiFiDirectError)ret);
+ return "";
+ }
+
+ return passphrase;
+ }
+
+ set
+ {
+ int ret = Interop.WiFiDirect.SetPassPhrase(value.ToString());
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set or update Wi-Fi Protected Access password, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+ }
+ }
+
+ internal int SessionTimer
+ {
+ get
+ {
+ int sessionTimer;
+ int ret = Interop.WiFiDirect.GetSessionTimer(out sessionTimer);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get the timer used to expire the connection session, Error - " + (WiFiDirectError)ret);
+ }
+
+ return sessionTimer;
+ }
+
+ set
+ {
+ int ret = Interop.WiFiDirect.SetSessionTimer(value);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set the timer used to expire the connection session, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+ }
+ }
+
+ internal void Activate()
+ {
+ int ret = Interop.WiFiDirect.Activate();
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to activate Wi-Fi direct service, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+ }
+
+ internal void Deactivate()
+ {
+ int ret = Interop.WiFiDirect.Deactivate();
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to deactivate Wi-Fi direct service, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+ }
+
+ internal void StartDiscovery(bool listenOnly, int duration, WiFiDirectDiscoveryChannel channel = WiFiDirectDiscoveryChannel.FullScan)
+ {
+ int ret = Interop.WiFiDirect.StartDiscoveryInChannel(listenOnly, duration, channel);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to start discovery, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+ }
+
+ internal void CancelDiscovery()
+ {
+ int ret = Interop.WiFiDirect.StopDiscovery();
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to cancel discovery, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+ }
+
+ internal IEnumerable<WiFiDirectPeer> GetDiscoveredPeers()
+ {
+ List<WiFiDirectPeer> discoveredPeerList = new List<WiFiDirectPeer>();
+ Interop.WiFiDirect.DiscoveredPeerCallback callback = (ref DiscoveredPeerStruct peer, IntPtr userData) =>
+ {
+ if (!peer.Equals(null))
+ {
+ discoveredPeerList.Add(WiFiDirectUtils.ConvertStructToDiscoveredPeer(peer));
+ }
+
+ return true;
+ };
+ int ret = Interop.WiFiDirect.GetDiscoveredPeers(callback, IntPtr.Zero);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get information of discovered peers, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+
+ return discoveredPeerList;
+ }
+
+ internal IEnumerable<WiFiDirectPeer> GetConnectedPeers()
+ {
+ List<WiFiDirectPeer> connectedPeerList = new List<WiFiDirectPeer>();
+ Interop.WiFiDirect.ConnectedPeerCallback callback = (ref ConnectedPeerStruct peer, IntPtr userData) =>
+ {
+ if (!peer.Equals(null))
+ {
+ connectedPeerList.Add(WiFiDirectUtils.ConvertStructToConnectedPeer(peer));
+ }
+
+ return true;
+ };
+ int ret = Interop.WiFiDirect.GetConnectedPeers(callback, IntPtr.Zero);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get information of connected peers, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+
+ return connectedPeerList;
+ }
+
+ internal void DisconnectAll()
+ {
+ int ret = Interop.WiFiDirect.DisconnectAll();
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to disconnect all connected links, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+ }
+
+ internal void CreateGroup()
+ {
+ int ret = Interop.WiFiDirect.CreateGroup();
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to create a WiFi-Direct group, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+ }
+
+ internal void DestroyGroup()
+ {
+ int ret = Interop.WiFiDirect.DestroyGroup();
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to destroy the WiFi-Direct group, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+ }
+
+ internal void ActivatePushButton()
+ {
+ int ret = Interop.WiFiDirect.ActivatePushButton();
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set the Wps config PBC, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+ }
+
+ internal IEnumerable<WiFiDirectWpsType> GetSupportedWpsTypes()
+ {
+ List<WiFiDirectWpsType> wpsList = new List<WiFiDirectWpsType>();
+ Interop.WiFiDirect.WpsTypeCallback callback = (WiFiDirectWpsType type, IntPtr userData) =>
+ {
+ if (!type.Equals(null))
+ {
+ wpsList.Add(type);
+ }
+
+ return true;
+ };
+ int ret = Interop.WiFiDirect.GetWpsTypes(callback, IntPtr.Zero);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get the supported WPS types, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+
+ return wpsList;
+ }
+
+ internal IEnumerable<WiFiDirectPersistentGroup> GetPersistentGroups()
+ {
+ List<WiFiDirectPersistentGroup> persistentGroupList = new List<WiFiDirectPersistentGroup>();
+ Interop.WiFiDirect.PersistentGroupCallback callback = (string address, string ssid, IntPtr userData) =>
+ {
+ if (address != null && ssid != null)
+ {
+ persistentGroupList.Add(new WiFiDirectPersistentGroup(address, ssid));
+ }
+
+ return true;
+ };
+ int ret = Interop.WiFiDirect.GetPersistentGroups(callback, IntPtr.Zero);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get the persistent groups, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+
+ return persistentGroupList;
+ }
+
+ internal void RemovePersistentGroup(WiFiDirectPersistentGroup group)
+ {
+ int ret = Interop.WiFiDirect.RemovePersistentGroup(group.MacAddress, group.Ssid);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to remove a persistent group, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+ }
+
+ internal void InitMiracast(bool enable)
+ {
+ int ret = Interop.WiFiDirect.InitMiracast(enable);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set the WiFi-Direct Display(MIRACAST) service, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+ }
+
+ internal void InitDisplay()
+ {
+ int ret = Interop.WiFiDirect.InitDisplay();
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to enable Wi-Fi Display functionality, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+
+ else
+ {
+ Globals.s_isDisplay = true;
+ }
+ }
+
+ internal void DeinitDisplay()
+ {
+ int ret = Interop.WiFiDirect.DeinitDisplay();
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to disable Wi-Fi Display functionality, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+
+ else
+ {
+ Globals.s_isDisplay = false;
+ }
+ }
+
+ internal void SetDisplay(WiFiDirectDisplayType type, int port, int hdcp)
+ {
+ int ret = Interop.WiFiDirect.SetDisplay(type, port, hdcp);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set the Wi-Fi Display parameters, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+ }
+
+ internal void SetDisplayAvailability(bool availability)
+ {
+ int ret = Interop.WiFiDirect.SetDisplayAvailability(availability);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set the Wi-Fi Display session availability, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+ }
+
+ internal void SetAutoGroupRemove(bool enable)
+ {
+ int ret = Interop.WiFiDirect.SetAutoGroupRemoval(enable);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set automatic group removal feature when all peers are disconnected, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+ }
+
+ internal uint RegisterService(WiFiDirectServiceType type, string info, string serviceInfo)
+ {
+ uint serviceId;
+ int ret = Interop.WiFiDirect.RegisterService(type, info, serviceInfo, out serviceId);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to register for service, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+
+ return serviceId;
+ }
+
+ internal void DeregisterService(uint serviceId)
+ {
+ int ret = Interop.WiFiDirect.DeregisterService(serviceId);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to deregister service, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+ }
+
+ internal static WiFiDirectManagerImpl Instance
+ {
+ get
+ {
+ if (_instance == null)
+ {
+ _instance = new WiFiDirectManagerImpl();
+ }
+
+ return _instance;
+ }
+ }
+
+ private WiFiDirectManagerImpl()
+ {
+ }
+
+ internal void Initialize()
+ {
+ int ret = Interop.WiFiDirect.Initialize();
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to initialize Wi-Fi direct, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+
+ else
+ {
+ Globals.s_isInitialize = true;
+ }
+ }
+
+ ~WiFiDirectManagerImpl()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (_disposed)
+ {
+ return;
+ }
+
+ if (disposing)
+ {
+ // Free managed objects.
+ }
+
+ //Free unmanaged objects
+ RemoveAllRegisteredEvent();
+ Deinitialize();
+ _disposed = true;
+ }
+
+ private void Deinitialize()
+ {
+ int ret = Interop.WiFiDirect.Deinitialize();
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to deinitialize Wi-Fi direct, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+
+ else
+ {
+ Globals.s_isInitialize = false;
+ }
+ }
+
+ private void RemoveAllRegisteredEvent()
+ {
+ //unregister all remaining events when this object is released.
+ if (_stateChanged != null)
+ {
+ UnregisterStateChangedEvent();
+ }
+
+ if (_discoveryStateChanged != null)
+ {
+ UnregisterDiscoveryStateChangedEvent();
+ }
+
+ if (_peerFound != null)
+ {
+ UnregisterPeerFoundEvent();
+ }
+
+ if (_deviceStateChanged != null)
+ {
+ UnregisterDeviceStateChangedEvent();
+ }
+
+ if (_connectionStatusChanged != null)
+ {
+ UnregisterConnectionStatusChangedEvent();
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectPeer.cs b/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectPeer.cs
new file mode 100644
index 0000000..aebf2a6
--- /dev/null
+++ b/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectPeer.cs
@@ -0,0 +1,754 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Collections.Concurrent;
+using System.Collections.ObjectModel;
+using System.Collections.Specialized;
+
+namespace Tizen.Network.WiFiDirect
+{
+ /// <summary>
+ /// WiFiDirectPeer class is used to handle the connection with remote devices using WiFi Direct.
+ /// </summary>
+ /// <privilege> http://tizen.org/privilege/wifidirect </privilege>
+ public class WiFiDirectPeer
+ {
+ private event EventHandler<ConnectionStateChangedEventArgs> _connectionStateChanged;
+ private event EventHandler<IpAddressAssignedEventArgs> _ipAddressAssigned;
+ private event EventHandler<ServiceStateChangedEventArgs> _serviceStateChanged;
+
+ private Interop.WiFiDirect.ConnectionStateChangedCallback _connectionStateChangedCallback;
+ private Interop.WiFiDirect.ClientIpAddressAssignedCallback _ipAddressAssignedCallback;
+ private Interop.WiFiDirect.ServiceStateChangedCallback _serviceStateChangedCallback;
+
+ internal string _peerDeviceName;
+ internal string _peerIpAddress;
+ internal string _peerMacAddress;
+ internal string _peerInterfaceAddress;
+ internal int _peerChannel;
+ internal bool _isPeerConnected;
+ internal bool _isPeerGroupOwner;
+ internal bool _peerP2PSupport;
+ internal WiFiDirectPrimaryDeviceType _peerPrimaryType;
+ internal WiFiDirectSecondaryDeviceType _peerSecondaryType;
+ internal int _peerWpsTypes;
+ internal bool _p2PInvitationSupported;
+ internal uint _peerServiceCount;
+ internal IEnumerable<string> _peerServiceList;
+ internal bool _isPeerMiracastDevice;
+
+ internal WiFiDirectPeer()
+ {
+ }
+
+ /// <summary>
+ /// Name of Peer device.
+ /// </summary>
+ public string Name
+ {
+ get
+ {
+ return _peerDeviceName;
+ }
+ }
+
+ /// <summary>
+ /// Ip address of the peer device.
+ /// </summary>
+ public string IpAddress
+ {
+ get
+ {
+ return _peerIpAddress;
+ }
+ }
+
+ /// <summary>
+ /// Mac address of the peer device.
+ /// </summary>
+ public string MacAddress
+ {
+ get
+ {
+ return _peerMacAddress;
+ }
+ }
+
+ /// <summary>
+ /// Interface address of the peer device.
+ /// </summary>
+ public string InterfaceAddress
+ {
+ get
+ {
+ return _peerInterfaceAddress;
+ }
+ }
+
+ /// <summary>
+ /// Listening channel of the peer device.
+ /// </summary>
+ public int Channel
+ {
+ get
+ {
+ return _peerChannel;
+ }
+ }
+
+ /// <summary>
+ /// Connected state of the peer device.
+ /// </summary>
+ public bool IsConnected
+ {
+ get
+ {
+ return _isPeerConnected;
+ }
+ }
+
+ /// <summary>
+ /// P2P group state of the peer device.
+ /// </summary>
+ public bool IsGroupOwner
+ {
+ get
+ {
+ return _isPeerGroupOwner;
+ }
+ }
+
+ /// <summary>
+ /// P2P state of the peer device.
+ /// </summary>
+ public bool P2PSupport
+ {
+ get
+ {
+ return _peerP2PSupport;
+ }
+ }
+
+ /// <summary>
+ /// Primary catagory of the peer device.
+ /// </summary>
+ public WiFiDirectPrimaryDeviceType PrimaryType
+ {
+ get
+ {
+ return _peerPrimaryType;
+ }
+ }
+
+ /// <summary>
+ /// Sub category of the peer device.
+ /// </summary>
+ public WiFiDirectSecondaryDeviceType SecondaryType
+ {
+ get
+ {
+ return _peerSecondaryType;
+ }
+ }
+
+ /// <summary>
+ /// List of supported WPS type of the peer device.
+ /// </summary>
+ public int WpsTypes
+ {
+ get
+ {
+ return _peerWpsTypes;
+ }
+ }
+
+ /// <summary>
+ /// P2P invitation state of the peer device.
+ /// </summary>
+ public bool IsP2PInvitationSupported
+ {
+ get
+ {
+ return _p2PInvitationSupported;
+ }
+ }
+
+ /// <summary>
+ /// Number of registered services of the peer device.
+ /// </summary>
+ public uint ServiceCount
+ {
+ get
+ {
+ return _peerServiceCount;
+ }
+ }
+
+ /// <summary>
+ /// List of registered services of the peer device.
+ /// </summary>
+ public IEnumerable<string> ServiceList
+ {
+ get
+ {
+ return _peerServiceList;
+ }
+ }
+
+ /// <summary>
+ /// Checks if peer device is a wifi display device.
+ /// </summary>
+ public bool IsMiracastDevice
+ {
+ get
+ {
+ return _isPeerMiracastDevice;
+ }
+ }
+
+ /// <summary>
+ /// Wi-Fi Display device type of the peer device.
+ /// </summary>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// If there is any error, default value of WiFiDirectDisplayType will be returned.
+ /// </remarks>
+ public WiFiDirectDisplayType Display
+ {
+ get
+ {
+ if (Globals.IsActivated)
+ {
+ WiFiDirectDisplayType displayType;
+ int ret = Interop.WiFiDirect.GetDisplayType(_peerMacAddress, out displayType);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get the peer display type, Error - " + (WiFiDirectError)ret);
+ }
+
+ return displayType;
+ }
+
+ else
+ {
+ return default(WiFiDirectDisplayType);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Wi-Fi Display Session Availability of the peer device.
+ /// </summary>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// If there is any error, false will be returned.
+ /// </remarks>
+ public bool DisplayAvailability
+ {
+ get
+ {
+ if (Globals.IsActivated)
+ {
+ bool displayAvailability;
+ int ret = Interop.WiFiDirect.GetDisplayAvailability(_peerMacAddress, out displayAvailability);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get the peer display availability, Error - " + (WiFiDirectError)ret);
+ }
+
+ return displayAvailability;
+ }
+
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Hdcp information of the peer device.
+ /// </summary>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// If there is any error, -1 will be returned.
+ /// </remarks>
+ public int Hdcp
+ {
+ get
+ {
+ if (Globals.IsActivated)
+ {
+ int hdcpSupport;
+ int ret = Interop.WiFiDirect.GetDisplayHdcp(_peerMacAddress, out hdcpSupport);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get the peer display hdcp support, Error - " + (WiFiDirectError)ret);
+ return -1;
+ }
+
+ return hdcpSupport;
+ }
+
+ else
+ {
+ return -1;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Port of the connected peer device.
+ /// </summary>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// If there is any error, -1 will be returned.
+ /// </remarks>
+ public int Port
+ {
+ get
+ {
+ if (Globals.IsActivated)
+ {
+ int displayPort;
+ int ret = Interop.WiFiDirect.GetDisplayPort(_peerMacAddress, out displayPort);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get the peer display port, Error - " + (WiFiDirectError)ret);
+ return -1;
+ }
+
+ return displayPort;
+ }
+
+ else
+ {
+ return -1;
+ }
+ }
+ }
+
+ /// <summary>
+ /// WiFi Display max throughput of the peer device.
+ /// </summary>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// If there is any error, -1 will be returned.
+ /// </remarks>
+ public int Throughput
+ {
+ get
+ {
+ if (Globals.IsActivated)
+ {
+ int displayThroughput;
+ int ret = Interop.WiFiDirect.GetDisplayThroughput(_peerMacAddress, out displayThroughput);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get the peer display max throughput, Error - " + (WiFiDirectError)ret);
+ return -1;
+ }
+
+ return displayThroughput;
+ }
+
+ else
+ {
+ return -1;
+ }
+ }
+ }
+
+ /// <summary>
+ /// WiFi RSSI value of the peer device.
+ /// </summary>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// If there is any error, -1 will be returned.
+ /// </remarks>
+ public int Rssi
+ {
+ get
+ {
+ if (Globals.IsActivated)
+ {
+ int rssi;
+ int ret = Interop.WiFiDirect.GetRssi(_peerMacAddress, out rssi);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to get the peer RSSI, Error - " + (WiFiDirectError)ret);
+ return -1;
+ }
+
+ return rssi;
+ }
+
+ else
+ {
+ return -1;
+ }
+ }
+ }
+ /// <summary>
+ /// (event) ConnectionStateChanged event is raised when the connection state of the peer device changes.
+ /// </summary>
+ public event EventHandler<ConnectionStateChangedEventArgs> ConnectionStateChanged
+ {
+ add
+ {
+ if (Globals.IsInitialize)
+ {
+ if (_connectionStateChanged == null)
+ {
+ RegisterConnectionStateChangedEvent();
+ }
+
+ _connectionStateChanged += value;
+ }
+ }
+
+ remove
+ {
+ if (Globals.IsInitialize)
+ {
+ _connectionStateChanged -= value;
+ if (_connectionStateChanged == null)
+ {
+ UnregisterConnectionStateChangedEvent();
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// (event) IpAddressAssigned event is raised when ip address of the peer device is assigned.
+ /// </summary>
+ public event EventHandler<IpAddressAssignedEventArgs> IpAddressAssigned
+ {
+ add
+ {
+ if (Globals.IsInitialize)
+ {
+ if (_ipAddressAssigned == null)
+ {
+ RegisterIpAddressAssignedEvent();
+ }
+
+ _ipAddressAssigned += value;
+ }
+ }
+
+ remove
+ {
+ if (Globals.IsInitialize)
+ {
+ _ipAddressAssigned -= value;
+ if (_ipAddressAssigned == null)
+ {
+ UnregisterIpAddressAssignedEvent();
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// (event) ServiceStateChanged is raised when state of service discovery is changed.
+ /// </summary>
+ public event EventHandler<ServiceStateChangedEventArgs> ServiceStateChanged
+ {
+ add
+ {
+ if (Globals.IsInitialize)
+ {
+ if (_serviceStateChanged == null)
+ {
+ RegisterServiceStateChangedEvent();
+ }
+
+ _serviceStateChanged += value;
+ }
+ }
+
+ remove
+ {
+ if (Globals.IsInitialize)
+ {
+ _serviceStateChanged -= value;
+ if (_serviceStateChanged == null)
+ {
+ UnregisterServiceStateChangedEvent();
+ }
+ }
+ }
+ }
+
+ private void RegisterConnectionStateChangedEvent()
+ {
+ _connectionStateChangedCallback = (int result, WiFiDirectConnectionState state, string address, IntPtr userData) =>
+ {
+ if (_connectionStateChanged != null)
+ {
+ WiFiDirectError res = (WiFiDirectError)result;
+ _connectionStateChanged(null, new ConnectionStateChangedEventArgs(res, state, address));
+ }
+ };
+ int ret = Interop.WiFiDirect.SetConnectionChangedCallback(_connectionStateChangedCallback, IntPtr.Zero);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set connection state changed callback, Error - " + (WiFiDirectError)ret);
+ }
+ }
+
+ private void UnregisterConnectionStateChangedEvent()
+ {
+ int ret = Interop.WiFiDirect.UnsetConnectionChangedCallback();
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset connection state changed callback, Error - " + (WiFiDirectError)ret);
+ }
+ }
+
+ private void RegisterIpAddressAssignedEvent()
+ {
+ _ipAddressAssignedCallback = (string macAddress, string ipAddress, string interfaceAddress, IntPtr userData) =>
+ {
+ if (_ipAddressAssigned != null)
+ {
+ _ipAddressAssigned(null, new IpAddressAssignedEventArgs(macAddress, ipAddress, interfaceAddress));
+ }
+ };
+ int ret = Interop.WiFiDirect.SetIpAddressAssignedCallback(_ipAddressAssignedCallback, IntPtr.Zero);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set ip address assigned callback, Error - " + (WiFiDirectError)ret);
+ }
+ }
+
+ private void UnregisterIpAddressAssignedEvent()
+ {
+ int ret = Interop.WiFiDirect.UnsetIpAddressAssignedCallback();
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset ip address assigned callback, Error - " + (WiFiDirectError)ret);
+ }
+ }
+
+ private void RegisterServiceStateChangedEvent()
+ {
+ _serviceStateChangedCallback = (int result, WiFiDirectServiceDiscoveryState stateInfo, WiFiDirectServiceType typeInfo, IntPtr responseData, string address, IntPtr userData) =>
+ {
+ if (_serviceStateChanged != null)
+ {
+ WiFiDirectError error = (WiFiDirectError)result;
+ WiFiDirectServiceDiscoveryState state = stateInfo;
+ WiFiDirectServiceType type = typeInfo;
+ string response = Marshal.PtrToStringAnsi(responseData);
+ IntPtr peer;
+ Interop.WiFiDirect.GetDiscoveredPeerInfo(address, out peer);
+ DiscoveredPeerStruct peerStruct = (DiscoveredPeerStruct)Marshal.PtrToStructure(peer, typeof(DiscoveredPeerStruct));
+
+ _serviceStateChanged(null, new ServiceStateChangedEventArgs(error, state, type, response, WiFiDirectUtils.ConvertStructToDiscoveredPeer(peerStruct)));
+ }
+ };
+ int ret = Interop.WiFiDirect.SetServiceStateChangedCallback(_serviceStateChangedCallback, IntPtr.Zero);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set service state changed callback, Error - " + (WiFiDirectError)ret);
+ }
+ }
+
+ private void UnregisterServiceStateChangedEvent()
+ {
+ int ret = Interop.WiFiDirect.UnsetServiceStateChangedCallback();
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to unset service state changed callback, Error - " + (WiFiDirectError)ret);
+ }
+ }
+
+ /// <summary>
+ /// Connects to a specified remote device.
+ /// </summary>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// If this succeeds, ConnectionStateChanged event will be invoked.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">Thrown when the wifidirect is not supported</exception>
+ public void Connect()
+ {
+ if (Globals.IsActivated)
+ {
+ int ret = Interop.WiFiDirect.Connect(_peerMacAddress);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to connect, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+ }
+
+ else
+ {
+ Log.Error(Globals.LogTag, "Wifi-direct is not activated");
+ WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
+ }
+ }
+
+ /// <summary>
+ /// Cancels the connection now in progress.
+ /// </summary>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">Thrown when the wifidirect is not supported</exception>
+ public void CancelConnection()
+ {
+ if (Globals.IsActivated)
+ {
+ int ret = Interop.WiFiDirect.CancelConnection(_peerMacAddress);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to cancel the connection, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+ }
+
+ else
+ {
+ Log.Error(Globals.LogTag, "Wifi-direct is not activated");
+ WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
+ }
+ }
+
+ /// <summary>
+ /// Disconnects the specified remote device.
+ /// </summary>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// If this succeeds, ConnectionStateChanged event will be invoked.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">Thrown when the wifidirect is not supported</exception>
+ public void Disconnect()
+ {
+ if (Globals.IsActivated)
+ {
+ int ret = Interop.WiFiDirect.Disconnect(_peerMacAddress);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to disconnect, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+ }
+
+ else
+ {
+ Log.Error(Globals.LogTag, "Wifi-direct is not activated");
+ WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
+ }
+ }
+
+ /// <summary>
+ /// Allows a device to connect automatically.
+ /// </summary>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">Thrown when the wifidirect is not supported</exception>
+ public void SetAutoConnect()
+ {
+ if (Globals.IsActivated)
+ {
+ int ret = Interop.WiFiDirect.SetAutoConnectionPeer(_peerMacAddress);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to set auto connection, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+ }
+
+ else
+ {
+ Log.Error(Globals.LogTag, "Wifi-direct is not activated");
+ WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
+ }
+ }
+
+ /// <summary>
+ /// Starts the Wi-Fi Direct service discovery.
+ /// </summary>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// If this succeeds, ServiceStateChanged event will be invoked.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">
+ /// Thrown during one of the following cases :
+ /// 1. When the wifidirect is not supported
+ /// 2. When the wifidirect service discovery is not supported
+ /// </exception>
+ /// <param name="type">Type of service.</param>
+ public void StartServiceDiscovery(WiFiDirectServiceType type)
+ {
+ if (Globals.IsActivated)
+ {
+ int ret = Interop.WiFiDirect.StartServiceDiscovery(_peerMacAddress, type);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to start Wi-Fi Direct service discovery, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+ }
+
+ else
+ {
+ Log.Error(Globals.LogTag, "Wifi-direct is not activated");
+ WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
+ }
+ }
+
+ /// <summary>
+ /// Stops the Wi-Fi Direct service discovery.
+ /// </summary>
+ /// <remarks>
+ /// Wi-Fi Direct must be activated.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">
+ /// Thrown during one of the following cases :
+ /// 1. When the wifidirect is not supported
+ /// 2. When the wifidirect service discovery is not supported
+ /// </exception>
+ /// <param name="type">Type of service.</param>
+ public void CancelServiceDiscovery(WiFiDirectServiceType type)
+ {
+ if (Globals.IsActivated)
+ {
+ int ret = Interop.WiFiDirect.StopServiceDiscovery(_peerMacAddress, type);
+ if (ret != (int)WiFiDirectError.None)
+ {
+ Log.Error(Globals.LogTag, "Failed to stop Wi-Fi Direct service discovery, Error - " + (WiFiDirectError)ret);
+ WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
+ }
+ }
+
+ else
+ {
+ Log.Error(Globals.LogTag, "Wifi-direct is not activated");
+ WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectPersistentGroup.cs b/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectPersistentGroup.cs
new file mode 100644
index 0000000..10274c9
--- /dev/null
+++ b/src/Tizen.Network.WiFiDirect/Tizen.Network.WiFiDirect/WiFiDirectPersistentGroup.cs
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Network.WiFiDirect
+{
+ /// <summary>
+ /// A class to handle persistent groups.
+ /// </summary>
+ public class WiFiDirectPersistentGroup
+ {
+ private string _address;
+ private string _ssid;
+
+ internal WiFiDirectPersistentGroup(string address, string id)
+ {
+ _address = address;
+ _ssid = id;
+ }
+
+ /// <summary>
+ /// MAC address of the persistent group owner.
+ /// </summary>
+ public string MacAddress
+ {
+ get
+ {
+ return _address;
+ }
+ }
+
+ /// <summary>
+ /// SSID (Service Set Identifier) of the persistent group owner.
+ /// </summary>
+ public string Ssid
+ {
+ get
+ {
+ return _ssid;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Interop/Interop.CkmcErrors.cs b/src/Tizen.Security.SecureRepository/Interop/Interop.CkmcErrors.cs
new file mode 100644
index 0000000..3e12547
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Interop/Interop.CkmcErrors.cs
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+using System;
+using Tizen.Internals.Errors;
+
+internal static partial class Interop
+{
+ private const int TizenErrorKeyManager = -0x01E10000;
+ private const string LogTag = "Tizen.Security.SecureRepository";
+
+ internal enum KeyManagerError : int
+ {
+ None = ErrorCode.None,
+ InvalidParameter = ErrorCode.InvalidParameter,
+ VerificationFailed = TizenErrorKeyManager | 0x0D // CKMC_ERROR_VERIFICATION_FAILED
+ };
+
+ internal static void CheckNThrowException(int err, string msg)
+ {
+ switch (err)
+ {
+ case (int)KeyManagerError.None:
+ return;
+ case (int)KeyManagerError.InvalidParameter:
+ throw new ArgumentException(string.Format("[{0}] {1}, error={2}",
+ LogTag, msg, ErrorFacts.GetErrorMessage(err)));
+ default:
+ throw new InvalidOperationException(string.Format("[{0}] {1}, error={2}",
+ LogTag, msg, ErrorFacts.GetErrorMessage(err)));
+ }
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Interop/Interop.CkmcManager.cs b/src/Tizen.Security.SecureRepository/Interop/Interop.CkmcManager.cs
new file mode 100644
index 0000000..51141d0
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Interop/Interop.CkmcManager.cs
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class CkmcManager
+ {
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_save_key", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int SaveKey(string alias, CkmcKey key, CkmcPolicy policy);
+ // int ckmc_save_key(const char *alias, const ckmc_key_s key, const ckmc_policy_s policy);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_get_key", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int GetKey(string alias, string password, out IntPtr key);
+ // int ckmc_get_key(const char *alias, const char *password, ckmc_key_s **ppkey);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_get_key_alias_list", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int GetKeyAliasList(out IntPtr aliases);
+ // int ckmc_get_key_alias_list(ckmc_alias_list_s **ppalias_list);
+
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_save_cert", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int SaveCert(string alias, CkmcCert cert, CkmcPolicy policy);
+ // int ckmc_save_cert(const char *alias, const ckmc_cert_s cert, const ckmc_policy_s policy);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_get_cert", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int GetCert(string alias, string password, out IntPtr data);
+ // int ckmc_get_cert(const char *alias, const char *password, ckmc_cert_s** ppcert);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_get_cert_alias_list", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int GetCertAliasList(out IntPtr aliases);
+ // int ckmc_get_cert_alias_list(ckmc_alias_list_s **ppalias_list);
+
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_save_data", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int SaveData(string alias, CkmcRawBuffer data, CkmcPolicy policy);
+ // int ckmc_save_data(const char *alias, ckmc_raw_buffer_s data, const ckmc_policy_s policy);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_get_data", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int GetData(string alias, string password, out IntPtr data);
+ // int ckmc_get_data(const char* alias, const char* password, ckmc_raw_buffer_s **ppdata);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_get_data_alias_list", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int GetDataAliasList(out IntPtr aliases);
+ // int ckmc_get_data_alias_list(ckmc_alias_list_s **ppalias_list);
+
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_remove_alias", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int RemoveAlias(string alias);
+ // int ckmc_remove_alias(const char *alias);
+
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_save_pkcs12", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int SavePkcs12(string alias, IntPtr p12, CkmcPolicy keyPolicy, CkmcPolicy certPolicy);
+ // int ckmc_save_pkcs12(const char *alias, const ckmc_pkcs12_s* pkcs, const ckmc_policy_s key_policy, const ckmc_policy_s cert_policy);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_get_pkcs12", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int GetPkcs12(string alias, string keyPassword, string certPassword, out IntPtr pkcs12);
+ // int ckmc_get_pkcs12(const char *alias, const char *key_password, const char* cert_password, ckmc_pkcs12_s **pkcs12);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_set_permission", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int SetPermission(string alias, string accessor, int permissions);
+ // int ckmc_set_permission(const char *alias, const char *accessor, int permissions);
+
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_create_key_pair_rsa", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int CreateKeyPairRsa(UIntPtr size, string privateKeyAlias, string publicKeyAlias,
+ CkmcPolicy privateKeyPolicy, CkmcPolicy publicKeyPolicy);
+ // int ckmc_create_key_pair_rsa(const size_t size, const char* private_key_alias, const char* public_key_alias,
+ // const ckmc_policy_s policy_private_key, const ckmc_policy_s policy_public_key);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_create_key_pair_dsa", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int CreateKeyPairDsa(UIntPtr size, string privateKeyAlias, string publicKeyAlias,
+ CkmcPolicy privateKeyPolicy, CkmcPolicy publicKeyPolicy);
+ // int ckmc_create_key_pair_dsa(const size_t size, const char* private_key_alias, const char* public_key_alias,
+ // const ckmc_policy_s policy_private_key, const ckmc_policy_s policy_public_key);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_create_key_pair_ecdsa", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int CreateKeyPairEcdsa(int ecType, string privateKeyAlias, string publicKeyAlias,
+ CkmcPolicy privateKeyPolicy, CkmcPolicy publicKeyPolicy);
+ // int ckmc_create_key_pair_ecdsa(const ckmc_ec_type_e type, const char* private_key_alias, const char* public_key_alias,
+ // const ckmc_policy_s policy_private_key, const ckmc_policy_s policy_public_key);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_create_key_aes", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int CreateKeyAes(UIntPtr size, string ceyAlias, CkmcPolicy keyPolicy);
+ // int ckmc_create_key_aes(size_t size, const char* key_alias, ckmc_policy_s key_policy);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_create_signature", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int CreateSignature(string privateKeyAlias, string password, CkmcRawBuffer message,
+ int hashAlgorithm, int paddingAlgorithm, out IntPtr signature);
+ // int ckmc_create_signature(const char *private_key_alias, const char* password, const ckmc_raw_buffer_s message,
+ // const ckmc_hash_algo_e hash, const ckmc_rsa_padding_algo_e padding, ckmc_raw_buffer_s **ppsignature);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_verify_signature", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int VerifySignature(string publicKeyAlias, string password, CkmcRawBuffer message,
+ CkmcRawBuffer signature, int hashAlgorithm, int paddingAlgorithm);
+ // int ckmc_verify_signature(const char *public_key_alias, const char* password, const ckmc_raw_buffer_s message,
+ // const ckmc_raw_buffer_s signature, const ckmc_hash_algo_e hash, const ckmc_rsa_padding_algo_e padding);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_encrypt_data", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int EncryptData(IntPtr parameters, string keyAlias, string password, CkmcRawBuffer plainText, out IntPtr cipherText);
+ // int ckmc_encrypt_data(ckmc_param_list_h params, const char* key_alias, const char* password,
+ // const ckmc_raw_buffer_s decrypted, ckmc_raw_buffer_s **ppencrypted);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_decrypt_data", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int DecryptData(IntPtr parameters, string keyAlias, string password, CkmcRawBuffer cipherText, out IntPtr plainText);
+ // int ckmc_decrypt_data(ckmc_param_list_h params, const char* key_alias, const char* password,
+ // const ckmc_raw_buffer_s encrypted, ckmc_raw_buffer_s **ppdecrypted);
+
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_get_cert_chain", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int GetCertChain(IntPtr cert, IntPtr untrustedCerts, out IntPtr certChain);
+ // int ckmc_get_cert_chain(const ckmc_cert_s *cert, const ckmc_cert_list_s* untrustedcerts, ckmc_cert_list_s **ppcert_chain_list);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_get_cert_chain_with_trustedcert", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int GetCertChainWithTrustedCerts(IntPtr cert, IntPtr untrustedCerts, IntPtr trustedCerts,
+ bool useTrustedSystemCerts, out IntPtr certChain);
+ // int ckmc_get_cert_chain_with_trustedcert(const ckmc_cert_s *cert, const ckmc_cert_list_s* untrustedcerts,
+ // const ckmc_cert_list_s* trustedcerts, const bool use_trustedsystemcerts, ckmc_cert_list_s **ppcert_chain_list);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_ocsp_check", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int OcspCheck(IntPtr certChain, ref int ocspStatus);
+ // int ckmc_ocsp_check(const ckmc_cert_list_s *pcert_chain_list, ckmc_ocsp_status_e* ocsp_status);
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Interop/Interop.CkmcTypes.cs b/src/Tizen.Security.SecureRepository/Interop/Interop.CkmcTypes.cs
new file mode 100644
index 0000000..6482a35
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Interop/Interop.CkmcTypes.cs
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct CkmcPolicy
+ {
+ public CkmcPolicy(string password, bool extractable)
+ {
+ this.password = password;
+ this.extractable = extractable;
+ }
+ [MarshalAs(UnmanagedType.LPStr)]
+ public readonly string password;
+ [MarshalAs(UnmanagedType.Bool)]
+ public readonly bool extractable;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct CkmcKey
+ {
+ public CkmcKey(IntPtr binary, int keySize, int keyType, string password)
+ {
+ this.rawKey = binary;
+ this.size = (UIntPtr)keySize;
+ this.keyType = keyType;
+ this.password = password;
+ }
+ public readonly IntPtr rawKey;
+ public readonly UIntPtr size;
+ public readonly int keyType;
+ [MarshalAs(UnmanagedType.LPStr)]
+ public readonly string password;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct CkmcCert
+ {
+ public CkmcCert(IntPtr binary, int size, int dataFormat)
+ {
+ this.rawCert = binary;
+ this.size = (UIntPtr)size;
+ this.dataFormat = dataFormat;
+ }
+ public readonly IntPtr rawCert;
+ public readonly UIntPtr size;
+ public readonly int dataFormat;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct CkmcRawBuffer
+ {
+ public CkmcRawBuffer(IntPtr binary, int size)
+ {
+ this.data = binary;
+ this.size = (UIntPtr)size;
+ }
+ public readonly IntPtr data;
+ public readonly UIntPtr size;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct CkmcAliasList
+ {
+ public readonly IntPtr alias;
+ public readonly IntPtr next;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct CkmcCertList
+ {
+ public CkmcCertList(IntPtr cert, IntPtr next)
+ {
+ this.cert = cert;
+ this.next = next;
+ }
+ public readonly IntPtr cert;
+ public readonly IntPtr next;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct CkmcPkcs12
+ {
+ public CkmcPkcs12(IntPtr privateKey, IntPtr certificate, IntPtr caChain)
+ {
+ this.privateKey = privateKey;
+ this.certificate = certificate;
+ this.caChain = caChain;
+ }
+ public readonly IntPtr privateKey;
+ public readonly IntPtr certificate;
+ public readonly IntPtr caChain;
+ }
+
+ internal static partial class CkmcTypes
+ {
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_key_new", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int KeyNew(byte[] rawKey, UIntPtr size, int keyType, string password, out IntPtr cert);
+ // int ckmc_key_new(unsigned char *raw_key, size_t key_size, ckmc_key_type_e key_type, char *password, ckmc_key_s **ppkey);
+ //
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_key_free", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void KeyFree(IntPtr buffer);
+ // void ckmc_key_free(ckmc_key_s *key);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_buffer_new", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int BufferNew(byte[] data, UIntPtr size, out IntPtr buffer);
+ // int ckmc_buffer_new(unsigned char *data, size_t size, ckmc_raw_buffer_s** ppbuffer);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_buffer_free", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void BufferFree(IntPtr buffer);
+ // void ckmc_buffer_free(ckmc_raw_buffer_s* buffer);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_cert_new", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int CertNew(byte[] rawCert, UIntPtr size, int dataFormat, out IntPtr cert);
+ // int ckmc_cert_new(unsigned char *raw_cert, size_t cert_size, ckmc_data_format_e data_format, ckmc_cert_s** ppcert);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_cert_free", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void CertFree(IntPtr buffer);
+ // void ckmc_cert_free(ckmc_cert_s *cert);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_load_cert_from_file", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int LoadCertFromFile(string filePath, out IntPtr cert);
+ // int ckmc_load_cert_from_file(const char *file_path, ckmc_cert_s **cert);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_pkcs12_new", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Pkcs12New(IntPtr key, IntPtr cert, IntPtr caCerts, out IntPtr p12_bundle);
+ // int ckmc_pkcs12_new(ckmc_key_s *private_key, ckmc_cert_s* cert, ckmc_cert_list_s *ca_cert_list, ckmc_pkcs12_s** pkcs12_bundle);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_pkcs12_load", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Pkcs12Load(string filePath, string password, out IntPtr pkcs12);
+ // int ckmc_pkcs12_load(const char *file_path, const char* passphrase, ckmc_pkcs12_s **pkcs12_bundle);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_pkcs12_free", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void Pkcs12Free(IntPtr pkcs12);
+ // void ckmc_pkcs12_free(ckmc_pkcs12_s *pkcs12);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_alias_list_new", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AliasListNew(string alias, out IntPtr aliasList);
+ // int ckmc_alias_list_new(char *alias, ckmc_alias_list_s **ppalias_list);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_alias_list_add", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AliasListAdd(IntPtr previous, string alias, out IntPtr aliasList);
+ // int ckmc_alias_list_add(ckmc_alias_list_s *previous, char* alias, ckmc_alias_list_s **pplast);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_alias_list_free", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AliasListFree(IntPtr first);
+ // void ckmc_alias_list_free(ckmc_alias_list_s* first);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_alias_list_all_free", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AliasListAllFree(IntPtr first);
+ // void ckmc_alias_list_all_free(ckmc_alias_list_s* first);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_cert_list_new", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int CertListNew(IntPtr cert, out IntPtr certList);
+ // int ckmc_cert_list_new(ckmc_cert_s *cert, ckmc_cert_list_s **ppcert_list);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_cert_list_add", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int CertListAdd(IntPtr previous, IntPtr cert, out IntPtr certList);
+ // int ckmc_cert_list_add(ckmc_cert_list_s *previous, ckmc_cert_s *cert, ckmc_cert_list_s** pplast);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_cert_list_free", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void CertListFree(IntPtr first);
+ // void ckmc_cert_list_free(ckmc_cert_list_s *first);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_cert_list_all_free", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void CertListAllFree(IntPtr first);
+ // void ckmc_cert_list_all_free(ckmc_cert_list_s *first);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_param_list_new", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int ParamListNew(out IntPtr paramList);
+ // int ckmc_param_list_new(ckmc_param_list_h *pparams);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_param_list_set_integer", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int ParamListSetInteger(IntPtr paramList, int name, long value);
+ // int ckmc_param_list_set_integer(ckmc_param_list_h params, ckmc_param_name_e name, uint64_t value);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_param_list_set_buffer", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int ParamListSetBuffer(IntPtr paramList, int name, IntPtr buffer);
+ // int ckmc_param_list_set_buffer(ckmc_param_list_h params, ckmc_param_name_e name, const ckmc_raw_buffer_s* buffer);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_param_list_get_integer", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int ParamListGetInteger(IntPtr paramList, int name, out long value);
+ // int ckmc_param_list_get_integer(ckmc_param_list_h params, ckmc_param_name_e name, uint64_t *pvalue);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_param_list_get_buffer", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int ParamListGetBuffer(IntPtr paramList, int name, out IntPtr buffer);
+ // int ckmc_param_list_get_buffer(ckmc_param_list_h params, ckmc_param_name_e name, ckmc_raw_buffer_s **ppbuffer);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_param_list_free", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void ParamListFree(IntPtr first);
+ // void ckmc_param_list_free(ckmc_param_list_h params);
+
+ [DllImport(Libraries.KeyManager, EntryPoint = "ckmc_generate_new_params", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int GenerateNewParam(int algoType, out IntPtr paramList);
+ // int ckmc_generate_new_params(ckmc_algo_type_e type, ckmc_param_list_h *pparams);
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Interop/Interop.Libraries.cs b/src/Tizen.Security.SecureRepository/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..d982269
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Interop/Interop.Libraries.cs
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string KeyManager = "libkey-manager-client.so.1";
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/NamespaceDoc.cs b/src/Tizen.Security.SecureRepository/NamespaceDoc.cs
new file mode 100644
index 0000000..c14b195
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/NamespaceDoc.cs
@@ -0,0 +1,41 @@
+/**
+<summary>
+Secure Repository function is provided by key-manager module in Tizen. The key manager provides a secure repository for keys, certificates, and sensitive data related to users and their password-protected APPs. Additionally, it provides secure cryptographic operations for non-exportable keys without revealing the key values to clients.
+</summary>
+
+<remarks>
+<h2>Overview</h2>
+<para>
+Secure Repository stores keys, certificates, and sensitive user data in a central secure repository. The central secure repository is protected by a password.
+</para>
+
+<para>
+Data Store Policy
+A client can specify simple access rules when storing data in the key manager:
+ Extractable or non-extractable
+ - Only for data tagged as extractable, the key manager returns the raw value of the data.
+ - If data is tagged as non-extractable, the key manager does not return its raw value. In that case, the key manager provides secure cryptographic operations for non-exportable keys without revealing the key values to the clients.
+ Per key password
+ - All data in the key manager is protected by a user password.
+ - A client can encrypt its data using their own password additionally.
+ - If a client provides a password when storing data, the data is encrypted with the password. This password must be provided when getting the data from the key manager.
+</para>
+
+<para>
+Data Access Control
+ By default, only the owner of a data can access to the data.
+ If the owner grants the access to other applications, those applications can read or delete the data from key-manager DB.
+ When an application is deleted, the data and access control information granted by the application are also removed.
+</para>
+
+<para>
+Alias Format
+ The format of alias is "package_id name" and the name should not contain any white space characters.
+ If package_id is not provided by a client, the key-manager will add the package_id of the client to the name internally.
+ The client can specify only its own pacakge id in the alias when storing a key, certificate, or data.
+ A client should specify the pacakge id of the owner in the alias to retrieve a a key, certificate, or data shared by other applications.
+ Aliases are returned from the key-manager as the format of package_id name.
+</para>
+</remarks>
+*/
+namespace Tizen.Security.SecureRepository {}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository.csproj b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository.csproj
new file mode 100644
index 0000000..d5717a4
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository.csproj
@@ -0,0 +1,15 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
+
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Certificate.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Certificate.cs
new file mode 100644
index 0000000..401a554
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Certificate.cs
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using static Interop;
+
+namespace Tizen.Security.SecureRepository
+{
+ /// <summary>
+ /// Class that represents a certificate.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class Certificate
+ {
+ /// <summary>
+ /// Load Certificate from the given file path.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="filePath">The path of certificate file to be loaded.</param>
+ /// <returns>Loaded certificate class instance.</returns>
+ /// <exception cref="ArgumentNullException">
+ /// filePath should not be null
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// Invalid certificate file format. Provided file path does not exist or
+ /// cannot be accessed.
+ /// </exception>
+ static public Certificate Load(string filePath)
+ {
+ if (filePath == null)
+ throw new ArgumentNullException("filepath should not be null");
+
+ IntPtr ptr = IntPtr.Zero;
+
+ Interop.CheckNThrowException(
+ CkmcTypes.LoadCertFromFile(filePath, out ptr),
+ "Failed to load Certificate: " + filePath);
+
+ return new Certificate(ptr);
+ }
+
+ /// <summary>
+ /// A constructor of Certificate that takes the binary and its format.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="binary">The binary data of a certificate.</param>
+ /// <param name="format">The format of the binary data.</param>
+ public Certificate(byte[] binary, DataFormat format)
+ {
+ this.Binary = binary;
+ this.Format = format;
+ }
+
+ internal Certificate(IntPtr ptr)
+ {
+ if (ptr == IntPtr.Zero)
+ throw new ArgumentNullException("Returned ptr from CAPI cannot be null");
+
+ var ckmcCert = Marshal.PtrToStructure<CkmcCert>(ptr);
+ this.Binary = new byte[(int)ckmcCert.size];
+ Marshal.Copy(ckmcCert.rawCert, this.Binary, 0, this.Binary.Length);
+ this.Format = (DataFormat)ckmcCert.dataFormat;
+ }
+
+ // Refresh handle(IntPtr) always. Because C# layer
+ // properties(Binary, Format) could be changed.
+ internal IntPtr GetHandle()
+ {
+ IntPtr ptr = IntPtr.Zero;
+ try
+ {
+ CheckNThrowException(
+ CkmcTypes.CertNew(
+ this.Binary, (UIntPtr)this.Binary.Length, (int)this.Format,
+ out ptr),
+ "Failed to create cert");
+
+ return ptr;
+ }
+ catch
+ {
+ if (ptr != IntPtr.Zero)
+ CkmcTypes.CertFree(ptr);
+
+ throw;
+ }
+ }
+
+ /// <summary>
+ /// The binary value of a certificate.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public byte[] Binary
+ {
+ get; set;
+ }
+
+ /// <summary>
+ /// The format of the binary value.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public DataFormat Format
+ {
+ get; set;
+ }
+
+ internal CkmcCert ToCkmcCert()
+ {
+ return new Interop.CkmcCert(
+ (Binary == null) ? IntPtr.Zero : new PinnedObject(this.Binary),
+ (Binary == null) ? 0 : this.Binary.Length,
+ (int)Format);
+ }
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/CertificateManager.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/CertificateManager.cs
new file mode 100644
index 0000000..c034267
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/CertificateManager.cs
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+using System;
+using System.Collections.Generic;
+using static Interop;
+
+namespace Tizen.Security.SecureRepository
+{
+ /// <summary>
+ /// This class provides the methods handling certificates.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class CertificateManager : Manager
+ {
+ /// <summary>
+ /// Gets a certificate from secure repository.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="alias">The name of a certificate to retrieve.</param>
+ /// <param name="password">
+ /// The password used in decrypting a certificate value. If password of
+ /// policy is provided in SaveCertificate(), the same password should be
+ /// provided.
+ /// </param>
+ /// <returns>A certificate specified by alias.</returns>
+ /// <exception cref="ArgumentNullException">
+ /// Alias argument is null
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// Alias argument is invalid format.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// Certificate does not exist with the alias or certificate-protecting
+ /// password isn't matched.
+ /// </exception>
+ static public Certificate Get(string alias, string password)
+ {
+ if (alias == null)
+ throw new ArgumentNullException("alias cannot be null");
+
+ IntPtr ptr = IntPtr.Zero;
+
+ try
+ {
+ Interop.CheckNThrowException(
+ Interop.CkmcManager.GetCert(alias, password, out ptr),
+ "Failed to get certificate. alias=" + alias);
+ return new Certificate(ptr);
+ }
+ finally
+ {
+ if (ptr != IntPtr.Zero)
+ Interop.CkmcTypes.CertFree(ptr);
+ }
+ }
+
+ /// <summary>
+ /// Gets all alias of certificates which the client can access.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>All alias of certificates which the client can access.</returns>
+ /// <exception cref="ArgumentException">No alias to get.</exception>
+ static public IEnumerable<string> GetAliases()
+ {
+ IntPtr ptr = IntPtr.Zero;
+
+ try
+ {
+ Interop.CheckNThrowException(
+ Interop.CkmcManager.GetCertAliasList(out ptr),
+ "Failed to get certificate aliases.");
+ return new SafeAliasListHandle(ptr).Aliases;
+ }
+ finally
+ {
+ if (ptr != IntPtr.Zero)
+ Interop.CkmcTypes.AliasListAllFree(ptr);
+ }
+ }
+
+ /// <summary>
+ /// Stores a certificate inside secure repository based on the provided policy.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="alias">The name of a certificate to be stored.</param>
+ /// <param name="cert">The certificate's binary value to be stored.</param>
+ /// <param name="policy">
+ /// The policy about how to store a certificate securely.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// Any of argument is null.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// Alias argument is invalid format. cert argument is invalid format.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// Certificate with alias does already exist.
+ /// </exception>
+ static public void Save(string alias, Certificate cert, Policy policy)
+ {
+ if (alias == null || cert == null || policy == null)
+ throw new ArgumentNullException("More than one of argument is null");
+
+ Interop.CheckNThrowException(
+ Interop.CkmcManager.SaveCert(
+ alias, cert.ToCkmcCert(), policy.ToCkmcPolicy()),
+ "Failed to save certificate. alias=" + alias);
+ }
+
+ /// <summary>
+ /// Verifies a certificate chain and returns that chain.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="certificate">The certificate to be verified.</param>
+ /// <param name="untrustedCertificates">
+ /// The untrusted CA certificates to be used in verifying a certificate chain.
+ /// </param>
+ /// <returns>A newly created certificate chain.</returns>
+ /// <exception cref="ArgumentNullException">
+ /// certificate argument is null.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// Some of certificate in arguments is invalid.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// Some of certificate in arguments is expired or not valid yet.
+ /// Certificate cannot build chain.
+ /// Root certificate is not in trusted system certificate store.
+ /// </exception>
+ /// <remarks>
+ /// The trusted root certificate of the chain should exist in the system's
+ /// certificate storage.
+ /// </remarks>
+ /// <remarks>
+ /// The trusted root certificate of the chain in system's certificate storage
+ /// is added to the certificate chain.
+ /// </remarks>
+ static public IEnumerable<Certificate> GetCertificateChain(
+ Certificate certificate, IEnumerable<Certificate> untrustedCertificates)
+ {
+ if (certificate == null)
+ throw new ArgumentNullException("Certificate is null");
+
+ IntPtr ptrCertChain = IntPtr.Zero;
+ IntPtr certPtr = IntPtr.Zero;
+ IntPtr untrustedPtr = IntPtr.Zero;
+
+ try
+ {
+ var untrusted = new SafeCertificateListHandle(untrustedCertificates);
+
+ certPtr = certificate.GetHandle();
+ untrustedPtr = untrusted.GetHandle();
+
+ Interop.CheckNThrowException(
+ Interop.CkmcManager.GetCertChain(
+ certPtr, untrustedPtr,
+ out ptrCertChain),
+ "Failed to get certificate chain");
+
+ return new SafeCertificateListHandle(ptrCertChain).Certificates;
+ }
+ finally
+ {
+ if (certPtr != IntPtr.Zero)
+ Interop.CkmcTypes.CertFree(certPtr);
+ if (untrustedPtr != IntPtr.Zero)
+ Interop.CkmcTypes.CertListAllFree(untrustedPtr);
+ }
+ }
+
+ /// <summary>
+ /// Verifies a certificate chain and returns that chain using user entered
+ /// trusted and untrusted CA certificates.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="certificate">The certificate to be verified.</param>
+ /// <param name="untrustedCertificates">
+ /// The untrusted CA certificates to be used in verifying a certificate chain.
+ /// </param>
+ /// <param name="trustedCertificates">
+ /// The trusted CA certificates to be used in verifying a certificate chain.
+ /// </param>
+ /// <param name="useTrustedSystemCertificates">
+ /// The flag indicating the use of the trusted root certificates in the
+ /// system's certificate storage.
+ /// </param>
+ /// <returns>A newly created certificate chain.</returns>
+ /// <exception cref="ArgumentNullException">
+ /// certificate argument is null.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// Some of certificate in arguments is invalid.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// Some of certificate in arguments is expired or not valid yet.
+ /// Certificate cannot build chain.
+ /// Root certificate is not in trusted system certificate store.
+ /// </exception>
+ /// <remarks>
+ /// The trusted root certificate of the chain in system's certificate storage
+ /// is added to the certificate chain.
+ /// </remarks>
+ static public IEnumerable<Certificate> GetCertificateChain(
+ Certificate certificate, IEnumerable<Certificate> untrustedCertificates,
+ IEnumerable<Certificate> trustedCertificates,
+ bool useTrustedSystemCertificates)
+ {
+ if (certificate == null)
+ throw new ArgumentNullException("Certificate is null");
+
+ IntPtr certPtr = IntPtr.Zero;
+ IntPtr untrustedPtr = IntPtr.Zero;
+ IntPtr trustedPtr = IntPtr.Zero;
+ IntPtr ptrCertChain = IntPtr.Zero;
+
+ try
+ {
+ var untrusted = new SafeCertificateListHandle(untrustedCertificates);
+ var trusted = new SafeCertificateListHandle(trustedCertificates);
+
+ certPtr = certificate.GetHandle();
+ untrustedPtr = untrusted.GetHandle();
+ trustedPtr = trusted.GetHandle();
+
+ Interop.CheckNThrowException(
+ Interop.CkmcManager.GetCertChainWithTrustedCerts(
+ certPtr, untrustedPtr, trustedPtr,
+ useTrustedSystemCertificates, out ptrCertChain),
+ "Failed to get certificate chain with trusted certificates");
+ return new SafeCertificateListHandle(ptrCertChain).Certificates;
+ }
+ finally
+ {
+ if (certPtr != IntPtr.Zero)
+ Interop.CkmcTypes.CertFree(certPtr);
+ if (untrustedPtr != IntPtr.Zero)
+ Interop.CkmcTypes.CertListAllFree(untrustedPtr);
+ if (trustedPtr != IntPtr.Zero)
+ Interop.CkmcTypes.CertListAllFree(trustedPtr);
+ }
+ }
+
+ /// <summary>
+ /// Perform OCSP which checks certificate is whether revoked or not.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="certificateChain">
+ /// Valid certificate chain to perform OCSP check.
+ /// </param>
+ /// <returns>A status result of OCSP check.</returns>
+ /// <exception cref="ArgumentNullException">
+ /// certificateChain argument is null.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// certificateChain is not valid chain or certificate.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// some of certificate in chain is expired or not valid yet.
+ /// </exception>
+ static public OcspStatus CheckOcsp(IEnumerable<Certificate> certificateChain)
+ {
+ if (certificateChain == null)
+ throw new ArgumentNullException("Certificate chain is null");
+
+ IntPtr ptr = IntPtr.Zero;
+
+ try
+ {
+ int ocspStatus = (int)OcspStatus.Good;
+ var certChain = new SafeCertificateListHandle(certificateChain);
+
+ ptr = certChain.GetHandle();
+
+ Interop.CheckNThrowException(
+ Interop.CkmcManager.OcspCheck(ptr, ref ocspStatus),
+ "Failed to get certificate chain with trusted certificates");
+ return (OcspStatus)ocspStatus;
+ }
+ finally
+ {
+ if (ptr != IntPtr.Zero)
+ Interop.CkmcTypes.CertListAllFree(ptr);
+ }
+ }
+
+ // to be static class safely
+ internal CertificateManager()
+ {
+ }
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/AesCbcCipherParameters.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/AesCbcCipherParameters.cs
new file mode 100644
index 0000000..36e8902
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/AesCbcCipherParameters.cs
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+namespace Tizen.Security.SecureRepository.Crypto
+{
+ /// <summary>
+ /// A class holding parameters for AES algorithm with CBC mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class AesCbcCipherParameters : AesCipherParameters
+ {
+ /// <summary>
+ /// A default constructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>The CipherAlgorithmType in CipherParameters is set to CipherAlgorithmType.AesCbc.</remarks>
+ public AesCbcCipherParameters() : base(CipherAlgorithmType.AesCbc)
+ {
+ }
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/AesCfbCipherParameters.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/AesCfbCipherParameters.cs
new file mode 100644
index 0000000..6bb35af
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/AesCfbCipherParameters.cs
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+namespace Tizen.Security.SecureRepository.Crypto
+{
+ /// <summary>
+ /// A class holding parameters for AES algorithm with CFB mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class AesCfbCipherParameters : AesCipherParameters
+ {
+ /// <summary>
+ /// A default constructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>The CipherAlgorithmType in CipherParameters is set to CipherAlgorithmType.AesCfb.</remarks>
+ public AesCfbCipherParameters() : base(CipherAlgorithmType.AesCfb)
+ {
+ }
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/AesCipherParameters.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/AesCipherParameters.cs
new file mode 100644
index 0000000..095f9ae
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/AesCipherParameters.cs
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+namespace Tizen.Security.SecureRepository.Crypto
+{
+ /// <summary>
+ /// A abstract class holding parameters for AES algorithm.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public abstract class AesCipherParameters : CipherParameters
+ {
+ /// <summary>
+ /// An initialization vector.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public byte[] IV
+ {
+ get { return this.GetBuffer(CipherParameterName.IV); }
+ set { this.Add(CipherParameterName.IV, value); }
+ }
+
+ // for inherited in internal only
+ internal AesCipherParameters()
+ {
+ }
+
+ internal AesCipherParameters(CipherAlgorithmType algorithm) : base(algorithm)
+ {
+ }
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/AesCtrCipherParameters.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/AesCtrCipherParameters.cs
new file mode 100644
index 0000000..731254f
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/AesCtrCipherParameters.cs
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+using System;
+
+namespace Tizen.Security.SecureRepository.Crypto
+{
+ /// <summary>
+ /// A class holding parameters for AES algorithm with counter mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class AesCtrCipherParameters : AesCipherParameters
+ {
+ /// <summary>
+ /// A default constructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>The CipherAlgorithmType in CipherParameters is set to CipherAlgorithmType.AesCtr.</remarks>
+ public AesCtrCipherParameters() : base(CipherAlgorithmType.AesCtr)
+ {
+ }
+
+ /// <summary>
+ /// Length of counter block in bits.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>Optional, only 128b is supported at the moment.</remarks>
+ /// <exception cref="ArgumentOutOfRangeException">value should be positive.</exception>
+ public long CounterLength
+ {
+ get
+ {
+ return GetInteger(CipherParameterName.CounterLength);
+ }
+ set
+ {
+ if (value < 0)
+ throw new ArgumentOutOfRangeException(
+ string.Format("invalid value{0} on CounterLength", value));
+ Add(CipherParameterName.CounterLength, value);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/AesGcmCipherParameters.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/AesGcmCipherParameters.cs
new file mode 100644
index 0000000..cab0ccc
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/AesGcmCipherParameters.cs
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+using System;
+
+namespace Tizen.Security.SecureRepository.Crypto
+{
+ /// <summary>
+ /// A class holding parameters for AES algorithm with GCM mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class AesGcmCipherParameters : AesCipherParameters
+ {
+ /// <summary>
+ /// A default constructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>The CipherAlgorithmType in CipherParameters is set to CipherAlgorithmType.AesGcm.</remarks>
+ public AesGcmCipherParameters() : base(CipherAlgorithmType.AesGcm)
+ {
+ }
+
+ /// <summary>
+ /// GCM tag length in bits.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>One of {32, 64, 96, 104, 112, 120, 128} (optional, if not present the length 128 is used.</remarks>
+ /// <exception cref="ArgumentOutOfRangeException">TagLength should be one of {32, 64, 96, 104, 112, 120, 128}</exception>
+ public long TagLength
+ {
+ get
+ {
+ return GetInteger(CipherParameterName.TagLength);
+ }
+ set
+ {
+ if (value != 32 && value != 64 && value != 96 && value != 104 &&
+ value != 112 && value != 120 && value != 128)
+ {
+ throw new ArgumentOutOfRangeException(
+ string.Format("invalid value{0} on TagLength", value));
+ }
+ else
+ {
+ Add(CipherParameterName.TagLength, value);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Additional authentication data(optional)
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public byte[] AAD
+ {
+ get { return GetBuffer(CipherParameterName.AAD); }
+ set { Add(CipherParameterName.AAD, value); }
+ }
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/Cipher.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/Cipher.cs
new file mode 100644
index 0000000..e84c070
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/Cipher.cs
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+using System;
+
+namespace Tizen.Security.SecureRepository.Crypto
+{
+ /// <summary>
+ /// This class provides the methods encrypting and decrypting data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class Cipher
+ {
+ private readonly CipherParameters _parameters;
+
+ /// <summary>
+ /// A constructor of Cipher that takes the algorithm specific parameters.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="parameters">The algorithm specific parameters.</param>
+ public Cipher(CipherParameters parameters)
+ {
+ _parameters = parameters;
+ }
+
+ /// <summary>
+ /// The algorithm specific parameters.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public CipherParameters Parameters
+ {
+ get { return _parameters; }
+ }
+
+ /// <summary>
+ /// Decrypts data using selected key and algorithm.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="keyAlias">Alias of the key to be used for decryption.</param>
+ /// <param name="password">
+ /// The password used in decrypting a key value. If password of policy is
+ /// provided in SaveKey(), the same password should be provided
+ /// </param>
+ /// <param name="cipherText">
+ /// Data to be decrypted (some algorithms may require additional information
+ /// embedded in encrypted data.AES GCM is an example).
+ /// </param>
+ /// <returns>Decrypted data.</returns>
+ /// <exception cref="ArgumentNullException">
+ /// keyAlias or cipherText is null.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// Mandatory algorithm parameter is missing or invalid.
+ /// Optional algorithm parameter is invalid.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// Key-protecting password isn't matched.
+ /// Key does not exist with keyAlias.
+ /// </exception>
+ /// <remarks>
+ /// The key type specified by keyAlias should be compatible with the algorithm
+ /// specified in Parameters.
+ /// </remarks>
+ public byte[] Decrypt(string keyAlias, string password, byte[] cipherText)
+ {
+ if (keyAlias == null || cipherText == null)
+ throw new ArgumentNullException("alias and ciphertxt should not be null");
+
+ IntPtr ptr = IntPtr.Zero;
+
+ try
+ {
+ Interop.CheckNThrowException(
+ Interop.CkmcManager.DecryptData(
+ Parameters.Ptr, keyAlias, password,
+ new Interop.CkmcRawBuffer(
+ new PinnedObject(cipherText), cipherText.Length),
+ out ptr),
+ "Failed to decrypt data");
+ return new SafeRawBufferHandle(ptr).Data;
+ }
+ finally
+ {
+ if (ptr != IntPtr.Zero)
+ Interop.CkmcTypes.BufferFree(ptr);
+ }
+ }
+
+ /// <summary>
+ /// Encrypts data using selected key and algorithm.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="keyAlias">Alias of the key to be used for encryption.</param>
+ /// <param name="password">
+ /// The password used in decrypting a key value. If password of policy is
+ /// provided in SaveKey(), the same password should be provided.
+ /// </param>
+ /// <param name="plainText">
+ /// Data to be encrypted. In case of AES algorithm there are no restrictions on
+ /// the size of data. For RSA the size must be smaller or equal to (key_size_in
+ /// bytes - 42). Example: for 1024 RSA key the maximum data size is
+ /// 1024/8 - 42 = 86.
+ /// </param>
+ /// <returns>Encrypted data.</returns>
+ /// <exception cref="ArgumentNullException">
+ /// keyAlias or plainText is null.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// Mandatory algorithm parameter is missing or invalid.
+ /// Optional algorithm parameter is invalid.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// Key-protecting password isn't matched.
+ /// Key does not exist with keyAlias.
+ /// </exception>
+ /// <remarks>
+ /// The key type specified by keyAlias should be compatible with the algorithm
+ /// specified in Parameters.
+ /// </remarks>
+ public byte[] Encrypt(string keyAlias, string password, byte[] plainText)
+ {
+ if (keyAlias == null || plainText == null)
+ throw new ArgumentNullException("alias or plaintxt should not be null");
+
+ IntPtr ptr = IntPtr.Zero;
+
+ try
+ {
+ Interop.CheckNThrowException(
+ Interop.CkmcManager.EncryptData(
+ Parameters.Ptr, keyAlias, password,
+ new Interop.CkmcRawBuffer(
+ new PinnedObject(plainText), plainText.Length),
+ out ptr),
+ "Failed to encrypt data");
+ return new SafeRawBufferHandle(ptr).Data;
+ }
+ finally
+ {
+ if (ptr != IntPtr.Zero)
+ Interop.CkmcTypes.BufferFree(ptr);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/CipherAlgorithmType.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/CipherAlgorithmType.cs
new file mode 100644
index 0000000..7487ebc
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/CipherAlgorithmType.cs
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+namespace Tizen.Security.SecureRepository.Crypto
+{
+ /// <summary>
+ /// Enumeration for crypto cipher algorithm types.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CipherAlgorithmType : int
+ {
+ /// <summary>
+ /// AES-CTR algorithm
+ /// Supported parameters:
+ /// - ParameterName.AlgorithmType = AesCtr(mandatory),
+ /// - ParameterName.IV = 16 - byte initialization vector(mandatory)
+ /// - ParameterName.CounterLength = length of counter block in bits
+ /// (optional, only 128b is supported at the moment)
+ /// </summary>
+ AesCtr = 0x01,
+ /// <summary>
+ /// AES-CBC algorithm
+ /// Supported parameters:
+ /// - ParameterName.AlgorithmType = AesCbc(mandatory),
+ /// - ParameterName.IV = 16-byte initialization vector(mandatory)
+ /// </summary>
+ AesCbc,
+ /// <summary>
+ /// AES-GCM algorithm
+ /// Supported parameters:
+ /// - ParameterName.AlgorithmType = AesGcm(mandatory),
+ /// - ParameterName.IV = initialization vector(mandatory)
+ /// - ParameterName.TagLength = GCM tag length in bits. One of
+ /// {32, 64, 96, 104, 112, 120, 128} (optional, if not present the length 128 is used)
+ /// - CKMC_PARAM_ED_AAD = additional authentication data(optional)
+ /// </summary>
+ AesGcm,
+ /// <summary>
+ /// AES-CFB algorithm
+ /// Supported parameters:
+ /// - ParameterName.AlgorithmType = AesCfb(mandatory),
+ /// - ParameterName.IV = 16-byte initialization vector(mandatory)
+ /// </summary>
+ AesCfb,
+ /// <summary>
+ /// RSA-OAEP algorithm
+ /// Supported parameters:
+ /// - ParameterName.AlgorithmType = RsaOaep(required),
+ /// - ParameterName.Label = label to be associated with the message
+ /// (optional, not supported at the moment)
+ /// </summary>
+ RsaOaep
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/CipherParameterName.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/CipherParameterName.cs
new file mode 100644
index 0000000..be3801e
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/CipherParameterName.cs
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+namespace Tizen.Security.SecureRepository.Crypto
+{
+ /// <summary>
+ /// Enumeration for cipher algorithm parameters.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CipherParameterName : int
+ {
+ /// <summary>
+ /// Algorithm Type
+ /// </summary>
+ AlgorithmType = 0x01,
+ /// <summary>
+ /// Initial Vector, 16B buffer (up to 2^64-1 bytes long in case of AES GCM)
+ /// </summary>
+ IV = 101,
+ /// <summary>
+ /// Integer - ctr length in bits
+ /// </summary>
+ CounterLength = 102,
+ /// <summary>
+ /// Additional authenticated data(AAD)
+ /// </summary>
+ AAD = 103,
+ /// <summary>
+ /// Tag Length
+ /// </summary>
+ TagLength = 104,
+ /// <summary>
+ /// Label
+ /// </summary>
+ Label = 105
+ }
+
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/CipherParameters.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/CipherParameters.cs
new file mode 100644
index 0000000..450b159
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/CipherParameters.cs
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+using System;
+
+namespace Tizen.Security.SecureRepository.Crypto
+{
+ /// <summary>
+ /// A abstract class holding parameters for encryption and decryption.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ abstract public class CipherParameters
+ {
+ private SafeCipherParametersHandle _handle;
+
+ /// <summary>
+ /// Cipher algorithm type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public CipherAlgorithmType Algorithm
+ {
+ get
+ {
+ return (CipherAlgorithmType)GetInteger(
+ CipherParameterName.AlgorithmType);
+ }
+ }
+
+ // for inherited in internal only
+ internal CipherParameters()
+ {
+ }
+
+ internal CipherParameters(CipherAlgorithmType algorithm)
+ {
+ this._handle = new SafeCipherParametersHandle(algorithm);
+ }
+
+ internal void Add(CipherParameterName name, long value)
+ {
+ this._handle.SetInteger(name, value);
+ }
+
+ internal void Add(CipherParameterName name, byte[] value)
+ {
+ this._handle.SetBuffer(name, value);
+ }
+
+ internal long GetInteger(CipherParameterName name)
+ {
+ return this._handle.GetInteger(name);
+ }
+
+ internal byte[] GetBuffer(CipherParameterName name)
+ {
+ return this._handle.GetBuffer(name);
+ }
+
+ internal IntPtr Ptr
+ {
+ get { return this._handle.Ptr; }
+ }
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/DsaSignatureParameters.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/DsaSignatureParameters.cs
new file mode 100644
index 0000000..2c58255
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/DsaSignatureParameters.cs
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+namespace Tizen.Security.SecureRepository.Crypto
+{
+ /// <summary>
+ /// A class holding parameters for DSA signature algorithm.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class DsaSignatureParameters : SignatureParameters
+ {
+ /// <summary>
+ /// A default constructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public DsaSignatureParameters() : base(SignatureAlgorithmType.Dsa)
+ {
+ }
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/EcdsaSignatureParameters.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/EcdsaSignatureParameters.cs
new file mode 100644
index 0000000..3cd6e65
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/EcdsaSignatureParameters.cs
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+namespace Tizen.Security.SecureRepository.Crypto
+{
+ /// <summary>
+ /// A class holding parameters for ECDSA signature algorithm.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class EcdsaSignatureParameters : SignatureParameters
+ {
+ /// <summary>
+ /// A default constructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public EcdsaSignatureParameters() : base(SignatureAlgorithmType.Ecdsa)
+ {
+ }
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/HashAlgorithm.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/HashAlgorithm.cs
new file mode 100644
index 0000000..66c6491
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/HashAlgorithm.cs
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+namespace Tizen.Security.SecureRepository.Crypto
+{
+ /// <summary>
+ /// Enumeration for hash algorithm
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum HashAlgorithm : int
+ {
+ /// <summary>
+ /// No Hash Algorithm
+ /// </summary>
+ None = 0,
+ /// <summary>
+ /// Hash Algorithm SHA1
+ /// </summary>
+ Sha1,
+ /// <summary>
+ /// Hash Algorithm SHA256
+ /// </summary>
+ Sha256,
+ /// <summary>
+ /// Hash Algorithm SHA384
+ /// </summary>
+ Sha384,
+ /// <summary>
+ /// Hash Algorithm SHA512
+ /// </summary>
+ Sha512
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/RsaOaepCipherParameters.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/RsaOaepCipherParameters.cs
new file mode 100644
index 0000000..f0fbe9f
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/RsaOaepCipherParameters.cs
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+namespace Tizen.Security.SecureRepository.Crypto
+{
+ /// <summary>
+ /// A class holding parameters for RSA algorithm with OAEP mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class RsaOaepCipherParameters : CipherParameters
+ {
+ /// <summary>
+ /// A default constructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>The CipherAlgorithmType in CipherParameters is set to CipherAlgorithmType.RsaOaep.</remarks>
+ public RsaOaepCipherParameters() : base(CipherAlgorithmType.RsaOaep)
+ {
+ }
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/RsaPaddingAlgorithm.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/RsaPaddingAlgorithm.cs
new file mode 100644
index 0000000..5da20f6
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/RsaPaddingAlgorithm.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+namespace Tizen.Security.SecureRepository.Crypto
+{
+ /// <summary>
+ /// Enumeration for RSA padding algorithm
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum RsaPaddingAlgorithm : int
+ {
+ /// <summary>
+ /// No Padding
+ /// </summary>
+ None = 0,
+ /// <summary>
+ /// PKCS#1 Padding
+ /// </summary>
+ Pkcs1,
+ /// <summary>
+ /// X9.31 padding
+ /// </summary>
+ X931
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/RsaSignatureParameters.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/RsaSignatureParameters.cs
new file mode 100644
index 0000000..b1dfe7b
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/RsaSignatureParameters.cs
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+namespace Tizen.Security.SecureRepository.Crypto
+{
+ /// <summary>
+ /// A class holding parameters for RSA signature algorithm.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class RsaSignatureParameters : SignatureParameters
+ {
+ /// <summary>
+ /// A default constructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>The RsaPadding is set to RsaPaddingAlgorithm.None.</remarks>
+ public RsaSignatureParameters() : base(SignatureAlgorithmType.Rsa)
+ {
+ }
+
+ /// <summary>
+ /// RSA padding algorithm
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public RsaPaddingAlgorithm RsaPadding
+ {
+ get { return (RsaPaddingAlgorithm)Get(SignatureParameterName.RsaPaddingAlgorithm); }
+ set { Add(SignatureParameterName.RsaPaddingAlgorithm, (int)value); }
+ }
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/SafeCipherParametersHandle.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/SafeCipherParametersHandle.cs
new file mode 100644
index 0000000..8d7e8cf
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/SafeCipherParametersHandle.cs
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Security.SecureRepository.Crypto
+{
+ internal class SafeCipherParametersHandle : SafeHandle
+ {
+ internal SafeCipherParametersHandle(CipherAlgorithmType algorithm) :
+ base(IntPtr.Zero, true)
+ {
+ IntPtr ptr = IntPtr.Zero;
+ Interop.CkmcTypes.GenerateNewParam((int)algorithm, out ptr);
+ this.SetHandle(ptr);
+ }
+
+ internal void SetInteger(CipherParameterName name, long value)
+ {
+ Interop.CheckNThrowException(
+ Interop.CkmcTypes.ParamListSetInteger(
+ Ptr, (int)name, value),
+ "Failed to add parameter.");
+ }
+
+ internal void SetBuffer(CipherParameterName name, byte[] value)
+ {
+ var rawBuff = new Interop.CkmcRawBuffer(new PinnedObject(value), value.Length);
+ IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(rawBuff));
+ try
+ {
+ Marshal.StructureToPtr<Interop.CkmcRawBuffer>(rawBuff, ptr, false);
+ Interop.CheckNThrowException(
+ Interop.CkmcTypes.ParamListSetBuffer(
+ Ptr, (int)name, ptr),
+ "Failed to add parameter.");
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(ptr);
+ }
+ }
+
+ internal long GetInteger(CipherParameterName name)
+ {
+ long value = 0;
+ Interop.CheckNThrowException(
+ Interop.CkmcTypes.ParamListGetInteger(
+ Ptr, (int)name, out value),
+ "Failed to get parameter.");
+ return value;
+ }
+
+ internal byte[] GetBuffer(CipherParameterName name)
+ {
+ IntPtr ptr = IntPtr.Zero;
+
+ try
+ {
+ Interop.CheckNThrowException(
+ Interop.CkmcTypes.ParamListGetBuffer(
+ Ptr, (int)name, out ptr),
+ "Failed to get parameter.");
+ return new SafeRawBufferHandle(ptr).Data;
+ }
+ finally
+ {
+ if (ptr != IntPtr.Zero)
+ Interop.CkmcTypes.BufferFree(ptr);
+ }
+ }
+
+ internal CipherAlgorithmType Algorithm
+ {
+ get
+ {
+ return (CipherAlgorithmType)GetInteger(
+ CipherParameterName.AlgorithmType);
+ }
+ }
+
+ internal IntPtr Ptr
+ {
+ get { return this.handle; }
+ }
+
+ public override bool IsInvalid
+ {
+ get { return this.handle == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ Interop.CkmcTypes.ParamListFree(this.handle);
+ this.SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/Signature.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/Signature.cs
new file mode 100644
index 0000000..3e34ce7
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/Signature.cs
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+using System;
+
+namespace Tizen.Security.SecureRepository.Crypto
+{
+ /// <summary>
+ /// This class provides the methods creating and verifying a signature.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class Signature
+ {
+ private SignatureParameters _parameters;
+
+ /// <summary>
+ /// A constructor of Signature that takes the algorithm specific parameters.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="parameters">The algorithm specific parameters.</param>
+ public Signature(SignatureParameters parameters)
+ {
+ _parameters = parameters;
+ }
+
+ /// <summary>
+ /// The algorithm specific parameters.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public SignatureParameters Parameters
+ {
+ get { return _parameters; }
+ }
+
+ /// <summary>
+ /// Creates a signature on a given message using a private key and returns
+ /// the signature.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="privateKeyAlias">The name of private key.</param>
+ /// <param name="password">
+ /// The password used in decrypting a private key value.
+ /// </param>
+ /// <param name="message">The message that is signed with a private key.</param>
+ /// <returns>A newly created signature.</returns>
+ /// <exception cref="ArgumentNullException">
+ /// privateKeyAlias or message is null.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// privateKeyAlias is invalid format.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// Key-protecting password isn't matched.
+ /// Key does not exist with privateKeyAlias.
+ /// </exception>
+ /// <remarks>
+ /// The key type specified by privateKeyAlias should be compatible with the
+ /// algorithm specified in Parameters.
+ /// </remarks>
+ /// <remarks>
+ /// If password of policy is provided during storing a key, the same password
+ /// should be provided.
+ /// </remarks>
+ public byte[] Sign(string privateKeyAlias, string password, byte[] message)
+ {
+ if (privateKeyAlias == null || message == null)
+ throw new ArgumentNullException("alias and message should not be null");
+
+ int hash = (int)HashAlgorithm.None;
+ try
+ {
+ hash = (int)Parameters.Get(SignatureParameterName.HashAlgorithm);
+ }
+ catch {}
+
+ int rsaPadding = (int)RsaPaddingAlgorithm.None;
+ try
+ {
+ rsaPadding = (int)Parameters.Get(SignatureParameterName.RsaPaddingAlgorithm);
+ }
+ catch {}
+
+ IntPtr ptr = IntPtr.Zero;
+
+ try
+ {
+ Interop.CheckNThrowException(
+ Interop.CkmcManager.CreateSignature(
+ privateKeyAlias, password,
+ new Interop.CkmcRawBuffer(
+ new PinnedObject(message), message.Length),
+ hash, rsaPadding, out ptr),
+ "Failed to generate signature");
+ return new SafeRawBufferHandle(ptr).Data;
+ }
+ finally
+ {
+ if (ptr != IntPtr.Zero)
+ Interop.CkmcTypes.BufferFree(ptr);
+ }
+ }
+
+ /// <summary>
+ /// Verifies a given signature on a given message using a public key and returns
+ /// the signature status.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="publicKeyAlias">The name of public key.</param>
+ /// <param name="password">
+ /// The password used in decrypting a public key value.
+ /// </param>
+ /// <param name="message">The input on which the signature is created.</param>
+ /// <param name="signature">The signature that is verified with public key.</param>
+ /// <returns>
+ /// The signature status. True is returned when the signature is valid.
+ /// </returns>
+ /// <exception cref="ArgumentNullException">
+ /// publicKeyAlias, message or signature is null.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// publicKeyAlias is invalid format.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// Key-protecting password isn't matched.
+ /// Key does not exist with publicKeyAlias.
+ /// </exception>
+ /// <remarks>
+ /// The key type specified by publicKeyAlias should be compatible with the
+ /// algorithm specified in Parameters.
+ /// </remarks>
+ /// <remarks>
+ /// If password of policy is provided during storing a key, the same password
+ /// should be provided.
+ /// </remarks>
+ public bool Verify(
+ string publicKeyAlias, string password, byte[] message, byte[] signature)
+ {
+ if (publicKeyAlias == null || message == null || signature == null)
+ throw new ArgumentNullException("mandatory arg should not be null");
+
+ int hash = (int)HashAlgorithm.None;
+ try
+ {
+ hash = (int)Parameters.Get(SignatureParameterName.HashAlgorithm);
+ }
+ catch {}
+
+ int rsaPadding = (int)RsaPaddingAlgorithm.None;
+ try
+ {
+ rsaPadding = (int)Parameters.Get(SignatureParameterName.RsaPaddingAlgorithm);
+ }
+ catch {}
+
+
+ int ret = Interop.CkmcManager.VerifySignature(
+ publicKeyAlias,
+ password,
+ new Interop.CkmcRawBuffer(new PinnedObject(message), message.Length),
+ new Interop.CkmcRawBuffer(new PinnedObject(signature), signature.Length),
+ hash,
+ rsaPadding);
+
+ if (ret == (int)Interop.KeyManagerError.VerificationFailed)
+ return false;
+ Interop.CheckNThrowException(ret, "Failed to verify signature");
+
+ return true;
+ }
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/SignatureAlgorithmType.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/SignatureAlgorithmType.cs
new file mode 100644
index 0000000..68b5ba1
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/SignatureAlgorithmType.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+namespace Tizen.Security.SecureRepository.Crypto
+{
+ /// <summary>
+ /// Enumeration for signature algorithm types.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum SignatureAlgorithmType : int
+ {
+ /// <summary>
+ /// RSA signature algorithm
+ /// </summary>
+ Rsa = 0x01,
+ /// <summary>
+ /// DSA signature algorithm
+ /// </summary>
+ Dsa,
+ /// <summary>
+ /// ECDSA signature algorithm
+ /// </summary>
+ Ecdsa
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/SignatureParameterName.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/SignatureParameterName.cs
new file mode 100644
index 0000000..1662ad1
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/SignatureParameterName.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+namespace Tizen.Security.SecureRepository.Crypto
+{
+ /// <summary>
+ /// Enumeration for signature algorithm parameters.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ internal enum SignatureParameterName : int
+ {
+ /// <summary>
+ /// Signaturea Algorithm Type
+ /// </summary>
+ AlgorithmType = 0x01,
+ /// <summary>
+ /// Hash Algorithm Type
+ /// </summary>
+ HashAlgorithm,
+ /// <summary>
+ /// RSA Padding Algorithm Type
+ /// </summary>
+ RsaPaddingAlgorithm
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/SignatureParameters.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/SignatureParameters.cs
new file mode 100644
index 0000000..bccf4cc
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Crypto/SignatureParameters.cs
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Security.SecureRepository.Crypto
+{
+ /// <summary>
+ /// A abstract class holding parameters for signing and verification.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ abstract public class SignatureParameters
+ {
+ private Dictionary<SignatureParameterName, int> _parameters;
+
+ /// <summary>
+ /// Signature algorithm type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public SignatureAlgorithmType SignatureAlgorithm
+ {
+ get { return (SignatureAlgorithmType)Get(SignatureParameterName.AlgorithmType); }
+ }
+
+ /// <summary>
+ /// Hash algorithm used in signing anve verification.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public HashAlgorithm HashAlgorithm
+ {
+ get { return (HashAlgorithm)Get(SignatureParameterName.HashAlgorithm); }
+ set { Add(SignatureParameterName.HashAlgorithm, (int)value); }
+ }
+
+ // for inherited in internal only
+ internal SignatureParameters()
+ {
+ }
+
+ internal SignatureParameters(SignatureAlgorithmType algorithm)
+ {
+ _parameters = new Dictionary<SignatureParameterName, int>();
+ Add(SignatureParameterName.AlgorithmType, (int)algorithm);
+ }
+
+ internal void Add(SignatureParameterName name, int value)
+ {
+ _parameters.Add(name, value);
+ }
+
+ internal int Get(SignatureParameterName name)
+ {
+ if (_parameters.ContainsKey(name))
+ return _parameters[name];
+ else
+ throw new ArgumentException("No parameter for a given SignatureParameterName ");
+ }
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/DataFormat.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/DataFormat.cs
new file mode 100644
index 0000000..cd96acf
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/DataFormat.cs
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+namespace Tizen.Security.SecureRepository
+{
+ /// <summary>
+ /// Enumeration for data format
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum DataFormat : int
+ {
+ /// <summary>
+ /// DER format base64 encoded data
+ /// </summary>
+ DerBase64 = 0,
+ /// <summary>
+ /// DER encoded data
+ /// </summary>
+ Der,
+ /// <summary>
+ /// PEM encoded data. It consists of the DER format base64 encoded
+ /// with additional header and footer lines.
+ /// </summary>
+ Pem
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/DataManager.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/DataManager.cs
new file mode 100644
index 0000000..38fd661
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/DataManager.cs
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+using System;
+using System.Collections.Generic;
+using static Interop;
+
+namespace Tizen.Security.SecureRepository
+{
+ /// <summary>
+ /// This class provides the methods storing and retrieving data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class DataManager : Manager
+ {
+ /// <summary>
+ /// Gets data from secure repository.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="alias">The name of a certificate to retrieve.</param>
+ /// <param name="password">
+ /// The password used in decrypting a data value.
+ /// If password of policy is provided in SaveData(), the same password should
+ /// be provided.
+ /// </param>
+ /// <returns>Data specified by alias.</returns>
+ /// <exception cref="ArgumentNullException">
+ /// Alias argument is null.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// Alias argument is invalid format.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// Data does not exist with the alias or data-protecting password isn't matched.
+ /// </exception>
+ static public byte[] Get(string alias, string password)
+ {
+ if (alias == null)
+ throw new ArgumentNullException("alias cannot be null");
+
+ IntPtr ptr = IntPtr.Zero;
+
+ try
+ {
+ Interop.CheckNThrowException(
+ Interop.CkmcManager.GetData(alias, password, out ptr),
+ "Failed to get certificate. alias=" + alias);
+ return new SafeRawBufferHandle(ptr).Data;
+ }
+ finally
+ {
+ if (ptr != IntPtr.Zero)
+ Interop.CkmcTypes.BufferFree(ptr);
+ }
+ }
+
+ /// <summary>
+ /// Gets all alias of data which the client can access.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>All alias of data which the client can access.</returns>
+ /// <exception cref="ArgumentException">No alias to get.</exception>
+ static public IEnumerable<string> GetAliases()
+ {
+ IntPtr ptr = IntPtr.Zero;
+
+ try
+ {
+ Interop.CheckNThrowException(
+ Interop.CkmcManager.GetDataAliasList(out ptr),
+ "Failed to get data aliases");
+ return new SafeAliasListHandle(ptr).Aliases;
+ }
+ finally
+ {
+ if (ptr != IntPtr.Zero)
+ Interop.CkmcTypes.AliasListAllFree(ptr);
+ }
+ }
+
+ /// <summary>
+ /// Stores data inside secure repository based on the provided policy.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="alias">The name of data to be stored.</param>
+ /// <param name="data">The binary value to be stored.</param>
+ /// <param name="policy">The policy about how to store data securely.</param>
+ /// <exception cref="ArgumentNullException">
+ /// Any of argument is null.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// Alias argument is invalid format. Data policy cannot be unextractable.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// Data with alias does already exist.
+ /// </exception>
+ static public void Save(string alias, byte[] data, Policy policy)
+ {
+ if (alias == null || data == null || policy == null)
+ throw new ArgumentNullException("alias and policy should be null");
+ else if (policy.Extractable == false)
+ throw new ArgumentException("Data should be extractable");
+
+ Interop.CheckNThrowException(
+ Interop.CkmcManager.SaveData(
+ alias,
+ new Interop.CkmcRawBuffer(new PinnedObject(data), data.Length),
+ policy.ToCkmcPolicy()),
+ "Failed to save data. alias=" + alias);
+ }
+
+ // to be static class safely
+ internal DataManager()
+ {
+ }
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/EllipticCurveType.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/EllipticCurveType.cs
new file mode 100644
index 0000000..6e52871
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/EllipticCurveType.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+namespace Tizen.Security.SecureRepository
+{
+ /// <summary>
+ /// Enumeration for elliptic curve
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum EllipticCurveType : int
+ {
+ /// <summary>
+ /// Elliptic curve domain "secp192r1" listed in "SEC 2" recommended elliptic curve domain
+ /// </summary>
+ Prime192V1 = 0,
+ /// <summary>
+ /// "SEC 2" recommended elliptic curve domain - secp256r1
+ /// </summary>
+ Prime256V1,
+ /// <summary>
+ /// NIST curve P-384(covers "secp384r1", the elliptic curve domain listed in See SEC 2
+ /// </summary>
+ Secp384R1
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Key.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Key.cs
new file mode 100644
index 0000000..e175f55
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Key.cs
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using static Interop;
+
+namespace Tizen.Security.SecureRepository
+{
+ /// <summary>
+ /// Class that represents a key.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class Key
+ {
+ /// <summary>
+ /// A constructor of Key that takes the binary, its type, and optional password
+ /// of binary.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="binary">
+ /// The binary value of a key. This binary may be encrypted with binaryPassword.
+ /// </param>
+ /// <param name="type">The key's type.</param>
+ /// <param name="binaryPassword">
+ /// The password used to decrypt binary when binary is encrypted.
+ /// </param>
+ public Key(byte[] binary, KeyType type, string binaryPassword)
+ {
+ this.Binary = binary;
+ this.Type = type;
+ this.BinaryPassword = binaryPassword;
+ }
+
+ internal Key(IntPtr ptr)
+ {
+ if (ptr == IntPtr.Zero)
+ throw new ArgumentNullException("Returned ptr from CAPI cannot be null");
+
+ var ckmcKey = Marshal.PtrToStructure<CkmcKey>(ptr);
+ this.Binary = new byte[(int)ckmcKey.size];
+ Marshal.Copy(ckmcKey.rawKey, this.Binary, 0, this.Binary.Length);
+ this.Type = (KeyType)ckmcKey.keyType;
+ this.BinaryPassword = ckmcKey.password;
+ }
+
+ // Refresh handle(IntPtr) always. Because C# layer
+ // properties(Binary, Type, BinaryPassword) could be changed.
+ internal IntPtr GetHandle()
+ {
+ IntPtr ptr = IntPtr.Zero;
+ try
+ {
+ CheckNThrowException(
+ Interop.CkmcTypes.KeyNew(
+ this.Binary, (UIntPtr)this.Binary.Length, (int)this.Type,
+ this.BinaryPassword, out ptr),
+ "Failed to create key");
+
+ return ptr;
+ }
+ catch
+ {
+ if (ptr != IntPtr.Zero)
+ Interop.CkmcTypes.KeyFree(ptr);
+
+ throw;
+ }
+ }
+
+ /// <summary>
+ /// The binary value of a key.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public byte[] Binary
+ {
+ get; set;
+ }
+
+ /// <summary>
+ /// The key's type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public KeyType Type
+ {
+ get; set;
+ }
+
+ /// <summary>
+ /// The password used to decrypt binary when binary is encrypted. It's optional.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string BinaryPassword
+ {
+ get; set;
+ }
+
+ internal CkmcKey ToCkmcKey()
+ {
+ return new Interop.CkmcKey(
+ (Binary == null) ? IntPtr.Zero : new PinnedObject(this.Binary),
+ (Binary == null) ? 0 : this.Binary.Length,
+ (int)this.Type,
+ this.BinaryPassword);
+ }
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/KeyManager.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/KeyManager.cs
new file mode 100644
index 0000000..cb2395f
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/KeyManager.cs
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Security.SecureRepository
+{
+ /// <summary>
+ /// This class provides the methods storing, retrieving, and creating keys.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class KeyManager : Manager
+ {
+ /// <summary>
+ /// Gets a key from secure repository.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="alias">The name of a key to retrieve.</param>
+ /// <param name="password">
+ /// The password used in decrypting a key value.
+ /// If password of policy is provided in SaveKey(), the same password should
+ /// be provided.
+ /// </param>
+ /// <returns>A key specified by alias.</returns>
+ /// <exception cref="ArgumentNullException">
+ /// Alias argument is null.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// Alias argument is invalid format.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// Key does not exist with the alias or key-protecting password isn't matched.
+ /// </exception>
+ static public Key Get(string alias, string password)
+ {
+ if (alias == null)
+ throw new ArgumentNullException("alias cannot be null");
+
+ IntPtr ptr = IntPtr.Zero;
+
+ try
+ {
+ Interop.CheckNThrowException(
+ Interop.CkmcManager.GetKey(alias, password, out ptr),
+ "Failed to get key. alias=" + alias);
+ return new Key(ptr);
+ }
+ finally
+ {
+ if (ptr != IntPtr.Zero)
+ Interop.CkmcTypes.KeyFree(ptr);
+ }
+ }
+
+ /// <summary>
+ /// Gets all alias of keys which the client can access.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>All alias of keys which the client can access.</returns>
+ /// <exception cref="ArgumentException">No alias to get.</exception>
+ static public IEnumerable<string> GetAliases()
+ {
+ IntPtr ptr = IntPtr.Zero;
+
+ try
+ {
+ Interop.CheckNThrowException(
+ Interop.CkmcManager.GetKeyAliasList(out ptr),
+ "Failed to get key aliases.");
+ return new SafeAliasListHandle(ptr).Aliases;
+ }
+ finally
+ {
+ if (ptr != IntPtr.Zero)
+ Interop.CkmcTypes.AliasListAllFree(ptr);
+ }
+ }
+
+ /// <summary>
+ /// Stores a key inside secure repository based on the provided policy.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="alias">The name of a key to be stored.</param>
+ /// <param name="key">The key's binary value to be stored.</param>
+ /// <param name="policy">The policy about how to store a key securely.</param>
+ /// <exception cref="ArgumentNullException">
+ /// Any of argument is null.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// Alias argument is invalid format. key argument is invalid format.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// Key with alias does already exist.
+ /// </exception>
+ /// <remarks>
+ /// Type in key may be set to KeyType.None as an input.
+ /// Type is determined inside secure reposioty during storing keys.
+ /// </remarks>
+ /// <remarks>
+ /// If password in policy is provided, the key is additionally encrypted with
+ /// the password in policy.
+ /// </remarks>
+ static public void Save(string alias, Key key, Policy policy)
+ {
+ if (alias == null || key == null || policy == null)
+ throw new ArgumentNullException("More than one of argument is null");
+
+ Interop.CheckNThrowException(
+ Interop.CkmcManager.SaveKey(
+ alias, key.ToCkmcKey(), policy.ToCkmcPolicy()),
+ "Failed to save Key. alias=" + alias);
+ }
+
+ /// <summary>
+ /// Creates RSA private/public key pair and stores them inside secure repository
+ /// based on each policy.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="size">
+ /// The size of key strength to be created. 1024, 2048, and 4096 are supported.
+ /// </param>
+ /// <param name="privateKeyAlias">The name of private key to be stored.</param>
+ /// <param name="publicKeyAlias">The name of public key to be stored.</param>
+ /// <param name="privateKeyPolicy">
+ /// The policy about how to store a private key securely.
+ /// </param>
+ /// <param name="publicKeyPolicy">
+ /// The policy about how to store a public key securely.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// Any of argument is null.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// size is invalid. privateKeyAlias or publicKeyAlias is invalid format.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// Key with privateKeyAlias or publicKeyAlias does already exist.
+ /// </exception>
+ /// <remarks>
+ /// If password in policy is provided, the key is additionally encrypted with the
+ /// password in policy.
+ /// </remarks>
+ static public void CreateRsaKeyPair(
+ int size, string privateKeyAlias, string publicKeyAlias,
+ Policy privateKeyPolicy, Policy publicKeyPolicy)
+ {
+ if (size != 1024 && size != 2048 && size != 4096)
+ throw new ArgumentException(string.Format("Invalid key size({0})", size));
+ else if (privateKeyAlias == null || publicKeyAlias == null ||
+ privateKeyPolicy == null || publicKeyPolicy == null)
+ throw new ArgumentNullException("alias and policy should not be null");
+
+ Interop.CheckNThrowException(
+ Interop.CkmcManager.CreateKeyPairRsa(
+ (UIntPtr)size, privateKeyAlias, publicKeyAlias,
+ privateKeyPolicy.ToCkmcPolicy(), publicKeyPolicy.ToCkmcPolicy()),
+ "Failed to Create RSA Key Pair");
+ }
+
+ /// <summary>
+ /// Creates DSA private/public key pair and stores them inside secure repository
+ /// based on each policy.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="size">
+ /// The size of key strength to be created. 1024, 2048, 3072, and 4096 are
+ /// supported.
+ /// </param>
+ /// <param name="privateKeyAlias">The name of private key to be stored.</param>
+ /// <param name="publicKeyAlias">The name of public key to be stored.</param>
+ /// <param name="privateKeyPolicy">
+ /// The policy about how to store a private key securely.
+ /// </param>
+ /// <param name="publicKeyPolicy">
+ /// The policy about how to store a public key securely.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// Any of argument is null.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// size is invalid. privateKeyAlias or publicKeyAlias is invalid format.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// Key with privateKeyAlias or publicKeyAlias does already exist.
+ /// </exception>
+ /// <remarks>
+ /// If password in policy is provided, the key is additionally encrypted with
+ /// the password in policy.
+ /// </remarks>
+ static public void CreateDsaKeyPair(
+ int size, string privateKeyAlias, string publicKeyAlias,
+ Policy privateKeyPolicy, Policy publicKeyPolicy)
+ {
+ if (size != 1024 && size != 2048 && size != 3072 && size != 4096)
+ throw new ArgumentException(string.Format("Invalid key size({0})", size));
+ else if (privateKeyAlias == null || publicKeyAlias == null ||
+ privateKeyPolicy == null || publicKeyPolicy == null)
+ throw new ArgumentNullException("alias and policy should not be null");
+
+ Interop.CheckNThrowException(
+ Interop.CkmcManager.CreateKeyPairDsa(
+ (UIntPtr)size, privateKeyAlias, publicKeyAlias,
+ privateKeyPolicy.ToCkmcPolicy(), publicKeyPolicy.ToCkmcPolicy()),
+ "Failed to Create DSA Key Pair");
+ }
+
+ /// <summary>
+ /// Creates ECDSA private/public key pair and stores them inside secure repository
+ /// based on each policy.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="type">The type of elliptic curve of ECDSA.</param>
+ /// <param name="privateKeyAlias">The name of private key to be stored.</param>
+ /// <param name="publicKeyAlias">The name of public key to be stored.</param>
+ /// <param name="privateKeyPolicy">
+ /// The policy about how to store a private key securely.
+ /// </param>
+ /// <param name="publicKeyPolicy">
+ /// The policy about how to store a public key securely.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// Any of argument is null.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// Elliptic curve type is invalid. privateKeyAlias or publicKeyAlias is
+ /// invalid format.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// Key with privateKeyAlias or publicKeyAlias does already exist.
+ /// </exception>
+ /// <remarks>
+ /// If password in policy is provided, the key is additionally encrypted with
+ /// the password in policy.
+ /// </remarks>
+ static public void CreateEcdsaKeyPair(
+ EllipticCurveType type, string privateKeyAlias, string publicKeyAlias,
+ Policy privateKeyPolicy, Policy publicKeyPolicy)
+ {
+ if (privateKeyAlias == null || publicKeyAlias == null ||
+ privateKeyPolicy == null || publicKeyPolicy == null)
+ throw new ArgumentNullException("alias and policy should not be null");
+
+ Interop.CheckNThrowException(
+ Interop.CkmcManager.CreateKeyPairEcdsa(
+ (int)type, privateKeyAlias, publicKeyAlias,
+ privateKeyPolicy.ToCkmcPolicy(), publicKeyPolicy.ToCkmcPolicy()),
+ "Failed to Create ECDSA Key Pair");
+ }
+
+ /// <summary>
+ /// Creates AES key and stores it inside secure repository based on each policy.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="size">
+ /// The size of key strength to be created. 128, 192 and 256 are supported.
+ /// </param>
+ /// <param name="keyAlias">The name of key to be stored.</param>
+ /// <param name="policy">The policy about how to store the key securely.</param>
+ /// <exception cref="ArgumentNullException">
+ /// keyAlias or policy is null.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// Key size is invalid. keyAlias is invalid format.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// Key with privateKeyAlias or publicKeyAlias does already exist.
+ /// </exception>
+ /// <remarks>
+ /// If password in policy is provided, the key is additionally encrypted with
+ /// the password in policy.
+ /// </remarks>
+ static public void CreateAesKey(int size, string keyAlias, Policy policy)
+ {
+ if (size != 128 && size != 192 && size != 256)
+ throw new ArgumentException(string.Format("Invalid key size({0})", size));
+ else if (keyAlias == null || policy == null)
+ throw new ArgumentNullException("alias and policy should not be null");
+
+ Interop.CheckNThrowException(
+ Interop.CkmcManager.CreateKeyAes(
+ (UIntPtr)size, keyAlias, policy.ToCkmcPolicy()),
+ "Failed to AES Key");
+ }
+
+ // to be static class safely
+ internal KeyManager()
+ {
+ }
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/KeyType.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/KeyType.cs
new file mode 100644
index 0000000..483af31
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/KeyType.cs
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+namespace Tizen.Security.SecureRepository
+{
+ /// <summary>
+ /// Enumeration for key types of key manager.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum KeyType : int
+ {
+ /// <summary>
+ /// Key type not specified
+ /// </summary>
+ None = 0,
+ /// <summary>
+ /// RSA public key
+ /// </summary>
+ RsaPublic,
+ /// <summary>
+ /// RSA private key
+ /// </summary>
+ RsaPrivate,
+ /// <summary>
+ /// ECDSA public key
+ /// </summary>
+ EcdsaPublic,
+ /// <summary>
+ /// ECDSA private key
+ /// </summary>
+ EcdsaPrivate,
+ /// <summary>
+ /// DSA public key
+ /// </summary>
+ DsaPublic,
+ /// <summary>
+ /// DSA private key
+ /// </summary>
+ DsaPrivate,
+ /// <summary>
+ /// AES key
+ /// </summary>
+ Aes
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Manager.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Manager.cs
new file mode 100644
index 0000000..035eb8e
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Manager.cs
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+using System;
+
+namespace Tizen.Security.SecureRepository
+{
+ /// <summary>
+ /// This class is a base class of XxxManager classes. It provides the common methods
+ /// for all sub classes.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class Manager
+ {
+ /// <summary>
+ /// Creates a new full alias which is concatenation of owner id and alias.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="ownerId">Data owner's id. This should be package id if data
+ /// owner is application. If you want to access data stored by system services,
+ /// use CreateFullSystemAlias() instead.</param>
+ /// <param name="alias">Data alias.</param>
+ static public string CreateFullAlias(string ownerId, string alias)
+ {
+ return ownerId + Manager.OwnerIdSeperator + alias;
+ }
+
+ /// <summary>
+ /// Creates a new full alias which is concatenation of system service's
+ /// owner id and alias.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="alias">Data alias which is owned by system service.</param>
+ static public string CreateFullSystemAlias(string alias)
+ {
+ return Manager.CreateFullAlias(Manager.SystemOwnerId, alias);
+ }
+
+ /// <summary>
+ /// Removes a an entry (no matter of type) from the key manager.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="alias">Item alias to be removed.</param>
+ /// <exception cref="ArgumentNullException">alias is null.</exception>
+ /// <exception cref="ArgumentException">alias is invalid format.</exception>
+ /// <exception cref="InvalidOperationException">alias does not exist.</exception>
+ /// <remarks>
+ /// To remove item, client must have remove permission to the specified item.
+ /// </remarks>
+ /// <remarks>The item owner can remove by default.</remarks>
+ static public void RemoveAlias(string alias)
+ {
+ if (alias == null)
+ throw new ArgumentNullException("alias should not be null");
+
+ Interop.CheckNThrowException(
+ Interop.CkmcManager.RemoveAlias(alias),
+ "Failed to remove alias. alias=" + alias);
+ }
+
+ /// <summary>
+ /// Allows another application to access client's application data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="alias">Item alias for which access will be granted.</param>
+ /// <param name="otherPackageId">
+ /// Package id of the application that will gain access rights.
+ /// </param>
+ /// <param name="permissions">
+ /// Mask of permissions(Permission enum) granted for an application with
+ /// otherPackageId.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// alias or otherPackageId is null.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// alias or otherPackageId is invalid format.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">alias does not exist.</exception>
+ /// <remarks>Data identified by alias should exist.</remarks>
+ /// <remarks>The item owner can set permissions.</remarks>
+ static public void SetPermission(
+ string alias, string otherPackageId, int permissions)
+ {
+ if (alias == null || otherPackageId == null)
+ throw new ArgumentNullException("alias or otherPackageId is null");
+
+ Interop.CheckNThrowException(
+ Interop.CkmcManager.SetPermission(alias, otherPackageId, permissions),
+ "Failed to set permission. alias=" + alias);
+ }
+
+ // to being static base class
+ internal Manager()
+ {
+ }
+
+ private const string OwnerIdSeperator = " ";
+ private const string SystemOwnerId = "/System";
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/OcspStatus.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/OcspStatus.cs
new file mode 100644
index 0000000..b6517e8
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/OcspStatus.cs
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tizen.Security.SecureRepository
+{
+ /// <summary>
+ /// Enumeration for OCSP status.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum OcspStatus : int
+ {
+ /// <summary>
+ /// OCSP status is good
+ /// </summary>
+ Good = 0x00,
+ /// <summary>
+ /// The certificate is revoked
+ /// </summary>
+ Revoked = 0x01,
+ /// <summary>
+ /// Unknown error
+ /// </summary>
+ Unknown = 0x02,
+ /// <summary>
+ /// The certificate does not provide OCSP extension
+ /// </summary>
+ Unsupported = 0x03,
+ /// <summary>
+ /// The invalid URL in certificate OCSP extension
+ /// </summary>
+ InvalidUrl = 0x04,
+ /// <summary>
+ /// The invalid response from OCSP server
+ /// </summary>
+ InvalidResponse = 0x05,
+ /// <summary>
+ /// OCSP remote server error
+ /// </summary>
+ RemoteError = 0x06,
+ /// <summary>
+ /// Network connection error
+ /// </summary>
+ NetworkError = 0x07,
+ /// <summary>
+ /// Internal error
+ /// </summary>
+ InternalError = 0x08
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Permission.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Permission.cs
new file mode 100644
index 0000000..9dc4bda
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Permission.cs
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+namespace Tizen.Security.SecureRepository
+{
+
+ /// <summary>
+ /// Enumeration for permissions to access/modify alias.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum Permission : int
+ {
+ /// <summary>
+ /// Clear permissions
+ /// </summary>
+ None = 0x00,
+ /// <summary>
+ /// Eead allowed
+ /// </summary>
+ Read = 0x01,
+ /// <summary>
+ /// Remove allowed
+ /// </summary>
+ Remove = 0x02
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/PinnedObject.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/PinnedObject.cs
new file mode 100644
index 0000000..83d3e4d
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/PinnedObject.cs
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Security.SecureRepository
+{
+ internal class PinnedObject : IDisposable
+ {
+ private bool _disposed = false;
+ private GCHandle _pinnedObj;
+
+ public PinnedObject(Object obj)
+ {
+ _pinnedObj = GCHandle.Alloc(obj, GCHandleType.Pinned);
+ }
+
+ ~PinnedObject()
+ {
+ Dispose(false);
+ }
+
+ public static implicit operator IntPtr(PinnedObject pinned)
+ {
+ return pinned._pinnedObj.AddrOfPinnedObject();
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_disposed)
+ return;
+ _pinnedObj.Free();
+ _disposed = true;
+ }
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Pkcs12.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Pkcs12.cs
new file mode 100644
index 0000000..fea73f9
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Pkcs12.cs
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using static Interop;
+
+namespace Tizen.Security.SecureRepository
+{
+ /// <summary>
+ /// Class that represents a PKCS#12 contents.
+ /// It has a private key or its certificate or all the members of a chain of trust.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class Pkcs12
+ {
+ private SafeCertificateListHandle _certChainHandle = null;
+
+ /// <summary>
+ /// Load Pkcs12 from the given PKCS#12 file path.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="filePath">The path of PKCS12 file to be loaded.</param>
+ /// <param name="filePassword">The passphrase used to decrypt the PCKS12 file.
+ /// If PKCS12 file is not encrypted, passphrase can be null.</param>
+ /// <exception cref="ArgumentNullException">filePath is null.</exception>
+ /// <exception cref="InvalidOperationException">
+ /// No file on filePath.
+ /// No permission to access file.
+ /// File is invalid PKCS12 format.
+ /// File cannot be extracted with provided filePassword.
+ /// </exception>
+ static public Pkcs12 Load(string filePath, string filePassword)
+ {
+ if (filePath == null)
+ throw new ArgumentNullException("filePath should not be null");
+
+ IntPtr ptr = IntPtr.Zero;
+
+ try
+ {
+ Interop.CheckNThrowException(
+ Interop.CkmcTypes.Pkcs12Load(filePath, filePassword, out ptr),
+ "Failed to load PKCS12. file=" + filePath);
+ return new Pkcs12(ptr);
+ }
+ finally
+ {
+ if (ptr != IntPtr.Zero)
+ Interop.CkmcTypes.Pkcs12Free(ptr);
+ }
+ }
+
+ /// <summary>
+ /// A constructor of Key that takes a private key.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="privateKey">A private key.</param>
+ public Pkcs12(Key privateKey)
+ {
+ this.PrivateKey = privateKey;
+ this.Certificate = null;
+ this.CaChain = null;
+ }
+
+ /// <summary>
+ /// A constructor of Key that takes a private key, its corresponding certicate,
+ /// and CA's certificate chain.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="privateKey">A private key.</param>
+ /// <param name="certificate">A certificate corresponding the private key</param>
+ /// <param name="caChain">
+ /// A certificate chain of CA(Certificate Authority) that issued the certificate.
+ /// </param>
+ public Pkcs12(Key privateKey,
+ Certificate certificate,
+ IEnumerable<Certificate> caChain)
+ {
+ this.PrivateKey = privateKey;
+ this.Certificate = certificate;
+ this.CaChain = caChain;
+ }
+
+ internal Pkcs12(IntPtr ptr)
+ {
+ var ckmcPkcs12 = Marshal.PtrToStructure<Interop.CkmcPkcs12>(ptr);
+
+ this.PrivateKey = new Key(ckmcPkcs12.privateKey);
+ if (ckmcPkcs12.certificate != IntPtr.Zero)
+ this.Certificate = new Certificate(ckmcPkcs12.certificate);
+ if (ckmcPkcs12.caChain != IntPtr.Zero)
+ this._certChainHandle = new SafeCertificateListHandle(ckmcPkcs12.caChain);
+ }
+
+ internal IntPtr GetHandle()
+ {
+ IntPtr keyPtr = IntPtr.Zero;
+ IntPtr certPtr = IntPtr.Zero;
+ IntPtr cacertPtr = IntPtr.Zero;
+ IntPtr p12Ptr = IntPtr.Zero;
+ try
+ {
+ keyPtr = this.PrivateKey.GetHandle();
+
+ if (this.Certificate != null)
+ certPtr = this.Certificate.GetHandle();
+
+ if (this._certChainHandle != null)
+ cacertPtr = this._certChainHandle.GetHandle();
+
+ Interop.CheckNThrowException(
+ Interop.CkmcTypes.Pkcs12New(keyPtr, certPtr, cacertPtr, out p12Ptr),
+ "Failed to create pkcs12");
+
+ return p12Ptr;
+ }
+ catch
+ {
+ if (p12Ptr != IntPtr.Zero)
+ {
+ Interop.CkmcTypes.Pkcs12Free(p12Ptr);
+ }
+ else
+ {
+ if (keyPtr != IntPtr.Zero)
+ Interop.CkmcTypes.KeyFree(keyPtr);
+ if (certPtr != IntPtr.Zero)
+ Interop.CkmcTypes.CertFree(certPtr);
+ if (cacertPtr != IntPtr.Zero)
+ Interop.CkmcTypes.CertListAllFree(cacertPtr);
+ }
+
+ throw;
+ }
+ }
+
+ /// <summary>
+ /// A private key.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public Key PrivateKey
+ {
+ get; set;
+ }
+
+ /// <summary>
+ /// A certificate corresponding the private key.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public Certificate Certificate
+ {
+ get; set;
+ }
+
+ /// <summary>
+ /// A certificate chain of CA(Certificate Authority) that issued the certificate.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public IEnumerable<Certificate> CaChain
+ {
+ get
+ {
+ if (this._certChainHandle == null)
+ return null;
+ else
+ return this._certChainHandle.Certificates;
+ }
+ set
+ {
+ if (value == null)
+ this._certChainHandle = null;
+ else
+ this._certChainHandle = new SafeCertificateListHandle(value);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Pkcs12Manager.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Pkcs12Manager.cs
new file mode 100644
index 0000000..661db40
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Pkcs12Manager.cs
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+using System;
+using static Interop;
+
+namespace Tizen.Security.SecureRepository
+{
+ /// <summary>
+ /// This class provides the methods storing, retrieving Pkcs12 contents.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class Pkcs12Manager : Manager
+ {
+ /// <summary>
+ /// Gets Pkcs12 contents from secure repository.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="alias">The name of data to retrieve.</param>
+ /// <param name="keyPassword">
+ /// The password used in decrypting a private key value. If password of
+ /// keyPolicy is provided in SavePkcs12(), the same password should be provided
+ /// </param>
+ /// <param name="cerificatePassword">
+ /// The password used in decrypting a certificate value. If password of
+ /// certificatePolicy is provided in SavePkcs12(), the same password should be
+ /// provided
+ /// </param>
+ /// <returns>A Pkcs12 data specified by alias.</returns>
+ /// <exception cref="ArgumentNullException">Alias argument is null.</exception>
+ /// <exception cref="ArgumentException">
+ /// Alias argument is invalid format.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// Pkcs12 does not exist with the alias.
+ /// Optional password of key in Pkcs12 isn't matched.
+ /// Optional password of certificate in Pkcs12 isn't matched.
+ /// </exception>
+ static public Pkcs12 Get(
+ string alias, string keyPassword, string cerificatePassword)
+ {
+ if (alias == null)
+ throw new ArgumentNullException("alias should not be null");
+
+ IntPtr ptr = IntPtr.Zero;
+
+ try
+ {
+ Interop.CheckNThrowException(
+ Interop.CkmcManager.GetPkcs12(
+ alias, keyPassword, cerificatePassword, out ptr),
+ "Failed to get PKCS12. alias=" + alias);
+ return new Pkcs12(ptr);
+ }
+ finally
+ {
+ if (ptr != IntPtr.Zero)
+ Interop.CkmcTypes.Pkcs12Free(ptr);
+ }
+ }
+
+ /// <summary>
+ /// Stores PKCS12's contents inside key manager based on the provided policies.
+ /// All items from the PKCS12 will use the same alias.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="alias">The name of a data to be stored.</param>
+ /// <param name="pkcs12">The pkcs12 data to be stored.</param>
+ /// <param name="keyPolicy">
+ /// The policy about how to store pkcs's private key.
+ /// </param>
+ /// <param name="certificatePolicy">
+ /// The policy about how to store pkcs's certificate.
+ /// </param>
+ /// <exception cref="ArgumentNullException">Any of argument is null.</exception>
+ /// <exception cref="ArgumentException">
+ /// Alias argument is invalid format. Pkcs12 argument is invalid format.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// Pkcs12 with alias does already exist.
+ /// </exception>
+ static public void Save(
+ string alias, Pkcs12 pkcs12, Policy keyPolicy, Policy certificatePolicy)
+ {
+ if (alias == null || pkcs12 == null || keyPolicy == null ||
+ certificatePolicy == null)
+ throw new ArgumentNullException("any of argument is null");
+
+ IntPtr ptr = IntPtr.Zero;
+ try
+ {
+ ptr = pkcs12.GetHandle();
+
+ Interop.CheckNThrowException(
+ Interop.CkmcManager.SavePkcs12(
+ alias, ptr, keyPolicy.ToCkmcPolicy(),
+ certificatePolicy.ToCkmcPolicy()),
+ "Failed to save PKCS12. alias=" + alias);
+ }
+ finally
+ {
+ if (ptr != IntPtr.Zero)
+ Interop.CkmcTypes.Pkcs12Free(ptr);
+ }
+ }
+
+ // to be static class safely
+ internal Pkcs12Manager()
+ {
+ }
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Policy.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Policy.cs
new file mode 100644
index 0000000..56fac91
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Policy.cs
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+using System;
+using static Interop;
+
+namespace Tizen.Security.SecureRepository
+{
+ /// <summary>
+ /// A class for a policy for storing key, certificate, and binary data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class Policy
+ {
+ /// <summary>
+ /// A default constructor of Policy with default policy.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>The default value for Password is null and the default value for Extractabl is false.</remarks>
+ public Policy()
+ {
+ Password = null;
+ Extractable = true;
+ }
+
+ /// <summary>
+ /// A constructor of Key that takes the password and the flag for extractable.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="password">Used to encrypt data secure repository.</param>
+ /// <param name="extractable">If true key may be extracted from secure repository.</param>
+ public Policy(String password, bool extractable)
+ {
+ Password = password;
+ Extractable = extractable;
+ }
+
+ /// <summary>
+ /// Used to encrypt data secure repository. If it is not null, the data
+ /// (or key, or certificate) is stored encrypted with this password inside secure repository
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public String Password
+ {
+ get; set;
+ }
+
+ /// <summary>
+ /// If true key may be extracted from secure repository.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool Extractable
+ {
+ get; set;
+ }
+
+ internal CkmcPolicy ToCkmcPolicy()
+ {
+ return new Interop.CkmcPolicy(Password, Extractable);
+ }
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/SafeAliasListHandle.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/SafeAliasListHandle.cs
new file mode 100644
index 0000000..13c15d6
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/SafeAliasListHandle.cs
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using static Interop;
+
+namespace Tizen.Security.SecureRepository
+{
+ internal class SafeAliasListHandle
+ {
+ public SafeAliasListHandle(IntPtr ptr)
+ {
+ var cur = ptr;
+ var aliases = new List<string>();
+ while (cur != IntPtr.Zero)
+ {
+ var ckmcAliasList = Marshal.PtrToStructure<Interop.CkmcAliasList>(cur);
+ aliases.Add(Marshal.PtrToStringAnsi(ckmcAliasList.alias));
+ cur = ckmcAliasList.next;
+ }
+
+ this.Aliases = aliases;
+ }
+
+ public List<string> Aliases
+ {
+ get; set;
+ }
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/SafeCertificateListHandle.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/SafeCertificateListHandle.cs
new file mode 100644
index 0000000..7b1f75a
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/SafeCertificateListHandle.cs
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using static Interop;
+
+namespace Tizen.Security.SecureRepository
+{
+ internal class SafeCertificateListHandle
+ {
+ private IEnumerable<Certificate> _certificates;
+
+ public SafeCertificateListHandle(IEnumerable<Certificate> certs)
+ {
+ _certificates = certs;
+ }
+
+ public SafeCertificateListHandle(IntPtr ptr)
+ {
+ var cur = ptr;
+ var certs = new List<Certificate>();
+ while (cur != IntPtr.Zero)
+ {
+ var ckmcCertList = Marshal.PtrToStructure<CkmcCertList>(cur);
+ certs.Add(new Certificate(ckmcCertList.cert));
+ cur = ckmcCertList.next;
+ }
+
+ this._certificates = certs;
+ }
+
+ public IEnumerable<Certificate> Certificates
+ {
+ get { return _certificates; }
+ }
+
+ internal IntPtr GetHandle()
+ {
+ if (_certificates == null)
+ return IntPtr.Zero;
+
+ IntPtr first = IntPtr.Zero;
+ IntPtr previous = IntPtr.Zero;
+ IntPtr certPtr = IntPtr.Zero;
+
+ try
+ {
+ foreach (var cert in this._certificates)
+ {
+ // initialize local variables to release memory safely for
+ // in case of exception occured
+ certPtr = IntPtr.Zero;
+
+ certPtr = cert.GetHandle();
+
+ IntPtr outCertList;
+ if (previous == IntPtr.Zero)
+ {
+ Interop.CheckNThrowException(
+ Interop.CkmcTypes.CertListNew(certPtr, out outCertList),
+ "Failed to create new CertificateList.");
+ first = outCertList;
+ }
+ else
+ {
+ Interop.CheckNThrowException(
+ Interop.CkmcTypes.CertListAdd(previous, certPtr,
+ out outCertList),
+ "Failed to add Certificate to CertificateList.");
+ }
+ previous = outCertList;
+ }
+
+ return first;
+ }
+ catch
+ {
+ if (first != IntPtr.Zero)
+ Interop.CkmcTypes.CertListAllFree(first);
+ if (certPtr != IntPtr.Zero)
+ Interop.CkmcTypes.CertFree(certPtr);
+
+ throw;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/SafeRawBufferHandle.cs b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/SafeRawBufferHandle.cs
new file mode 100644
index 0000000..04c0db6
--- /dev/null
+++ b/src/Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/SafeRawBufferHandle.cs
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using static Interop;
+
+namespace Tizen.Security.SecureRepository
+{
+ internal class SafeRawBufferHandle
+ {
+ public SafeRawBufferHandle(IntPtr ptr)
+ {
+ if (ptr == IntPtr.Zero)
+ throw new ArgumentNullException("Returned ptr from CAPI cannot be null");
+
+ var ckmcBuf = Marshal.PtrToStructure<CkmcRawBuffer>(ptr);
+ byte[] data = new byte[(int)ckmcBuf.size];
+ Marshal.Copy(ckmcBuf.data, data, 0, data.Length);
+ this.Data = data;
+ }
+
+ internal IntPtr GetHandle()
+ {
+ IntPtr ptr = IntPtr.Zero;
+ try
+ {
+ CheckNThrowException(
+ Interop.CkmcTypes.BufferNew(
+ this.Data, (UIntPtr)this.Data.Length, out ptr),
+ "Failed to create buf");
+
+ return ptr;
+ }
+ catch
+ {
+ if (ptr != IntPtr.Zero)
+ Interop.CkmcTypes.BufferFree(ptr);
+
+ throw;
+ }
+ }
+
+ public byte[] Data
+ {
+ get; set;
+ }
+ }
+}
diff --git a/src/Tizen.Security.TEEC/.gitignore b/src/Tizen.Security.TEEC/.gitignore
new file mode 100644
index 0000000..a6c57f5
--- /dev/null
+++ b/src/Tizen.Security.TEEC/.gitignore
@@ -0,0 +1 @@
+*.json
diff --git a/src/Tizen.Security.TEEC/Interop/Interop.Errors.cs b/src/Tizen.Security.TEEC/Interop/Interop.Errors.cs
new file mode 100644
index 0000000..eb86422
--- /dev/null
+++ b/src/Tizen.Security.TEEC/Interop/Interop.Errors.cs
@@ -0,0 +1,39 @@
+/*
+ * Interop.Errors.cs
+ *
+ * Created on: Apr 4, 2017
+ * Author: k.dynowski
+ */
+
+using System;
+
+internal static partial class Interop
+{
+
+ private const string LogTag = "Tizen.Security.Libteec";
+ internal enum LibteecError : uint
+ {
+ None = 0,
+ NotImplemented = 0xFFFF0009,
+ CommunicationFailed = 0xFFFF000E,
+ };
+
+ internal static void CheckNThrowException(int err, string msg)
+ {
+ switch ((uint)err)
+ {
+ case (uint)LibteecError.None:
+ return ;
+ case (uint)LibteecError.NotImplemented:
+ throw new NotSupportedException(string.Format("[{0}] {1} error=0x{2}",
+ LogTag, msg, err.ToString("X")));
+ case (uint)LibteecError.CommunicationFailed:
+ throw new Exception(string.Format("[{0}] {1} error=0x{2}",
+ LogTag, msg, err.ToString("X")));
+ default:
+ throw new InvalidOperationException(string.Format("[{0}] {1}, error=0x{2}",
+ LogTag, msg, err.ToString("X")));
+
+ }
+ }
+}
diff --git a/src/Tizen.Security.TEEC/Interop/Interop.Libraries.cs b/src/Tizen.Security.TEEC/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..25c903e
--- /dev/null
+++ b/src/Tizen.Security.TEEC/Interop/Interop.Libraries.cs
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string Libteec = "libteec.so";
+ }
+}
diff --git a/src/Tizen.Security.TEEC/Interop/Interop.Libteec.cs b/src/Tizen.Security.TEEC/Interop/Interop.Libteec.cs
new file mode 100644
index 0000000..1c1f969
--- /dev/null
+++ b/src/Tizen.Security.TEEC/Interop/Interop.Libteec.cs
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+using System;
+using System.Runtime.InteropServices;
+//using Interop.Liibteec.Types;
+
+internal static partial class Interop
+{
+ internal static partial class Libteec
+ {
+ /// <summary>
+ /// This function initializes a new TEE Context, forming a connection between this Client Application and the
+ /// TEE identified by the string identifier name.
+ /// The Client Application MAY pass name with a value of NULL, which means that the Implementation MUST
+ /// select a default TEE to connect to. The supported name strings, the mapping of these names to a specific
+ /// TEE, and the nature of the default TEE are implementation-defined.
+ /// </summary>
+ //TEEC_Result TEEC_InitializeContext(const char *name, TEEC_Context *context);
+ [DllImport(Libraries.Libteec, EntryPoint = "TEEC_InitializeContext", CallingConvention = CallingConvention.Cdecl)]
+ static public extern int InitializeContext(string name, ref TEEC_Context context);
+
+ /// <summary>
+ /// This function destroys an initialized TEE Context, closing the connection between the Client Application
+ /// and the TEE. The Client Application MUST only call this function when all Sessions inside this TEE
+ /// Context have been closed and all Shared Memory blocks have been released.
+ /// The implementation of this function MUST NOT be able to fail; after this function returns the Client
+ /// Application must be able to consider that the Context has been closed.
+ /// The function implementation MUST do nothing if the value of the context pointer is NULL.
+ /// </summary>
+ //void TEEC_FinalizeContext(TEEC_Context *context);
+ [DllImport(Libraries.Libteec, EntryPoint = "TEEC_FinalizeContext", CallingConvention = CallingConvention.Cdecl)]
+ static public extern void FinalizeContext(ref TEEC_Context context);
+
+ /// <summary>
+ /// This function registers a block of existing Client Application memory as a block of Shared Memory within
+ /// the scope of the specified TEE Context, in accordance with the parameters which have been set by the
+ /// Client Application inside the sharedMem structure.
+ /// The input context MUST point to an initialized TEE Context.
+ /// The input sharedMem MUST point to the Shared Memory structure defining the memory region to register
+ /// </summary>
+ //EEC_Result TEEC_RegisterSharedMemory(TEEC_Context *context, TEEC_SharedMemory *sharedMem);
+ [DllImport(Libraries.Libteec, EntryPoint = "TEEC_RegisterSharedMemory", CallingConvention = CallingConvention.Cdecl)]
+ static public extern int RegisterSharedMemory(ref TEEC_Context context, ref TEEC_SharedMemory sharedMem);
+
+ /// <summary>
+ /// This function allocates a new block of memory as a block of Shared Memory within the scope of the
+ /// specified TEE Context, in accordance with the parameters which have been set by the Client Application
+ /// inside the sharedMem structure.
+ /// The input context MUST point to an initialized TEE Context.
+ /// The input sharedMem MUST point to the Shared Memory structure defining the region to allocate.
+ /// </summary>
+ //TEEC_Result TEEC_AllocateSharedMemory(TEEC_Context *context, TEEC_SharedMemory *sharedMem);
+ [DllImport(Libraries.Libteec, EntryPoint = "TEEC_AllocateSharedMemory", CallingConvention = CallingConvention.Cdecl)]
+ static public extern int AllocateSharedMemory(ref TEEC_Context context, ref TEEC_SharedMemory sharedMem);
+
+ /// <summary>
+ /// This function deregisters or deallocates a previously initialized block of Shared Memory.
+ /// For a memory buffer allocated using AllocateSharedMemory the Implementation MUST free the
+ /// underlying memory and the Client Application MUST NOT access this region after this function has been
+ /// called. In this case the Implementation MUST set the buffer and size fields of the sharedMem
+ /// structure to NULL and 0 respectively before returning.
+ /// For memory registered using RegisterSharedMemory the implementation MUST deregister the
+ /// underlying memory from the TEE, but the memory region will stay available to the Client Application for
+ /// other purposes as the memory is owned by it.
+ /// The implementation MUST do nothing if the value of the sharedMem parameter is NULL.
+ /// </summary>
+ //void TEEC_ReleaseSharedMemory(TEEC_SharedMemory *sharedMem);
+ [DllImport(Libraries.Libteec, EntryPoint = "TEEC_ReleaseSharedMemory", CallingConvention = CallingConvention.Cdecl)]
+ static public extern void ReleaseSharedMemory(ref TEEC_SharedMemory sharedMem);
+
+ /// <summary>
+ /// This function opens a new Session between the Client Application and the specified Trusted Application.
+ /// The Implementation MUST assume that all fields of this session structure are in an undefined state.
+ /// When this function returns TEEC_SUCCESS the Implementation MUST have populated this structure with
+ /// any information necessary for subsequent operations within the Session.
+ /// The target Trusted Application is identified by a UUID passed in the parameter destination.
+ /// </summary>
+ //TEEC_Result TEEC_OpenSession(TEEC_Context *context, TEEC_Session *session, const TEEC_UUID *destination, uint connectionMethod, const void *connectionData, TEEC_Operation *operation, uint *returnOrigin);
+ [DllImport(Libraries.Libteec, EntryPoint = "TEEC_OpenSession", CallingConvention = CallingConvention.Cdecl)]
+ static public extern int OpenSession(ref TEEC_Context context, ref TEEC_Session session, TEEC_UUID destination, uint connectionMethod, byte[] connectionData, ref TEEC_Operation operation, out uint returnOrigin);
+
+ /// <summary>
+ /// This function closes a Session which has been opened with a Trusted Application.
+ /// All Commands within the Session MUST have completed before this function can be called.
+ /// The Implementation MUST do nothing if the input session parameter is NULL.
+ /// The implementation of this function MUST NOT be able to fail; after this function returns the Client
+ /// Application must be able to consider that the Session has been closed.
+ /// </summary>
+ //void TEEC_CloseSession(TEEC_Session *session);
+ [DllImport(Libraries.Libteec, EntryPoint = "TEEC_CloseSession", CallingConvention = CallingConvention.Cdecl)]
+ static public extern void CloseSession(ref TEEC_Session session);
+
+ /// <summary>
+ /// This function invokes a Command within the specified Session.
+ /// The parameter session MUST point to a valid open Session.
+ /// The parameter commandID is an identifier that is used to indicate which of the exposed Trusted
+ /// Application functions should be invoked. The supported command identifier values are defined by the
+ /// Trusted Application‟s protocol.
+ /// </summary>
+ //TEEC_Result TEEC_InvokeCommand(TEEC_Session *session, uint commandID, TEEC_Operation *operation, uint *returnOrigin);
+ [DllImport(Libraries.Libteec, EntryPoint = "TEEC_InvokeCommand", CallingConvention = CallingConvention.Cdecl)]
+ static public extern int InvokeCommand(ref TEEC_Session session, uint commandID, ref TEEC_Operation operation, out uint returnOrigin);
+
+ /// <summary>
+ /// This function requests the cancellation of a pending open Session operation or a Command invocation
+ /// operation. As this is a synchronous API, this function must be called from a thread other than the one
+ /// executing the OpenSession or InvokeCommand function.
+ /// This function just sends a cancellation signal to the TEE and returns immediately; the operation is not
+ /// guaranteed to have been cancelled when this function returns. In addition, the cancellation request is just
+ /// a hint; the TEE or the Trusted Application MAY ignore the cancellation request.
+ /// </summary>
+ //void TEEC_RequestCancellation(TEEC_Operation *operation);
+ [DllImport(Libraries.Libteec, EntryPoint = "TEEC_RequestCancellation", CallingConvention = CallingConvention.Cdecl)]
+ static public extern void RequestCancellation(ref TEEC_Operation operation);
+ }
+}
diff --git a/src/Tizen.Security.TEEC/Interop/Interop.Types.cs b/src/Tizen.Security.TEEC/Interop/Interop.Types.cs
new file mode 100644
index 0000000..75955d1
--- /dev/null
+++ b/src/Tizen.Security.TEEC/Interop/Interop.Types.cs
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct TEEC_Context
+ {
+ public readonly IntPtr imp;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct TEEC_Session
+ {
+ public readonly IntPtr imp;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct TEEC_UUID
+ {
+ public UInt32 timeLow;
+ public UInt16 timeMid;
+ public UInt16 timeHiAndVersion;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
+ public byte[] clockSeqAndNode;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct sTEEC_SharedMemoryImp
+ {
+ public IntPtr context;
+ public IntPtr context_imp;
+ public UInt32 flags;
+ public UInt32 memid;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct TEEC_SharedMemory
+ {
+ public IntPtr buffer;
+ public UInt32 size;
+ public UInt32 flags;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct TEEC_Parameter
+ {
+ public UInt32 a;
+ public UInt32 b;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct TEEC_Operation
+ {
+ public UInt32 started;
+ public UInt32 paramTypes;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
+ public TEEC_Parameter[] paramlist;
+ public IntPtr imp;
+ }
+}
+
diff --git a/src/Tizen.Security.TEEC/Tizen.Security.TEEC.csproj b/src/Tizen.Security.TEEC/Tizen.Security.TEEC.csproj
new file mode 100644
index 0000000..d5717a4
--- /dev/null
+++ b/src/Tizen.Security.TEEC/Tizen.Security.TEEC.csproj
@@ -0,0 +1,15 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
+
diff --git a/src/Tizen.Security.TEEC/Tizen.Security.TEEC/Libteec.cs b/src/Tizen.Security.TEEC/Tizen.Security.TEEC/Libteec.cs
new file mode 100644
index 0000000..5393400
--- /dev/null
+++ b/src/Tizen.Security.TEEC/Tizen.Security.TEEC/Libteec.cs
@@ -0,0 +1,608 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Tizen.Security.TEEC
+{
+ /// <summary>
+ /// This type denotes Session Login Method used in OpenSession
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class LoginMethod
+ {
+ /// <summary>No login data is provided.</summary>
+ public const uint Public = 0x00000000;
+ /// <summary>Login data about the user running the Client Application process is provided.</summary>
+ public const uint User = 0x00000001;
+ /// <summary>Login data about the group running the Client Application process is provided.</summary>
+ public const uint Group = 0x00000002;
+ /// <summary>Login data about the running Client Application itself is provided.</summary>
+ public const uint Application = 0x00000003;
+ }
+
+ /// <summary>
+ /// This type denotes Value parameter
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum TEFValueType : UInt32
+ {
+ /// <summary>The Parameter is a ValueType tagged as input.</summary>
+ Input = 0x00000001,
+ /// <summary>The Parameter is a ValueType tagged as output.</summary>
+ Output = 0x00000002,
+ /// <summary>The Parameter is a ValueType tagged as both as input and output.</summary>
+ InOut = 0x00000003,
+ }
+
+ /// <summary>
+ /// This type denotes TempMemoryReference parameter
+ /// describing a region of memory which needs to be temporarily registered for the duration of the operation.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum TEFTempMemoryType : UInt32
+ {
+ /// <summary>The Parameter is a TempMemoryType and is tagged as input.</summary>
+ Input = 0x00000005,
+ /// <summary>Same as Input, but the Memory Reference is tagged as output.</summary>
+ Output = 0x00000006,
+ /// <summary>A Temporary Memory Reference tagged as both input and output.</summary>
+ InOut = 0x00000007,
+ }
+
+ /// <summary>
+ /// This type denotes SharedMemoryReference parameter
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum TEFRegisteredMemoryType : UInt32
+ {
+ /// <summary>The Parameter is a Registered Memory Reference that refers to the entirety of its parent Shared Memory block.</summary>
+ Whole = 0x0000000C,
+ /// <summary>A Registered Memory Reference structure that refers to a partial region of its parent Shared Memory block and is tagged as input.</summary>
+ PartialInput = 0x0000000D,
+ /// <summary>A Registered Memory Reference structure that refers to a partial region of its parent Shared Memory block and is tagged as output.</summary>
+ PartialOutput = 0x0000000E,
+ /// <summary>A Registered Memory Reference structure that refers to a partial region of its parent Shared Memory block and is tagged as both input and output.</summary>
+ PartialInOut = 0x0000000F,
+ }
+
+ /// <summary>
+ /// This type denotes SharedMemory access direction
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ [Flags]
+ public enum SharedMemoryFlags : UInt32
+ {
+ /// <summary>A flag indicates Shared Memory can be read.</summary>
+ Input = 0x00000001,
+ /// <summary>A flag indicates Shared Memory can be written.</summary>
+ Output = 0x00000002,
+ /// <summary>A flag indicates Shared Memory can be read and written.</summary>
+ InOut = Input | Output,
+ }
+
+ /// <summary>
+ /// This type denotes a Shared Memory block which has either been registered
+ /// with the implementation or allocated by it.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public sealed class SharedMemory
+ {
+ internal Interop.TEEC_SharedMemory shm;
+ internal SharedMemory(Interop.TEEC_SharedMemory shm)
+ {
+ this.shm=shm;
+ }
+ /// <summary>
+ /// This property represents shared memory size in bytes.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public UInt32 Size
+ {
+ get { return shm.size; }
+ }
+ /// <summary>
+ /// This property represents start address of shared memory block.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public IntPtr Address
+ {
+ get { return shm.buffer; }
+ }
+
+ /// <summary>
+ /// This function makes a copy and is designed for convenient operations on small buffers.
+ /// For large buffers direct address should be used.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="data">Source data buffer to copy data from</param>
+ /// <param name="dstOffs">Starting offset in destination shared memory</param>
+ /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
+ public void SetData(byte[] data, int dstOffs)
+ {
+ if ((shm.flags & (uint)SharedMemoryFlags.Output) == 0) throw new InvalidOperationException("No write access");
+ //TODO copy data into shared memory starting at given offset
+ }
+ /// <summary>
+ /// This function makes a copy and is designed for convenient operations on small buffers.
+ /// For large buffers direct address should be used.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="data">Destination data buffer to copy data into</param>
+ /// <param name="srcOffs">Starting offset in source shared memory</param>
+ /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
+ public void GetData(byte[] data, int srcOffs)
+ {
+ if ((shm.flags & (uint)SharedMemoryFlags.Input) == 0) throw new InvalidOperationException("No read access");
+ //TODO copy data from shared memory starting at given offset
+ }
+ };
+
+ /// <summary>
+ /// This type defines the payload of either an open Session operation or an invoke Command operation. It is
+ /// also used for cancellation of operations, which may be desirable even if no payload is passed.
+ /// Parameters are used to exchange data between CA and TA
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public abstract class Parameter
+ {
+ internal Parameter(uint t)
+ {
+ this.NativeType = t;
+ }
+ internal uint NativeType { get; }
+ };
+
+ /// <summary>
+ /// This type defines a template for parameter types.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public abstract class BaseParameter<TEnum> : Parameter where TEnum : struct, IComparable, IFormattable, IConvertible // as close to Enum as possible
+ {
+ internal BaseParameter(TEnum t) : base((uint)(object)t)
+ {
+ Type = t;
+ }
+
+ /// <summary>
+ /// This property represents access type to this parameter.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public TEnum Type { get; }
+ }
+
+ /// <summary>
+ /// This type defines a temporary memory reference.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public sealed class TempMemoryReference : BaseParameter<TEFTempMemoryType>
+ {
+ /// <summary>
+ /// Constructs Prameter object which holds info about temporary memory copied to/from TA
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="buffer">Address of allocated memory buffer</param>
+ /// <param name="size">Size of the buffer</param>
+ /// <param name="type">Kind of access allowed for TA <see cref="TEFTempMemoryType"/></param>
+ public TempMemoryReference(IntPtr buffer, uint size, TEFTempMemoryType type) :
+ base(type)
+ {
+ this.Buffer = buffer;
+ this.Size = size;
+ }
+ /// <summary>
+ /// This property represents memory address of buffer.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public IntPtr Buffer { get; }
+ /// <summary>
+ /// This property represents size of buffer.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public uint Size { get; }
+ };
+
+ /// <summary>
+ /// This type defines a memory reference that uses a pre-registered or pre-allocated Shared Memory block.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public sealed class RegisteredMemoryReference : BaseParameter<TEFRegisteredMemoryType>
+ {
+ /// <summary>
+ /// Constructs Prameter object which holds info about registered memory shared with TA
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="parent">Shared memory - registered or allocated</param>
+ /// <param name="size">Size of the buffer part</param>
+ /// <param name="offset">Offset of buffer in shared memory</param>
+ /// <param name="type">Kind of access allowed for TA <see cref="TEFRegisteredMemoryType"/></param>
+ public RegisteredMemoryReference(SharedMemory parent, uint size, uint offset, TEFRegisteredMemoryType type) :
+ base(type)
+ {
+ this.Parent = parent;
+ this.Size = size;
+ this.Offset = offset;
+ }
+ /// <summary>
+ /// This property represents SharedMemory that is referred to.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public SharedMemory Parent { get; }
+ /// <summary>
+ /// This property represents size (in bytes) of SharedMemory.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public uint Size { get; }
+ /// <summary>
+ /// This property represents offset (in bytes) from the begin of SharedMemory.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public uint Offset { get; }
+ };
+
+ /// <summary>
+ /// This type defines a parameter that is not referencing shared memory, but carries instead small raw data
+ /// passed by value.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public sealed class Value : BaseParameter<TEFValueType>
+ {
+ /// <summary>
+ /// Constructs Prameter object which holds info about int values copied to/from TA
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="a">User paramter A</param>
+ /// <param name="b">User paramter B</param>
+ /// <param name="type">Kind of access allowed for TA <see cref="TEFValueType"/></param>
+ public Value(uint a, uint b, TEFValueType type) :
+ base(type)
+ {
+ this.A = a;
+ this.B = b;
+ }
+ /// <summary>
+ /// This property represents unsigned integer A.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public uint A { get; }
+ /// <summary>
+ /// This property represents unsigned integer B.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public uint B { get; }
+ };
+
+
+ /// <summary>
+ /// This type denotes a TEE Session, the logical container linking a Client Application with a particular Trusted Application.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public sealed class Session
+ {
+ private Interop.TEEC_Context context;
+ private Interop.TEEC_Session session;
+
+ internal Session(Interop.TEEC_Context context) {
+ this.context = context;
+ this.session = new Interop.TEEC_Session();
+ }
+
+ ~Session()
+ {
+ Close();
+ }
+
+ internal void Open(Guid destination, uint loginMethod, byte[] connectionData, Parameter[] paramlist)
+ {
+ Interop.TEEC_UUID uuid = new Interop.TEEC_UUID();
+ Interop.TEEC_Operation op = new Interop.TEEC_Operation();
+ uint ro;
+
+ int ret = Interop.Libteec.OpenSession(ref context, ref session, uuid, loginMethod, connectionData, ref op, out ro);
+ //MAYBE map origin of return code to specyfic Exception
+ Interop.CheckNThrowException(ret, string.Format("OpenSession('{0}')", destination));
+ }
+
+ /// <summary>
+ /// This function closes a Session which has been opened with a Trusted Application.
+ /// All Commands within the Session MUST have completed before this function can be called.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/tee.client</privilege>
+ /// <privlevel>partner</privlevel>
+ /// <feature>http://tizen.org/feature/security.tee</feature>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
+ public void Close() {
+ Interop.Libteec.CloseSession(ref session);
+ //session = null;
+ }
+
+ /// <summary>
+ /// This function invokes a Command within the specified Session.
+ /// The parameter commandID is an identifier that is used to indicate which of the exposed Trusted
+ /// Application functions should be invoked. The supported command identifier values are defined by the
+ /// Trusted Application's protocol.
+ /// There can be up to four Parameter objects given in the <paramref name="paramlist"/> array
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="commandID">The command</param>
+ /// <param name="paramlist">The array of parameters</param>
+ /// <privilege>http://tizen.org/privilege/tee.client</privilege>
+ /// <privlevel>partner</privlevel>
+ /// <feature>http://tizen.org/feature/security.tee</feature>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
+ /// <exception cref="ArgumentException">The argument <paramref name="paramlist"/> is wrong</exception>
+ public void InvokeCommand(uint commandID, Parameter[] paramlist)
+ {
+ Interop.TEEC_Operation op = new Interop.TEEC_Operation();
+ op.started=0;
+ op.paramTypes=0;
+
+ for (int i=0; i < 4; ++i) {
+ Parameter p = paramlist[i];
+ //TODO fill TEEC_Operation struct
+ }
+
+ uint ro;
+ int ret = Interop.Libteec.InvokeCommand(ref session, commandID, ref op, out ro);
+ //MAYBE map origin of return code to specific Exception
+ Interop.CheckNThrowException(ret, string.Format("InvokeCommand({0})", commandID));
+ }
+
+ /// <summary>
+ /// Asynchronous version of InvokeCommand
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="commandID">The command</param>
+ /// <param name="paramlist">The array of parameters</param>
+ /// <param name="token">The token for task manipulation</param>
+ /// <returns>Returns Task executing invoke command in backgroung</returns>
+ /// <privilege>http://tizen.org/privilege/tee.client</privilege>
+ /// <privlevel>partner</privlevel>
+ /// <feature>http://tizen.org/feature/security.tee</feature>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
+ /// <exception cref="ArgumentException">One of arguments is wrong</exception>
+ public async Task InvokeCommandAsync(uint commandID, Parameter[] paramlist, CancellationToken token = default(CancellationToken))
+ {
+ await Task.Factory.StartNew(() => InvokeCommand(commandID, paramlist));
+ }
+
+ };
+
+ /// <summary>
+ /// This type denotes a TEE Context, the main logical container linking a Client Application with a particular TEE.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public sealed class Context : IDisposable
+ {
+ private Interop.TEEC_Context context;
+
+ /// <summary>
+ /// This function (constructor) initializes a new TEE Context, forming a connection between this Client Application and the
+ /// TEE identified by the string identifier name (empty or null name denotes default TEE).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="name">The TEE name</param>
+ /// <privilege>http://tizen.org/privilege/tee.client</privilege>
+ /// <privlevel>partner</privlevel>
+ /// <feature>http://tizen.org/feature/security.tee</feature>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
+ public Context(string name)
+ {
+ context = new Interop.TEEC_Context();
+ int ret = Interop.Libteec.InitializeContext(name, ref context);
+ Interop.CheckNThrowException(ret, string.Format("InititalizeContext('{0}')", name));
+ }
+
+ ~Context()
+ {
+ Dispose();
+ }
+
+ /// <summary>
+ /// This function implements IDisposable interface
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/tee.client</privilege>
+ /// <privlevel>partner</privlevel>
+ /// <feature>http://tizen.org/feature/security.tee</feature>
+ public void Dispose() {
+ Interop.Libteec.FinalizeContext(ref context);
+ //context.imp = null;
+ }
+
+ /// <summary>
+ /// This function opens a new Session between the Client Application and the specified Trusted Application.
+ /// The target Trusted Application is identified by a UUID passed in the parameter destination.
+ /// There can be up to four Parameter objects given in the <paramref name="paramlist"/> array
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="destination">The UUID of destination TA</param>
+ /// <param name="loginMethod">The authentication algorithm <see cref="LoginMethod" /></param>
+ /// <param name="connectionData">The data to be verified by given login method</param>
+ /// <param name="paramlist">The parameters to be passed to TA open-session-callback</param>
+ /// <returns>Returns opened session</returns>
+ /// <privilege>http://tizen.org/privilege/tee.client</privilege>
+ /// <privlevel>partner</privlevel>
+ /// <feature>http://tizen.org/feature/security.tee</feature>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
+ /// <exception cref="ArgumentException">One of arguments is wrong</exception>
+ public Session OpenSession(Guid destination, uint loginMethod, byte[] connectionData, Parameter[] paramlist)
+ {
+ Session ses = new Session(context);
+ ses.Open(destination, loginMethod, connectionData, paramlist);
+ return ses;
+ }
+ /// <summary>
+ /// @see OpenSession(Guid destination, uint connectionMethod, byte[] connectionData, Parameter[] paramlist, CancellationToken token)
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="destination">The UUID of destination TA</param>
+ /// <returns>Returns opened session</returns>
+ /// <privilege>http://tizen.org/privilege/tee.client</privilege>
+ /// <privlevel>partner</privlevel>
+ /// <feature>http://tizen.org/feature/security.tee</feature>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
+ public Session OpenSession(Guid destination)
+ {
+ Session ses = new Session(context);
+ ses.Open(destination, LoginMethod.Public, null, null);
+ return ses;
+ }
+
+ /// <summary>
+ /// Asynchronous version of OpenSession
+ /// @see OpenSession(Guid destination, uint connectionMethod, byte[] connectionData, Parameter[] paramlist, CancellationToken token)
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="destination">The UUID of destination TA</param>
+ /// <param name="loginMethod">The authentication algorithm <see cref="LoginMethod" /></param>
+ /// <param name="connectionData">The data to be verified by given login method</param>
+ /// <param name="paramlist">The parameters to be passed to TA open-session-callback</param>
+ /// <param name="token">The token for task manipulation</param>
+ /// <returns>Returns Task executing session open in backgroung</returns>
+ /// <privilege>http://tizen.org/privilege/tee.client</privilege>
+ /// <privlevel>partner</privlevel>
+ /// <feature>http://tizen.org/feature/security.tee</feature>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
+ /// <exception cref="ArgumentException">One of arguments is wrong</exception>
+ public async Task<Session> OpenSessionAsync(Guid destination, uint loginMethod, byte[] connectionData, Parameter[] paramlist, CancellationToken token = default(CancellationToken))
+ {
+ Task<Session> task = Task<Session>.Factory.StartNew(() =>
+ {
+ return OpenSession(destination, loginMethod, connectionData, paramlist);
+ });
+ return await task;
+ }
+ /// <summary>
+ /// Asynchronous version of OpenSession
+ /// @see OpenSession(Guid destination, uint connectionMethod, byte[] connectionData, Parameter[] paramlist, CancellationToken token)
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="destination">The UUID of destination TA</param>
+ /// <param name="token">The token for task manipulation</param>
+ /// <returns>Returns Task executing session open in backgroung</returns>
+ /// <privilege>http://tizen.org/privilege/tee.client</privilege>
+ /// <privlevel>partner</privlevel>
+ /// <feature>http://tizen.org/feature/security.tee</feature>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
+ public async Task<Session> OpenSessionAsync(Guid destination, CancellationToken token = default(CancellationToken))
+ {
+ Task<Session> task = Task<Session>.Factory.StartNew(() =>
+ {
+ return OpenSession(destination);
+ });
+ return await task;
+ }
+
+ /// <summary>
+ /// This function registers a block of existing Client Application memory as a block of Shared Memory within
+ /// the scope of the specified Context, in accordance with the parameters.
+ /// The input <paramref name="memaddr"/> MUST point to the shared memory region to register
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="memaddr">The address of shared memory</param>
+ /// <param name="size">The size of shared memory</param>
+ /// <param name="flags">The flags describing access modes (Input and/or Output)</param>
+ /// <returns>Returns SharedMemory handler</returns>
+ /// <privilege>http://tizen.org/privilege/tee.client</privilege>
+ /// <privlevel>partner</privlevel>
+ /// <feature>http://tizen.org/feature/security.tee</feature>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
+ /// <exception cref="ArgumentException">The argument <paramref name="memaddr"/> is wrong</exception>
+ public SharedMemory RegisterSharedMemory(IntPtr memaddr, UInt32 size, SharedMemoryFlags flags)
+ {
+ Interop.TEEC_SharedMemory shm = new Interop.TEEC_SharedMemory();
+ shm.buffer = memaddr;
+ shm.size = size;
+ shm.flags = (UInt32)flags;
+ int ret = Interop.Libteec.RegisterSharedMemory(ref context, ref shm);
+ Interop.CheckNThrowException(ret, "RegisterSharedMemory");
+ return new SharedMemory(shm);
+ }
+
+ /// <summary>
+ /// This function allocates a new block of memory as a block of Shared Memory within the scope of the
+ /// specified Context, in accordance with the parameters.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="size">The size of shared memory</param>
+ /// <param name="flags">The flags describing access modes (Input and/or Output)</param>
+ /// <returns>Returns SharedMemory handler</returns>
+ /// <privilege>http://tizen.org/privilege/tee.client</privilege>
+ /// <privlevel>partner</privlevel>
+ /// <feature>http://tizen.org/feature/security.tee</feature>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
+ public SharedMemory AllocateSharedMemory(UInt32 size, SharedMemoryFlags flags)
+ {
+ Interop.TEEC_SharedMemory shm = new Interop.TEEC_SharedMemory();
+ shm.size = size;
+ shm.flags = (UInt32)flags;
+ int ret = Interop.Libteec.AllocateSharedMemory(ref context, ref shm);
+ Interop.CheckNThrowException(ret, "AllocateSharedMemory");
+ return new SharedMemory(shm);
+ }
+
+ /// <summary>
+ /// This function deregisters or deallocates a previously initialized block of Shared Memory.
+ /// </summary>
+ /// <remarks>
+ /// For a memory buffer allocated using AllocateSharedMemory the Implementation MUST free the
+ /// underlying memory and the Client Application MUST NOT access this region after this function has been
+ /// called. In this case the Implementation MUST clear the buffer and size fields of the sharedMem
+ /// structure before returning.
+ /// For memory registered using RegisterSharedMemory the implementation MUST deregister the
+ /// underlying memory from the TEE, but the memory region will stay available to the Client Application for
+ /// other purposes as the memory is owned by it.
+ /// </remarks>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="shm">The shared memory object returned by RegisterSharedMemory or AllocateSharedMemory</param>
+ /// <privilege>http://tizen.org/privilege/tee.client</privilege>
+ /// <privlevel>partner</privlevel>
+ /// <feature>http://tizen.org/feature/security.tee</feature>
+ /// <exception cref="UnauthorizedAccessException">Thrown when application does not have privilege to access this method.</exception>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
+ /// <exception cref="ArgumentException">The argument is wrong</exception>
+ public void ReleaseSharedMemory(SharedMemory shm)
+ {
+ Interop.Libteec.ReleaseSharedMemory(ref shm.shm);
+ }
+ };
+}
diff --git a/src/Tizen.Security.TEEC/Tizen.Security.TEEC/NamespaceDoc.cs b/src/Tizen.Security.TEEC/Tizen.Security.TEEC/NamespaceDoc.cs
new file mode 100644
index 0000000..36e1b15
--- /dev/null
+++ b/src/Tizen.Security.TEEC/Tizen.Security.TEEC/NamespaceDoc.cs
@@ -0,0 +1,78 @@
+/**
+<summary>
+The communication API for connecting Client Applications running in a rich operating environment
+with security related Trusted Applications running inside a Trusted Execution Environment (TEE).
+</summary>
+
+<remarks>
+<h2>Overview</h2>
+<para>
+A TEE provides an execution environment with security capabilities, which are either available to Trusted Applications
+running inside the TEE or exposed externally to Client Applications.
+The TEE Client API concentrates on the interface to enable efficient communications between
+a Client Application and a Trusted Application running inside the TEE.
+Higher level standards and protocol layers may be built on top of the foundation
+provided by the TEE Client API – for example, to cover common tasks such as secure storage,
+cryptography, and run-time installation of new Trusted Applications.
+The separation between the rich environment and the TEE is guaranted.
+</para>
+<para>
+The key design principles of the TEE Client API are:
+<list type="bullet">
+<item>
+ <term>Client-side memory allocations</term>
+ <description>
+ Where possible the design of the TEE Client API has placed the responsibility for memory
+ allocation on the calling Client Application code. This gives the Client developer choice of
+ memory allocation locations, enabling simple optimizations such as stack-based allocation
+ or enhanced flexibility using placements in static global memory or thread-local storage.<br />
+ This design choice is evident in the API by the use of pointers to structures rather than
+ opaque handles to represent any manipulated objects.
+ </description>
+</item>
+<item>
+ <term>Aim for zero-copy data transfer</term>
+ <description>
+ The features of the TEE Client API are chosen to maximize the possibility of zero-copy
+ data transfer between the Client Application and the Trusted Application.<br />
+ However, short messages can also be passed by copy, which avoids the overhead of
+ sharing memory.
+ </description>
+</item>
+<item>
+ <term>Support memory sharing by pointers</term>
+ <description>
+ The TEE Client API will be used to implement higher-level APIs, such as cryptography or
+ secure storage, where the caller will often provide memory buffers for input or output data
+ using simple C pointers. The TEE Client API must allow efficient sharing of this type of
+ memory, and as such does not rely on the Client Application being able to use bulk
+ memory buffers allocated by the TEE Client API.
+ </description>
+</item>
+<item>
+ <term>Specify only communication mechanisms</term>
+ <description>
+ This API focuses on defining the underlying communications channel. It does not define
+ the format of the messages which pass over the channel, or the protocols used by specific
+ Trusted Applications.
+ </description>
+</item>
+
+</list>
+</para>
+</remarks>
+
+<example>
+The following example demonstrates how to invoke command on Trused Application.
+<code>
+ Guid ta_uuid = new Guid("TA-guid-put-here");
+ Context ctx = new Context(null);
+ Session ses = ctx.OpenSession(ta_uuid);
+ Parameter[] p = { new Value(1,2,TEFValueType.In) };
+ ses.InvokeCommand(1, p);
+ ses.Close();
+ ctx.Dispose();
+</code>
+</example>
+*/
+namespace Tizen.Security.TEEC {}
diff --git a/src/Tizen.Security/.gitignore b/src/Tizen.Security/.gitignore
new file mode 100644
index 0000000..fba4e61
--- /dev/null
+++ b/src/Tizen.Security/.gitignore
@@ -0,0 +1,2 @@
+/obj
+/bin
diff --git a/src/Tizen.Security/Interop/Interop.Libraries.cs b/src/Tizen.Security/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..7188262
--- /dev/null
+++ b/src/Tizen.Security/Interop/Interop.Libraries.cs
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string Privilege = "libprivilege-info.so.1";
+ }
+}
diff --git a/src/Tizen.Security/Interop/Interop.Privilege.cs b/src/Tizen.Security/Interop/Interop.Privilege.cs
new file mode 100755
index 0000000..8b921e8
--- /dev/null
+++ b/src/Tizen.Security/Interop/Interop.Privilege.cs
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+using Tizen.Security;
+
+internal static partial class Interop
+{
+ internal static partial class Privilege
+ {
+ internal static string LogTag = "Tizen.Security.Privilege";
+
+ [DllImport(Libraries.Privilege, EntryPoint = "privilege_info_get_display_name")]
+ internal static extern int GetDisplayName(string apiVersion, string privilege, out string displayName);
+
+ [DllImport(Libraries.Privilege, EntryPoint = "privilege_info_get_description")]
+ internal static extern int GetDescription(string apiVersion, string privilege, out string description);
+
+ [DllImport(Libraries.Privilege, EntryPoint = "privilege_info_get_display_name_by_pkgtype")]
+ internal static extern int GetDisplayNameByPkgtype(string packageType, string apiVersion, string privilege, out string displayName);
+
+ [DllImport(Libraries.Privilege, EntryPoint = "privilege_info_get_description_by_pkgtype")]
+ internal static extern int GetDescriptionByPkgtype(string packageType, string apiVersion, string privilege, out string description);
+
+ [DllImport(Libraries.Privilege, EntryPoint = "privilege_info_get_privacy_display_name")]
+ internal static extern int GetPrivacyDisplayName(string privilege, out string displayName);
+
+ [DllImport(Libraries.Privilege, EntryPoint = "privilege_info_get_privacy_privilege_status")]
+ internal static extern int GetPrivacyPrivilegeStatus(string privilege, out bool status);
+ }
+}
diff --git a/src/Tizen.Security/Tizen.Security.csproj b/src/Tizen.Security/Tizen.Security.csproj
new file mode 100644
index 0000000..b877776
--- /dev/null
+++ b/src/Tizen.Security/Tizen.Security.csproj
@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen.Applications.PackageManager\Tizen.Applications.PackageManager.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
+
diff --git a/src/Tizen.Security/Tizen.Security/Privilege.cs b/src/Tizen.Security/Tizen.Security/Privilege.cs
new file mode 100755
index 0000000..a59cfd5
--- /dev/null
+++ b/src/Tizen.Security/Tizen.Security/Privilege.cs
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Internals.Errors;
+using Tizen.Applications;
+
+namespace Tizen.Security
+{
+ /// <summary>
+ /// The class provides the information of the given privilege and API version.
+ /// </summary>
+ public static class Privilege
+ {
+ internal static readonly string PackageTypeTpk = "PRVINFO_PACKAGE_TYPE_NATIVE";
+ internal static readonly string PackageTypeWgt = "PRVINFO_PACKAGE_TYPE_WEB";
+ internal static string ToPackageTypeString(PackageType type)
+ {
+ if (type == PackageType.TPK)
+ {
+ return PackageTypeTpk;
+ }
+ else if (type == PackageType.WGT)
+ {
+ return PackageTypeWgt;
+ }
+ else
+ {
+ Tizen.Log.Error(Interop.Privilege.LogTag, "Invalid Parameter: PackageType doesn't include TPK or WGT");
+ throw new ArgumentException();
+ }
+ }
+
+ /// <summary>
+ /// Gets the display name of the given privilege.
+ /// </summary>
+ /// <remarks>If there's no matching privilege then it returns last token of given privilege.</remarks>
+ /// <param name="apiVersion">The api version</param>
+ /// <param name="privilege">The privilege</param>
+ /// <returns>The display name of given privilege at given api version</returns>
+ /// <exception cref="System.ArgumentNullException">Thrown when there is a null parameter.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when there is an invalid parameter.</exception>
+ /// <exception cref="System.OutOfMemoryException">Thrown when out of memory occurs</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when internal error occurs.</exception>
+ public static string GetDisplayName(string apiVersion, string privilege)
+ {
+ string displayName;
+ if (apiVersion == null || privilege == null)
+ PrivilegeErrorFactory.ThrowException(new ArgumentNullException(), "apiVersion and privilege should not be null.");
+ PrivilegeErrorFactory.CheckNThrowException(
+ Interop.Privilege.GetDisplayName(apiVersion, privilege, out displayName),
+ "Failed to Get Privilege's Display Name.");
+ return displayName;
+ }
+
+ /// <summary>
+ /// Gets the display name of the given privilege.
+ /// </summary>
+ /// <remarks>If there's no matching privilege then it returns last token of given privilege.</remarks>
+ /// <param name="apiVersion">The api version</param>
+ /// <param name="privilege">The privilege</param>
+ /// <param name="packageType">The type of application package</param>
+ /// <returns>The display name of given privilege at given api version and the package type</returns>
+ /// <exception cref="System.ArgumentNullException">Thrown when there is a null parameter.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when there is an invalid parameter.</exception>
+ /// <exception cref="System.OutOfMemoryException">Thrown when out of memory occurs</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when internal error occurs.</exception>
+ public static string GetDisplayName(string apiVersion, string privilege, PackageType packageType)
+ {
+ string displayName;
+ if (apiVersion == null || privilege == null)
+ PrivilegeErrorFactory.ThrowException(new ArgumentNullException(), "apiVersion and privilege should not be null.");
+ PrivilegeErrorFactory.CheckNThrowException(
+ Interop.Privilege.GetDisplayNameByPkgtype(ToPackageTypeString(packageType), apiVersion, privilege, out displayName),
+ "Failed to Get Privilege's Display Name.");
+ return displayName;
+ }
+
+ /// <summary>
+ /// Gets the description of the given privilege.
+ /// </summary>
+ /// <remarks>If there's no matching privilege then it returns description string for undefined privilege.</remarks>
+ /// <param name="apiVersion">The api version</param>
+ /// <param name="privilege">The privilege</param>
+ /// <returns>The description of given privilege at given api version</returns>
+ /// <exception cref="System.ArgumentNullException">Thrown when there is a null parameter.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when there is an invalid parameter.</exception>
+ /// <exception cref="System.OutOfMemoryException">Thrown when out of memory occurs</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when internal error occurs.</exception>
+ public static string GetDescription(string apiVersion, string privilege)
+ {
+ string description;
+ if (apiVersion == null || privilege == null)
+ PrivilegeErrorFactory.ThrowException(new ArgumentNullException(), "apiVersion and privilege should not be null.");
+ PrivilegeErrorFactory.CheckNThrowException(
+ Interop.Privilege.GetDescription(apiVersion, privilege, out description),
+ "Failed to Get Privilege's Description.");
+ return description;
+ }
+
+ /// <summary>
+ /// Gets the description of the given privilege.
+ /// </summary>
+ /// <remarks>If there's no matching privilege then it returns description string for undefined privilege.</remarks>
+ /// <param name="apiVersion">The api version</param>
+ /// <param name="privilege">The privilege</param>
+ /// <param name="packageType">The type of application package</param>
+ /// <returns>The description of given privilege at given api version and the package type</returns>
+ /// <exception cref="System.ArgumentNullException">Thrown when there is a null parameter.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when there is an invalid parameter.</exception>
+ /// <exception cref="System.OutOfMemoryException">Thrown when out of memory occurs</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when internal error occurs.</exception>
+ public static string GetDescription(string apiVersion, string privilege, PackageType packageType)
+ {
+ string description;
+ if (apiVersion == null || privilege == null)
+ PrivilegeErrorFactory.ThrowException(new ArgumentNullException(), "apiVersion and privilege should not be null.");
+ PrivilegeErrorFactory.CheckNThrowException(
+ Interop.Privilege.GetDescriptionByPkgtype(ToPackageTypeString(packageType),apiVersion, privilege, out description),
+ "Failed to Get Privilege's Description.");
+ return description;
+ }
+
+ /// <summary>
+ /// Gets the display name of the privacy group in which the given privilege is included.
+ /// </summary>
+ /// <param name="privilege">The privilege</param>
+ /// <remarks>The privilege must be privacy related.</remarks>
+ /// <returns>The privacy group's display name that the given privilege is included in</returns>
+ /// <exception cref="System.ArgumentNullException">Thrown when there is a null parameter.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when there is an invalid parameter.</exception>
+ /// <exception cref="System.OutOfMemoryException">Thrown when out of memory occurs</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when internal error occurs.</exception>
+ public static string GetPrivacyDisplayName(string privilege)
+ {
+ string displayName;
+ if (privilege == null)
+ PrivilegeErrorFactory.ThrowException(new ArgumentNullException(), "privilege should not be null.");
+ PrivilegeErrorFactory.CheckNThrowException(
+ Interop.Privilege.GetPrivacyDisplayName(privilege, out displayName),
+ "Failed to Get Privacy's Display Name in Which the Given Privilege is included.");
+ return displayName;
+ }
+
+ /// <summary>
+ /// Gets the status of the given privacy related privilege.
+ /// </summary>
+ /// <param name="privilege">The privilege</param>
+ /// <remarks>The privilege must be privacy related.</remarks>
+ /// <returns>status true if the privilege is on and false if the privilege is off.</returns>
+ /// <exception cref="System.ArgumentNullException">Thrown when there is a null parameter.</exception>
+ /// <exception cref="System.ArgumentException">Thrown when there is an invalid parameter.</exception>
+ /// <exception cref="System.OutOfMemoryException">Thrown when out of memory occurs</exception>
+ /// <exception cref="System.InvalidOperationException">Thrown when internal error occurs.</exception>
+ public static bool GetPrivacyPrivilegeStatus(string privilege)
+ {
+ bool status;
+ if (privilege == null)
+ PrivilegeErrorFactory.ThrowException(new ArgumentNullException(), "privilege should not be null.");
+ PrivilegeErrorFactory.CheckNThrowException(
+ Interop.Privilege.GetPrivacyPrivilegeStatus(privilege, out status),
+ "Failed to Get Privacy Privilege's Status.");
+ return status;
+ }
+ }
+
+ internal static class PrivilegeErrorFactory
+ {
+ internal static void ThrowException(Exception e, string msg)
+ {
+ Tizen.Log.Error(Interop.Privilege.LogTag, "[" + e.ToString() + "] " + msg);
+ throw e;
+ }
+ internal static void CheckNThrowException(int err, string msg)
+ {
+ if (err == (int)ErrorCode.None)
+ return;
+ string errorMessage = string.Format("[{0}] {1}", ErrorFacts.GetErrorMessage(err), msg);
+ Tizen.Log.Error(Interop.Privilege.LogTag, errorMessage);
+ switch (err)
+ {
+ case (int)ErrorCode.InvalidParameter:
+ throw new ArgumentException();
+ case (int)ErrorCode.OutOfMemory:
+ throw new OutOfMemoryException();
+ default:
+ throw new InvalidOperationException();
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Interop/Interop.Libraries.cs b/src/Tizen.Sensor/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..4c856be
--- /dev/null
+++ b/src/Tizen.Sensor/Interop/Interop.Libraries.cs
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string Sensor = "libcapi-system-sensor.so.0";
+ public const string Libc = "libc.so.6";
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Sensor/Interop/Interop.Sensor.cs b/src/Tizen.Sensor/Interop/Interop.Sensor.cs
new file mode 100644
index 0000000..58a6b1e
--- /dev/null
+++ b/src/Tizen.Sensor/Interop/Interop.Sensor.cs
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Sensor;
+
+internal static partial class Interop
+{
+ internal static class Sensor
+ {
+ //Sensor Hardware CAPI
+ [DllImport(Libraries.Sensor, EntryPoint = "sensor_get_name")]
+ internal static extern int GetName(IntPtr sensorhandle, out String name);
+
+ [DllImport(Libraries.Sensor, EntryPoint = "sensor_get_vendor")]
+ internal static extern int GetVendor(IntPtr sensorHandle, out String vendor);
+
+ [DllImport(Libraries.Sensor, EntryPoint = "sensor_get_type")]
+ internal static extern int GetType(IntPtr sensorHandle, out SensorType type);
+
+ [DllImport(Libraries.Sensor, EntryPoint = "sensor_get_min_range")]
+ internal static extern int GetMinRange(IntPtr sensorHandle, out float minRange);
+
+ [DllImport(Libraries.Sensor, EntryPoint = "sensor_get_max_range")]
+ internal static extern int GetMaxRange(IntPtr sensorHandle, out float maxRange);
+
+ [DllImport(Libraries.Sensor, EntryPoint = "sensor_get_resolution")]
+ internal static extern int GetResolution(IntPtr sensorHandle, out float resolution);
+
+ [DllImport(Libraries.Sensor, EntryPoint = "sensor_get_min_interval")]
+ internal static extern int GetMinInterval(IntPtr sensorHandle, out int minInterval);
+
+ [DllImport(Libraries.Sensor, EntryPoint = "sensor_get_fifo_count")]
+ internal static extern int GetFifoCount(IntPtr sensorHandle, out int fifoCount);
+
+ [DllImport(Libraries.Sensor, EntryPoint = "sensor_get_max_batch_count")]
+ internal static extern int GetMaxBatchCount(IntPtr sensorHandle, out int maxBatchCount);
+ }
+ internal static class SensorListener
+ {
+ //Sensor Listener CAPI
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void SensorEventCallback(IntPtr sensorHandle, IntPtr eventData, IntPtr data);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void SensorAccuracyCallback(IntPtr sensorHandle, ulong timestamp, SensorDataAccuracy accuracy, IntPtr data);
+
+ [DllImport(Libraries.Sensor, EntryPoint = "sensor_create_listener")]
+ internal static extern int CreateListener(IntPtr sensorHandle, out IntPtr listenerHandle);
+
+ [DllImport(Libraries.Sensor, EntryPoint = "sensor_destroy_listener")]
+ internal static extern int DestroyListener(IntPtr listenerHandle);
+
+ [DllImport(Libraries.Sensor, EntryPoint = "sensor_listener_start")]
+ internal static extern int StartListener(IntPtr listenerHandle);
+
+ [DllImport(Libraries.Sensor, EntryPoint = "sensor_listener_stop")]
+ internal static extern int StopListener(IntPtr listenerHandle);
+
+ [DllImport(Libraries.Sensor, EntryPoint = "sensor_listener_set_event_cb")]
+ internal static extern int SetEventCallback(IntPtr listenerHandle, uint intervalMs, SensorEventCallback callback, IntPtr data);
+
+ [DllImport(Libraries.Sensor, EntryPoint = "sensor_listener_unset_event_cb")]
+ internal static extern int UnsetEventCallback(IntPtr listernerHandle);
+
+ [DllImport(Libraries.Sensor, EntryPoint = "sensor_listener_set_accuracy_cb")]
+ internal static extern int SetAccuracyCallback(IntPtr listenerHandle, SensorAccuracyCallback callback, IntPtr data);
+
+ [DllImport(Libraries.Sensor, EntryPoint = "sensor_listener_unset_accuracy_cb")]
+ internal static extern int UnsetAccuracyCallback(IntPtr listernerHandle);
+
+ [DllImport(Libraries.Sensor, EntryPoint = "sensor_listener_set_interval")]
+ internal static extern int SetInterval(IntPtr listenerHandle, uint intervalMs);
+
+ [DllImport(Libraries.Sensor, EntryPoint = "sensor_listener_set_max_batch_latency")]
+ internal static extern int SetMaxBatchLatency(IntPtr listenerHandle, uint maxBatchLatency);
+
+ [DllImport(Libraries.Sensor, EntryPoint = "sensor_listener_set_attribute_int")]
+ internal static extern int SetAttribute(IntPtr listenerHandle, SensorAttribute sensorAttribute, int option);
+ }
+
+ internal static class SensorManager
+ {
+ //Sensor Manager CAPI
+ [DllImport(Libraries.Sensor, EntryPoint = "sensor_is_supported")]
+ internal static extern int SensorIsSupported(SensorType type, out bool supported);
+
+ [DllImport(Libraries.Sensor, EntryPoint = "sensor_get_default_sensor")]
+ internal static extern int GetDefaultSensor(SensorType type, out IntPtr sensor);
+
+ [DllImport(Libraries.Sensor, EntryPoint = "sensor_get_sensor_list")]
+ internal static extern int GetSensorList(SensorType type, out IntPtr list, out int sensor_count);
+ }
+
+ internal static partial class Libc
+ {
+ [DllImport(Libraries.Libc, EntryPoint = "free", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int Free(IntPtr ptr);
+ }
+
+ [StructLayout(LayoutKind.Sequential, Pack = 0)]
+ internal struct SensorEventStruct
+ {
+ internal SensorDataAccuracy accuracy;
+ internal UInt64 timestamp;
+ internal int value_count;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
+ internal float[] values;
+ }
+
+ internal static IntPtr[] IntPtrToIntPtrArray(IntPtr unmanagedArray, int size)
+ {
+ IntPtr[] managedArray = new IntPtr[size];
+ Marshal.Copy(unmanagedArray, managedArray, 0, size);
+ return managedArray;
+ }
+
+ internal static SensorEventStruct IntPtrToEventStruct(IntPtr unmanagedVariable)
+ {
+ SensorEventStruct outStruct = (SensorEventStruct)Marshal.PtrToStructure(unmanagedVariable, typeof(SensorEventStruct));
+ return outStruct;
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor.csproj b/src/Tizen.Sensor/Tizen.Sensor.csproj
new file mode 100644
index 0000000..e84e6f7
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor.csproj
@@ -0,0 +1,16 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ <ProjectReference Include="..\Tizen.System.Information\Tizen.System.Information.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
+
diff --git a/src/Tizen.Sensor/Tizen.Sensor/EventArgs/AccelerometerDataUpdatedEventArgs.cs b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/AccelerometerDataUpdatedEventArgs.cs
new file mode 100755
index 0000000..f87f24e
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/AccelerometerDataUpdatedEventArgs.cs
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// Accelerometer changed event arguments. Class for storing the data returned by accelerometer
+ /// </summary>
+ public class AccelerometerDataUpdatedEventArgs : EventArgs
+ {
+ internal AccelerometerDataUpdatedEventArgs(float[] values)
+ {
+ X = values[0];
+ Y = values[1];
+ Z = values[2];
+ }
+
+ /// <summary>
+ /// Gets the X component of the acceleration.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> X </value>
+ public float X { get; private set; }
+
+ /// <summary>
+ /// Gets the Y component of the acceleration.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Y </value>
+ public float Y { get; private set; }
+
+ /// <summary>
+ /// Gets the Z component of the acceleration.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Z </value>
+ public float Z { get; private set; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Sensor/Tizen.Sensor/EventArgs/FaceDownGestureDetectorDataUpdatedEventArgs.cs b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/FaceDownGestureDetectorDataUpdatedEventArgs.cs
new file mode 100755
index 0000000..b92bb6f
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/FaceDownGestureDetectorDataUpdatedEventArgs.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// FaceDownGestureDetector changed event arguments. Class for storing the data returned by face down gesture detector.
+ /// </summary>
+ public class FaceDownGestureDetectorDataUpdatedEventArgs : EventArgs
+ {
+ internal FaceDownGestureDetectorDataUpdatedEventArgs(float state)
+ {
+ FaceDown = (DetectorState) state;
+ }
+
+ /// <summary>
+ /// Gets the face down state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Face down state </value>
+ public DetectorState FaceDown { get; private set; }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/EventArgs/GravitySensorDataUpdatedEventArgs.cs b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/GravitySensorDataUpdatedEventArgs.cs
new file mode 100755
index 0000000..b7812a9
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/GravitySensorDataUpdatedEventArgs.cs
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// GravitySensor changed event arguments. Class for storing the data returned by gravity sensor
+ /// </summary>
+ public class GravitySensorDataUpdatedEventArgs : EventArgs
+ {
+ internal GravitySensorDataUpdatedEventArgs(float[] values)
+ {
+ X = values[0];
+ Y = values[1];
+ Z = values[2];
+ }
+
+ /// <summary>
+ /// Gets the X component of the gravity.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> X </value>
+ public float X { get; private set; }
+
+ /// <summary>
+ /// Gets the Y component of the gravity.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Y </value>
+ public float Y { get; private set; }
+
+ /// <summary>
+ /// Gets the Z component of the gravity.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Z </value>
+ public float Z { get; private set; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Sensor/Tizen.Sensor/EventArgs/GyroscopeDataUpdatedEventArgs.cs b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/GyroscopeDataUpdatedEventArgs.cs
new file mode 100755
index 0000000..58724c1
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/GyroscopeDataUpdatedEventArgs.cs
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// Gyroscope changed event arguments. Class for storing the data returned by gyroscope
+ /// </summary>
+ public class GyroscopeDataUpdatedEventArgs : EventArgs
+ {
+ internal GyroscopeDataUpdatedEventArgs(float[] values)
+ {
+ X = values[0];
+ Y = values[1];
+ Z = values[2];
+ }
+
+ /// <summary>
+ /// Gets the X component of the gyroscope data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> X </value>
+ public float X { get; private set; }
+
+ /// <summary>
+ /// Gets the Y component of the gyroscope data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Y </value>
+ public float Y { get; private set; }
+
+ /// <summary>
+ /// Gets the Z component of the gyroscope data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Z </value>
+ public float Z { get; private set; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Sensor/Tizen.Sensor/EventArgs/GyroscopeRotationVectorSensorDataUpdatedEventArgs.cs b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/GyroscopeRotationVectorSensorDataUpdatedEventArgs.cs
new file mode 100755
index 0000000..48c0238
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/GyroscopeRotationVectorSensorDataUpdatedEventArgs.cs
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// GyroscopeRotationVectorSensor changed event arguments. Class for storing the data returned by gyroscope rotation vector sensor
+ /// </summary>
+ public class GyroscopeRotationVectorSensorDataUpdatedEventArgs : EventArgs
+ {
+ internal GyroscopeRotationVectorSensorDataUpdatedEventArgs(float[] values, SensorDataAccuracy accuracy)
+ {
+ X = values[0];
+ Y = values[1];
+ Z = values[2];
+ W = values[3];
+ Accuracy = accuracy;
+ }
+
+ /// <summary>
+ /// Gets the X component of the gyroscope rotation vector.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> X </value>
+ public float X { get; private set; }
+
+ /// <summary>
+ /// Gets the Y component of the gyroscope rotation vector.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Y </value>
+ public float Y { get; private set; }
+
+ /// <summary>
+ /// Gets the Z component of the gyroscope rotation vector.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Z </value>
+ public float Z { get; private set; }
+
+ /// <summary>
+ /// Gets the W component of the gyroscope rotation vector.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> W </value>
+ public float W { get; private set; }
+
+ /// <summary>
+ /// Gets the accuracy of the gyroscope rotation vector data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Accuracy </value>
+ public SensorDataAccuracy Accuracy { get; private set; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Sensor/Tizen.Sensor/EventArgs/HeartRateMonitorDataUpdatedEventArgs.cs b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/HeartRateMonitorDataUpdatedEventArgs.cs
new file mode 100755
index 0000000..68b9fe7
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/HeartRateMonitorDataUpdatedEventArgs.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// HeartRateMonitor changed event arguments. Class for storing the data returned by heart rate monitor
+ /// </summary>
+ public class HeartRateMonitorDataUpdatedEventArgs : EventArgs
+ {
+ internal HeartRateMonitorDataUpdatedEventArgs(int heartRate)
+ {
+ HeartRate = heartRate;
+ }
+
+ /// <summary>
+ /// Gets the value of the heartRate.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Heart rate </value>
+ public int HeartRate { get; private set; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Sensor/Tizen.Sensor/EventArgs/HumiditySensorDataUpdatedEventArgs.cs b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/HumiditySensorDataUpdatedEventArgs.cs
new file mode 100755
index 0000000..c8e7c32
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/HumiditySensorDataUpdatedEventArgs.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// HumiditySensor changed event arguments. Class for storing the data returned by humidity sensor
+ /// </summary>
+ public class HumiditySensorDataUpdatedEventArgs : EventArgs
+ {
+ internal HumiditySensorDataUpdatedEventArgs(float humidity)
+ {
+ Humidity = humidity;
+ }
+
+ /// <summary>
+ /// Gets the value of the humidity.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Humidity </value>
+ public float Humidity { get; private set; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Sensor/Tizen.Sensor/EventArgs/InVehicleActivityDetectorDataUpdatedEventArgs.cs b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/InVehicleActivityDetectorDataUpdatedEventArgs.cs
new file mode 100755
index 0000000..4e6e8f0
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/InVehicleActivityDetectorDataUpdatedEventArgs.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// InVehicleActivityDetector changed event arguments. Class for storing the data returned by in-vehicle activity detector
+ /// </summary>
+ public class InVehicleActivityDetectorDataUpdatedEventArgs : EventArgs
+ {
+ internal InVehicleActivityDetectorDataUpdatedEventArgs(float state)
+ {
+ InVehicle = (DetectorState) state;
+ }
+
+ /// <summary>
+ /// Gets the in-vehicle state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> In-vehicle state </value>
+ public DetectorState InVehicle { get; private set; }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/EventArgs/LightSensorDataUpdatedEventArgs.cs b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/LightSensorDataUpdatedEventArgs.cs
new file mode 100755
index 0000000..dfcc8de
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/LightSensorDataUpdatedEventArgs.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// LightSensor changed event arguments. Class for storing the data returned by light sensor
+ /// </summary>
+ public class LightSensorDataUpdatedEventArgs : EventArgs
+ {
+ internal LightSensorDataUpdatedEventArgs(float level)
+ {
+ Level = level;
+ }
+
+ /// <summary>
+ /// Gets the level of the light.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Light level </value>
+ public float Level { get; private set; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Sensor/Tizen.Sensor/EventArgs/LinearAccelerationSensorDataUpdatedEventArgs.cs b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/LinearAccelerationSensorDataUpdatedEventArgs.cs
new file mode 100755
index 0000000..273c0a2
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/LinearAccelerationSensorDataUpdatedEventArgs.cs
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// LinearAccelerationSensor changed event arguments. Class for storing the data returned by linear acceleration sensor
+ /// </summary>
+ public class LinearAccelerationSensorDataUpdatedEventArgs : EventArgs
+ {
+ internal LinearAccelerationSensorDataUpdatedEventArgs(float[] values)
+ {
+ X = values[0];
+ Y = values[1];
+ Z = values[2];
+ }
+
+ /// <summary>
+ /// Gets the X component of the linear acceleration.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> X </value>
+ public float X { get; private set; }
+
+ /// <summary>
+ /// Gets the Y component of the linear acceleration.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Y </value>
+ public float Y { get; private set; }
+
+ /// <summary>
+ /// Gets the Z component of the linear acceleration.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Z </value>
+ public float Z { get; private set; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Sensor/Tizen.Sensor/EventArgs/MagnetometerDataUpdatedEventArgs.cs b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/MagnetometerDataUpdatedEventArgs.cs
new file mode 100755
index 0000000..eb1803d
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/MagnetometerDataUpdatedEventArgs.cs
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// Magnetometer changed event arguments. Class for storing the data returned by magnetometer sensor
+ /// </summary>
+ public class MagnetometerDataUpdatedEventArgs : EventArgs
+ {
+ internal MagnetometerDataUpdatedEventArgs(float[] values)
+ {
+ X = values[0];
+ Y = values[1];
+ Z = values[2];
+ }
+
+ /// <summary>
+ /// Gets the X component of the magnetometer.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> X </value>
+ public float X { get; private set; }
+
+ /// <summary>
+ /// Gets the Y component of the magnetometer.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Y </value>
+ public float Y { get; private set; }
+
+ /// <summary>
+ /// Gets the Z component of the magnetometer.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Z </value>
+ public float Z { get; private set; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Sensor/Tizen.Sensor/EventArgs/MagnetometerRotationVectorSensorDataUpdatedEventArgs.cs b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/MagnetometerRotationVectorSensorDataUpdatedEventArgs.cs
new file mode 100755
index 0000000..7ac6ba3
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/MagnetometerRotationVectorSensorDataUpdatedEventArgs.cs
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// MagnetometerRotationVectorSensor changed event arguments. Class for storing the data returned by magnetometer rotation vector sensor
+ /// </summary>
+ public class MagnetometerRotationVectorSensorDataUpdatedEventArgs : EventArgs
+ {
+ internal MagnetometerRotationVectorSensorDataUpdatedEventArgs(float[] values, SensorDataAccuracy accuracy)
+ {
+ X = values[0];
+ Y = values[1];
+ Z = values[2];
+ W = values[3];
+ Accuracy = accuracy;
+ }
+
+ /// <summary>
+ /// Gets the X component of the magnetometer rotation vector.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> X </value>
+ public float X { get; private set; }
+
+ /// <summary>
+ /// Gets the Y component of the magnetometer rotation vector.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Y </value>
+ public float Y { get; private set; }
+
+ /// <summary>
+ /// Gets the Z component of the magnetometer rotation vector.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Z </value>
+ public float Z { get; private set; }
+
+ /// <summary>
+ /// Gets the W component of the magnetometer rotation vector.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> W </value>
+ public float W { get; private set; }
+
+ /// <summary>
+ /// Gets the accuracy of the magnetometer rotation vector data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Accuracy </value>
+ public SensorDataAccuracy Accuracy { get; private set; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Sensor/Tizen.Sensor/EventArgs/OrientationSensorDataUpdatedEventArgs.cs b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/OrientationSensorDataUpdatedEventArgs.cs
new file mode 100755
index 0000000..4fc4b6a
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/OrientationSensorDataUpdatedEventArgs.cs
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// OrientationSensor changed event arguments. Class for storing the data returned by orientation sensor
+ /// </summary>
+ public class OrientationSensorDataUpdatedEventArgs : EventArgs
+ {
+ internal OrientationSensorDataUpdatedEventArgs(float[] values)
+ {
+ Azimuth = values[0];
+ Pitch = values[1];
+ Roll = values[2];
+ }
+
+ /// <summary>
+ /// Gets the azimuth component of the orientation.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Azimuth </value>
+ public float Azimuth { get; private set; }
+
+ /// <summary>
+ /// Gets the pitch component of the orientation.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Pitch </value>
+ public float Pitch { get; private set; }
+
+ /// <summary>
+ /// Gets the roll component of the orientation.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Roll </value>
+ public float Roll { get; private set; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Sensor/Tizen.Sensor/EventArgs/PedometerDataUpdatedEventArgs.cs b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/PedometerDataUpdatedEventArgs.cs
new file mode 100755
index 0000000..f4865ac
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/PedometerDataUpdatedEventArgs.cs
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// Pedometer changed event arguments. Class for storing the data returned by pedometer
+ /// </summary>
+ public class PedometerDataUpdatedEventArgs : EventArgs
+ {
+ internal PedometerDataUpdatedEventArgs(float[] values)
+ {
+ StepCount = (uint) values[0];
+ WalkStepCount = (uint) values[1];
+ RunStepCount = (uint) values[2];
+ MovingDistance = values[3];
+ CalorieBurned = values[4];
+ LastSpeed = values[5];
+ LastSteppingFrequency = values[6];
+ LastStepStatus = (PedometerState) values[7];
+ }
+
+ /// <summary>
+ /// Gets the step count
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Step count </value>
+ public uint StepCount { get; private set; }
+
+ /// <summary>
+ /// Gets the walking step count
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Walk step count </value>
+ public uint WalkStepCount { get; private set; }
+
+ /// <summary>
+ /// Gets the running step count
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Run step count</value>
+ public uint RunStepCount { get; private set; }
+
+ /// <summary>
+ /// Gets the moving distance
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Moving distance </value>
+ public float MovingDistance { get; private set; }
+
+ /// <summary>
+ /// Gets the calorie burned
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Calorie burned </value>
+ public float CalorieBurned { get; private set; }
+
+ /// <summary>
+ /// Gets the last speed
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Last speed </value>
+ public float LastSpeed { get; private set; }
+
+ /// <summary>
+ /// Gets the last stepping frequency
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Last stepping frequency </value>
+ public float LastSteppingFrequency { get; private set; }
+
+ /// <summary>
+ /// Gets the last step status
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Last stepping status </value>
+ public PedometerState LastStepStatus { get; private set; }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/EventArgs/PickUpGestureDetectorDataUpdatedEventArgs.cs b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/PickUpGestureDetectorDataUpdatedEventArgs.cs
new file mode 100755
index 0000000..a5fee58
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/PickUpGestureDetectorDataUpdatedEventArgs.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// PickUpGestureDetector changed event arguments. Class for storing the data returned by pick up gesture detector
+ /// </summary>
+ public class PickUpGestureDetectorDataUpdatedEventArgs : EventArgs
+ {
+ internal PickUpGestureDetectorDataUpdatedEventArgs(float state)
+ {
+ PickUp = (DetectorState) state;
+ }
+
+ /// <summary>
+ /// Gets the pick up state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Pick up state </value>
+ public DetectorState PickUp { get; private set; }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/EventArgs/PressureSensorDataUpdatedEventArgs.cs b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/PressureSensorDataUpdatedEventArgs.cs
new file mode 100755
index 0000000..0cf7b73
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/PressureSensorDataUpdatedEventArgs.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// PressureSensor changed event arguments. Class for storing the data returned by pressure sensor
+ /// </summary>
+ public class PressureSensorDataUpdatedEventArgs : EventArgs
+ {
+ internal PressureSensorDataUpdatedEventArgs(float pressure)
+ {
+ Pressure = pressure;
+ }
+
+ /// <summary>
+ /// Gets the value of the pressure.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Pressure </value>
+ public float Pressure { get; private set; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Sensor/Tizen.Sensor/EventArgs/ProximitySensorDataUpdatedEventArgs.cs b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/ProximitySensorDataUpdatedEventArgs.cs
new file mode 100755
index 0000000..2dc8847
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/ProximitySensorDataUpdatedEventArgs.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// ProximitySensor changed event arguments. Class for storing the data returned by proximity sensor
+ /// </summary>
+ public class ProximitySensorDataUpdatedEventArgs : EventArgs
+ {
+ internal ProximitySensorDataUpdatedEventArgs(float proximity)
+ {
+ Proximity = (ProximitySensorState) proximity;
+ }
+
+ /// <summary>
+ /// Gets the proximity state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Proximity state </value>
+ public ProximitySensorState Proximity { get; private set; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Sensor/Tizen.Sensor/EventArgs/RotationVectorSensorDataUpdatedEventArgs.cs b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/RotationVectorSensorDataUpdatedEventArgs.cs
new file mode 100755
index 0000000..29ddccd
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/RotationVectorSensorDataUpdatedEventArgs.cs
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// RotationVectorSensor changed event arguments. Class for storing the data returned by rotation vector sensor
+ /// </summary>
+ public class RotationVectorSensorDataUpdatedEventArgs : EventArgs
+ {
+ internal RotationVectorSensorDataUpdatedEventArgs(float[] values, SensorDataAccuracy accuracy)
+ {
+ X = values[0];
+ Y = values[1];
+ Z = values[2];
+ W = values[3];
+ Accuracy = accuracy;
+ }
+
+ /// <summary>
+ /// Gets the X component of the rotation vector.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> X </value>
+ public float X { get; private set; }
+
+ /// <summary>
+ /// Gets the Y component of the rotation vector.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Y </value>
+ public float Y { get; private set; }
+
+ /// <summary>
+ /// Gets the Z component of the rotation vector.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Z </value>
+ public float Z { get; private set; }
+
+ /// <summary>
+ /// Gets the W component of the rotation vector.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> W </value>
+ public float W { get; private set;}
+
+ /// <summary>
+ /// Gets the accuracy of the rotation vector data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Accuracy </value>
+ public SensorDataAccuracy Accuracy { get; private set; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Sensor/Tizen.Sensor/EventArgs/RunningActivityDetectorDataUpdatedEventArgs.cs b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/RunningActivityDetectorDataUpdatedEventArgs.cs
new file mode 100755
index 0000000..309ad7d
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/RunningActivityDetectorDataUpdatedEventArgs.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// RunningActivityDetector changed event arguments. Class for storing the data returned by running activity detector
+ /// </summary>
+ public class RunningActivityDetectorDataUpdatedEventArgs : EventArgs
+ {
+ internal RunningActivityDetectorDataUpdatedEventArgs(float state)
+ {
+ Running = (DetectorState) state;
+ }
+
+ /// <summary>
+ /// Gets the running state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Running state </value>
+ public DetectorState Running { get; private set; }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/EventArgs/SensorAccuracyChangedEventArgs.cs b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/SensorAccuracyChangedEventArgs.cs
new file mode 100755
index 0000000..8479600
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/SensorAccuracyChangedEventArgs.cs
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// Sensor accuracy changed event arguments Class. Contains the parameters to be returned through accuracy callback
+ /// </summary>
+ public class SensorAccuracyChangedEventArgs : EventArgs
+ {
+ internal SensorAccuracyChangedEventArgs(TimeSpan timespan, SensorDataAccuracy accuracy)
+ {
+ TimeSpan = timespan;
+ Accuracy = accuracy;
+ }
+
+ /// <summary>
+ /// Gets the time stamp.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Time span </value>
+ public TimeSpan TimeSpan { get; private set; }
+
+ /// <summary>
+ /// Gets the accuracy.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Accuracy </value>
+ public SensorDataAccuracy Accuracy { get; private set; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Sensor/Tizen.Sensor/EventArgs/SleepMonitorDataUpdatedEventArgs.cs b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/SleepMonitorDataUpdatedEventArgs.cs
new file mode 100755
index 0000000..fe631ed
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/SleepMonitorDataUpdatedEventArgs.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// SleepMonitor changed event arguments. Class for storing the data returned by sleep monitor
+ /// </summary>
+ public class SleepMonitorDataUpdatedEventArgs : EventArgs
+ {
+ internal SleepMonitorDataUpdatedEventArgs(int sleepState)
+ {
+ SleepState = (SleepMonitorState) sleepState;
+ }
+
+ /// <summary>
+ /// Gets the value of the sleep state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Sleep state </value>
+ public SleepMonitorState SleepState { get; private set; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Sensor/Tizen.Sensor/EventArgs/StationaryActivityDetectorDataUpdatedEventArgs.cs b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/StationaryActivityDetectorDataUpdatedEventArgs.cs
new file mode 100755
index 0000000..2ad9a1d
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/StationaryActivityDetectorDataUpdatedEventArgs.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// StationaryActivityDetector changed event arguments. Class for storing the data returned by stationary activity detector
+ /// </summary>
+ public class StationaryActivityDetectorDataUpdatedEventArgs : EventArgs
+ {
+ internal StationaryActivityDetectorDataUpdatedEventArgs(float state)
+ {
+ Stationary = (DetectorState) state;
+ }
+
+ /// <summary>
+ /// Gets the stationary state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Stationary state </value>
+ public DetectorState Stationary { get; private set; }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/EventArgs/TemperatureSensorDataUpdatedEventArgs.cs b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/TemperatureSensorDataUpdatedEventArgs.cs
new file mode 100755
index 0000000..127c725
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/TemperatureSensorDataUpdatedEventArgs.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// TemperatureSensor changed event arguments. Class for storing the data returned by temperature sensor
+ /// </summary>
+ public class TemperatureSensorDataUpdatedEventArgs : EventArgs
+ {
+ internal TemperatureSensorDataUpdatedEventArgs(float temperature)
+ {
+ Temperature = temperature;
+ }
+
+ /// <summary>
+ /// Gets the value of the temperature.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Temperature </value>
+ public float Temperature { get; private set; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Sensor/Tizen.Sensor/EventArgs/UltravioletSensorDataUpdatedEventArgs.cs b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/UltravioletSensorDataUpdatedEventArgs.cs
new file mode 100755
index 0000000..1a025f9
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/UltravioletSensorDataUpdatedEventArgs.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// UltravioletSensor changed event arguments. Class for storing the data returned by ultraviolet sensor
+ /// </summary>
+ public class UltravioletSensorDataUpdatedEventArgs : EventArgs
+ {
+ internal UltravioletSensorDataUpdatedEventArgs(float ultravioletIndex)
+ {
+ UltravioletIndex = ultravioletIndex;
+ }
+
+ /// <summary>
+ /// Gets the value of the ultraviolet index.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Ultraviolet index </value>
+ public float UltravioletIndex { get; private set; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Sensor/Tizen.Sensor/EventArgs/UncalibratedGyroscopeDataUpdatedEventArgs.cs b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/UncalibratedGyroscopeDataUpdatedEventArgs.cs
new file mode 100755
index 0000000..9475bc0
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/UncalibratedGyroscopeDataUpdatedEventArgs.cs
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// UncalibratedGyroscope changed event arguments. Class for storing the data returned by uncalibrated gyroscope
+ /// </summary>
+ public class UncalibratedGyroscopeDataUpdatedEventArgs : EventArgs
+ {
+ internal UncalibratedGyroscopeDataUpdatedEventArgs(float[] values)
+ {
+ X = values[0];
+ Y = values[1];
+ Z = values[2];
+ BiasX = values[3];
+ BiasY = values[4];
+ BiasZ = values[5];
+ }
+
+ /// <summary>
+ /// Gets the X component of the uncalibrated gyroscope data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> X </value>
+ public float X { get; private set; }
+
+ /// <summary>
+ /// Gets the Y component of the uncalibrated gyroscope data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Y </value>
+ public float Y { get; private set; }
+
+ /// <summary>
+ /// Gets the Z component of the uncalibrated gyroscope data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Z </value>
+ public float Z { get; private set; }
+
+ /// <summary>
+ /// Gets the BiasX component of the uncalibrated gyroscope data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> X bias </value>
+ public float BiasX { get; private set; }
+
+ /// <summary>
+ /// Gets the BiasY component of the uncalibrated gyroscope data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Y bias </value>
+ public float BiasY { get; private set; }
+
+ /// <summary>
+ /// Gets the BiasZ component of the uncalibrated gyroscope data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Z bias </value>
+ public float BiasZ { get; private set; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Sensor/Tizen.Sensor/EventArgs/UncalibratedMagnetometerDataUpdatedEventArgs.cs b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/UncalibratedMagnetometerDataUpdatedEventArgs.cs
new file mode 100755
index 0000000..b9cfc9c
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/UncalibratedMagnetometerDataUpdatedEventArgs.cs
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// UncalibratedMagnetometer changed event arguments. Class for storing the data returned by uncalibrated magnetometer
+ /// </summary>
+ public class UncalibratedMagnetometerDataUpdatedEventArgs : EventArgs
+ {
+ internal UncalibratedMagnetometerDataUpdatedEventArgs(float[] values)
+ {
+ X = values[0];
+ Y = values[1];
+ Z = values[2];
+ BiasX = values[3];
+ BiasY = values[4];
+ BiasZ = values[5];
+ }
+
+ /// <summary>
+ /// Gets the X component of the uncalibrated magnetometer data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> X </value>
+ public float X { get; private set; }
+
+ /// <summary>
+ /// Gets the Y component of the uncalibrated magnetometer data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Y </value>
+ public float Y { get; private set; }
+
+ /// <summary>
+ /// Gets the Z component of the uncalibrated magnetometer data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Z </value>
+ public float Z { get; private set; }
+
+ /// <summary>
+ /// Gets the BiasX component of the uncalibrated magnetometer data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> X bias </value>
+ public float BiasX { get; private set; }
+
+ /// <summary>
+ /// Gets the BiasY component of the uncalibrated magnetometer data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Y bias </value>
+ public float BiasY { get; private set; }
+
+ /// <summary>
+ /// Gets the BiasZ component of the uncalibrated magnetometer data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Z bias </value>
+ public float BiasZ { get; private set; }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Sensor/Tizen.Sensor/EventArgs/WalkingActivityDetectorDataUpdatedEventArgs.cs b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/WalkingActivityDetectorDataUpdatedEventArgs.cs
new file mode 100755
index 0000000..0de9fc7
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/WalkingActivityDetectorDataUpdatedEventArgs.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// WalkingActivityDetector changed event arguments. Class for storing the data returned by walking activity detector
+ /// </summary>
+ public class WalkingActivityDetectorDataUpdatedEventArgs : EventArgs
+ {
+ internal WalkingActivityDetectorDataUpdatedEventArgs(float state)
+ {
+ Walking = (DetectorState) state;
+ }
+
+ /// <summary>
+ /// Gets the walking state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Walking state </value>
+ public DetectorState Walking { get; private set; }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/EventArgs/WristUpGestureDetectorDataUpdatedEventArgs.cs b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/WristUpGestureDetectorDataUpdatedEventArgs.cs
new file mode 100755
index 0000000..811862f
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/EventArgs/WristUpGestureDetectorDataUpdatedEventArgs.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// WristUpGestureDetector changed event arguments. Class for storing the data returned by wrist up gesture detector
+ /// </summary>
+ public class WristUpGestureDetectorDataUpdatedEventArgs : EventArgs
+ {
+ internal WristUpGestureDetectorDataUpdatedEventArgs(float state)
+ {
+ WristUp = (DetectorState) state;
+ }
+
+ /// <summary>
+ /// Gets the wrist up state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Wrist up state </value>
+ public DetectorState WristUp { get; private set; }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/Plugins/Accelerometer.cs b/src/Tizen.Sensor/Tizen.Sensor/Plugins/Accelerometer.cs
new file mode 100755
index 0000000..1651eb2
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/Plugins/Accelerometer.cs
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// Accelerometer Sensor Class. Used for registering callbacks for accelerometer and getting accelerometer data
+ /// </summary>
+ public sealed class Accelerometer : Sensor
+ {
+ private static string AccelerometerKey = "http://tizen.org/feature/sensor.accelerometer";
+ /// <summary>
+ /// Gets the X component of the acceleration.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> X </value>
+ public float X { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the Y component of the acceleration.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Y </value>
+ public float Y { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the Z component of the acceleration.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Z </value>
+ public float Z { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Returns true or false based on whether accelerometer sensor is supported by device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value><c>true</c> if supported; otherwise, <c>false</c>.</value>
+ public static bool IsSupported
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Checking if the Accelerometer sensor is supported");
+ return CheckIfSupported(SensorType.Accelerometer, AccelerometerKey);
+ }
+ }
+
+ /// <summary>
+ /// Returns the number of accelerometer sensors available on the device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The count of accelerometer sensors </value>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ public static int Count
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the count of accelerometer sensors");
+ return GetCount();
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Tizen.Sensor.Accelerometer"/> class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>http://tizen.org/feature/sensor.accelerometer</feature>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="NotSupportedException">Thrown when the sensor is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <param name='index'>
+ /// Index. Default value for this is 0. Index refers to a particular accelerometer sensor in case of multiple sensors
+ /// </param>
+ public Accelerometer(uint index = 0) : base(index)
+ {
+ Log.Info(Globals.LogTag, "Creating Accelerometer object");
+ }
+
+ internal override SensorType GetSensorType()
+ {
+ return SensorType.Accelerometer;
+ }
+
+ /// <summary>
+ /// Event Handler for storing the callback functions for event corresponding to change in accelerometer sensor data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<AccelerometerDataUpdatedEventArgs> DataUpdated;
+
+ private static int GetCount()
+ {
+ IntPtr list;
+ int count;
+ int error = Interop.SensorManager.GetSensorList(SensorType.Accelerometer, out list, out count);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor list for accelerometer");
+ count = 0;
+ }
+ else
+ Interop.Libc.Free(list);
+ return count;
+ }
+
+ private static Interop.SensorListener.SensorEventCallback _callback;
+
+ internal override void EventListenStart()
+ {
+ _callback = (IntPtr sensorHandle, IntPtr eventPtr, IntPtr data) => {
+ Interop.SensorEventStruct sensorData = Interop.IntPtrToEventStruct(eventPtr);
+
+ TimeSpan = new TimeSpan((Int64)sensorData.timestamp);
+ X = sensorData.values[0];
+ Y = sensorData.values[1];
+ Z = sensorData.values[2];
+
+ DataUpdated?.Invoke(this, new AccelerometerDataUpdatedEventArgs(sensorData.values));
+ };
+
+ int error = Interop.SensorListener.SetEventCallback(ListenerHandle, Interval, _callback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting event callback for accelerometer sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set event callback for accelerometer");
+ }
+ }
+
+ internal override void EventListenStop()
+ {
+ int error = Interop.SensorListener.UnsetEventCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting event callback for accelerometer sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset event callback for accelerometer");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/Plugins/ActivityDetector.cs b/src/Tizen.Sensor/Tizen.Sensor/Plugins/ActivityDetector.cs
new file mode 100755
index 0000000..e9eff3b
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/Plugins/ActivityDetector.cs
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// Activity Detector class for storing common activity information
+ /// </summary>
+ public abstract class ActivityDetector : Sensor
+ {
+ protected const int ActivityAttribute = (((int)SensorType.InVehicleActivityDetector << 8) | 0x80 | 0x1);
+
+ protected enum ActivityType
+ {
+ Unknown = 1,
+ Stationary = 2,
+ Walking = 4,
+ Running = 8,
+ InVehicle = 16,
+ OnBicycle = 32,
+ };
+
+ /// <summary>
+ /// Gets the activity accuracy of activity detector
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Activity accuracy </value>
+ public SensorDataAccuracy ActivityAccuracy { get; protected set; }
+
+ internal ActivityDetector(uint index) : base(index)
+ {
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/Plugins/FaceDownGestureDetector.cs b/src/Tizen.Sensor/Tizen.Sensor/Plugins/FaceDownGestureDetector.cs
new file mode 100755
index 0000000..40362d2
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/Plugins/FaceDownGestureDetector.cs
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// FaceDownGestureDetector Class. Used for registering callbacks for face down gesture detector and getting the face down state
+ /// </summary>
+ public sealed class FaceDownGestureDetector : Sensor
+ {
+ private static string GestureDetectorKey = "http://tizen.org/feature/sensor.gesture_recognition";
+
+ /// <summary>
+ /// Gets the state of the face down gesture.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Face down state </value>
+ public DetectorState FaceDown { get; private set; } = DetectorState.Unknown;
+
+ /// <summary>
+ /// Returns true or false based on whether face down gesture detector is supported by device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value><c>true</c> if supported; otherwise, <c>false</c>.</value>
+ public static bool IsSupported
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Checking if the face down gesture detector is supported");
+ return CheckIfSupported(SensorType.FaceDownGestureDetector, GestureDetectorKey);
+ }
+ }
+
+ /// <summary>
+ /// Returns the number of face down gesture detectors available on the device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The count of face down gesture detectors </value>
+ public static int Count
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the count of face down gesture detectors");
+ return GetCount();
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Tizen.Sensor.FaceDownGestureDetector"/> class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>http://tizen.org/feature/sensor.gesture_recognition</feature>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="NotSupportedException">Thrown when the sensor is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <param name='index'>
+ /// Index. Default value for this is 0. Index refers to a particular face down gesture detector in case of multiple sensors.
+ /// </param>
+ public FaceDownGestureDetector(uint index = 0) : base(index)
+ {
+ Log.Info(Globals.LogTag, "Creating face down gesture detector object");
+ }
+
+ internal override SensorType GetSensorType()
+ {
+ return SensorType.FaceDownGestureDetector;
+ }
+
+ private static int GetCount()
+ {
+ IntPtr list;
+ int count;
+ int error = Interop.SensorManager.GetSensorList(SensorType.FaceDownGestureDetector, out list, out count);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor list for face down gesture detector");
+ count = 0;
+ }
+ else
+ Interop.Libc.Free(list);
+ return count;
+ }
+
+ /// <summary>
+ /// Event Handler for storing the callback functions for event corresponding to change in face down gesture detector data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<FaceDownGestureDetectorDataUpdatedEventArgs> DataUpdated;
+
+ private static Interop.SensorListener.SensorEventCallback _callback;
+
+ internal override void EventListenStart()
+ {
+ _callback = (IntPtr sensorHandle, IntPtr eventPtr, IntPtr data) => {
+ Interop.SensorEventStruct sensorData = Interop.IntPtrToEventStruct(eventPtr);
+
+ TimeSpan = new TimeSpan((Int64)sensorData.timestamp);
+ FaceDown = (DetectorState) sensorData.values[0];
+
+ DataUpdated?.Invoke(this, new FaceDownGestureDetectorDataUpdatedEventArgs(sensorData.values[0]));
+ };
+
+ int error = Interop.SensorListener.SetEventCallback(ListenerHandle, Interval, _callback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting event callback for face down gesture detector");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set event callback for face down gesture detector");
+ }
+ }
+
+ internal override void EventListenStop()
+ {
+ int error = Interop.SensorListener.UnsetEventCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting event callback for face down gesture detector");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset event callback for face down gesture detector");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/Plugins/GravitySensor.cs b/src/Tizen.Sensor/Tizen.Sensor/Plugins/GravitySensor.cs
new file mode 100755
index 0000000..c2a38c0
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/Plugins/GravitySensor.cs
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// GravitySensor Class. Used for registering callbacks for gravity sensor and getting gravity data
+ /// </summary>
+ public sealed class GravitySensor : Sensor
+ {
+ private const string GravitySensorKey = "http://tizen.org/feature/sensor.gravity";
+
+ private event EventHandler<SensorAccuracyChangedEventArgs> _accuracyChanged;
+ /// <summary>
+ /// Gets the X component of the gravity.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> X </value>
+ public float X { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the Y component of the gravity.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Y </value>
+ public float Y { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the Z component of the gravity.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Z </value>
+ public float Z { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Returns true or false based on whether gravity sensor is supported by device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value><c>true</c> if supported; otherwise, <c>false</c>.</value>
+ public static bool IsSupported
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Checking if the GravitySensor is supported");
+ return CheckIfSupported(SensorType.GravitySensor, GravitySensorKey);
+ }
+ }
+
+ /// <summary>
+ /// Returns the number of gravity sensors available on the device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The count of gravity sensors </value>
+ public static int Count
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the count of gravity sensors");
+ return GetCount();
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Tizen.Sensor.GravitySensor"/> class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>http://tizen.org/feature/sensor.gravity</feature>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="NotSupportedException">Thrown when the sensor is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <param name='index'>
+ /// Index. Default value for this is 0. Index refers to a particular gravity sensor in case of multiple sensors
+ /// </param>
+ public GravitySensor (uint index = 0) : base(index)
+ {
+ Log.Info(Globals.LogTag, "Creating GravitySensor object");
+ }
+
+ internal override SensorType GetSensorType()
+ {
+ return SensorType.GravitySensor;
+ }
+
+ /// <summary>
+ /// Event Handler for storing the callback functions for event corresponding to change in gravity sensor data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+
+ public event EventHandler<GravitySensorDataUpdatedEventArgs> DataUpdated;
+
+ /// <summary>
+ /// Event handler for accuracy changed events.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<SensorAccuracyChangedEventArgs> AccuracyChanged
+ {
+ add
+ {
+ if (_accuracyChanged == null)
+ {
+ AccuracyListenStart();
+ }
+ _accuracyChanged += value;
+ }
+ remove
+ {
+ _accuracyChanged -= value;
+ if (_accuracyChanged == null)
+ {
+ AccuracyListenStop();
+ }
+ }
+ }
+
+ private static int GetCount()
+ {
+ IntPtr list;
+ int count;
+ int error = Interop.SensorManager.GetSensorList(SensorType.GravitySensor, out list, out count);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor list for gravity");
+ count = 0;
+ }
+ else
+ Interop.Libc.Free(list);
+ return count;
+ }
+
+ private static Interop.SensorListener.SensorEventCallback _callback;
+
+ internal override void EventListenStart()
+ {
+ _callback = (IntPtr sensorHandle, IntPtr eventPtr, IntPtr data) => {
+ Interop.SensorEventStruct sensorData = Interop.IntPtrToEventStruct(eventPtr);
+
+ TimeSpan = new TimeSpan((Int64)sensorData.timestamp);
+ X = sensorData.values[0];
+ Y = sensorData.values[1];
+ Z = sensorData.values[2];
+
+ DataUpdated?.Invoke(this, new GravitySensorDataUpdatedEventArgs(sensorData.values));
+ };
+
+ int error = Interop.SensorListener.SetEventCallback(ListenerHandle, Interval, _callback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting event callback for gravity sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set event callback for gravity");
+ }
+ }
+
+ internal override void EventListenStop()
+ {
+ int error = Interop.SensorListener.UnsetEventCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting event callback for gravity sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset event callback for gravity");
+ }
+ }
+
+ private static Interop.SensorListener.SensorAccuracyCallback _accuracyCallback;
+
+ private void AccuracyListenStart()
+ {
+ _accuracyCallback = (IntPtr sensorHandle, UInt64 timestamp, SensorDataAccuracy accuracy, IntPtr data) => {
+ TimeSpan = new TimeSpan((Int64)timestamp);
+ _accuracyChanged?.Invoke(this, new SensorAccuracyChangedEventArgs(new TimeSpan((Int64)timestamp), accuracy));
+ };
+
+ int error = Interop.SensorListener.SetAccuracyCallback(ListenerHandle, _accuracyCallback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting accuracy event callback for gravity sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set accuracy event callback for gravity");
+ }
+ }
+
+ private void AccuracyListenStop()
+ {
+ int error = Interop.SensorListener.UnsetAccuracyCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting accuracy event callback for gravity sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset accuracy event callback for gravity");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/Plugins/Gyroscope.cs b/src/Tizen.Sensor/Tizen.Sensor/Plugins/Gyroscope.cs
new file mode 100755
index 0000000..192f076
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/Plugins/Gyroscope.cs
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// Gyroscope Sensor Class. Used for registering callbacks for gyroscope and getting gyroscope data
+ /// </summary>
+ public sealed class Gyroscope : Sensor
+ {
+ private const string GyroscopeKey = "http://tizen.org/feature/sensor.gyroscope";
+
+ /// <summary>
+ /// Gets the X component of the acceleration.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> X </value>
+ public float X { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the Y component of the acceleration.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Y </value>
+ public float Y { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the Z component of the acceleration.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Z </value>
+ public float Z { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Returns true or false based on whether gyroscope sensor is supported by device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value><c>true</c> if supported; otherwise, <c>false</c>.</value>
+ public static bool IsSupported
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Checking if the Gyroscope sensor is supported");
+ return CheckIfSupported(SensorType.Gyroscope, GyroscopeKey);
+ }
+ }
+
+ /// <summary>
+ /// Returns the number of gyroscope sensors available on the device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The count of gyroscope sensors </value>
+ public static int Count
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the count of gyroscope sensors");
+ return GetCount();
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Tizen.Sensor.Gyroscope"/> class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>http://tizen.org/feature/sensor.gyroscope</feature>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="NotSupportedException">Thrown when the sensor is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <param name='index'>
+ /// Index. Default value for this is 0. Index refers to a particular gyroscope sensor in case of multiple sensors
+ /// </param>
+ public Gyroscope(uint index = 0) : base(index)
+ {
+ Log.Info(Globals.LogTag, "Creating Gyroscope object");
+ }
+
+ internal override SensorType GetSensorType()
+ {
+ return SensorType.Gyroscope;
+ }
+
+ /// <summary>
+ /// Event Handler for storing the callback functions for event corresponding to change in gyroscope sensor data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+
+ public event EventHandler<GyroscopeDataUpdatedEventArgs> DataUpdated;
+
+ private static int GetCount()
+ {
+ IntPtr list;
+ int count;
+ int error = Interop.SensorManager.GetSensorList(SensorType.Gyroscope, out list, out count);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor list for gyroscope");
+ count = 0;
+ }
+ else
+ Interop.Libc.Free(list);
+ return count;
+ }
+
+ private static Interop.SensorListener.SensorEventCallback _callback;
+
+ internal override void EventListenStart()
+ {
+ _callback = (IntPtr sensorHandle, IntPtr eventPtr, IntPtr data) => {
+ Interop.SensorEventStruct sensorData = Interop.IntPtrToEventStruct(eventPtr);
+
+ TimeSpan = new TimeSpan((Int64)sensorData.timestamp);
+ X = sensorData.values[0];
+ Y = sensorData.values[1];
+ Z = sensorData.values[2];
+
+ DataUpdated?.Invoke(this, new GyroscopeDataUpdatedEventArgs(sensorData.values));
+ };
+
+ int error = Interop.SensorListener.SetEventCallback(ListenerHandle, Interval, _callback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting event callback for gyroscope sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set event callback for gyroscope");
+ }
+ }
+
+ internal override void EventListenStop()
+ {
+ int error = Interop.SensorListener.UnsetEventCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting event callback for gyroscope sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset event callback for gyroscope");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/Plugins/GyroscopeRotationVectorSensor.cs b/src/Tizen.Sensor/Tizen.Sensor/Plugins/GyroscopeRotationVectorSensor.cs
new file mode 100755
index 0000000..2f52a1d
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/Plugins/GyroscopeRotationVectorSensor.cs
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// GyroscopeRotationVectorSensor Class. Used for registering callbacks for gyroscope rotation vector sensor and getting gyroscope rotation vector data
+ /// </summary>
+ public sealed class GyroscopeRotationVectorSensor : Sensor
+ {
+ private const string GyroscopeRVKey = "http://tizen.org/feature/sensor.gyroscope_rotation_vector";
+
+ /// <summary>
+ /// Gets the X component of the gyroscope rotation vector.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> X </value>
+ public float X { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the Y component of the gyroscope rotation vector.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Y </value>
+ public float Y { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the Z component of the gyroscope rotation vector.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Z </value>
+ public float Z { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the W component of the gyroscope rotation vector.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> W </value>
+ public float W { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the Accuracy of the gyroscope rotation vector data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Accuracy </value>
+ public SensorDataAccuracy Accuracy { get; private set; }
+
+ /// <summary>
+ /// Returns true or false based on whether gyroscope rotation vector sensor is supported by device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value><c>true</c> if supported; otherwise, <c>false</c>.</value>
+ public static bool IsSupported
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Checking if the GyroscopeRotationVectorSensor is supported");
+ return CheckIfSupported(SensorType.GyroscopeRotationVectorSensor, GyroscopeRVKey);
+ }
+ }
+
+ /// <summary>
+ /// Returns the number of gyroscope rotation vector sensors available on the device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The count of accelerometer rotation vector sensors </value>
+ public static int Count
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the count of gyroscope rotation vector sensors");
+ return GetCount();
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Tizen.Sensor.GyroscopeRotationVectorSensor"/> class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>http://tizen.org/feature/sensor.gyroscope_rotation_vector</feature>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="NotSupportedException">Thrown when the sensor is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <param name='index'>
+ /// Index. Default value for this is 0. Index refers to a particular gyroscope rotation vector sensor in case of multiple sensors
+ /// </param>
+ public GyroscopeRotationVectorSensor(uint index = 0) : base(index)
+ {
+ Log.Info(Globals.LogTag, "Creating GyroscopeRotationVectorSensor object");
+ }
+
+ internal override SensorType GetSensorType()
+ {
+ return SensorType.GyroscopeRotationVectorSensor;
+ }
+
+ /// <summary>
+ /// Event Handler for storing the callback functions for event corresponding to change in gyroscope rotation vector sensor data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+
+ public event EventHandler<GyroscopeRotationVectorSensorDataUpdatedEventArgs> DataUpdated;
+
+ private static int GetCount()
+ {
+ IntPtr list;
+ int count;
+ int error = Interop.SensorManager.GetSensorList(SensorType.GyroscopeRotationVectorSensor, out list, out count);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor list for gyroscope rotation vector");
+ count = 0;
+ }
+ else
+ Interop.Libc.Free(list);
+ return count;
+ }
+
+ private static Interop.SensorListener.SensorEventCallback _callback;
+
+ internal override void EventListenStart()
+ {
+ _callback = (IntPtr sensorHandle, IntPtr eventPtr, IntPtr data) => {
+ Interop.SensorEventStruct sensorData = Interop.IntPtrToEventStruct(eventPtr);
+
+ TimeSpan = new TimeSpan((Int64)sensorData.timestamp);
+ X = sensorData.values[0];
+ Y = sensorData.values[1];
+ Z = sensorData.values[2];
+ W = sensorData.values[3];
+ Accuracy = sensorData.accuracy;
+
+ DataUpdated?.Invoke(this, new GyroscopeRotationVectorSensorDataUpdatedEventArgs(sensorData.values, sensorData.accuracy));
+ };
+
+ int error = Interop.SensorListener.SetEventCallback(ListenerHandle, Interval, _callback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting event callback for gyroscope rotation vector sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set event callback for gyroscope rotation vector");
+ }
+ }
+
+ internal override void EventListenStop()
+ {
+ int error = Interop.SensorListener.UnsetEventCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting event callback for gyroscope rotation vector sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset event callback for gyroscope rotation vector");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/Plugins/HeartRateMonitor.cs b/src/Tizen.Sensor/Tizen.Sensor/Plugins/HeartRateMonitor.cs
new file mode 100755
index 0000000..0e254ea
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/Plugins/HeartRateMonitor.cs
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// HeartRateMonitor Class. Used for registering callbacks for heart rate monitor and getting heart rate data
+ /// </summary>
+ public sealed class HeartRateMonitor : Sensor
+ {
+ private const string HRMKey = "http://tizen.org/feature/sensor.heart_rate_monitor";
+
+ /// <summary>
+ /// Gets the value of the heart rate monitor.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Heart rate </value>
+ public int HeartRate { get; private set; } = int.MinValue;
+
+ /// <summary>
+ /// Returns true or false based on whether heart rate monitor is supported by device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value><c>true</c> if supported; otherwise, <c>false</c>.</value>
+ public static bool IsSupported
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Checking if the HeartRateMonitor is supported");
+ return CheckIfSupported(SensorType.HeartRateMonitor, HRMKey);
+ }
+ }
+
+ /// <summary>
+ /// Returns the number of heart rate monitors available on the device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The count of heart rate monitors </value>
+ public static int Count
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the count of heart rate monitors");
+ return GetCount();
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Tizen.Sensor.HeartRateMonitor"/> class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/healthinfo</privilege>
+ /// <privlevel>public</privlevel>
+ /// <feature>http://tizen.org/feature/sensor.heart_rate_monitor</feature>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="NotSupportedException">Thrown when the sensor is not supported</exception>
+ /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the sensor</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <param name='index'>
+ /// Index. Default value for this is 0. Index refers to a particular heart rate monitor in case of multiple sensors
+ /// </param>
+ public HeartRateMonitor(uint index = 0) : base(index)
+ {
+ Log.Info(Globals.LogTag, "Creating HeartRateMonitor object");
+ }
+
+ internal override SensorType GetSensorType()
+ {
+ return SensorType.HeartRateMonitor;
+ }
+
+ /// <summary>
+ /// Event Handler for storing the callback functions for event corresponding to change in heart rate monitor data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<HeartRateMonitorDataUpdatedEventArgs> DataUpdated;
+
+ private static int GetCount()
+ {
+ IntPtr list;
+ int count;
+ int error = Interop.SensorManager.GetSensorList(SensorType.HeartRateMonitor, out list, out count);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor list for heart rate");
+ count = 0;
+ }
+ else
+ Interop.Libc.Free(list);
+ return count;
+ }
+
+ private static Interop.SensorListener.SensorEventCallback _callback;
+
+ internal override void EventListenStart()
+ {
+ _callback = (IntPtr sensorHandle, IntPtr eventPtr, IntPtr data) => {
+ Interop.SensorEventStruct sensorData = Interop.IntPtrToEventStruct(eventPtr);
+
+ TimeSpan = new TimeSpan((Int64)sensorData.timestamp);
+ HeartRate = (int)sensorData.values[0];
+
+ DataUpdated?.Invoke(this, new HeartRateMonitorDataUpdatedEventArgs((int)sensorData.values[0]));
+ };
+
+ int error = Interop.SensorListener.SetEventCallback(ListenerHandle, Interval, _callback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting event callback for heart rate monitor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set event callback for heart rate");
+ }
+ }
+
+ internal override void EventListenStop()
+ {
+ int error = Interop.SensorListener.UnsetEventCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting event callback for heart rate monitor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset event callback for heart rate");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/Plugins/HumiditySensor.cs b/src/Tizen.Sensor/Tizen.Sensor/Plugins/HumiditySensor.cs
new file mode 100755
index 0000000..3ef6def
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/Plugins/HumiditySensor.cs
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// HumiditySensor Class. Used for registering callbacks for humidity sensor and getting humidity data
+ /// </summary>
+ public sealed class HumiditySensor : Sensor
+ {
+ private const string HumiditySensorKey = "http://tizen.org/feature/sensor.humidity";
+
+ /// <summary>
+ /// Gets the value of the humidity sensor.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Humidity </value>
+ public float Humidity { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Returns true or false based on whether humidity sensor is supported by device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value><c>true</c> if supported; otherwise, <c>false</c>.</value>
+ public static bool IsSupported
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Checking if the HumiditySensor is supported");
+ return CheckIfSupported(SensorType.HumiditySensor, HumiditySensorKey);
+ }
+ }
+
+ /// <summary>
+ /// Returns the number of humidity sensors available on the device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The count of humidity sensors </value>
+ public static int Count
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the count of humidity sensors");
+ return GetCount();
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Tizen.Sensor.HumiditySensor"/> class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>http://tizen.org/feature/sensor.humidity</feature>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="NotSupportedException">Thrown when the sensor is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <param name='index'>
+ /// Index. Default value for this is 0. Index refers to a particular humidity sensor in case of multiple sensors
+ /// </param>
+ public HumiditySensor(uint index = 0) : base(index)
+ {
+ Log.Info(Globals.LogTag, "Creating HumiditySensor object");
+ }
+
+ internal override SensorType GetSensorType()
+ {
+ return SensorType.HumiditySensor;
+ }
+
+ /// <summary>
+ /// Event Handler for storing the callback functions for event corresponding to change in humidity sensor data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+
+ public event EventHandler<HumiditySensorDataUpdatedEventArgs> DataUpdated;
+
+ private static int GetCount()
+ {
+ IntPtr list;
+ int count;
+ int error = Interop.SensorManager.GetSensorList(SensorType.HumiditySensor, out list, out count);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor list for humidity");
+ count = 0;
+ }
+ else
+ Interop.Libc.Free(list);
+ return count;
+ }
+
+ private static Interop.SensorListener.SensorEventCallback _callback;
+
+ internal override void EventListenStart()
+ {
+ _callback = (IntPtr sensorHandle, IntPtr eventPtr, IntPtr data) => {
+ Interop.SensorEventStruct sensorData = Interop.IntPtrToEventStruct(eventPtr);
+
+ TimeSpan = new TimeSpan((Int64)sensorData.timestamp);
+ Humidity = sensorData.values[0];
+
+ DataUpdated?.Invoke(this, new HumiditySensorDataUpdatedEventArgs(sensorData.values[0]));
+ };
+
+ int error = Interop.SensorListener.SetEventCallback(ListenerHandle, Interval, _callback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting event callback for humidity sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set event callback for humidity");
+ }
+ }
+
+ internal override void EventListenStop()
+ {
+ int error = Interop.SensorListener.UnsetEventCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting event callback for humidity sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset event callback for humidity");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/Plugins/InVehicleActivityDetector.cs b/src/Tizen.Sensor/Tizen.Sensor/Plugins/InVehicleActivityDetector.cs
new file mode 100755
index 0000000..0d6aa55
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/Plugins/InVehicleActivityDetector.cs
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// InVehicleActivityDetector Class. Used for registering callbacks for in vehicle activity detector and getting the in vehicle state
+ /// </summary>
+ public sealed class InVehicleActivityDetector : ActivityDetector
+ {
+ private const string ActivityDetectorKey = "http://tizen.org/feature/sensor.activity_recognition";
+
+ /// <summary>
+ /// Gets the state of in-vehicle activity detector
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> In-vehicle state </value>
+ public DetectorState InVehicle { get; private set; } = DetectorState.Unknown;
+
+ /// <summary>
+ /// Returns true or false based on whether in-vehicle activity detector is supported by device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value><c>true</c> if supported; otherwise, <c>false</c>.</value>
+ public static bool IsSupported
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Checking if the in-vehicle activity detector is supported");
+ return CheckIfSupported(SensorType.InVehicleActivityDetector, ActivityDetectorKey);
+ }
+ }
+
+ /// <summary>
+ /// Returns the number of in-vehicle activity detectors available on the device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The count of in-vehicle activity detectors </value>
+ public static int Count
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the count of in-vehicle activity detectors");
+ return GetCount();
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Tizen.Sensor.InVehicleActivityDetector"/> class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>http://tizen.org/feature/sensor.activity_recognition</feature>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="NotSupportedException">Thrown when the sensor is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <param name='index'>
+ /// Index. Default value for this is 0. Index refers to a particular in-vehicle activity detector in case of multiple sensors.
+ /// </param>
+ public InVehicleActivityDetector(uint index = 0) : base(index)
+ {
+ SetAttribute((SensorAttribute)ActivityAttribute, (int)ActivityType.InVehicle);
+ Log.Info(Globals.LogTag, "Creating in-vehicle activity detector object");
+ }
+
+ private static int GetCount()
+ {
+ IntPtr list;
+ int count;
+ int error = Interop.SensorManager.GetSensorList(SensorType.InVehicleActivityDetector, out list, out count);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor list for in-vehicle activity detector");
+ count = 0;
+ }
+ else
+ Interop.Libc.Free(list);
+ return count;
+ }
+
+ /// <summary>
+ /// Event Handler for storing the callback functions for event corresponding to change in in-vehicle activity detector data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<InVehicleActivityDetectorDataUpdatedEventArgs> DataUpdated;
+
+ private static Interop.SensorListener.SensorEventCallback _callback;
+
+ internal override void EventListenStart()
+ {
+ _callback = (IntPtr sensorHandle, IntPtr eventPtr, IntPtr data) => {
+ Interop.SensorEventStruct sensorData = Interop.IntPtrToEventStruct(eventPtr);
+
+ TimeSpan = new TimeSpan((Int64)sensorData.timestamp);
+ InVehicle = (DetectorState)sensorData.values[0];
+ ActivityAccuracy = (SensorDataAccuracy) sensorData.accuracy;
+
+ DataUpdated?.Invoke(this, new InVehicleActivityDetectorDataUpdatedEventArgs(sensorData.values[0]));
+ };
+
+ int error = Interop.SensorListener.SetEventCallback(ListenerHandle, Interval, _callback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting event callback for invehicle activity detector");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set event callback for invehicle activity detector");
+ }
+ }
+
+ internal override void EventListenStop()
+ {
+ int error = Interop.SensorListener.UnsetEventCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting event callback for invehicle activity detector");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset event callback for invehicle activity detector");
+ }
+ }
+
+ internal override SensorType GetSensorType()
+ {
+ return SensorType.InVehicleActivityDetector;
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/Plugins/LightSensor.cs b/src/Tizen.Sensor/Tizen.Sensor/Plugins/LightSensor.cs
new file mode 100755
index 0000000..2ec7c43
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/Plugins/LightSensor.cs
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// LightSensor Class. Used for registering callbacks for light sensor and getting light data
+ /// </summary>
+ public sealed class LightSensor : Sensor
+ {
+ private const string LightSensorKey = "http://tizen.org/feature/sensor.photometer";
+
+ /// <summary>
+ /// Gets the Level of the light.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Light level </value>
+ public float Level { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Returns true or false based on whether light sensor is supported by device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value><c>true</c> if supported; otherwise, <c>false</c>.</value>
+ public static bool IsSupported
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Checking if the LightSensor is supported");
+ return CheckIfSupported(SensorType.LightSensor, LightSensorKey);
+ }
+ }
+
+ /// <summary>
+ /// Returns the number of light sensors available on the device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The count of light sensors </value>
+ public static int Count
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the count of light sensors");
+ return GetCount();
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Tizen.Sensor.LightSensor"/> class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>http://tizen.org/feature/sensor.photometer</feature>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="NotSupportedException">Thrown when the sensor is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <param name='index'>
+ /// Index. Default value for this is 0. Index refers to a particular light sensor in case of multiple sensors
+ /// </param>
+ public LightSensor(uint index = 0) : base(index)
+ {
+ Log.Info(Globals.LogTag, "Creating LightSensor object");
+ }
+
+ internal override SensorType GetSensorType()
+ {
+ return SensorType.LightSensor;
+ }
+
+ /// <summary>
+ /// Event Handler for storing the callback functions for event corresponding to change in light sensor data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+
+ public event EventHandler<LightSensorDataUpdatedEventArgs> DataUpdated;
+
+ private static int GetCount()
+ {
+ IntPtr list;
+ int count;
+ int error = Interop.SensorManager.GetSensorList(SensorType.LightSensor, out list, out count);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor list for light");
+ count = 0;
+ }
+ else
+ Interop.Libc.Free(list);
+ return count;
+ }
+
+ private static Interop.SensorListener.SensorEventCallback _callback;
+
+ internal override void EventListenStart()
+ {
+ _callback = (IntPtr sensorHandle, IntPtr eventPtr, IntPtr data) => {
+ Interop.SensorEventStruct sensorData = Interop.IntPtrToEventStruct(eventPtr);
+
+ TimeSpan = new TimeSpan((Int64)sensorData.timestamp);
+ Level = sensorData.values[0];
+
+ DataUpdated?.Invoke(this, new LightSensorDataUpdatedEventArgs(sensorData.values[0]));
+ };
+
+ int error = Interop.SensorListener.SetEventCallback(ListenerHandle, Interval, _callback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting event callback for light sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set event callback for light");
+ }
+ }
+
+ internal override void EventListenStop()
+ {
+ int error = Interop.SensorListener.UnsetEventCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting event callback for light sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset event callback for light");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/Plugins/LinearAccelerationSensor.cs b/src/Tizen.Sensor/Tizen.Sensor/Plugins/LinearAccelerationSensor.cs
new file mode 100755
index 0000000..6fbf056
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/Plugins/LinearAccelerationSensor.cs
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// LinearAccelerationSensor Class. Used for registering callbacks for linear acceleration sensor and getting linear acceleration data
+ /// </summary>
+ public sealed class LinearAccelerationSensor : Sensor
+ {
+ private const string LinearAccelerationSensorKey = "http://tizen.org/feature/sensor.linear_acceleration";
+
+ private event EventHandler<SensorAccuracyChangedEventArgs> _accuracyChanged;
+ /// <summary>
+ /// Gets the X component of the linear acceleration.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> X </value>
+ public float X { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the Y component of the linear acceleration.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Y </value>
+ public float Y { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the Z component of the linear acceleration.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Z </value>
+ public float Z { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Returns true or false based on whether linear acceleration sensor is supported by device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value><c>true</c> if supported; otherwise, <c>false</c>.</value>
+ public static bool IsSupported
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Checking if the LinearAccelerationSensor is supported");
+ return CheckIfSupported(SensorType.LinearAccelerationSensor, LinearAccelerationSensorKey);
+ }
+ }
+
+ /// <summary>
+ /// Returns the number of linear acceleration sensors available on the device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The count of linear acceleration sensors </value>
+ public static int Count
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the count of linear acceleration sensors");
+ return GetCount();
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Tizen.Sensor.LinearAccelerationSensor"/> class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>http://tizen.org/feature/sensor.linear_acceleration</feature>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="NotSupportedException">Thrown when the sensor is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <param name='index'>
+ /// Index. Default value for this is 0. Index refers to a particular linear acceleration sensor in case of multiple sensors
+ /// </param>
+ public LinearAccelerationSensor(uint index = 0) : base(index)
+ {
+ Log.Info(Globals.LogTag, "Creating LinearAccelerationSensor object");
+ }
+
+ internal override SensorType GetSensorType()
+ {
+ return SensorType.LinearAccelerationSensor;
+ }
+
+ /// <summary>
+ /// Event Handler for storing the callback functions for event corresponding to change in linear acceleration sensor data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+
+ public event EventHandler<LinearAccelerationSensorDataUpdatedEventArgs> DataUpdated;
+
+ /// <summary>
+ /// Event handler for accuracy changed events.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<SensorAccuracyChangedEventArgs> AccuracyChanged
+ {
+ add
+ {
+ if (_accuracyChanged == null)
+ {
+ AccuracyListenStart();
+ }
+ _accuracyChanged += value;
+ }
+ remove
+ {
+ _accuracyChanged -= value;
+ if (_accuracyChanged == null)
+ {
+ AccuracyListenStop();
+ }
+ }
+ }
+
+ private static int GetCount()
+ {
+ IntPtr list;
+ int count;
+ int error = Interop.SensorManager.GetSensorList(SensorType.LinearAccelerationSensor, out list, out count);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor list for linear acceleration sensor");
+ count = 0;
+ }
+ else
+ Interop.Libc.Free(list);
+ return count;
+ }
+
+ private static Interop.SensorListener.SensorEventCallback _callback;
+
+ internal override void EventListenStart()
+ {
+ _callback = (IntPtr sensorHandle, IntPtr eventPtr, IntPtr data) => {
+ Interop.SensorEventStruct sensorData = Interop.IntPtrToEventStruct(eventPtr);
+
+ TimeSpan = new TimeSpan((Int64)sensorData.timestamp);
+ X = sensorData.values[0];
+ Y = sensorData.values[1];
+ Z = sensorData.values[2];
+
+ DataUpdated?.Invoke(this, new LinearAccelerationSensorDataUpdatedEventArgs(sensorData.values));
+ };
+
+ int error = Interop.SensorListener.SetEventCallback(ListenerHandle, Interval, _callback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting event callback for linear acceleration sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set event callback for linear acceleration sensor");
+ }
+ }
+
+ internal override void EventListenStop()
+ {
+ int error = Interop.SensorListener.UnsetEventCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting event callback for linear acceleration sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset event callback for linear acceleration");
+ }
+ }
+
+ private static Interop.SensorListener.SensorAccuracyCallback _accuracyCallback;
+
+ private void AccuracyListenStart()
+ {
+ _accuracyCallback = (IntPtr sensorHandle, UInt64 timestamp, SensorDataAccuracy accuracy, IntPtr data) => {
+ TimeSpan = new TimeSpan((Int64)timestamp);
+ _accuracyChanged?.Invoke(this, new SensorAccuracyChangedEventArgs(new TimeSpan((Int64)timestamp), accuracy));
+ };
+
+ int error = Interop.SensorListener.SetAccuracyCallback(ListenerHandle, _accuracyCallback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting accuracy event callback for linear acceleration sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set accuracy event callback for linear acceleration sensor");
+ }
+ }
+
+ private void AccuracyListenStop()
+ {
+ int error = Interop.SensorListener.UnsetAccuracyCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting accuracy event callback for linear acceleration sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset accuracy event callback for linear acceleration sensor");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/Plugins/Magnetometer.cs b/src/Tizen.Sensor/Tizen.Sensor/Plugins/Magnetometer.cs
new file mode 100755
index 0000000..83dd226
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/Plugins/Magnetometer.cs
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// Magnetometer Class. Used for registering callbacks for magnetometer and getting magnetometer data
+ /// </summary>
+ public sealed class Magnetometer : Sensor
+ {
+ private static string MagnetometerKey = "http://tizen.org/feature/sensor.magnetometer";
+
+ private event EventHandler<SensorAccuracyChangedEventArgs> _accuracyChanged;
+ /// <summary>
+ /// Gets the X component of the magnetometer.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> X </value>
+ public float X { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the Y component of the magnetometer.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Y </value>
+ public float Y { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the Z component of the magnetometer.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Z </value>
+ public float Z { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Returns true or false based on whether magnetometer is supported by device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value><c>true</c> if supported; otherwise, <c>false</c>.</value>
+ public static bool IsSupported
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Checking if the Magnetometer is supported");
+ return CheckIfSupported(SensorType.Magnetometer, MagnetometerKey);
+ }
+ }
+
+ /// <summary>
+ /// Returns the number of magnetometers available on the device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The count of magnetometers </value>
+ public static int Count
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the count of magnetometers");
+ return GetCount();
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Tizen.Sensor.Magnetometer"/> class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>http://tizen.org/feature/sensor.magnetometer</feature>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="NotSupportedException">Thrown when the sensor is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <param name='index'>
+ /// Index. Default value for this is 0. Index refers to a particular magnetometer in case of multiple sensors
+ /// </param>
+ public Magnetometer(uint index = 0) : base(index)
+ {
+ Log.Info(Globals.LogTag, "Creating Magnetometer object");
+ }
+
+ internal override SensorType GetSensorType()
+ {
+ return SensorType.Magnetometer;
+ }
+
+ /// <summary>
+ /// Event Handler for storing the callback functions for event corresponding to change in magnetometer data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+
+ public event EventHandler<MagnetometerDataUpdatedEventArgs> DataUpdated;
+
+ /// <summary>
+ /// Event handler for accuracy changed events.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<SensorAccuracyChangedEventArgs> AccuracyChanged
+ {
+ add
+ {
+ if (_accuracyChanged == null)
+ {
+ AccuracyListenStart();
+ }
+ _accuracyChanged += value;
+ }
+ remove
+ {
+ _accuracyChanged -= value;
+ if (_accuracyChanged == null)
+ {
+ AccuracyListenStop();
+ }
+ }
+ }
+
+ private static int GetCount()
+ {
+ IntPtr list;
+ int count;
+ int error = Interop.SensorManager.GetSensorList(SensorType.Magnetometer, out list, out count);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor list for magnetometer");
+ count = 0;
+ }
+ else
+ Interop.Libc.Free(list);
+ return count;
+ }
+
+ private static Interop.SensorListener.SensorEventCallback _callback;
+
+ internal override void EventListenStart()
+ {
+ _callback = (IntPtr sensorHandle, IntPtr eventPtr, IntPtr data) => {
+ Interop.SensorEventStruct sensorData = Interop.IntPtrToEventStruct(eventPtr);
+
+ TimeSpan = new TimeSpan((Int64)sensorData.timestamp);
+ X = sensorData.values[0];
+ Y = sensorData.values[1];
+ Z = sensorData.values[2];
+
+ DataUpdated?.Invoke(this, new MagnetometerDataUpdatedEventArgs(sensorData.values));
+ };
+
+ int error = Interop.SensorListener.SetEventCallback(ListenerHandle, Interval, _callback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting event callback for magnetometer");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set event callback for magnetometer");
+ }
+ }
+
+ internal override void EventListenStop()
+ {
+ int error = Interop.SensorListener.UnsetEventCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting event callback for magnetometer");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset event callback for magnetometer");
+ }
+ }
+
+ private static Interop.SensorListener.SensorAccuracyCallback _accuracyCallback;
+
+ private void AccuracyListenStart()
+ {
+ _accuracyCallback = (IntPtr sensorHandle, UInt64 timestamp, SensorDataAccuracy accuracy, IntPtr data) => {
+ TimeSpan = new TimeSpan((Int64)timestamp);
+ _accuracyChanged?.Invoke(this, new SensorAccuracyChangedEventArgs(new TimeSpan((Int64)timestamp), accuracy));
+ };
+
+ int error = Interop.SensorListener.SetAccuracyCallback(ListenerHandle, _accuracyCallback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting accuracy event callback for magnetometer");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set accuracy event callback for magnetometer");
+ }
+ }
+
+ private void AccuracyListenStop()
+ {
+ int error = Interop.SensorListener.UnsetAccuracyCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting accuracy event callback for magnetometer");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset accuracy event callback for magnetometer");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/Plugins/MagnetometerRotationVectorSensor.cs b/src/Tizen.Sensor/Tizen.Sensor/Plugins/MagnetometerRotationVectorSensor.cs
new file mode 100755
index 0000000..02afa13
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/Plugins/MagnetometerRotationVectorSensor.cs
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// MagnetometerRotationVectorSensor Class. Used for registering callbacks for magnetometer rotation vector sensor and getting magnetometer rotation vector data
+ /// </summary>
+ public sealed class MagnetometerRotationVectorSensor : Sensor
+ {
+ private static string MagnetometerRVKey = "http://tizen.org/feature/sensor.geomagnetic_rotation_vector";
+
+ private event EventHandler<SensorAccuracyChangedEventArgs> _accuracyChanged;
+ /// <summary>
+ /// Gets the X component of the magnetometer rotation vector.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> X </value>
+ public float X { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the Y component of the magnetometer rotation vector.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Y </value>
+ public float Y { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the Z component of the magnetometer rotation vector.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Z </value>
+ public float Z { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the W component of the magnetometer rotation vector.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> W </value>
+ public float W { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the Accuracy of the magnetometer rotation vector data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Accuracy </value>
+ public SensorDataAccuracy Accuracy { get; private set; }
+
+ /// <summary>
+ /// Returns true or false based on whether magnetometer rotation vector sensor is supported by device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value><c>true</c> if supported; otherwise, <c>false</c>.</value>
+ public static bool IsSupported
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Checking if the MagnetometerRotationVectorSensor is supported");
+ return CheckIfSupported(SensorType.MagnetometerRotationVectorSensor, MagnetometerRVKey);
+ }
+ }
+
+ /// <summary>
+ /// Returns the number of magnetometer rotation vector sensors available on the device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The count of magnetometer rotation vector sensors </value>
+ public static int Count
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the count of magnetometer rotation vector sensors");
+ return GetCount();
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Tizen.Sensor.MagnetometerRotationVectorSensor"/> class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>http://tizen.org/feature/sensor.geomagnetic_rotation_vector</feature>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="NotSupportedException">Thrown when the sensor is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <param name='index'>
+ /// Index. Default value for this is 0. Index refers to a particular magnetometer rotation vector sensor in case of multiple sensors
+ /// </param>
+ public MagnetometerRotationVectorSensor(uint index = 0) : base(index)
+ {
+ Log.Info(Globals.LogTag, "Creating MagnetometerRotationVectorSensor object");
+ }
+
+ internal override SensorType GetSensorType()
+ {
+ return SensorType.MagnetometerRotationVectorSensor;
+ }
+
+ /// <summary>
+ /// Event Handler for storing the callback functions for event corresponding to change in magnetometer rotation vector sensor data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+
+ public event EventHandler<MagnetometerRotationVectorSensorDataUpdatedEventArgs> DataUpdated;
+
+ /// <summary>
+ /// Event handler for accuracy changed events.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<SensorAccuracyChangedEventArgs> AccuracyChanged
+ {
+ add
+ {
+ if (_accuracyChanged == null)
+ {
+ AccuracyListenStart();
+ }
+ _accuracyChanged += value;
+ }
+ remove
+ {
+ _accuracyChanged -= value;
+ if (_accuracyChanged == null)
+ {
+ AccuracyListenStop();
+ }
+ }
+ }
+
+ private static bool CheckIfSupported()
+ {
+ bool isSupported;
+ int error = Interop.SensorManager.SensorIsSupported(SensorType.MagnetometerRotationVectorSensor, out isSupported);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error checking if magnetometer rotation vector sensor is supported");
+ isSupported = false;
+ }
+ return isSupported;
+ }
+
+ private static int GetCount()
+ {
+ IntPtr list;
+ int count;
+ int error = Interop.SensorManager.GetSensorList(SensorType.MagnetometerRotationVectorSensor, out list, out count);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor list for magnetometer rotation vector");
+ count = 0;
+ }
+ else
+ Interop.Libc.Free(list);
+ return count;
+ }
+
+ private static Interop.SensorListener.SensorEventCallback _callback;
+
+ internal override void EventListenStart()
+ {
+ _callback = (IntPtr sensorHandle, IntPtr eventPtr, IntPtr data) => {
+ Interop.SensorEventStruct sensorData = Interop.IntPtrToEventStruct(eventPtr);
+
+ TimeSpan = new TimeSpan((Int64)sensorData.timestamp);
+ X = sensorData.values[0];
+ Y = sensorData.values[1];
+ Z = sensorData.values[2];
+ W = sensorData.values[3];
+ Accuracy = sensorData.accuracy;
+
+ DataUpdated?.Invoke(this, new MagnetometerRotationVectorSensorDataUpdatedEventArgs(sensorData.values, sensorData.accuracy));
+ };
+
+ int error = Interop.SensorListener.SetEventCallback(ListenerHandle, Interval, _callback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting event callback for magnetometer rotation vector sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set event callback for magnetometer rotation vector");
+ }
+ }
+
+ internal override void EventListenStop()
+ {
+ int error = Interop.SensorListener.UnsetEventCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting event callback for magnetometer rotation vector sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset event callback for magnetometer rotation vector");
+ }
+ }
+
+ private static Interop.SensorListener.SensorAccuracyCallback _accuracyCallback;
+
+ private void AccuracyListenStart()
+ {
+ _accuracyCallback = (IntPtr sensorHandle, UInt64 timestamp, SensorDataAccuracy accuracy, IntPtr data) => {
+ TimeSpan = new TimeSpan((Int64)timestamp);
+ Accuracy = accuracy;
+ _accuracyChanged?.Invoke(this, new SensorAccuracyChangedEventArgs(new TimeSpan((Int64)timestamp), accuracy));
+ };
+
+ int error = Interop.SensorListener.SetAccuracyCallback(ListenerHandle, _accuracyCallback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting accuracy event callback for magnetometer rotation vector sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set accuracy event callback for magnetometer rotation vector");
+ }
+ }
+
+ private void AccuracyListenStop()
+ {
+ int error = Interop.SensorListener.UnsetAccuracyCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting accuracy event callback for magnetometer rotation vector sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset accuracy event callback for magnetometer rotation vector");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/Plugins/OrientationSensor.cs b/src/Tizen.Sensor/Tizen.Sensor/Plugins/OrientationSensor.cs
new file mode 100755
index 0000000..2bba50a
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/Plugins/OrientationSensor.cs
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// OrientationSensor Class. Used for registering callbacks for orientation sensor and getting orientation data
+ /// </summary>
+ public sealed class OrientationSensor : Sensor
+ {
+ private static string OrientationSensorKey = "http://tizen.org/feature/sensor.tiltmeter";
+
+ private event EventHandler<SensorAccuracyChangedEventArgs> _accuracyChanged;
+ /// <summary>
+ /// Gets the Azimuth component of the orientation.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Azimuth </value>
+ public float Azimuth { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the Pitch component of the orientation.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Pitch </value>
+ public float Pitch { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the Roll component of the orientation.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Roll </value>
+ public float Roll { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Returns true or false based on whether orientation sensor is supported by device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value><c>true</c> if supported; otherwise, <c>false</c>.</value>
+ public static bool IsSupported
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Checking if the OrientationSensor is supported");
+ return CheckIfSupported(SensorType.OrientationSensor, OrientationSensorKey);
+ }
+ }
+
+ /// <summary>
+ /// Returns the number of orientation sensors available on the device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The count of orientation sensors </value>
+ public static int Count
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the count of orientation sensors");
+ return GetCount();
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Tizen.Sensor.OrientationSensor"/> class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>http://tizen.org/feature/sensor.tiltmeter</feature>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="NotSupportedException">Thrown when the sensor is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <param name='index'>
+ /// Index. Default value for this is 0. Index refers to a particular orientation sensor in case of multiple sensors
+ /// </param>
+ public OrientationSensor(uint index = 0) : base(index)
+ {
+ Log.Info(Globals.LogTag, "Creating OrientationSensor object");
+ }
+
+ internal override SensorType GetSensorType()
+ {
+ return SensorType.OrientationSensor;
+ }
+
+ /// <summary>
+ /// Event Handler for storing the callback functions for event corresponding to change in orientation sensor data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+
+ public event EventHandler<OrientationSensorDataUpdatedEventArgs> DataUpdated;
+
+ /// <summary>
+ /// Event handler for accuracy changed events.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<SensorAccuracyChangedEventArgs> AccuracyChanged
+ {
+ add
+ {
+ if (_accuracyChanged == null)
+ {
+ AccuracyListenStart();
+ }
+ _accuracyChanged += value;
+ }
+ remove
+ {
+ _accuracyChanged -= value;
+ if (_accuracyChanged == null)
+ {
+ AccuracyListenStop();
+ }
+ }
+ }
+
+ private static int GetCount()
+ {
+ IntPtr list;
+ int count;
+ int error = Interop.SensorManager.GetSensorList(SensorType.OrientationSensor, out list, out count);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor list for orientation");
+ count = 0;
+ }
+ else
+ Interop.Libc.Free(list);
+ return count;
+ }
+
+ private static Interop.SensorListener.SensorEventCallback _callback;
+
+ internal override void EventListenStart()
+ {
+ _callback = (IntPtr sensorHandle, IntPtr eventPtr, IntPtr data) => {
+ Interop.SensorEventStruct sensorData = Interop.IntPtrToEventStruct(eventPtr);
+
+ TimeSpan = new TimeSpan((Int64)sensorData.timestamp);
+ Azimuth = sensorData.values[0];
+ Pitch = sensorData.values[1];
+ Roll = sensorData.values[2];
+
+ DataUpdated?.Invoke(this, new OrientationSensorDataUpdatedEventArgs(sensorData.values));
+ };
+
+ int error = Interop.SensorListener.SetEventCallback(ListenerHandle, Interval, _callback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting event callback for orientation sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set event callback for orientation");
+ }
+ }
+
+ internal override void EventListenStop()
+ {
+ int error = Interop.SensorListener.UnsetEventCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting event callback for orientation sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset event callback for orientation");
+ }
+ }
+
+ private static Interop.SensorListener.SensorAccuracyCallback _accuracyCallback;
+
+ private void AccuracyListenStart()
+ {
+ _accuracyCallback = (IntPtr sensorHandle, UInt64 timestamp, SensorDataAccuracy accuracy, IntPtr data) => {
+ TimeSpan = new TimeSpan((Int64)timestamp);
+ _accuracyChanged?.Invoke(this, new SensorAccuracyChangedEventArgs(new TimeSpan((Int64)timestamp), accuracy));
+ };
+
+ int error = Interop.SensorListener.SetAccuracyCallback(ListenerHandle, _accuracyCallback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting accuracy event callback for orientation sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set accuracy accuracy event callback for orientation");
+ }
+ }
+
+ private void AccuracyListenStop()
+ {
+ int error = Interop.SensorListener.UnsetAccuracyCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting event callback for orientation sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset accuracy event callback for orientation");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/Plugins/Pedometer.cs b/src/Tizen.Sensor/Tizen.Sensor/Plugins/Pedometer.cs
new file mode 100755
index 0000000..8f39050
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/Plugins/Pedometer.cs
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// Pedometer Sensor Class. Used for registering callbacks for pedometer and getting pedometer data
+ /// </summary>
+ public sealed class Pedometer : Sensor
+ {
+ private static string PedometerKey = "http://tizen.org/feature/sensor.pedometer";
+
+ /// <summary>
+ /// Gets the step count
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Step count </value>
+ public uint StepCount { get; private set; } = 0;
+
+ /// <summary>
+ /// Gets the walking step count
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Walk step count </value>
+ public uint WalkStepCount { get; private set; } = 0;
+
+ /// <summary>
+ /// Gets the running step count
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Run step count </value>
+ public uint RunStepCount { get; private set; } = 0;
+
+ /// <summary>
+ /// Gets the moving distance
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Moving distance </value>
+ public float MovingDistance { get; private set; } = 0;
+
+ /// <summary>
+ /// Gets the calorie burned
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Calorie Burned </value>
+ public float CalorieBurned { get; private set; } = 0;
+
+ /// <summary>
+ /// Gets the last speed
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Last speed </value>
+ public float LastSpeed { get; private set; } = 0;
+
+ /// <summary>
+ /// Gets the last stepping frequency
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Last stepping frequency </value>
+ public float LastSteppingFrequency { get; private set; } = 0;
+
+ /// <summary>
+ /// Gets the last step status
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Last step status </value>
+ public PedometerState LastStepStatus { get; private set; } = PedometerState.Unknown;
+
+ /// <summary>
+ /// Returns true or false based on whether pedometer sensor is supported by device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value><c>true</c> if supported; otherwise, <c>false</c>.</value>
+ public static bool IsSupported
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Checking if the Pedometer sensor is supported");
+ return CheckIfSupported(SensorType.Pedometer, PedometerKey);
+ }
+ }
+
+ /// <summary>
+ /// Returns the number of pedometer sensors available on the device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The count of pedometer sensors </value>
+ public static int Count
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the count of pedometer sensors");
+ return GetCount();
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Tizen.Sensor.Pedometer"/> class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/healthinfo</privilege>
+ /// <privlevel>public</privlevel>
+ /// <feature>http://tizen.org/feature/sensor.pedometer</feature>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="NotSupportedException">Thrown when the sensor is not supported</exception>
+ /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the sensor</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <param name='index'>
+ /// Index. Default value for this is 0. Index refers to a particular pedometer sensor in case of multiple sensors
+ /// </param>
+ public Pedometer(uint index = 0) : base(index)
+ {
+ Log.Info(Globals.LogTag, "Creating Pedometer object");
+ }
+
+ internal override SensorType GetSensorType()
+ {
+ return SensorType.Pedometer;
+ }
+
+ /// <summary>
+ /// Event Handler for storing the callback functions for event corresponding to change in pedometer sensor data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+
+ public event EventHandler<PedometerDataUpdatedEventArgs> DataUpdated;
+
+ private static int GetCount()
+ {
+ IntPtr list;
+ int count;
+ int error = Interop.SensorManager.GetSensorList(SensorType.Pedometer, out list, out count);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor list for pedometer");
+ count = 0;
+ }
+ else
+ Interop.Libc.Free(list);
+ return count;
+ }
+
+ private static Interop.SensorListener.SensorEventCallback _callback;
+
+ internal override void EventListenStart()
+ {
+ _callback = (IntPtr sensorHandle, IntPtr eventPtr, IntPtr data) => {
+ Interop.SensorEventStruct sensorData = Interop.IntPtrToEventStruct(eventPtr);
+
+ TimeSpan = new TimeSpan((Int64)sensorData.timestamp);
+ StepCount = (uint)sensorData.values[0];
+ WalkStepCount = (uint)sensorData.values[1];
+ RunStepCount = (uint)sensorData.values[2];
+ MovingDistance = sensorData.values[3];
+ CalorieBurned = sensorData.values[4];
+ LastSpeed = sensorData.values[5];
+ LastSteppingFrequency = sensorData.values[6];
+ LastStepStatus = (PedometerState)sensorData.values[7];
+
+ DataUpdated?.Invoke(this, new PedometerDataUpdatedEventArgs(sensorData.values));
+ };
+
+ int error = Interop.SensorListener.SetEventCallback(ListenerHandle, Interval, _callback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting event callback for pedometer sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set event callback for pedometer");
+ }
+ }
+
+ internal override void EventListenStop()
+ {
+ int error = Interop.SensorListener.UnsetEventCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting event callback for pedometer sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset event callback for pedometer");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/Plugins/PickUpGestureDetector.cs b/src/Tizen.Sensor/Tizen.Sensor/Plugins/PickUpGestureDetector.cs
new file mode 100755
index 0000000..f0a870b
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/Plugins/PickUpGestureDetector.cs
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// PickUpGestureDetector Class. Used for registering callbacks for pick up activity detector and getting the pick up state
+ /// </summary>
+ public sealed class PickUpGestureDetector : Sensor
+ {
+ private static string GestureDetectorKey = "http://tizen.org/feature/sensor.gesture_recognition";
+
+ /// <summary>
+ /// Gets the state of the pick up gesture.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Pick up state </value>
+ public DetectorState PickUp { get; private set; } = DetectorState.Unknown;
+
+ /// <summary>
+ /// Returns true or false based on whether pick up gesture detector is supported by device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value><c>true</c> if supported; otherwise, <c>false</c>.</value>
+ public static bool IsSupported
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Checking if the pick up gesture detector is supported");
+ return CheckIfSupported(SensorType.PickUpGestureDetector, GestureDetectorKey);
+ }
+ }
+
+ /// <summary>
+ /// Returns the number of pick up gesture detectors available on the device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The count of pick up gesture detectors </value>
+ public static int Count
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the count of pick up gesture detectors");
+ return GetCount();
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Tizen.Sensor.PickUpGestureDetector"/> class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>http://tizen.org/feature/sensor.gesture_recognition</feature>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="NotSupportedException">Thrown when the sensor is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <param name='index'>
+ /// Index. Default value for this is 0. Index refers to a particular pick up gesture detector in case of multiple sensors.
+ /// </param>
+ public PickUpGestureDetector(uint index = 0) : base(index)
+ {
+ Log.Info(Globals.LogTag, "Creating pick up gesture detector object");
+ }
+
+ internal override SensorType GetSensorType()
+ {
+ return SensorType.PickUpGestureDetector;
+ }
+
+ private static bool CheckIfSupported()
+ {
+ bool isSupported;
+ int error = Interop.SensorManager.SensorIsSupported(SensorType.PickUpGestureDetector, out isSupported);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error checking if pick up gesture detector is supported");
+ isSupported = false;
+ }
+ return isSupported;
+ }
+
+ private static int GetCount()
+ {
+ IntPtr list;
+ int count;
+ int error = Interop.SensorManager.GetSensorList(SensorType.PickUpGestureDetector, out list, out count);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor list for pick up gesture detector");
+ count = 0;
+ }
+ else
+ Interop.Libc.Free(list);
+ return count;
+ }
+
+ /// <summary>
+ /// Event Handler for storing the callback functions for event corresponding to change in pick up gesture detector data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<PickUpGestureDetectorDataUpdatedEventArgs> DataUpdated;
+
+ private static Interop.SensorListener.SensorEventCallback _callback;
+
+ internal override void EventListenStart()
+ {
+ _callback = (IntPtr sensorHandle, IntPtr eventPtr, IntPtr data) => {
+ Interop.SensorEventStruct sensorData = Interop.IntPtrToEventStruct(eventPtr);
+
+ TimeSpan = new TimeSpan((Int64)sensorData.timestamp);
+ PickUp = (DetectorState) sensorData.values[0];
+
+ DataUpdated?.Invoke(this, new PickUpGestureDetectorDataUpdatedEventArgs(sensorData.values[0]));
+ };
+
+ int error = Interop.SensorListener.SetEventCallback(ListenerHandle, Interval, _callback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting event callback for pick up gesture detector");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set event callback for pick up gesture detector");
+ }
+ }
+
+ internal override void EventListenStop()
+ {
+ int error = Interop.SensorListener.UnsetEventCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting event callback for pick up gesture detector");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset event callback for pick up gesture detector");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/Plugins/PressureSensor.cs b/src/Tizen.Sensor/Tizen.Sensor/Plugins/PressureSensor.cs
new file mode 100755
index 0000000..f17c590
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/Plugins/PressureSensor.cs
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// PressureSensor Class. Used for registering callbacks for pressure sensor and getting pressure data
+ /// </summary>
+ public sealed class PressureSensor : Sensor
+ {
+ private static string PressureSensorKey = "http://tizen.org/feature/sensor.barometer";
+
+ /// <summary>
+ /// Gets the value of the pressure sensor.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Pressure </value>
+ public float Pressure { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Returns true or false based on whether pressure sensor is supported by device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value><c>true</c> if supported; otherwise, <c>false</c>.</value>
+ public static bool IsSupported
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Checking if the PressureSensor is supported");
+ return CheckIfSupported(SensorType.PressureSensor, PressureSensorKey);
+ }
+ }
+
+ /// <summary>
+ /// Returns the number of pressure sensors available on the device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The count of pressure sensors </value>
+ public static int Count
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the count of pressure sensors");
+ return GetCount();
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Tizen.Sensor.PressureSensor"/> class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>http://tizen.org/feature/sensor.barometer</feature>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="NotSupportedException">Thrown when the sensor is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <param name='index'>
+ /// Index. Default value for this is 0. Index refers to a particular pressure sensor in case of multiple sensors
+ /// </param>
+ public PressureSensor(uint index = 0) : base(index)
+ {
+ Log.Info(Globals.LogTag, "Creating PressureSensor object");
+ }
+
+ internal override SensorType GetSensorType()
+ {
+ return SensorType.PressureSensor;
+ }
+
+ /// <summary>
+ /// Event Handler for storing the callback functions for event corresponding to change in pressure sensor data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+
+ public event EventHandler<PressureSensorDataUpdatedEventArgs> DataUpdated;
+
+
+ private static int GetCount()
+ {
+ IntPtr list;
+ int count;
+ int error = Interop.SensorManager.GetSensorList(SensorType.PressureSensor, out list, out count);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor list for pressure");
+ count = 0;
+ }
+ else
+ Interop.Libc.Free(list);
+ return count;
+ }
+
+ private static Interop.SensorListener.SensorEventCallback _callback;
+
+ internal override void EventListenStart()
+ {
+ _callback = (IntPtr sensorHandle, IntPtr eventPtr, IntPtr data) => {
+ Interop.SensorEventStruct sensorData = Interop.IntPtrToEventStruct(eventPtr);
+
+ TimeSpan = new TimeSpan((Int64)sensorData.timestamp);
+ Pressure = sensorData.values[0];
+
+ DataUpdated?.Invoke(this, new PressureSensorDataUpdatedEventArgs(sensorData.values[0]));
+ };
+
+ int error = Interop.SensorListener.SetEventCallback(ListenerHandle, Interval, _callback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting event callback for pressure sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set event callback for pressure");
+ }
+ }
+
+ internal override void EventListenStop()
+ {
+ int error = Interop.SensorListener.UnsetEventCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting event callback for pressure sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset event callback for pressure");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/Plugins/ProximitySensor.cs b/src/Tizen.Sensor/Tizen.Sensor/Plugins/ProximitySensor.cs
new file mode 100755
index 0000000..927087a
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/Plugins/ProximitySensor.cs
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// ProximitySensor Class. Used for registering callbacks for proximity sensor and getting proximity data
+ /// </summary>
+ public sealed class ProximitySensor : Sensor
+ {
+ private static string ProximitySensorKey = "http://tizen.org/feature/sensor.proximity";
+
+ /// <summary>
+ /// Gets the proximity state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Proximity state </value>
+ public ProximitySensorState Proximity { get; private set; } = ProximitySensorState.Unknown;
+
+ /// <summary>
+ /// Returns true or false based on whether proximity sensor is supported by device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value><c>true</c> if supported; otherwise, <c>false</c>.</value>
+ public static bool IsSupported
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Checking if the ProximitySensor is supported");
+ return CheckIfSupported(SensorType.ProximitySensor, ProximitySensorKey);
+ }
+ }
+
+ /// <summary>
+ /// Returns the number of proximity sensors available on the device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The count of proximity sensors </value>
+ public static int Count
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the count of proximity sensors");
+ return GetCount();
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Tizen.Sensor.ProximitySensor"/> class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>http://tizen.org/feature/sensor.proximity</feature>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="NotSupportedException">Thrown when the sensor is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <param name='index'>
+ /// Index. Default value for this is 0. Index refers to a particular proximity sensor in case of multiple sensors
+ /// </param>
+ public ProximitySensor(uint index = 0) : base(index)
+ {
+ Log.Info(Globals.LogTag, "Creating ProximitySensor object");
+ }
+
+ internal override SensorType GetSensorType()
+ {
+ return SensorType.ProximitySensor;
+ }
+
+ /// <summary>
+ /// Event Handler for storing the callback functions for event corresponding to change in proximity sensor data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+
+ public event EventHandler<ProximitySensorDataUpdatedEventArgs> DataUpdated;
+
+ private static int GetCount()
+ {
+ IntPtr list;
+ int count;
+ int error = Interop.SensorManager.GetSensorList(SensorType.ProximitySensor, out list, out count);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor list for proximity");
+ count = 0;
+ }
+ else
+ Interop.Libc.Free(list);
+ return count;
+ }
+
+ private static Interop.SensorListener.SensorEventCallback _callback;
+
+ internal override void EventListenStart()
+ {
+ _callback = (IntPtr sensorHandle, IntPtr eventPtr, IntPtr data) => {
+ Interop.SensorEventStruct sensorData = Interop.IntPtrToEventStruct(eventPtr);
+
+ TimeSpan = new TimeSpan((Int64)sensorData.timestamp);
+ Proximity = (ProximitySensorState) sensorData.values[0];
+
+ DataUpdated?.Invoke(this, new ProximitySensorDataUpdatedEventArgs(sensorData.values[0]));
+ };
+
+ int error = Interop.SensorListener.SetEventCallback(ListenerHandle, Interval, _callback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting event callback for proximity sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set event callback for proximity");
+ }
+ }
+
+ internal override void EventListenStop()
+ {
+ int error = Interop.SensorListener.UnsetEventCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting event callback for proximity sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset event callback for proximity");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/Plugins/RotationVectorSensor.cs b/src/Tizen.Sensor/Tizen.Sensor/Plugins/RotationVectorSensor.cs
new file mode 100755
index 0000000..8489d11
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/Plugins/RotationVectorSensor.cs
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// RotationVectorSensor Class. Used for registering callbacks for rotation vector sensor and getting rotation vector data
+ /// </summary>
+ public sealed class RotationVectorSensor : Sensor
+ {
+ private static string RotationVectorKey = "http://tizen.org/feature/sensor.rotation_vector";
+
+ private event EventHandler<SensorAccuracyChangedEventArgs> _accuracyChanged;
+ /// <summary>
+ /// Gets the X component of the rotation vector.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> X </value>
+ public float X { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the Y component of the rotation vector.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Y </value>
+ public float Y { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the Z component of the rotation vector.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Z </value>
+ public float Z { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the W component of the rotation vector.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> W </value>
+ public float W { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the Accuracy of the rotation vector data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Accuracy </value>
+ public SensorDataAccuracy Accuracy { get; private set; } = SensorDataAccuracy.Undefined;
+
+ /// <summary>
+ /// Returns true or false based on whether rotation vector sensor is supported by device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value><c>true</c> if supported; otherwise, <c>false</c>.</value>
+ public static bool IsSupported
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Checking if the RotationVectorSensor is supported");
+ return CheckIfSupported(SensorType.RotationVectorSensor, RotationVectorKey);
+ }
+ }
+
+ /// <summary>
+ /// Returns the number of rotation vector sensors available on the device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The count of rotation vector sensors </value>
+ public static int Count
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the count of rotation vector sensors");
+ return GetCount();
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Tizen.Sensor.RotationVectorSensor"/> class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>http://tizen.org/feature/sensor.rotation_vector</feature>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="NotSupportedException">Thrown when the sensor is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <param name='index'>
+ /// Index. Default value for this is 0. Index refers to a particular rotation vector sensor in case of multiple sensors
+ /// </param>
+ public RotationVectorSensor(uint index = 0) : base(index)
+ {
+ Log.Info(Globals.LogTag, "Creating RotationVectorSensor object");
+ }
+
+ internal override SensorType GetSensorType()
+ {
+ return SensorType.RotationVectorSensor;
+ }
+
+ /// <summary>
+ /// Event Handler for storing the callback functions for event corresponding to change in rotation vector sensor data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+
+ public event EventHandler<RotationVectorSensorDataUpdatedEventArgs> DataUpdated;
+
+ /// <summary>
+ /// Event handler for accuracy changed events.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<SensorAccuracyChangedEventArgs> AccuracyChanged
+ {
+ add
+ {
+ if (_accuracyChanged == null)
+ {
+ AccuracyListenStart();
+ }
+ _accuracyChanged += value;
+ }
+ remove
+ {
+ _accuracyChanged -= value;
+ if (_accuracyChanged == null)
+ {
+ AccuracyListenStop();
+ }
+ }
+ }
+
+ private static int GetCount()
+ {
+ IntPtr list;
+ int count;
+ int error = Interop.SensorManager.GetSensorList(SensorType.RotationVectorSensor, out list, out count);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor list for rotation vector");
+ count = 0;
+ }
+ else
+ Interop.Libc.Free(list);
+ return count;
+ }
+
+ private static Interop.SensorListener.SensorEventCallback _callback;
+
+ internal override void EventListenStart()
+ {
+ _callback = (IntPtr sensorHandle, IntPtr eventPtr, IntPtr data) => {
+ Interop.SensorEventStruct sensorData = Interop.IntPtrToEventStruct(eventPtr);
+
+ TimeSpan = new TimeSpan((Int64)sensorData.timestamp);
+ X = sensorData.values[0];
+ Y = sensorData.values[1];
+ Z = sensorData.values[2];
+ W = sensorData.values[3];
+ Accuracy = sensorData.accuracy;
+
+ DataUpdated?.Invoke(this, new RotationVectorSensorDataUpdatedEventArgs(sensorData.values, sensorData.accuracy));
+ };
+
+ int error = Interop.SensorListener.SetEventCallback(ListenerHandle, Interval, _callback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting event callback for rotation vector sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set event callback for rotation vector");
+ }
+ }
+
+ internal override void EventListenStop()
+ {
+ int error = Interop.SensorListener.UnsetEventCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting event callback for rotation vector sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset event callback for rotation vector");
+ }
+ }
+
+ private static Interop.SensorListener.SensorAccuracyCallback _accuracyCallback;
+
+ private void AccuracyListenStart()
+ {
+ _accuracyCallback = (IntPtr sensorHandle, UInt64 timestamp, SensorDataAccuracy accuracy, IntPtr data) => {
+ TimeSpan = new TimeSpan((Int64)timestamp);
+ Accuracy = accuracy;
+ _accuracyChanged?.Invoke(this, new SensorAccuracyChangedEventArgs(new TimeSpan((Int64)timestamp), accuracy));
+ };
+
+ int error = Interop.SensorListener.SetAccuracyCallback(ListenerHandle, _accuracyCallback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting accuracy event callback for rotation vector sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set accuracy event callback for rotation vector");
+ }
+ }
+
+ private void AccuracyListenStop()
+ {
+ int error = Interop.SensorListener.UnsetAccuracyCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting accuracy event callback for rotation vector sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset accuracy event callback for rotation vector");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/Plugins/RunningActivityDetector.cs b/src/Tizen.Sensor/Tizen.Sensor/Plugins/RunningActivityDetector.cs
new file mode 100755
index 0000000..fc2ec5b
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/Plugins/RunningActivityDetector.cs
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// RunningActivityDetector Class. Used for registering callbacks for running activity detector and getting the running state
+ /// </summary>
+ public sealed class RunningActivityDetector : ActivityDetector
+ {
+ private static string ActivityDetectorKey = "http://tizen.org/feature/sensor.activity_recognition";
+
+ /// <summary>
+ /// Gets the state of running activity detector
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Running state </value>
+ public DetectorState Running { get; private set; } = DetectorState.Unknown;
+
+ /// <summary>
+ /// Returns true or false based on whether running activity detector is supported by device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value><c>true</c> if supported; otherwise, <c>false</c>.</value>
+ public static bool IsSupported
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Checking if the running activity detector is supported");
+ return CheckIfSupported(SensorType.RunningActivityDetector, ActivityDetectorKey);
+ }
+ }
+
+ /// <summary>
+ /// Returns the number of running activity detector available on the device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The count of running activity detectors </value>
+ public static int Count
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the count of running activity detectors");
+ return GetCount();
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Tizen.Sensor.RunningActivityDetector"/> class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>http://tizen.org/feature/sensor.activity_recognition</feature>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="NotSupportedException">Thrown when the sensor is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <param name='index'>
+ /// Index. Default value for this is 0. Index refers to a particular running activity detector in case of multiple sensors.
+ /// </param>
+ public RunningActivityDetector(uint index = 0) : base(index)
+ {
+ SetAttribute((SensorAttribute)ActivityAttribute, (int)ActivityType.Running);
+ Log.Info(Globals.LogTag, "Creating running activity detector object");
+ }
+
+ private static int GetCount()
+ {
+ IntPtr list;
+ int count;
+ int error = Interop.SensorManager.GetSensorList(SensorType.RunningActivityDetector, out list, out count);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor list for running activity detector");
+ count = 0;
+ }
+ else
+ Interop.Libc.Free(list);
+ return count;
+ }
+
+ /// <summary>
+ /// Event Handler for storing the callback functions for event corresponding to change in running activity detector data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<RunningActivityDetectorDataUpdatedEventArgs> DataUpdated;
+
+ private static Interop.SensorListener.SensorEventCallback _callback;
+
+ internal override void EventListenStart()
+ {
+ _callback = (IntPtr sensorHandle, IntPtr eventPtr, IntPtr data) => {
+ Interop.SensorEventStruct sensorData = Interop.IntPtrToEventStruct(eventPtr);
+
+ TimeSpan = new TimeSpan((Int64)sensorData.timestamp);
+ Running = (DetectorState)sensorData.values[0];
+ ActivityAccuracy = (SensorDataAccuracy) sensorData.accuracy;
+
+ DataUpdated?.Invoke(this, new RunningActivityDetectorDataUpdatedEventArgs(sensorData.values[0]));
+ };
+
+ int error = Interop.SensorListener.SetEventCallback(ListenerHandle, Interval, _callback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting event callback for running activity detector");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set event callback for running activity detector");
+ }
+ }
+
+ internal override void EventListenStop()
+ {
+ int error = Interop.SensorListener.UnsetEventCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting event callback for running activity detector");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset event callback for running activity detector");
+ }
+ }
+
+ internal override SensorType GetSensorType()
+ {
+ return SensorType.RunningActivityDetector;
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/Plugins/SleepMonitor.cs b/src/Tizen.Sensor/Tizen.Sensor/Plugins/SleepMonitor.cs
new file mode 100755
index 0000000..8291cfa
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/Plugins/SleepMonitor.cs
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// SleepMonitor Class. Used for registering callbacks for sleep monitor and getting sleep data
+ /// </summary>
+ public sealed class SleepMonitor : Sensor
+ {
+ private static string SleepMonitorKey = "http://tizen.org/feature/sensor.sleep_monitor";
+
+ /// <summary>
+ /// Gets the value of the sleep state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Sleep state </value>
+ public SleepMonitorState SleepState { get; private set; } = SleepMonitorState.Unknown;
+
+ /// <summary>
+ /// Returns true or false based on whether sleep monitor is supported by device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value><c>true</c> if supported; otherwise, <c>false</c>.</value>
+ public static bool IsSupported
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Checking if the SleepMonitor is supported");
+ return CheckIfSupported(SensorType.SleepMonitor, SleepMonitorKey);
+ }
+ }
+
+ /// <summary>
+ /// Returns the number of sleep monitors available on the device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The count of sleep monitors </value>
+ public static int Count
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the count of sleep monitors");
+ return GetCount();
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Tizen.Sensor.SleepMonitor"/> class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/healthinfo</privilege>
+ /// <privlevel>public</privlevel>
+ /// <feature>http://tizen.org/feature/sensor.sleep_monitor</feature>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="NotSupportedException">Thrown when the sensor is not supported</exception>
+ /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the sensor</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <param name='index'>
+ /// Index. Default value for this is 0. Index refers to a particular sleep monitor in case of multiple sensors
+ /// </param>
+ public SleepMonitor(uint index = 0) : base(index)
+ {
+ Log.Info(Globals.LogTag, "Creating SleepMonitor object");
+ }
+
+ internal override SensorType GetSensorType()
+ {
+ return SensorType.SleepMonitor;
+ }
+
+ /// <summary>
+ /// Event Handler for storing the callback functions for event corresponding to change in sleep monitor data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+
+ public event EventHandler<SleepMonitorDataUpdatedEventArgs> DataUpdated;
+
+
+ private static int GetCount()
+ {
+ IntPtr list;
+ int count;
+ int error = Interop.SensorManager.GetSensorList(SensorType.SleepMonitor, out list, out count);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor list for sleep");
+ count = 0;
+ }
+ else
+ Interop.Libc.Free(list);
+ return count;
+ }
+
+ private static Interop.SensorListener.SensorEventCallback _callback;
+
+ internal override void EventListenStart()
+ {
+ _callback = (IntPtr sensorHandle, IntPtr eventPtr, IntPtr data) => {
+ Interop.SensorEventStruct sensorData = Interop.IntPtrToEventStruct(eventPtr);
+
+ TimeSpan = new TimeSpan((Int64)sensorData.timestamp);
+ SleepState = (SleepMonitorState)sensorData.values[0];
+
+ DataUpdated?.Invoke(this, new SleepMonitorDataUpdatedEventArgs((int)sensorData.values[0]));
+ };
+
+ int error = Interop.SensorListener.SetEventCallback(ListenerHandle, Interval, _callback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting event callback for sleep monitor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set event callback for sleep");
+ }
+ }
+
+ internal override void EventListenStop()
+ {
+ int error = Interop.SensorListener.UnsetEventCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting event callback for sleep monitor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset event callback for sleep");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/Plugins/StationaryActivityDetector.cs b/src/Tizen.Sensor/Tizen.Sensor/Plugins/StationaryActivityDetector.cs
new file mode 100755
index 0000000..c8b0251
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/Plugins/StationaryActivityDetector.cs
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// StationaryActivityDetector Class. Used for registering callbacks for stationary activity detector and getting the stationary state
+ /// </summary>
+ public sealed class StationaryActivityDetector : ActivityDetector
+ {
+ private static string ActivityDetectorKey = "http://tizen.org/feature/sensor.activity_recognition";
+
+ /// <summary>
+ /// Gets the state of stationary activity detector
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Stationary state </value>
+ public DetectorState Stationary { get; private set; } = DetectorState.Unknown;
+
+ /// <summary>
+ /// Returns true or false based on whether stationary activity detector is supported by device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value><c>true</c> if supported; otherwise, <c>false</c>.</value>
+ public static bool IsSupported
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Checking if the stationary activity detector is supported");
+ return CheckIfSupported(SensorType.StationaryActivityDetector, ActivityDetectorKey);
+ }
+ }
+
+ /// <summary>
+ /// Returns the number of stationary activity detectors available on the device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The count of stationary activity detectors </value>
+ public static int Count
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the count of stationary activity detectors");
+ return GetCount();
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Tizen.Sensor.stationaryActivityDetector"/> class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>http://tizen.org/feature/sensor.activity_recognition</feature>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="NotSupportedException">Thrown when the sensor is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <param name='index'>
+ /// Index. Default value for this is 0. Index refers to a particular stationary activity detector in case of multiple sensors.
+ /// </param>
+ public StationaryActivityDetector(uint index = 0) : base(index)
+ {
+ SetAttribute((SensorAttribute)ActivityAttribute, (int)ActivityType.Stationary);
+ Log.Info(Globals.LogTag, "Creating stationary activity detector object");
+ }
+
+ private static int GetCount()
+ {
+ IntPtr list;
+ int count;
+ int error = Interop.SensorManager.GetSensorList(SensorType.StationaryActivityDetector, out list, out count);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor list for stationary activity detector");
+ count = 0;
+ }
+ else
+ Interop.Libc.Free(list);
+ return count;
+ }
+
+ /// <summary>
+ /// Event Handler for storing the callback functions for event corresponding to change in stationary activity detector data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<StationaryActivityDetectorDataUpdatedEventArgs> DataUpdated;
+
+ internal static Interop.SensorListener.SensorEventCallback _callback;
+
+ internal override void EventListenStart()
+ {
+ _callback = (IntPtr sensorHandle, IntPtr eventPtr, IntPtr data) => {
+ Interop.SensorEventStruct sensorData = Interop.IntPtrToEventStruct(eventPtr);
+
+ TimeSpan = new TimeSpan((Int64)sensorData.timestamp);
+ Stationary = (DetectorState)sensorData.values[0];
+ ActivityAccuracy = (SensorDataAccuracy) sensorData.accuracy;
+
+ DataUpdated?.Invoke(this, new StationaryActivityDetectorDataUpdatedEventArgs(sensorData.values[0]));
+ };
+
+ int error = Interop.SensorListener.SetEventCallback(ListenerHandle, Interval, _callback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting event callback for stationary activity detector");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set event callback for stationary activity detector");
+ }
+ }
+
+ internal override void EventListenStop()
+ {
+ int error = Interop.SensorListener.UnsetEventCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting event callback for stationary activity detector");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset event callback for stationary activity detector");
+ }
+ }
+
+ internal override SensorType GetSensorType()
+ {
+ return SensorType.StationaryActivityDetector;
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/Plugins/TemperatureSensor.cs b/src/Tizen.Sensor/Tizen.Sensor/Plugins/TemperatureSensor.cs
new file mode 100755
index 0000000..b90b1bc
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/Plugins/TemperatureSensor.cs
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// TemperatureSensor Class. Used for registering callbacks for temperature sensor and getting temperature data
+ /// </summary>
+ public sealed class TemperatureSensor : Sensor
+ {
+ private static string TemperatureSensorKey = "http://tizen.org/feature/sensor.temperature";
+
+ /// <summary>
+ /// Gets the value of the temperature sensor.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Temperature (Celsius) </value>
+ public float Temperature { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Returns true or false based on whether temperature sensor is supported by device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value><c>true</c> if supported; otherwise, <c>false</c>.</value>
+ public static bool IsSupported
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Checking if the TemperatureSensor is supported");
+ return CheckIfSupported(SensorType.TemperatureSensor, TemperatureSensorKey);
+ }
+ }
+
+ /// <summary>
+ /// Returns the number of temperature sensors available on the device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The count of temperature sensors </value>
+ public static int Count
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the count of temperature sensors");
+ return GetCount();
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Tizen.Sensor.TemperatureSensor"/> class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>http://tizen.org/feature/sensor.temperature</feature>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="NotSupportedException">Thrown when the sensor is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <param name='index'>
+ /// Index. Default value for this is 0. Index refers to a particular temperature sensor in case of multiple sensors
+ /// </param>
+ public TemperatureSensor(uint index = 0) : base(index)
+ {
+ Log.Info(Globals.LogTag, "Creating TemperatureSensor object");
+ }
+
+ internal override SensorType GetSensorType()
+ {
+ return SensorType.TemperatureSensor;
+ }
+
+ /// <summary>
+ /// Event Handler for storing the callback functions for event corresponding to change in temperature sensor data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+
+ public event EventHandler<TemperatureSensorDataUpdatedEventArgs> DataUpdated;
+
+
+ private static int GetCount()
+ {
+ IntPtr list;
+ int count;
+ int error = Interop.SensorManager.GetSensorList(SensorType.TemperatureSensor, out list, out count);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor list for temperature");
+ count = 0;
+ }
+ else
+ Interop.Libc.Free(list);
+ return count;
+ }
+
+ private static Interop.SensorListener.SensorEventCallback _callback;
+
+ internal override void EventListenStart()
+ {
+ _callback = (IntPtr sensorHandle, IntPtr eventPtr, IntPtr data) => {
+ Interop.SensorEventStruct sensorData = Interop.IntPtrToEventStruct(eventPtr);
+
+ TimeSpan = new TimeSpan((Int64)sensorData.timestamp);
+ Temperature = sensorData.values[0];
+
+ DataUpdated?.Invoke(this, new TemperatureSensorDataUpdatedEventArgs(sensorData.values[0]));
+ };
+
+ int error = Interop.SensorListener.SetEventCallback(ListenerHandle, Interval, _callback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting event callback for temperature sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set event callback for temperature");
+ }
+ }
+
+ internal override void EventListenStop()
+ {
+ int error = Interop.SensorListener.UnsetEventCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting event callback for temperature sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset event callback for temperature");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/Plugins/UltravioletSensor.cs b/src/Tizen.Sensor/Tizen.Sensor/Plugins/UltravioletSensor.cs
new file mode 100755
index 0000000..07c3d2e
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/Plugins/UltravioletSensor.cs
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// UltravioletSensor Class. Used for registering callbacks for ultraviolet sensor and getting ultraviolet data
+ /// </summary>
+ public sealed class UltravioletSensor : Sensor
+ {
+ private static string UltravioletSensorKey = "http://tizen.org/feature/sensor.ultraviolet";
+
+ /// <summary>
+ /// Gets the value of the ultraviolet sensor.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Ultraviolet index </value>
+ public float UltravioletIndex { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Returns true or false based on whether ultraviolet sensor is supported by device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value><c>true</c> if supported; otherwise, <c>false</c>.</value>
+ public static bool IsSupported
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Checking if the UltravioletSensor is supported");
+ return CheckIfSupported(SensorType.UltravioletSensor, UltravioletSensorKey);
+ }
+ }
+
+ /// <summary>
+ /// Returns the number of ultraviolet sensors available on the device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The count of ultraviolet sensors </value>
+ public static int Count
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the count of ultraviolet sensors");
+ return GetCount();
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Tizen.Sensor.UltravioletSensor"/> class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>http://tizen.org/feature/sensor.ultraviolet</feature>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="NotSupportedException">Thrown when the sensor is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <param name='index'>
+ /// Index. Default value for this is 0. Index refers to a particular ultraviolet sensor in case of multiple sensors
+ /// </param>
+ public UltravioletSensor(uint index = 0) : base(index)
+ {
+ Log.Info(Globals.LogTag, "Creating UltravioletSensor object");
+ }
+
+ internal override SensorType GetSensorType()
+ {
+ return SensorType.UltravioletSensor;
+ }
+
+ /// <summary>
+ /// Event Handler for storing the callback functions for event corresponding to change in ultraviolet sensor data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+
+ public event EventHandler<UltravioletSensorDataUpdatedEventArgs> DataUpdated;
+
+
+ private static int GetCount()
+ {
+ IntPtr list;
+ int count;
+ int error = Interop.SensorManager.GetSensorList(SensorType.UltravioletSensor, out list, out count);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor list for ultraviolet");
+ count = 0;
+ }
+ else
+ Interop.Libc.Free(list);
+ return count;
+ }
+
+ private static Interop.SensorListener.SensorEventCallback _callback;
+
+ internal override void EventListenStart()
+ {
+ _callback = (IntPtr sensorHandle, IntPtr eventPtr, IntPtr data) => {
+ Interop.SensorEventStruct sensorData = Interop.IntPtrToEventStruct(eventPtr);
+
+ TimeSpan = new TimeSpan((Int64)sensorData.timestamp);
+ UltravioletIndex = sensorData.values[0];
+
+ DataUpdated?.Invoke(this, new UltravioletSensorDataUpdatedEventArgs(sensorData.values[0]));
+ };
+
+ int error = Interop.SensorListener.SetEventCallback(ListenerHandle, Interval, _callback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting event callback for ultraviolet sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set event callback for ultraviolet");
+ }
+ }
+
+ internal override void EventListenStop()
+ {
+ int error = Interop.SensorListener.UnsetEventCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting event callback for ultraviolet sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset event callback for ultraviolet");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/Plugins/UncalibratedGyroscope.cs b/src/Tizen.Sensor/Tizen.Sensor/Plugins/UncalibratedGyroscope.cs
new file mode 100755
index 0000000..18900d5
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/Plugins/UncalibratedGyroscope.cs
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// UncalibratedGyroscope Sensor Class. Used for registering callbacks for uncalibrated gyroscope and getting uncalibrated gyroscope data
+ /// </summary>
+ public sealed class UncalibratedGyroscope : Sensor
+ {
+ private static string UncalibratedGyroscopeKey = "http://tizen.org/feature/sensor.gyroscope.uncalibrated";
+
+ /// <summary>
+ /// Gets the X component of the acceleration.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> X </value>
+ public float X { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the Y component of the acceleration.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Y </value>
+ public float Y { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the Z component of the acceleration.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Z </value>
+ public float Z { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the BiasX component of the uncalibrated gyroscope data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> X bias </value>
+ public float BiasX { get; private set; } = 0;
+
+ /// <summary>
+ /// Gets the BiasY component of the uncalibrated gyroscope data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Y bias </value>
+ public float BiasY { get; private set; } = 0;
+
+ /// <summary>
+ /// Gets the BiasZ component of the uncalibrated gyroscope data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Z bias </value>
+ public float BiasZ { get; private set; } = 0;
+
+ /// <summary>
+ /// Returns true or false based on whether uncalibrated gyroscope sensor is supported by device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value><c>true</c> if supported; otherwise, <c>false</c>.</value>
+ public static bool IsSupported
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Checking if the UncalibratedGyroscope sensor is supported");
+ return CheckIfSupported(SensorType.UncalibratedGyroscope, UncalibratedGyroscopeKey);
+ }
+ }
+
+ /// <summary>
+ /// Returns the number of uncalibrated gyroscope sensors available on the device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The count of uncalibrated gyroscope sensors </value>
+ public static int Count
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the count of uncalibrated gyroscope sensors");
+ return GetCount();
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Tizen.Sensor.UncalibratedGyroscope"/> class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>http://tizen.org/feature/sensor.gyroscope.uncalibrated</feature>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="NotSupportedException">Thrown when the sensor is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <param name='index'>
+ /// Index. Default value for this is 0. Index refers to a particular uncalibrated gyroscope sensor in case of multiple sensors
+ /// </param>
+ public UncalibratedGyroscope(uint index = 0) : base(index)
+ {
+ Log.Info(Globals.LogTag, "Creating UncalibratedGyroscope object");
+ }
+
+ internal override SensorType GetSensorType()
+ {
+ return SensorType.UncalibratedGyroscope;
+ }
+
+ /// <summary>
+ /// Event Handler for storing the callback functions for event corresponding to change in uncalibrated gyroscope sensor data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+
+ public event EventHandler<UncalibratedGyroscopeDataUpdatedEventArgs> DataUpdated;
+
+ private static int GetCount()
+ {
+ IntPtr list;
+ int count;
+ int error = Interop.SensorManager.GetSensorList(SensorType.UncalibratedGyroscope, out list, out count);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor list for uncalibrated gyroscope");
+ count = 0;
+ }
+ else
+ Interop.Libc.Free(list);
+ return count;
+ }
+
+ private static Interop.SensorListener.SensorEventCallback _callback;
+
+ internal override void EventListenStart()
+ {
+ _callback = (IntPtr sensorHandle, IntPtr eventPtr, IntPtr data) => {
+ Interop.SensorEventStruct sensorData = Interop.IntPtrToEventStruct(eventPtr);
+
+ TimeSpan = new TimeSpan((Int64)sensorData.timestamp);
+ X = sensorData.values[0];
+ Y = sensorData.values[1];
+ Z = sensorData.values[2];
+ BiasX = sensorData.values[3];
+ BiasY = sensorData.values[4];
+ BiasZ = sensorData.values[5];
+
+ DataUpdated?.Invoke(this, new UncalibratedGyroscopeDataUpdatedEventArgs(sensorData.values));
+ };
+
+ int error = Interop.SensorListener.SetEventCallback(ListenerHandle, Interval, _callback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting event callback for uncalibrated gyroscope sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set event callback for uncalibrated gyroscope");
+ }
+ }
+
+ internal override void EventListenStop()
+ {
+ int error = Interop.SensorListener.UnsetEventCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting event callback for uncalibrated gyroscope sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset event callback for uncalibrated gyroscope");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/Plugins/UncalibratedMagnetometer.cs b/src/Tizen.Sensor/Tizen.Sensor/Plugins/UncalibratedMagnetometer.cs
new file mode 100755
index 0000000..04709e7
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/Plugins/UncalibratedMagnetometer.cs
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// UncalibratedMagnetometer Sensor Class. Used for registering callbacks for uncalibrated magnetometer and getting uncalibrated magnetometer data
+ /// </summary>
+ public sealed class UncalibratedMagnetometer : Sensor
+ {
+ private static string UncalibratedMagnetometerKey = "http://tizen.org/feature/sensor.magnetometer.uncalibrated";
+
+ private event EventHandler<SensorAccuracyChangedEventArgs> _accuracyChanged;
+ /// <summary>
+ /// Gets the X component of the acceleration.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> X </value>
+ public float X { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the Y component of the acceleration.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Y </value>
+ public float Y { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the Z component of the acceleration.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Z </value>
+ public float Z { get; private set; } = float.MinValue;
+
+ /// <summary>
+ /// Gets the BiasX component of the uncalibrated magnetometer data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> X bias </value>
+ public float BiasX { get; private set; } = 0;
+
+ /// <summary>
+ /// Gets the BiasY component of the uncalibrated magnetometer data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Y bias </value>
+ public float BiasY { get; private set; } = 0;
+
+ /// <summary>
+ /// Gets the BiasZ component of the uncalibrated magnetometer data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Z bias </value>
+ public float BiasZ { get; private set; } = 0;
+
+ /// <summary>
+ /// Returns true or false based on whether uncalibrated magnetometer sensor is supported by device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value><c>true</c> if supported; otherwise, <c>false</c>.</value>
+ public static bool IsSupported
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Checking if the UncalibratedMagnetometer sensor is supported");
+ return CheckIfSupported(SensorType.UncalibratedMagnetometer, UncalibratedMagnetometerKey);
+ }
+ }
+
+ /// <summary>
+ /// Returns the number of uncalibrated magnetometer sensors available on the device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The count of uncalibrated magnetometer sensors </value>
+ public static int Count
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the count of uncalibrated magnetometer sensors");
+ return GetCount();
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Tizen.Sensor.UncalibratedMagnetometer"/> class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>http://tizen.org/feature/sensor.magnetometer.uncalibrated</feature>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="NotSupportedException">Thrown when the sensor is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <param name='index'>
+ /// Index. Default value for this is 0. Index refers to a particular uncalibrated magnetometer sensor in case of multiple sensors
+ /// </param>
+ public UncalibratedMagnetometer(uint index = 0) : base(index)
+ {
+ Log.Info(Globals.LogTag, "Creating UncalibratedMagnetometer object");
+ }
+
+ internal override SensorType GetSensorType()
+ {
+ return SensorType.UncalibratedMagnetometer;
+ }
+
+ /// <summary>
+ /// Event Handler for storing the callback functions for event corresponding to change in uncalibrated magnetometer sensor data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+
+ public event EventHandler<UncalibratedMagnetometerDataUpdatedEventArgs> DataUpdated;
+
+ /// <summary>
+ /// Event handler for accuracy changed events.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<SensorAccuracyChangedEventArgs> AccuracyChanged
+ {
+ add
+ {
+ if (_accuracyChanged == null)
+ {
+ AccuracyListenStart();
+ }
+ _accuracyChanged += value;
+ }
+ remove
+ {
+ _accuracyChanged -= value;
+ if (_accuracyChanged == null)
+ {
+ AccuracyListenStop();
+ }
+ }
+ }
+
+ private static int GetCount()
+ {
+ IntPtr list;
+ int count;
+ int error = Interop.SensorManager.GetSensorList(SensorType.UncalibratedMagnetometer, out list, out count);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor list for uncalibrated magnetometer");
+ count = 0;
+ }
+ else
+ Interop.Libc.Free(list);
+ return count;
+ }
+
+ private static Interop.SensorListener.SensorEventCallback _callback;
+
+ internal override void EventListenStart()
+ {
+ _callback = (IntPtr sensorHandle, IntPtr eventPtr, IntPtr data) => {
+ Interop.SensorEventStruct sensorData = Interop.IntPtrToEventStruct(eventPtr);
+
+ TimeSpan = new TimeSpan((Int64)sensorData.timestamp);
+ X = sensorData.values[0];
+ Y = sensorData.values[1];
+ Z = sensorData.values[2];
+ BiasX = sensorData.values[3];
+ BiasY = sensorData.values[4];
+ BiasZ = sensorData.values[5];
+
+ DataUpdated?.Invoke(this, new UncalibratedMagnetometerDataUpdatedEventArgs(sensorData.values));
+ };
+
+ int error = Interop.SensorListener.SetEventCallback(ListenerHandle, Interval, _callback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting event callback for uncalibrated magnetometer sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set event callback for uncalibrated magnetometer");
+ }
+ }
+
+ internal override void EventListenStop()
+ {
+ int error = Interop.SensorListener.UnsetEventCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting event callback for uncalibrated magnetometer sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset event callback for uncalibrated magnetometer");
+ }
+ }
+
+ private static Interop.SensorListener.SensorAccuracyCallback _accuracyCallback;
+
+ private void AccuracyListenStart()
+ {
+ _accuracyCallback = (IntPtr sensorHandle, UInt64 timestamp, SensorDataAccuracy accuracy, IntPtr data) => {
+ TimeSpan = new TimeSpan((Int64)timestamp);
+ _accuracyChanged?.Invoke(this, new SensorAccuracyChangedEventArgs(new TimeSpan((Int64)timestamp), accuracy));
+ };
+
+ int error = Interop.SensorListener.SetAccuracyCallback(ListenerHandle, _accuracyCallback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting accuracy event callback for uncalibrated magnetometer");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set accuracy event callback for uncalibrated magnetometer");
+ }
+ }
+
+ private void AccuracyListenStop()
+ {
+ int error = Interop.SensorListener.UnsetAccuracyCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting accuracy event callback for uncalibrated magnetometer");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset accuracy event callback for uncalibrated magnetometer");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/Plugins/WalkingActivityDetector.cs b/src/Tizen.Sensor/Tizen.Sensor/Plugins/WalkingActivityDetector.cs
new file mode 100755
index 0000000..8fd5960
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/Plugins/WalkingActivityDetector.cs
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// WalkingActivityDetector Class. Used for registering callbacks for walking activity detector and getting the walking state
+ /// </summary>
+ public sealed class WalkingActivityDetector : ActivityDetector
+ {
+ private static string ActivityDetectorKey = "http://tizen.org/feature/sensor.activity_recognition";
+
+ /// <summary>
+ /// Gets the state of walking activity detector
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Walking state </value>
+ public DetectorState Walking { get; private set; } = DetectorState.Unknown;
+
+ /// <summary>
+ /// Returns true or false based on whether walking activity detector is supported by device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value><c>true</c> if supported; otherwise, <c>false</c>.</value>
+ public static bool IsSupported
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Checking if the walking activity detector is supported");
+ return CheckIfSupported(SensorType.WalkingActivityDetector, ActivityDetectorKey);
+ }
+ }
+
+ /// <summary>
+ /// Returns the number of walking activity detectors available on the device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The count of walking activity detectors </value>
+ public static int Count
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the count of walking activity detectors");
+ return GetCount();
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Tizen.Sensor.walkingActivityDetector"/> class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>http://tizen.org/feature/sensor.activity_recognition</feature>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="NotSupportedException">Thrown when the sensor is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <param name='index'>
+ /// Index. Default value for this is 0. Index refers to a particular walking activity detector in case of multiple sensors.
+ /// </param>
+ public WalkingActivityDetector(uint index = 0) : base(index)
+ {
+ SetAttribute((SensorAttribute)ActivityAttribute, (int)ActivityType.Walking);
+ Log.Info(Globals.LogTag, "Creating walking activity gesture detector object");
+ }
+
+ private static int GetCount()
+ {
+ IntPtr list;
+ int count;
+ int error = Interop.SensorManager.GetSensorList(SensorType.WalkingActivityDetector, out list, out count);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor list for walking activity detector");
+ count = 0;
+ }
+ else
+ Interop.Libc.Free(list);
+ return count;
+ }
+
+ /// <summary>
+ /// Event Handler for storing the callback functions for event corresponding to change in walking activity gesture detector data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<WalkingActivityDetectorDataUpdatedEventArgs> DataUpdated;
+
+ internal static Interop.SensorListener.SensorEventCallback _callback;
+
+ internal override void EventListenStart()
+ {
+ _callback = (IntPtr sensorHandle, IntPtr eventPtr, IntPtr data) => {
+ Interop.SensorEventStruct sensorData = Interop.IntPtrToEventStruct(eventPtr);
+
+ TimeSpan = new TimeSpan((Int64)sensorData.timestamp);
+ Walking = (DetectorState)sensorData.values[0];
+ ActivityAccuracy = (SensorDataAccuracy) sensorData.accuracy;
+
+ DataUpdated?.Invoke(this, new WalkingActivityDetectorDataUpdatedEventArgs(sensorData.values[0]));
+ };
+
+ int error = Interop.SensorListener.SetEventCallback(ListenerHandle, Interval, _callback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting event callback for walking activity detector");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set event callback for walking activity detector");
+ }
+ }
+
+ internal override void EventListenStop()
+ {
+ int error = Interop.SensorListener.UnsetEventCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting event callback for walking activity detector");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset event callback for walking activity detector");
+ }
+ }
+
+ internal override SensorType GetSensorType()
+ {
+ return SensorType.WalkingActivityDetector;
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/Plugins/WristUpGestureDetector.cs b/src/Tizen.Sensor/Tizen.Sensor/Plugins/WristUpGestureDetector.cs
new file mode 100755
index 0000000..761e374
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/Plugins/WristUpGestureDetector.cs
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// WristUpGestureDetector Class. Used for registering callbacks for wrist up gesture detector and getting the wrist up state
+ /// </summary>
+ public sealed class WristUpGestureDetector : Sensor
+ {
+ private static string WristUpKey = "http://tizen.org/feature/sensor.wrist_up";
+
+ /// <summary>
+ /// Gets the state of the wrist up gesture.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> Wrist up state </value>
+ public DetectorState WristUp { get; private set; } = DetectorState.Unknown;
+
+ /// <summary>
+ /// Returns true or false based on whether wrist up gesture detector is supported by device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value><c>true</c> if supported; otherwise, <c>false</c>.</value>
+ public static bool IsSupported
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Checking if the wrist up gesture detector is supported");
+ return CheckIfSupported(SensorType.WristUpGestureDetector, WristUpKey);
+ }
+ }
+
+ /// <summary>
+ /// Returns the number of wrist up gesture detectors available on the device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The count of wrist up gesture detectors </value>
+ public static int Count
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the count of wrist up gesture detectors");
+ return GetCount();
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Tizen.Sensor.WristUpGestureDetector"/> class.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>http://tizen.org/feature/sensor.wrist_up</feature>
+ /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
+ /// <exception cref="NotSupportedException">Thrown when the sensor is not supported</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <param name='index'>
+ /// Index. Default value for this is 0. Index refers to a particular wrist up gesture detector in case of multiple sensors.
+ /// </param>
+ public WristUpGestureDetector(uint index = 0) : base(index)
+ {
+ Log.Info(Globals.LogTag, "Creating wrist up gesture detector object");
+ }
+
+ internal override SensorType GetSensorType()
+ {
+ return SensorType.WristUpGestureDetector;
+ }
+
+ private static int GetCount()
+ {
+ IntPtr list;
+ int count;
+ int error = Interop.SensorManager.GetSensorList(SensorType.WristUpGestureDetector, out list, out count);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor list for wrist up gesture detector");
+ count = 0;
+ }
+ else
+ Interop.Libc.Free(list);
+ return count;
+ }
+
+ /// <summary>
+ /// Event Handler for storing the callback functions for event corresponding to change in wrist up gesture detector data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<WristUpGestureDetectorDataUpdatedEventArgs> DataUpdated;
+
+ private static Interop.SensorListener.SensorEventCallback _callback;
+
+ internal override void EventListenStart()
+ {
+ _callback = (IntPtr sensorHandle, IntPtr eventPtr, IntPtr data) => {
+ Interop.SensorEventStruct sensorData = Interop.IntPtrToEventStruct(eventPtr);
+
+ TimeSpan = new TimeSpan((Int64)sensorData.timestamp);
+ WristUp = (DetectorState) sensorData.values[0];
+
+ DataUpdated?.Invoke(this, new WristUpGestureDetectorDataUpdatedEventArgs(sensorData.values[0]));
+ };
+
+ int error = Interop.SensorListener.SetEventCallback(ListenerHandle, Interval, _callback, IntPtr.Zero);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting event callback for wrist up gesture detector");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set event callback for wrist up gesture detector");
+ }
+ }
+
+ internal override void EventListenStop()
+ {
+ int error = Interop.SensorListener.UnsetEventCallback(ListenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error unsetting event callback for wrist up gesture detector");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset event callback for wrist up gesture detector");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/Sensor.cs b/src/Tizen.Sensor/Tizen.Sensor/Sensor.cs
new file mode 100755
index 0000000..fa512c2
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/Sensor.cs
@@ -0,0 +1,533 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Tizen.System;
+
+namespace Tizen.Sensor
+{
+ internal static class Globals
+ {
+ internal const string LogTag = "Tizen.Sensor";
+ }
+
+ /// <summary>
+ /// Sensor class for storing hardware information about a particular sensor
+ /// </summary>
+ public abstract class Sensor : IDisposable
+ {
+ private string _name;
+ private string _vendor;
+ private float _minValue;
+ private float _maxValue;
+ private float _resolution;
+ private int _minInterval;
+ private int _fifoCount;
+ private int _maxBatchCount;
+ private bool _isSensing = false;
+ private bool _disposed = false;
+ private TimeSpan _timeSpan;
+ private uint _interval = 0;
+ private uint _maxBatchLatency = 0;
+ private SensorPausePolicy _pausePolicy = SensorPausePolicy.None;
+ private IntPtr _sensorHandle = IntPtr.Zero;
+ private IntPtr _listenerHandle = IntPtr.Zero;
+
+ internal abstract SensorType GetSensorType();
+ internal abstract void EventListenStart();
+ internal abstract void EventListenStop();
+
+ internal Sensor(uint index)
+ {
+ SensorType type = GetSensorType();
+ GetHandleList(type, index);
+ if (CheckSensorHandle())
+ {
+ CreateListener();
+ GetProperty();
+ }
+ }
+
+ ~Sensor()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Property: For getting the name of the sensor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The name of sensor </value>
+ public string Name
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the sensor name");
+ return _name;
+ }
+ }
+
+ /// <summary>
+ /// Property: Gets the vendor.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The vendor name of sensor </value>
+ public string Vendor
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the sensor vendor name");
+ return _vendor;
+ }
+ }
+
+ /// <summary>
+ /// Property: Gets the minimum value of range of sensor data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The lower bound of range of sensor reading </value>
+ public float MinValue
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the min value of the sensor");
+ return _minValue;
+ }
+ }
+
+ /// <summary>
+ /// Property: Gets the maximum value of range of sensor data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The upper bound of range of sensor reading </value>
+ public float MaxValue
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the max value of the sensor");
+ return _maxValue;
+ }
+ }
+
+ /// <summary>
+ /// Property: Gets the resolution.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The resolution </value>
+ public float Resolution
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the resolution of the sensor");
+ return _resolution;
+ }
+ }
+
+ /// <summary>
+ /// Property: Gets the minimum interval.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The minimum update interval </value>
+ public int MinInterval
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the min interval for the sensor");
+ return _minInterval;
+ }
+ }
+
+ /// <summary>
+ /// Property: Gets the fifo count.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The size of the hardware FIFO </value>
+ public int FifoCount
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the fifo count of the sensor");
+ return _fifoCount;
+ }
+ }
+
+ /// <summary>
+ /// Property: Gets the maximum batch count.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The maximum batch count </value>
+ public int MaxBatchCount
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the max batch count of the sensor");
+ return _maxBatchCount;
+ }
+ }
+
+ /// <summary>
+ /// Sets the interval of the sensor for sensor data event
+ /// Callbacks will be called at frequency of this interval
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <value> The interval of the sensor </value>
+ public uint Interval
+ {
+ set
+ {
+ Log.Info(Globals.LogTag, "Setting the interval of the sensor");
+ _interval = value;
+ SetInterval();
+ }
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the interval of the sensor");
+ return _interval;
+ }
+ }
+
+ /// <summary>
+ /// Sets the max batch latency for the sensor corresponding to the sensor data event.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <value> The max batch latency </value>
+ public uint MaxBatchLatency
+ {
+ set
+ {
+ Log.Info(Globals.LogTag, "Setting the max batch latency of the sensor");
+ _maxBatchLatency = value;
+ SetMaxBatchLatency();
+ }
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the max batch latency of the sensor");
+ return _maxBatchLatency;
+ }
+ }
+
+ /// <summary>
+ /// Sets the pause policy of the sensor.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>The pause policy</value>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ /// <value> The pause policy </value>
+ public SensorPausePolicy PausePolicy
+ {
+ set
+ {
+ Log.Info(Globals.LogTag, "Setting the pause policy of the sensor");
+ _pausePolicy = value;
+ SetAttribute(SensorAttribute.PausePolicy, (int)_pausePolicy);
+ }
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the pause policy of the sensor");
+ return _pausePolicy;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the time span.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value> The time span </value>
+ public TimeSpan TimeSpan
+ {
+ set
+ {
+ Log.Info(Globals.LogTag, "Setting the timespan of the sensor values");
+ _timeSpan = value;
+ }
+ get
+ {
+ Log.Info(Globals.LogTag, "Getting the timespan of the sensor values");
+ return _timeSpan;
+ }
+ }
+
+ /// <summary>
+ /// Indicates whether this sensor is sensing.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value><c>true</c> if this sensor is sensing; otherwise, <c>false</c>.</value>
+ public bool IsSensing
+ {
+ get
+ {
+ Log.Info(Globals.LogTag, "Checking if the sensor is started");
+ return _isSensing;
+ }
+ }
+
+ internal IntPtr ListenerHandle
+ {
+ get
+ {
+ return _listenerHandle;
+ }
+ }
+
+ internal static bool CheckIfSupported(SensorType type, String key)
+ {
+ bool isSupported = false;
+ bool error = SystemInfo.TryGetValue(key, out isSupported);
+
+ if (!error || !isSupported)
+ {
+ Log.Error(Globals.LogTag, "Error checking if sensor is supported(systeminfo)");
+ return false;
+ }
+
+ int ret = Interop.SensorManager.SensorIsSupported(type, out isSupported);
+ if (ret != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error checking if sensor is supported");
+ isSupported = false;
+ }
+
+ return isSupported;
+ }
+
+ /// <summary>
+ /// Starts the sensor.
+ /// After this the event handlers will start receiving events.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ public void Start()
+ {
+ Log.Info(Globals.LogTag, "Starting the sensor");
+ if (CheckListenerHandle())
+ {
+ int error = Interop.SensorListener.StartListener(_listenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error starting sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to Start Sensor Listener");
+ }
+ EventListenStart();
+ _isSensing = true;
+ Log.Info(Globals.LogTag, "Sensor started");
+ }
+ }
+
+ /// <summary>
+ /// Stop the sensor.
+ /// After this the event handlers will stop receiving the events
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
+ public void Stop()
+ {
+ Log.Info(Globals.LogTag, "Stopping the sensor");
+ if (_isSensing)
+ {
+ int error = Interop.SensorListener.StopListener(_listenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error stopping the sensor");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Unable to Stop Sensor Listener");
+ }
+ EventListenStop();
+ _isSensing = false;
+ Log.Info(Globals.LogTag, "Sensor stopped");
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_disposed)
+ return;
+
+ DestroyHandles();
+ _disposed = true;
+ }
+
+ internal void SetAttribute(SensorAttribute attribute, int option)
+ {
+ if (CheckListenerHandle())
+ {
+ int error = Interop.SensorListener.SetAttribute(_listenerHandle, attribute, option);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting sensor pause policy");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Setting Sensor.PausePolicy Failed");
+ }
+ }
+ }
+
+ private void GetHandleList(SensorType type, uint index)
+ {
+ IntPtr list;
+ IntPtr[] sensorList;
+ int count;
+ int error = Interop.SensorManager.GetSensorList(type, out list, out count);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor list");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.GetSensorList Failed");
+ }
+ sensorList = Interop.IntPtrToIntPtrArray(list, count);
+ _sensorHandle = sensorList[index];
+ Interop.Libc.Free(list);
+ }
+
+ private void GetProperty()
+ {
+ int error = (int)SensorError.None;
+
+ error = Interop.Sensor.GetName(_sensorHandle, out _name);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor name");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.Name Failed");
+ }
+
+ error = Interop.Sensor.GetVendor(_sensorHandle, out _vendor);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor vendor name");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.Vendor Failed");
+ }
+
+ error = Interop.Sensor.GetMinRange(_sensorHandle, out _minValue);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor min value");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.MinValue Failed");
+ }
+
+ error = Interop.Sensor.GetMaxRange(_sensorHandle, out _maxValue);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor max value");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.MaxValue Failed");
+ }
+
+ error = Interop.Sensor.GetResolution(_sensorHandle, out _resolution);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor resolution");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.Resolution Failed");
+ }
+
+ error = Interop.Sensor.GetMinInterval(_sensorHandle, out _minInterval);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor min interval");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.MinInterval Failed");
+ }
+
+ error = Interop.Sensor.GetFifoCount(_sensorHandle, out _fifoCount);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor fifo count");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.FifoCount Failed");
+ }
+
+ error = Interop.Sensor.GetMaxBatchCount(_sensorHandle, out _maxBatchCount);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error getting sensor max batch count");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.MaxBatchCount Failed");
+ }
+ }
+
+ private void CreateListener()
+ {
+ int error = Interop.SensorListener.CreateListener(_sensorHandle, out _listenerHandle);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error cerating sensor listener handle");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.CreateListener Failed");
+ }
+ }
+
+ private void SetInterval()
+ {
+ if (CheckListenerHandle())
+ {
+ if (_isSensing)
+ {
+ int error = Interop.SensorListener.SetInterval(_listenerHandle, _interval);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting sensor interval");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Setting Sensor.SetInterval Failed");
+ }
+ }
+ }
+ }
+
+ private void SetMaxBatchLatency()
+ {
+ if (CheckListenerHandle())
+ {
+ int error = Interop.SensorListener.SetMaxBatchLatency(_listenerHandle, _maxBatchLatency);
+ if (error != (int)SensorError.None)
+ {
+ Log.Error(Globals.LogTag, "Error setting max batch latency");
+ throw SensorErrorFactory.CheckAndThrowException(error, "Setting Sensor.MaxBatchLatency Failed");
+ }
+ }
+ }
+
+ private bool CheckListenerHandle()
+ {
+ bool result = false;
+ if (_listenerHandle != IntPtr.Zero)
+ {
+ result = true;
+ }
+ else
+ {
+ Log.Error(Globals.LogTag, "Sensor listener handle is null");
+ throw new ArgumentException("Invalid Parameter: Sensor is null");
+ }
+ return result;
+ }
+
+ private bool CheckSensorHandle()
+ {
+ bool result = false;
+ if (_sensorHandle != IntPtr.Zero)
+ {
+ result = true;
+ }
+ else
+ {
+ Log.Error(Globals.LogTag, "Sensor handle is null");
+ throw new ArgumentException("Invalid Parameter: Sensor is null");
+ }
+ return result;
+ }
+
+ private void DestroyHandles()
+ {
+ Interop.SensorListener.DestroyListener(_listenerHandle);
+ }
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/SensorEnumerations.cs b/src/Tizen.Sensor/Tizen.Sensor/SensorEnumerations.cs
new file mode 100755
index 0000000..84e2571
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/SensorEnumerations.cs
@@ -0,0 +1,322 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Sensor
+{
+ /// <summary>
+ /// The SensorType Enum defintion for all sensor types.
+ /// </summary>
+ internal enum SensorType
+ {
+ /// <summary>
+ /// All sensors. This can be used to retrieve Sensor class object for all available sensors.
+ /// </summary>
+ All = -1,
+ /// <summary>
+ /// Accelerometer sensor.
+ /// </summary>
+ Accelerometer = 0,
+ /// <summary>
+ /// Gravity sensor.
+ /// </summary>
+ GravitySensor = 1,
+ /// <summary>
+ /// Linear Acceleration sensor.
+ /// </summary>
+ LinearAccelerationSensor = 2,
+ /// <summary>
+ /// Magnetometer sensor.
+ /// </summary>
+ Magnetometer = 3,
+ /// <summary>
+ /// Rotation Vector sensor.
+ /// </summary>
+ RotationVectorSensor = 4,
+ /// <summary>
+ /// Orientation sensor.
+ /// </summary>
+ OrientationSensor = 5,
+ /// <summary>
+ /// Gyroscope sensor.
+ /// </summary>
+ Gyroscope = 6,
+ /// <summary>
+ /// Light sensor.
+ /// </summary>
+ LightSensor = 7,
+ /// <summary>
+ /// Proximity sensor.
+ /// </summary>
+ ProximitySensor = 8,
+ /// <summary>
+ /// Pressure sensor.
+ /// </summary>
+ PressureSensor = 9,
+ /// <summary>
+ /// Ultraviolet sensor.
+ /// </summary>
+ UltravioletSensor = 10,
+ /// <summary>
+ /// Temperature sensor.
+ /// </summary>
+ TemperatureSensor = 11,
+ /// <summary>
+ /// Humidity sensor.
+ /// </summary>
+ HumiditySensor = 12,
+ /// <summary>
+ /// Hear rate monitor sensor.
+ /// </summary>
+ HeartRateMonitor = 13,
+ /// <summary>
+ /// Uncalibrated Gyroscope sensor.
+ /// </summary>
+ UncalibratedGyroscope = 17,
+ /// <summary>
+ /// Uncalibrated Geomagnetic sensor.
+ /// </summary>
+ UncalibratedMagnetometer = 18,
+ /// <summary>
+ /// Gyroscope-based rotation vector sensor.
+ /// </summary>
+ GyroscopeRotationVectorSensor = 19,
+ /// <summary>
+ /// Geomagnetic-based rotation vector sensor.
+ /// </summary>
+ MagnetometerRotationVectorSensor = 20,
+ /// <summary>
+ /// Pedometer sensor.
+ /// </summary>
+ Pedometer = 0x300,
+ /// <summary>
+ /// Sleep monitor sensor.
+ /// </summary>
+ SleepMonitor = 0x301,
+ /// <summary>
+ /// Walking activity detector.
+ /// </summary>
+ WalkingActivityDetector = 0x1A00,
+ /// <summary>
+ /// Running activity detector.
+ /// </summary>
+ RunningActivityDetector = 0x1A00,
+ /// <summary>
+ /// Stationary activity detector.
+ /// </summary>
+ StationaryActivityDetector = 0x1A00,
+ /// <summary>
+ /// InVehicle activity detector.
+ /// </summary>
+ InVehicleActivityDetector = 0x1A00,
+ /// <summary>
+ /// Wrist up gesture detector.
+ /// </summary>
+ WristUpGestureDetector = 0x1201,
+ /// <summary>
+ /// Pick up gesture detector.
+ /// </summary>
+ PickUpGestureDetector = 0x1204,
+ /// <summary>
+ /// Face down gesture detector.
+ /// </summary>
+ FaceDownGestureDetector = 0x1205
+ }
+
+ /// <summary>
+ /// Sensor attribute.
+ /// </summary>
+ internal enum SensorAttribute
+ {
+ /// <summary>
+ /// The axis orientation.
+ /// </summary>
+ AxisOrientation,
+
+ /// <summary>
+ /// The pause policy.
+ /// </summary>
+ PausePolicy
+ }
+
+ /// <summary>
+ /// SensorDataAccuracy Enum definition for all possible sensor data accuracy Values.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum SensorDataAccuracy
+ {
+ /// <summary>
+ /// Undefined sensor data accuracy.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Undefined = -1,
+ /// <summary>
+ /// Sensor data not accurate.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Bad = 0,
+ /// <summary>
+ /// Moderately accurate sensor data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Normal = 1,
+ /// <summary>
+ /// Highly accurate sensor data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Good = 2,
+ /// <summary>
+ /// Very highly accurate sensor data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ VeryGood = 3
+ }
+
+ /// <summary>
+ /// Sensor Option Enum definition for sensor option Values
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum SensorPausePolicy
+ {
+ /// <summary>
+ /// Does not receive data when the LCD is off and in the power save mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ None,
+ /// <summary>
+ /// Receives data when the LCD is off.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ DisplayOff,
+ /// <summary>
+ /// Receives data in the power save mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ PowerSaveMode,
+ /// <summary>
+ /// Receives data when the LCD is off and in the power save mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ All
+ }
+
+ /// <summary>
+ /// Pedometer state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum PedometerState
+ {
+ /// <summary>
+ /// Unknown.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Unknown = -1,
+
+ /// <summary>
+ /// Stop state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Stop,
+
+ /// <summary>
+ /// Walking state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Walk,
+
+ /// <summary>
+ /// Running state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Run
+ }
+
+ /// <summary>
+ /// Sleep monitor state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum SleepMonitorState
+ {
+ /// <summary>
+ /// Unknown.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Unknown = -1,
+
+ /// <summary>
+ /// The wake state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Wake,
+
+ /// <summary>
+ /// The sleeping state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Sleep
+ }
+
+ /// <summary>
+ /// Proximity sensor state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum ProximitySensorState
+ {
+ /// <summary>
+ /// Unknown.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Unknown = -1,
+
+ /// <summary>
+ /// Near sate.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Near = 0,
+
+ /// <summary>
+ /// Far state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Far = 5
+ }
+
+ /// <summary>
+ /// Detector sensor state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum DetectorState
+ {
+ /// <summary>
+ /// Unknown.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Unknown = -1,
+
+ /// <summary>
+ /// None sate.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ NotDetected = 0,
+
+ /// <summary>
+ /// Detected state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Detected = 1
+ }
+}
diff --git a/src/Tizen.Sensor/Tizen.Sensor/SensorErrorFactory.cs b/src/Tizen.Sensor/Tizen.Sensor/SensorErrorFactory.cs
new file mode 100644
index 0000000..67cf82b
--- /dev/null
+++ b/src/Tizen.Sensor/Tizen.Sensor/SensorErrorFactory.cs
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Sensor
+{
+ internal enum SensorError
+ {
+ None = ErrorCode.None,
+ IOError = ErrorCode.IoError,
+ InvalidParameter = ErrorCode.InvalidParameter,
+ NotSupported = ErrorCode.NotSupported,
+ PermissionDenied = ErrorCode.PermissionDenied,
+ OutOfMemory = ErrorCode.OutOfMemory,
+ NotNeedCalibration = -0x02440000 | 0x03,
+ OperationFailed = -0x02440000 | 0x06
+ }
+
+ internal static class SensorErrorFactory
+ {
+ static internal Exception CheckAndThrowException(int error, string msg)
+ {
+ SensorError e = (SensorError)error;
+ switch (e)
+ {
+ case SensorError.None:
+ return null;
+ case SensorError.IOError:
+ return new InvalidOperationException("I/O Error: " + msg);
+ case SensorError.InvalidParameter:
+ return new ArgumentException("Invalid Parameter: " + msg);
+ case SensorError.NotSupported:
+ return new NotSupportedException("Not Supported: " + msg);
+ case SensorError.PermissionDenied:
+ return new UnauthorizedAccessException("Permission Denied: " + msg);
+ case SensorError.OutOfMemory:
+ return new InvalidOperationException("Out of Memory: " + msg);
+ case SensorError.NotNeedCalibration:
+ return new InvalidOperationException("Sensor doesn't need calibration: " + msg);
+ case SensorError.OperationFailed:
+ return new InvalidOperationException("Operation Failed: " + msg);
+ default:
+ return new InvalidOperationException("Unknown Error Code: " + msg);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.System.Feedback/Feedback/Feedback.cs b/src/Tizen.System.Feedback/Feedback/Feedback.cs
new file mode 100644
index 0000000..5bd1d0c
--- /dev/null
+++ b/src/Tizen.System.Feedback/Feedback/Feedback.cs
@@ -0,0 +1,375 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Collections.Generic;
+
+
+namespace Tizen.System
+{
+ /// <summary>
+ /// Class for constants
+ /// </summary>
+ internal static class Constants
+ {
+ internal const int NumberOfPattern = 39;
+ }
+
+ /// <summary>
+ /// The Feedback API provides functions to control haptic and sound.
+ /// The Feedback API provides the way to play and stop feedback and get the information whether specific pattern is supported.
+ /// Below is supported pattern string.
+ /// Tap
+ /// SoftInputPanel
+ /// Key0
+ /// Key1
+ /// Key2
+ /// Key3
+ /// Key4
+ /// Key5
+ /// Key6
+ /// Key7
+ /// Key8
+ /// Key9
+ /// KeyStar
+ /// KeySharp
+ /// KeyBack
+ /// Hold
+ /// HardwareKeyPressed
+ /// HardwareKeyHold
+ /// Message
+ /// Email
+ /// WakeUp
+ /// Schedule
+ /// Timer
+ /// General
+ /// PowerOn
+ /// PowerOff
+ /// ChargerConnected
+ /// ChargingError
+ /// FullyCharged
+ /// LowBattery
+ /// Lock
+ /// UnLock
+ /// VibrationModeAbled
+ /// SilentModeDisabled
+ /// BluetoothDeviceConnected
+ /// BluetoothDeviceDisconnected
+ /// ListReorder
+ /// ListSlider
+ /// VolumeKeyPressed
+ /// </summary>
+ /// <privilege>
+ /// For controlling haptic device:
+ /// http://tizen.org/privilege/haptic
+ /// For controlling sound, previlege is not needed.
+ /// </privilege>
+ /// <code>
+ /// Feedback feedback = new Feedback();
+ /// bool res = feedback.IsSupportedPattern(FeedbackType.Vibration, "Tap");
+ /// </code>
+ public class Feedback
+ {
+ private const string LogTag = "Tizen.System.Feedback";
+
+ private readonly FeedbackPattern[] Pattern = new FeedbackPattern[39];
+ public Feedback()
+ {
+ Pattern[0].PatternNumber = 0;
+ Pattern[0].PatternString = "Tap";
+ Pattern[1].PatternNumber = 1;
+ Pattern[1].PatternString = "SoftInputPanel";
+ Pattern[2].PatternNumber = 6;
+ Pattern[2].PatternString = "Key0";
+ Pattern[3].PatternNumber = 7;
+ Pattern[3].PatternString = "Key1";
+ Pattern[4].PatternNumber = 8;
+ Pattern[4].PatternString = "Key2";
+ Pattern[5].PatternNumber = 9;
+ Pattern[5].PatternString = "Key3";
+ Pattern[6].PatternNumber = 10;
+ Pattern[6].PatternString = "Key4";
+ Pattern[7].PatternNumber = 11;
+ Pattern[7].PatternString = "Key5";
+ Pattern[8].PatternNumber = 12;
+ Pattern[8].PatternString = "Key6";
+ Pattern[9].PatternNumber = 13;
+ Pattern[9].PatternString = "Key7";
+ Pattern[10].PatternNumber = 14;
+ Pattern[10].PatternString = "Key8";
+ Pattern[11].PatternNumber = 15;
+ Pattern[11].PatternString = "Key9";
+ Pattern[12].PatternNumber = 16;
+ Pattern[12].PatternString = "KeyStar";
+ Pattern[13].PatternNumber = 17;
+ Pattern[13].PatternString = "KeySharp";
+ Pattern[14].PatternNumber = 18;
+ Pattern[14].PatternString = "KeyBack";
+ Pattern[15].PatternNumber = 19;
+ Pattern[15].PatternString = "Hold";
+ Pattern[16].PatternNumber = 21;
+ Pattern[16].PatternString = "HardwareKeyPressed";
+ Pattern[17].PatternNumber = 22;
+ Pattern[17].PatternString = "HardwareKeyHold";
+ Pattern[18].PatternNumber = 23;
+ Pattern[18].PatternString = "Message";
+ Pattern[19].PatternNumber = 25;
+ Pattern[19].PatternString = "Email";
+ Pattern[20].PatternNumber = 27;
+ Pattern[20].PatternString = "WakeUp";
+ Pattern[21].PatternNumber = 29;
+ Pattern[21].PatternString = "Schedule";
+ Pattern[22].PatternNumber = 31;
+ Pattern[22].PatternString = "Timer";
+ Pattern[23].PatternNumber = 33;
+ Pattern[23].PatternString = "General";
+ Pattern[24].PatternNumber = 36;
+ Pattern[24].PatternString = "PowerOn";
+ Pattern[25].PatternNumber = 37;
+ Pattern[25].PatternString = "PowerOff";
+ Pattern[26].PatternNumber = 38;
+ Pattern[26].PatternString = "ChargerConnected";
+ Pattern[27].PatternNumber = 40;
+ Pattern[27].PatternString = "ChargingError";
+ Pattern[28].PatternNumber = 42;
+ Pattern[28].PatternString = "FullyCharged";
+ Pattern[29].PatternNumber = 44;
+ Pattern[29].PatternString = "LowBattery";
+ Pattern[30].PatternNumber = 46;
+ Pattern[30].PatternString = "Lock";
+ Pattern[31].PatternNumber = 47;
+ Pattern[31].PatternString = "UnLock";
+ Pattern[32].PatternNumber = 55;
+ Pattern[32].PatternString = "VibrationModeAbled";
+ Pattern[33].PatternNumber = 56;
+ Pattern[33].PatternString = "SilentModeDisabled";
+ Pattern[34].PatternNumber = 57;
+ Pattern[34].PatternString = "BluetoothDeviceConnected";
+ Pattern[35].PatternNumber = 58;
+ Pattern[35].PatternString = "BluetoothDeviceDisconnected";
+ Pattern[36].PatternNumber = 62;
+ Pattern[36].PatternString = "ListReorder";
+ Pattern[37].PatternNumber = 63;
+ Pattern[37].PatternString = "ListSlider";
+ Pattern[38].PatternNumber = 64;
+ Pattern[38].PatternString = "VolumeKeyPressed";
+
+ Interop.Feedback.FeedbackError res = (Interop.Feedback.FeedbackError)Interop.Feedback.Initialize();
+ if (res != Interop.Feedback.FeedbackError.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to initialize feedback. err = {0}", res));
+ switch (res)
+ {
+ case Interop.Feedback.FeedbackError.NotSupported:
+ throw new NotSupportedException("Device is not supported");
+ default:
+ throw new InvalidOperationException("Failed to initialize");
+ }
+ }
+ }
+
+ ~Feedback()
+ {
+ Interop.Feedback.FeedbackError res = (Interop.Feedback.FeedbackError)Interop.Feedback.Deinitialize();
+ if (res != Interop.Feedback.FeedbackError.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to deinitialize feedback. err = {0}", res));
+ switch (res)
+ {
+ case Interop.Feedback.FeedbackError.NotInitialized:
+ throw new Exception("Not initialized");
+ default:
+ throw new InvalidOperationException("Failed to initialize");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Get supported information about specific type and pattern
+ /// </summary>
+ /// <remarks>
+ /// Now, IsSupportedPattern is not working for FeedbackType.All.
+ /// This API is working for FeedbackType.Sound and FeedbackType.Vibration only.
+ /// If you use FeedbackType.All for type parameter, this API will throw ArgumentException.
+ /// To get supported information for Vibration type, app should have http://tizen.org/privilege/haptic privilege.
+ /// </remarks>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="type">Feedback type</param>
+ /// <param name="pattern">Feedback pattern string</param>
+ /// <returns>Information whether pattern is supported</returns>
+ /// <exception cref="Exception">Thrown when failed because feedback is not initialized</exception>
+ /// <exception cref="ArgumentException">Thrown when failed because of a invalid arguament</exception>
+ /// <exception cref="NotSupportedException">Thrown when failed becuase device(haptic, sound) is not supported</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when failed because access is not granted(No privilege)</exception>
+ /// <exception cref="InvalidOperationException">Thrown when failed because of system error</exception>
+ /// <privilege>http://tizen.org/privilege/haptic</privilege>
+ /// <example>
+ /// <code>
+ /// Feedback feedback = new Feedback();
+ /// bool res = feedback.IsSupportedPattern(FeedbackType.Vibration, "Tap");
+ /// </code>
+ /// </example>
+ public bool IsSupportedPattern(FeedbackType type, String pattern)
+ {
+ bool supported = false;
+ bool found = false;
+ int i = 0;
+ Interop.Feedback.FeedbackError res;
+
+ for (i = 0; i < Constants.NumberOfPattern; i++)
+ {
+ if (String.Compare(pattern, Pattern[i].PatternString) == 0)
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ throw new ArgumentException("Invalid Arguments");
+
+ res = (Interop.Feedback.FeedbackError)Interop.Feedback.IsSupportedPattern((Interop.Feedback.FeedbackType)type, Pattern[i].PatternNumber, out supported);
+
+
+ if (res != Interop.Feedback.FeedbackError.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to get supported information. err = {0}", res));
+ switch (res)
+ {
+ case Interop.Feedback.FeedbackError.NotInitialized:
+ throw new Exception("Not initialized");
+ case Interop.Feedback.FeedbackError.InvalidParameter:
+ throw new ArgumentException("Invalid Arguments");
+ case Interop.Feedback.FeedbackError.NotSupported:
+ throw new NotSupportedException("Device is not supported");
+ case Interop.Feedback.FeedbackError.PermissionDenied:
+ throw new UnauthorizedAccessException("Access is not granted");
+ case Interop.Feedback.FeedbackError.OperationFailed:
+ default:
+ throw new InvalidOperationException("Failed to get supported information");
+ }
+ }
+ return supported;
+ }
+
+ /// <summary>
+ /// Play specific feedback pattern
+ /// </summary>
+ /// <remarks>
+ /// To play Vibration type, app should have http://tizen.org/privilege/haptic privilege.
+ /// </remarks>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="type">Feedback type</param>
+ /// <param name="pattern">Feedback pattern string</param>
+ /// <exception cref="Exception">Thrown when failed because feedback is not initialized</exception>
+ /// <exception cref="ArgumentException">Thrown when failed because of a invalid arguament</exception>
+ /// <exception cref="NotSupportedException">Thrown when failed because device(haptic, sound) or specific pattern is not supported</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when failed because access is not granted(No privilege)</exception>
+ /// <exception cref="InvalidOperationException">Thrown when failed because of system error</exception>
+ /// <privilege>http://tizen.org/privilege/haptic</privilege>
+ /// <example>
+ /// <code>
+ /// Feedback feedback = new Feedback();
+ /// feedback.Play(FeedbackType.All, "Tap");
+ /// </code>
+ /// </example>
+ public void Play(FeedbackType type, String pattern)
+ {
+ bool found = false;
+ int i = 0;
+ Interop.Feedback.FeedbackError res;
+
+ for (i = 0; i < Constants.NumberOfPattern; i++)
+ {
+ if (String.Compare(pattern, Pattern[i].PatternString) == 0)
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ throw new ArgumentException("Invalid Arguments");
+
+ if (type == FeedbackType.All)
+ res = (Interop.Feedback.FeedbackError)Interop.Feedback.Play(Pattern[i].PatternNumber);
+ else
+ res = (Interop.Feedback.FeedbackError)Interop.Feedback.PlayType((Interop.Feedback.FeedbackType)type, Pattern[i].PatternNumber);
+
+ if (res != Interop.Feedback.FeedbackError.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to play feedback. err = {0}", res));
+ switch (res)
+ {
+ case Interop.Feedback.FeedbackError.NotInitialized:
+ throw new Exception("Not initialized");
+ case Interop.Feedback.FeedbackError.InvalidParameter:
+ throw new ArgumentException("Invalid Arguments");
+ case Interop.Feedback.FeedbackError.NotSupported:
+ throw new NotSupportedException("Not supported");
+ case Interop.Feedback.FeedbackError.PermissionDenied:
+ throw new UnauthorizedAccessException("Access is not granted");
+ case Interop.Feedback.FeedbackError.OperationFailed:
+ default:
+ throw new InvalidOperationException("Failed to play pattern");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Stop to play feedback
+ /// </summary>
+ /// <remarks>
+ /// To stop vibration, app should have http://tizen.org/privilege/haptic privilege.
+ /// </remarks>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="Exception">Thrown when failed because feedback is not initialized</exception>
+ /// <exception cref="ArgumentException">Thrown when failed because of a invalid arguament</exception>
+ /// <exception cref="NotSupportedException">Thrown when failed because device(haptic, sound) or specific pattern is not supported</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when failed because access is not granted(No privilege)</exception>
+ /// <exception cref="InvalidOperationException">Thrown when failed because of system error</exception>
+ /// <privilege>http://tizen.org/privilege/haptic</privilege>
+ /// <example>
+ /// <code>
+ /// Feedback Feedback1 = new Feedback();
+ /// Feedback1.Stop();
+ /// </code>
+ /// </example>
+ public void Stop()
+ {
+ Interop.Feedback.FeedbackError res = (Interop.Feedback.FeedbackError)Interop.Feedback.Stop();
+
+ if (res != Interop.Feedback.FeedbackError.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to stop feedback. err = {0}", res));
+ switch (res)
+ {
+ case Interop.Feedback.FeedbackError.NotInitialized:
+ throw new Exception("Not initialized");
+ case Interop.Feedback.FeedbackError.InvalidParameter:
+ throw new ArgumentException("Invalid Arguments");
+ case Interop.Feedback.FeedbackError.NotSupported:
+ throw new NotSupportedException("Not supported");
+ case Interop.Feedback.FeedbackError.PermissionDenied:
+ throw new UnauthorizedAccessException("Access is not granted");
+ case Interop.Feedback.FeedbackError.OperationFailed:
+ default:
+ throw new InvalidOperationException("Failed to stop pattern");
+ }
+ }
+ }
+ }
+}
diff --git a/src/Tizen.System.Feedback/Feedback/FeedbackPattern.cs b/src/Tizen.System.Feedback/Feedback/FeedbackPattern.cs
new file mode 100644
index 0000000..2ebc82f
--- /dev/null
+++ b/src/Tizen.System.Feedback/Feedback/FeedbackPattern.cs
@@ -0,0 +1,33 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+namespace Tizen.System
+{
+ /// <summary>
+ /// String and Enumeration for feedback patterns.
+ /// </summary>
+ internal struct FeedbackPattern
+ {
+ internal int PatternNumber;
+ internal string PatternString;
+
+ internal FeedbackPattern(int n, string s)
+ {
+ PatternNumber = n;
+ PatternString = s;
+ }
+ }
+}
diff --git a/src/Tizen.System.Feedback/Feedback/FeedbackType.cs b/src/Tizen.System.Feedback/Feedback/FeedbackType.cs
new file mode 100644
index 0000000..e387b1c
--- /dev/null
+++ b/src/Tizen.System.Feedback/Feedback/FeedbackType.cs
@@ -0,0 +1,41 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+namespace Tizen.System
+{
+ /// <summary>
+ /// Enumeration for feedback device types.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum FeedbackType
+ {
+ /// <summary>
+ /// Sound and Vibration
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ All = 0,
+ /// <summary>
+ /// Sound feedback
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Sound = Interop.Feedback.FeedbackType.Sound,
+ /// <summary>
+ /// Vibration
+ /// /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Vibration = Interop.Feedback.FeedbackType.Vibration,
+ }
+}
diff --git a/src/Tizen.System.Feedback/Interop/Interop.Feedback.cs b/src/Tizen.System.Feedback/Interop/Interop.Feedback.cs
new file mode 100644
index 0000000..6b3e572
--- /dev/null
+++ b/src/Tizen.System.Feedback/Interop/Interop.Feedback.cs
@@ -0,0 +1,59 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Feedback
+ {
+ internal enum FeedbackError
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None,
+ OperationFailed = Tizen.Internals.Errors.ErrorCode.NotPermitted,
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+ NotSupported = Tizen.Internals.Errors.ErrorCode.NoSuchDevice,
+ PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied,
+ NotInitialized = -0x00020000 | 0x12,
+ }
+
+ // Any change here might require changes in Tizen.System.FeedbackType enum
+ internal enum FeedbackType
+ {
+ Sound = 1,
+ Vibration = 2,
+ }
+
+ [DllImport(Libraries.Feedback, EntryPoint = "feedback_initialize")]
+ internal static extern int Initialize();
+
+ [DllImport(Libraries.Feedback, EntryPoint = "feedback_deinitialize")]
+ internal static extern int Deinitialize();
+
+ [DllImport(Libraries.Feedback, EntryPoint = "feedback_play")]
+ internal static extern int Play(int pattern);
+
+ [DllImport(Libraries.Feedback, EntryPoint = "feedback_play_type")]
+ internal static extern int PlayType(FeedbackType type, int pattern);
+
+ [DllImport(Libraries.Feedback, EntryPoint = "feedback_stop")]
+ internal static extern int Stop();
+
+ [DllImport(Libraries.Feedback, EntryPoint = "feedback_is_supported_pattern")]
+ internal static extern int IsSupportedPattern(FeedbackType type, int pattern, out bool supported);
+ }
+}
diff --git a/src/Tizen.System.Feedback/Interop/Interop.Libraries.cs b/src/Tizen.System.Feedback/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..c84daae
--- /dev/null
+++ b/src/Tizen.System.Feedback/Interop/Interop.Libraries.cs
@@ -0,0 +1,23 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ internal const string Feedback = "libfeedback.so.0";
+ }
+}
diff --git a/src/Tizen.System.Feedback/Tizen.System.Feedback.csproj b/src/Tizen.System.Feedback/Tizen.System.Feedback.csproj
new file mode 100644
index 0000000..d5717a4
--- /dev/null
+++ b/src/Tizen.System.Feedback/Tizen.System.Feedback.csproj
@@ -0,0 +1,15 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
+
diff --git a/src/Tizen.System.Information/Interop/Interop.Libraries.cs b/src/Tizen.System.Information/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..ddb1884
--- /dev/null
+++ b/src/Tizen.System.Information/Interop/Interop.Libraries.cs
@@ -0,0 +1,24 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ internal const string RuntimeInfo = "libcapi-system-runtime-info.so.0";
+ internal const string SystemInfo = "libcapi-system-info.so.0";
+ }
+}
diff --git a/src/Tizen.System.Information/Interop/Interop.RuntimeInfo.cs b/src/Tizen.System.Information/Interop/Interop.RuntimeInfo.cs
new file mode 100644
index 0000000..21ab05e
--- /dev/null
+++ b/src/Tizen.System.Information/Interop/Interop.RuntimeInfo.cs
@@ -0,0 +1,104 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.System;
+
+internal static partial class Interop
+{
+ internal static partial class RuntimeInfo
+ {
+ public delegate void RuntimeInformationChangedCallback(RuntimeInformationKey key, IntPtr userData);
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct MemoryInfo
+ {
+ public readonly int Total;
+ public readonly int Used;
+ public readonly int Free;
+ public readonly int Cache;
+ public readonly int Swap;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct ProcessMemoryInfo
+ {
+ public readonly int Vsz;
+ public readonly int Rss;
+ public readonly int Pss;
+ public readonly int SharedClean;
+ public readonly int SharedDirty;
+ public readonly int PrivateClean;
+ public readonly int PrivateDirty;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct CpuUsage
+ {
+ public readonly double User;
+ public readonly double System;
+ public readonly double Nice;
+ public readonly double IoWait;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct ProcessCpuUsage
+ {
+ public readonly uint UTime;
+ public readonly uint STime;
+ }
+
+ [DllImport(Libraries.RuntimeInfo, EntryPoint = "runtime_info_get_value_int")]
+ public static extern int GetValue(RuntimeInformationKey key, out int status);
+
+ [DllImport(Libraries.RuntimeInfo, EntryPoint = "runtime_info_get_value_bool")]
+ public static extern int GetValue(RuntimeInformationKey key, out bool status);
+
+ [DllImport(Libraries.RuntimeInfo, EntryPoint = "runtime_info_get_value_double")]
+ public static extern int GetValue(RuntimeInformationKey key, out double status);
+
+ [DllImport(Libraries.RuntimeInfo, EntryPoint = "runtime_info_get_value_string")]
+ public static extern int GetValue(RuntimeInformationKey key, out string status);
+
+ [DllImport(Libraries.RuntimeInfo, EntryPoint = "runtime_info_get_system_memory_info")]
+ public static extern int GetSystemMemoryInfo(out MemoryInfo memoryInfo);
+
+ [DllImport(Libraries.RuntimeInfo, EntryPoint = "runtime_info_get_process_memory_info")]
+ public static extern int GetProcessMemoryInfo(int[] pid, int size, out ProcessMemoryInfo[] array);
+
+ [DllImport(Libraries.RuntimeInfo, EntryPoint = "runtime_info_get_cpu_usage")]
+ public static extern int GetCpuUsage(out CpuUsage cpuUsage);
+
+ [DllImport(Libraries.RuntimeInfo, EntryPoint = "runtime_info_get_process_cpu_usage")]
+ public static extern int GetProcessCpuUsage(int[] pid, int size, out ProcessCpuUsage[] array);
+
+ [DllImport(Libraries.RuntimeInfo, EntryPoint = "runtime_info_get_processor_count")]
+ public static extern int GetProcessorCount(out int processorCount);
+
+ [DllImport(Libraries.RuntimeInfo, EntryPoint = "runtime_info_get_processor_current_frequency")]
+ public static extern int GetProcessorCurrentFrequency(int coreId, out int cpuFreq);
+
+ [DllImport(Libraries.RuntimeInfo, EntryPoint = "runtime_info_get_processor_max_frequency")]
+ public static extern int GetProcessorMaxFrequency(int coreId, out int cpuFreq);
+
+ [DllImport(Libraries.RuntimeInfo, EntryPoint = "runtime_info_set_changed_cb")]
+ public static extern int SetRuntimeInfoChangedCallback(RuntimeInformationKey runtimeInfoKey, RuntimeInformationChangedCallback cb, IntPtr userData);
+
+ [DllImport(Libraries.RuntimeInfo, EntryPoint = "runtime_info_unset_changed_cb")]
+ public static extern int UnsetRuntimeInfoChangedCallback(RuntimeInformationKey runtimeInfoKey);
+ }
+}
diff --git a/src/Tizen.System.Information/Interop/Interop.SystemInfo.cs b/src/Tizen.System.Information/Interop/Interop.SystemInfo.cs
new file mode 100644
index 0000000..de7282e
--- /dev/null
+++ b/src/Tizen.System.Information/Interop/Interop.SystemInfo.cs
@@ -0,0 +1,79 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class SystemInfo
+ {
+ internal enum ErrorCode
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None,
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+ OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
+ IoError = Tizen.Internals.Errors.ErrorCode.IoError,
+ PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied,
+ NotSupported = Tizen.Internals.Errors.ErrorCode.NoSuchDevice,
+ }
+
+ internal enum SystemInfoValueType
+ {
+ Bool = 0,
+ Int = 1,
+ Double = 2,
+ String = 3,
+ }
+
+ internal enum SystemInfoType
+ {
+ platform,
+ Custom,
+ None,
+ }
+
+ [DllImport(Libraries.SystemInfo, EntryPoint = "system_info_get_platform_type")]
+ internal static extern ErrorCode SystemInfoGetPlatformType(string key, out SystemInfoValueType type);
+
+ [DllImport(Libraries.SystemInfo, EntryPoint = "system_info_get_custom_type")]
+ internal static extern ErrorCode SystemInfoGetCustomType(string key, out SystemInfoValueType type);
+
+ [DllImport(Libraries.SystemInfo, EntryPoint = "system_info_get_platform_bool")]
+ internal static extern ErrorCode SystemInfoGetPlatformBool(string key, out bool value);
+
+ [DllImport(Libraries.SystemInfo, EntryPoint = "system_info_get_platform_int")]
+ internal static extern ErrorCode SystemInfoGetPlatformInt(string key, out int value);
+
+ [DllImport(Libraries.SystemInfo, EntryPoint = "system_info_get_platform_double")]
+ internal static extern ErrorCode SystemInfoGetPlatformDouble(string key, out double value);
+
+ [DllImport(Libraries.SystemInfo, EntryPoint = "system_info_get_platform_string")]
+ internal static extern ErrorCode SystemInfoGetPlatformString(string key, out string value);
+
+ [DllImport(Libraries.SystemInfo, EntryPoint = "system_info_get_custom_bool")]
+ internal static extern ErrorCode SystemInfoGetCustomBool(string key, out bool value);
+
+ [DllImport(Libraries.SystemInfo, EntryPoint = "system_info_get_custom_int")]
+ internal static extern ErrorCode SystemInfoGetCustomInt(string key, out int value);
+
+ [DllImport(Libraries.SystemInfo, EntryPoint = "system_info_get_custom_double")]
+ internal static extern ErrorCode SystemInfoGetCustomDouble(string key, out double value);
+
+ [DllImport(Libraries.SystemInfo, EntryPoint = "system_info_get_custom_string")]
+ internal static extern ErrorCode SystemInfoGetCustomString(string key, out string value);
+ }
+}
diff --git a/src/Tizen.System.Information/RuntimeInfo/CpuUsage.cs b/src/Tizen.System.Information/RuntimeInfo/CpuUsage.cs
new file mode 100755
index 0000000..813036c
--- /dev/null
+++ b/src/Tizen.System.Information/RuntimeInfo/CpuUsage.cs
@@ -0,0 +1,77 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.ComponentModel;
+
+namespace Tizen.System
+{
+ /// <summary>
+ /// Structure for CPU usage.
+ /// </summary>
+ public class CpuUsage
+ {
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ internal CpuUsage(Interop.RuntimeInfo.CpuUsage usage)
+ {
+ IoWait = usage.IoWait;
+ Nice = usage.IoWait;
+ System = usage.System;
+ User = usage.User;
+ }
+ /// <summary>
+ /// Time running un-niced user processes (Percent)
+ /// </summary>
+ public double User { get; internal set; }
+ /// <summary>
+ /// Time running kernel processes (Percent)
+ /// </summary>
+ public double System { get; internal set; }
+ /// <summary>
+ /// Time running niced user processes (Percent)
+ /// </summary>
+ public double Nice { get; internal set; }
+ /// <summary>
+ /// Time waiting for I/O completion (Percent)
+ /// </summary>
+ public double IoWait { get; internal set; }
+ }
+
+ /// <summary>
+ /// Structure for CPU usage per processes
+ /// </summary>
+ public class ProcessCpuUsage
+ {
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ internal ProcessCpuUsage(Interop.RuntimeInfo.ProcessCpuUsage usage)
+ {
+ UTime = usage.UTime;
+ STime = usage.STime;
+ }
+ /// <summary>
+ /// Amount of time that this process has been scheduled in user mode (clock ticks)
+ /// </summary>
+ public uint UTime { get; internal set; }
+ /// <summary>
+ /// Amount of time that this process has been scheduled in kernel mode (clock ticks)
+ /// </summary>
+ public uint STime { get; internal set; }
+ }
+}
diff --git a/src/Tizen.System.Information/RuntimeInfo/Enumerations.cs b/src/Tizen.System.Information/RuntimeInfo/Enumerations.cs
new file mode 100755
index 0000000..c35afeb
--- /dev/null
+++ b/src/Tizen.System.Information/RuntimeInfo/Enumerations.cs
@@ -0,0 +1,143 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+
+namespace Tizen.System
+{
+ /// <summary>
+ /// Enumeration for keys for runtime information
+ /// </summary>
+ public enum RuntimeInformationKey
+ {
+ /// <summary>
+ /// Indicates whether Bluetooth is enabled.
+ /// </summary>
+ Bluetooth = 2,
+ /// <summary>
+ /// Indicates whether Wi-Fi hotspot is enabled.
+ /// <see cref="WifiStatus"/>
+ /// </summary>
+ WifiHotspot = 3,
+ /// <summary>
+ /// Indicates whether Bluetooth tethering is enabled.
+ /// </summary>
+ BluetoothTethering = 4,
+ /// <summary>
+ /// Indicates whether USB tethering is enabled.
+ /// </summary>
+ UsbTethering = 5,
+ /// <summary>
+ /// Indicates Whether the packet data through 3G network is enabled.
+ /// </summary>
+ PacketData = 9,
+ /// <summary>
+ /// Indicates whether data roaming is enabled.
+ /// </summary>
+ DataRoaming = 10,
+ /// <summary>
+ /// Indicates whether vibration is enabled.
+ /// </summary>
+ Vibration = 12,
+ /// <summary>
+ /// Indicates whether audio jack is connected.
+ /// </summary>
+ AudioJack = 17,
+ /// <summary>
+ /// Indicates the current status of GPS.
+ /// <see cref="GpsStatus"/>
+ /// </summary>
+ Gps = 18,
+ /// <summary>
+ /// Indicates the battery is currently charging.
+ /// </summary>
+ BatteryIsCharging = 19,
+ /// <summary>
+ /// Indicates whether TV out is connected.
+ /// </summary>
+ TvOut = 20,
+ /// <summary>
+ /// Indicates the change in audio jack connector type.
+ /// <see cref="AudioJackConnectionType"/>
+ /// </summary>
+ AudioJackConnector = 21,
+ /// <summary>
+ /// Indicates whether charger is connected.
+ /// </summary>
+ Charger = 24,
+ /// <summary>
+ /// Indicates whether auto rotation is enabled.
+ /// </summary>
+ AutoRotation = 26
+ }
+
+ /// <summary>
+ /// Enumeration for Wi-Fi status
+ /// </summary>
+ public enum WifiStatus
+ {
+ /// <summary>
+ /// Wi-Fi is disabled.
+ /// </summary>
+ Disabled,
+ /// <summary>
+ /// Wi-Fi is enabled and network connection is not established.
+ /// </summary>
+ Unconnected,
+ /// <summary>
+ /// Network connection is established in Wi-Fi network.
+ /// </summary>
+ Connected
+ }
+
+ /// <summary>
+ /// Enumeration for GPS status.
+ /// </summary>
+ public enum GpsStatus
+ {
+ /// <summary>
+ /// GPS is disabled.
+ /// </summary>
+ Disabled,
+ /// <summary>
+ /// GPS is searching for satellites.
+ /// </summary>
+ Searching,
+ /// <summary>
+ /// GPS connection is established.
+ /// </summary>
+ Connected
+ }
+
+ /// <summary>
+ /// Enumeration for type of audio jack connected.
+ /// </summary>
+ public enum AudioJackConnectionType
+ {
+ /// <summary>
+ /// Audio jack is not connected
+ /// </summary>
+ Unconnected,
+ /// <summary>
+ /// 3-conductor wire is connected.
+ /// </summary>
+ ThreeWireConnected,
+ /// <summary>
+ /// 4-conductor wire is connected.
+ /// </summary>
+ FourWireConnected
+ }
+}
diff --git a/src/Tizen.System.Information/RuntimeInfo/MemoryInformation.cs b/src/Tizen.System.Information/RuntimeInfo/MemoryInformation.cs
new file mode 100755
index 0000000..64d6713
--- /dev/null
+++ b/src/Tizen.System.Information/RuntimeInfo/MemoryInformation.cs
@@ -0,0 +1,107 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.ComponentModel;
+
+namespace Tizen.System
+{
+ /// <summary>
+ /// Memory information.
+ /// </summary>
+ public class SystemMemoryInformation
+ {
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ internal SystemMemoryInformation(Interop.RuntimeInfo.MemoryInfo info)
+ {
+ Total = info.Total;
+ Used = info.Used;
+ Cache = info.Cache;
+ Free = info.Free;
+ Swap = info.Swap;
+ }
+ /// <summary>
+ /// Total memory (KiB)
+ /// </summary>
+ public int Total { get; internal set; }
+ /// <summary>
+ /// Used memory (KiB)
+ /// </summary>
+ public int Used { get; internal set; }
+ /// <summary>
+ /// Free memory (KiB)
+ /// </summary>
+ public int Free { get; internal set; }
+ /// <summary>
+ /// Cache memory (KiB)
+ /// </summary>
+ public int Cache { get; internal set; }
+ /// <summary>
+ /// Swap memory (KiB)
+ /// </summary>
+ public int Swap { get; internal set; }
+ }
+
+ /// <summary>
+ /// Memory information per processes
+ /// </summary>
+ public class ProcessMemoryInformation
+ {
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ internal ProcessMemoryInformation(Interop.RuntimeInfo.ProcessMemoryInfo info)
+ {
+ PrivateClean = info.PrivateClean;
+ PrivateDirty = info.PrivateDirty;
+ Pss = info.Pss;
+ Rss = info.Rss;
+ SharedClean = info.SharedClean;
+ SharedDirty = info.SharedDirty;
+ Vsz = info.Vsz;
+ }
+ /// <summary>
+ /// Virtual memory size (KiB)
+ /// </summary>
+ public int Vsz { get; internal set; }
+ /// <summary>
+ /// Resident set size (KiB)
+ /// </summary>
+ public int Rss { get; internal set; }
+ /// <summary>
+ /// Proportional set size (KiB)
+ /// </summary>
+ public int Pss { get; internal set; }
+ /// <summary>
+ /// Not modified and mapped by other processes (KiB)
+ /// </summary>
+ public int SharedClean { get; internal set; }
+ /// <summary>
+ /// Modified and mapped by other processes (KiB)
+ /// </summary>
+ public int SharedDirty { get; internal set; }
+ /// <summary>
+ /// Not modified and available only to that process (KiB)
+ /// </summary>
+ public int PrivateClean { get; internal set; }
+ /// <summary>
+ /// Modified and available only to that process (KiB)
+ /// </summary>
+ public int PrivateDirty { get; internal set; }
+ }
+}
diff --git a/src/Tizen.System.Information/RuntimeInfo/RuntimeInfoErrorFactory.cs b/src/Tizen.System.Information/RuntimeInfo/RuntimeInfoErrorFactory.cs
new file mode 100755
index 0000000..e9fee57
--- /dev/null
+++ b/src/Tizen.System.Information/RuntimeInfo/RuntimeInfoErrorFactory.cs
@@ -0,0 +1,75 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.IO;
+using System.ComponentModel;
+using Tizen.Internals.Errors;
+
+namespace Tizen.System
+{
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ internal enum RuntimeInfoError
+ {
+ None = ErrorCode.None,
+ InvalidParameter = ErrorCode.InvalidParameter,
+ OutOfMemory = ErrorCode.OutOfMemory,
+ Io = ErrorCode.IoError,
+ RemoteIo = ErrorCode.RemoteIo,
+ PermissionDenied = ErrorCode.PermissionDenied,
+ NotSupported = ErrorCode.NotSupported,
+ NoData = ErrorCode.NoData
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ internal static class RuntimeInfoErrorFactory
+ {
+ internal const string LogTag = "Tizen.System.RuntimeInformation";
+
+ internal static void ThrowException(int err)
+ {
+ RuntimeInfoError error = (RuntimeInfoError)err;
+ if (error == RuntimeInfoError.InvalidParameter)
+ {
+ throw new ArgumentException("Invalid parameter");
+ }
+ else if (error == RuntimeInfoError.OutOfMemory)
+ {
+ throw new OutOfMemoryException("Out of memory");
+ }
+ else if (error == RuntimeInfoError.Io)
+ {
+ throw new IOException("I/O Error");
+ }
+ else if (error == RuntimeInfoError.RemoteIo)
+ {
+ throw new IOException("Remote I/O Error");
+ }
+ else if (error == RuntimeInfoError.PermissionDenied)
+ {
+ throw new UnauthorizedAccessException("Permission denied");
+ }
+ else if (error == RuntimeInfoError.NotSupported)
+ {
+ throw new NotSupportedException("Not supported");
+ }
+ else if (error == RuntimeInfoError.NoData)
+ {
+ throw new NotSupportedException("No data");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.System.Information/RuntimeInfo/RuntimeInformation.cs b/src/Tizen.System.Information/RuntimeInfo/RuntimeInformation.cs
new file mode 100755
index 0000000..bf5fea6
--- /dev/null
+++ b/src/Tizen.System.Information/RuntimeInfo/RuntimeInformation.cs
@@ -0,0 +1,891 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.ComponentModel;
+
+namespace Tizen.System
+{
+ /// <summary>
+ /// The RuntimeInformation provides functions to obtain runtime information of various system preferences.
+ /// </summary>
+ public static class RuntimeInformation
+ {
+ private static event EventHandler<RuntimeKeyStatusChangedEventArgs> s_bluetoothEnabled;
+ private static event EventHandler<RuntimeKeyStatusChangedEventArgs> s_wifiHotspotEnabled;
+ private static event EventHandler<RuntimeKeyStatusChangedEventArgs> s_bluetoothTetheringEnabled;
+ private static event EventHandler<RuntimeKeyStatusChangedEventArgs> s_usbTetheringEnabled;
+ private static event EventHandler<RuntimeKeyStatusChangedEventArgs> s_packetDataEnabled;
+ private static event EventHandler<RuntimeKeyStatusChangedEventArgs> s_dataRoamingEnabled;
+ private static event EventHandler<RuntimeKeyStatusChangedEventArgs> s_vibrationEnabled;
+ private static event EventHandler<RuntimeKeyStatusChangedEventArgs> s_audioJackConnected;
+ private static event EventHandler<RuntimeKeyStatusChangedEventArgs> s_gpsStatusChanged;
+ private static event EventHandler<RuntimeKeyStatusChangedEventArgs> s_batteryIsCharging;
+ private static event EventHandler<RuntimeKeyStatusChangedEventArgs> s_tvOutConnected;
+ private static event EventHandler<RuntimeKeyStatusChangedEventArgs> s_audioJackConnectorChanged;
+ private static event EventHandler<RuntimeKeyStatusChangedEventArgs> s_chargerConnected;
+ private static event EventHandler<RuntimeKeyStatusChangedEventArgs> s_autoRotationEnabled;
+
+ private static readonly Interop.RuntimeInfo.RuntimeInformationChangedCallback s_runtimeInfoChangedCallback = (RuntimeInformationKey key, IntPtr userData) =>
+ {
+ RuntimeKeyStatusChangedEventArgs eventArgs = new RuntimeKeyStatusChangedEventArgs()
+ {
+ Key = key
+ };
+ switch (key)
+ {
+ case RuntimeInformationKey.Bluetooth:
+ {
+ s_bluetoothEnabled?.Invoke(null, eventArgs);
+ break;
+ };
+ case RuntimeInformationKey.WifiHotspot:
+ {
+ s_wifiHotspotEnabled?.Invoke(null, eventArgs);
+ break;
+ };
+ case RuntimeInformationKey.BluetoothTethering:
+ {
+ s_bluetoothTetheringEnabled?.Invoke(null, eventArgs);
+ break;
+ };
+ case RuntimeInformationKey.UsbTethering:
+ {
+ s_usbTetheringEnabled?.Invoke(null, eventArgs);
+ break;
+ };
+ case RuntimeInformationKey.PacketData:
+ {
+ s_packetDataEnabled?.Invoke(null, eventArgs);
+ break;
+ };
+ case RuntimeInformationKey.DataRoaming:
+ {
+ s_dataRoamingEnabled?.Invoke(null, eventArgs);
+ break;
+ };
+ case RuntimeInformationKey.Vibration:
+ {
+ s_vibrationEnabled?.Invoke(null, eventArgs);
+ break;
+ };
+ case RuntimeInformationKey.AudioJack:
+ {
+ s_audioJackConnected?.Invoke(null, eventArgs);
+ break;
+ };
+ case RuntimeInformationKey.Gps:
+ {
+ s_gpsStatusChanged?.Invoke(null, eventArgs);
+ break;
+ };
+ case RuntimeInformationKey.BatteryIsCharging:
+ {
+ s_batteryIsCharging?.Invoke(null, eventArgs);
+ break;
+ };
+ case RuntimeInformationKey.TvOut:
+ {
+ s_tvOutConnected?.Invoke(null, eventArgs);
+ break;
+ };
+ case RuntimeInformationKey.AudioJackConnector:
+ {
+ s_audioJackConnectorChanged?.Invoke(null, eventArgs);
+ break;
+ };
+ case RuntimeInformationKey.Charger:
+ {
+ s_chargerConnected?.Invoke(null, eventArgs);
+ break;
+ };
+ case RuntimeInformationKey.AutoRotation:
+ {
+ s_autoRotationEnabled?.Invoke(null, eventArgs);
+ break;
+ };
+ default:
+ break;
+ };
+ };
+
+ internal static readonly Dictionary<RuntimeInformationKey, Type> s_keyDataTypeMapping = new Dictionary<RuntimeInformationKey, Type>
+ {
+ [RuntimeInformationKey.Bluetooth] = typeof(bool),
+ [RuntimeInformationKey.WifiHotspot] = typeof(bool),
+ [RuntimeInformationKey.BluetoothTethering] = typeof(bool),
+ [RuntimeInformationKey.UsbTethering] = typeof(bool),
+ [RuntimeInformationKey.PacketData] = typeof(bool),
+ [RuntimeInformationKey.DataRoaming] = typeof(bool),
+ [RuntimeInformationKey.Vibration] = typeof(bool),
+ [RuntimeInformationKey.AudioJack] = typeof(bool),
+ [RuntimeInformationKey.BatteryIsCharging] = typeof(bool),
+ [RuntimeInformationKey.TvOut] = typeof(bool),
+ [RuntimeInformationKey.Charger] = typeof(bool),
+ [RuntimeInformationKey.AutoRotation] = typeof(bool),
+ [RuntimeInformationKey.Gps] = typeof(int),
+ [RuntimeInformationKey.AudioJackConnector] = typeof(int)
+ };
+
+ internal static readonly Dictionary<RuntimeInformationKey, int> s_keyTVkeyMapping = new Dictionary<RuntimeInformationKey, int>
+ {
+ [RuntimeInformationKey.Bluetooth] = 5,
+ [RuntimeInformationKey.WifiHotspot] = 6,
+ [RuntimeInformationKey.BluetoothTethering] = 7,
+ [RuntimeInformationKey.UsbTethering] = 8,
+ [RuntimeInformationKey.PacketData] = 13,
+ [RuntimeInformationKey.DataRoaming] = 14,
+ [RuntimeInformationKey.Vibration] = 16,
+ [RuntimeInformationKey.AudioJack] = 20,
+ [RuntimeInformationKey.BatteryIsCharging] = 22,
+ [RuntimeInformationKey.TvOut] = 18,
+ [RuntimeInformationKey.Charger] = 26,
+ [RuntimeInformationKey.AutoRotation] = 28,
+ [RuntimeInformationKey.Gps] = 21,
+ [RuntimeInformationKey.AudioJackConnector] = 20
+ };
+
+ internal static int is_TV_product = -1;
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ /// This function is for TV product. It will be removed
+ internal static RuntimeInformationKey ConvertKeyIfTvProduct(RuntimeInformationKey key)
+ {
+ bool is_key_existed = false;
+ string profile;
+ int key_TV = -1;
+
+ if (is_TV_product == -1)
+ {
+ is_key_existed = SystemInfo.TryGetValue<string>("http://com.samsung/build_config/product_type", out profile);
+ if (is_key_existed && String.Compare(profile, "TV") == 0)
+ {
+ is_TV_product = 1;
+ }
+ else
+ {
+ is_TV_product = 0;
+ }
+ }
+
+ if (is_TV_product == 0)
+ {
+ return key;
+ }
+ else
+ {
+ if (!s_keyTVkeyMapping.TryGetValue(key, out key_TV))
+ {
+ RuntimeInfoErrorFactory.ThrowException((int)RuntimeInfoError.InvalidParameter);
+ }
+ return (RuntimeInformationKey)key_TV;
+ }
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ internal static object GetStatus(RuntimeInformationKey key)
+ {
+ Type value;
+ if (!s_keyDataTypeMapping.TryGetValue(key, out value))
+ {
+ RuntimeInfoErrorFactory.ThrowException((int)RuntimeInfoError.InvalidParameter);
+ }
+
+ if (s_keyDataTypeMapping[key] == typeof(int))
+ {
+ int status;
+ int ret = Interop.RuntimeInfo.GetValue(ConvertKeyIfTvProduct(key), out status);
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to get value for key {0}", key.ToString());
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+
+ return status;
+ }
+ else
+ {
+ bool status;
+ int ret = Interop.RuntimeInfo.GetValue(ConvertKeyIfTvProduct(key), out status);
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to get value for key {0}", key.ToString());
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+
+ return status;
+ }
+ }
+
+ /// <summary>
+ /// Validates the data type of the status represented by Runtime Key.
+ /// Note that this is a generic method.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <typeparam name="T">The generic type to validate.</typeparam>
+ /// <param name="key">The runtime information key for which the status type is validated </param>
+ /// <returns>true if the data type matches</returns>.
+ /// <exception cref="ArgumentException">Thrown when the <paramref name="key"/> is invalid.</exception>
+ public static bool Is<T>(RuntimeInformationKey key)
+ {
+ if (!s_keyDataTypeMapping.ContainsKey(key))
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Invalid data type");
+ throw new ArgumentException("Invalid parameter");
+ }
+
+ return s_keyDataTypeMapping[key] == typeof(T);
+ }
+
+ /// <summary>
+ /// Gets the status of Runtime Key.
+ /// Note that this is a generic method.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <typeparam name="T">The generic type to return.</typeparam>
+ /// <param name="key">The runtime information key for which the current should be read </param>
+ /// <returns>The current status of the given key</returns>.
+ /// <exception cref="ArgumentException">Thrown when the <paramref name="key"/> is invalid.</exception>
+ /// <exception cref="IOException">Thrown when I/O error is occurred while reading from system.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the feature related <paramref name="key"/> is not supported.</exception>
+ public static T GetStatus<T>(RuntimeInformationKey key)
+ {
+ return (T)GetStatus(key);
+ }
+
+ /// <summary>
+ /// Gets system memory information
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <returns>The system memory information structure.</returns>
+ /// <exception cref="IOException">Thrown when I/O error is occurred while reading from system.</exception>
+ public static SystemMemoryInformation GetSystemMemoryInformation()
+ {
+ Interop.RuntimeInfo.MemoryInfo info = new Interop.RuntimeInfo.MemoryInfo();
+ int ret = Interop.RuntimeInfo.GetSystemMemoryInfo(out info);
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to get System memory information");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+
+ return new SystemMemoryInformation(info);
+ }
+
+ /// <summary>
+ /// Gets memory information per processes
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="pid">List of unique process ids </param>
+ /// <returns>List of memory information per processes</returns>
+ /// <privilege>http://tizen.org/privilege/systemmonitor</privilege>
+ /// <exception cref="ArgumentException">Thrown when the <paramref name="pid"/> is empty.</exception>
+ /// <exception cref="IOException">Thrown when I/O error is occurred while reading from system or requesting to resource management daemon.</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when the memory is not enough to allocate.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when caller doesn't have a privilege to use this method.</exception>
+ public static IDictionary<int, ProcessMemoryInformation> GetProcessMemoryInformation(IEnumerable<int> pid)
+ {
+ int[] processArray = pid.ToArray<int>();
+ Interop.RuntimeInfo.ProcessMemoryInfo[] processMemoryArray = new Interop.RuntimeInfo.ProcessMemoryInfo[pid.Count<int>()];
+ Dictionary<int, ProcessMemoryInformation> map = new Dictionary<int, ProcessMemoryInformation>();
+ int ret = Interop.RuntimeInfo.GetProcessMemoryInfo(processArray, pid.Count<int>(), out processMemoryArray);
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to get Process memory information");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+
+ int idx = 0;
+ foreach (Interop.RuntimeInfo.ProcessMemoryInfo cur in processMemoryArray)
+ {
+ ProcessMemoryInformation processMemory = new ProcessMemoryInformation(cur);
+ map.Add(processArray[idx], processMemory);
+ idx++;
+ }
+
+ return map;
+ }
+
+ /// <summary>
+ /// Gets system CPU usage time
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <returns>The system CPU usage time structure.</returns>
+ /// <exception cref="IOException">Thrown when I/O error is occurred while reading from system.</exception>
+ public static CpuUsage GetCpuUsage()
+ {
+ Interop.RuntimeInfo.CpuUsage usage = new Interop.RuntimeInfo.CpuUsage();
+ int ret = Interop.RuntimeInfo.GetCpuUsage(out usage);
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to get cpu usage");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ return new CpuUsage(usage);
+ }
+
+ /// <summary>
+ /// Gets the CPU usage time per process
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="pid">List of unique process ids </param>
+ /// <returns>List of CPU usage information per processes</returns>
+ /// <privilege>http://tizen.org/privilege/systemmonitor</privilege>
+ /// <exception cref="ArgumentException">Thrown when the <paramref name="pid"/> is empty.</exception>
+ /// <exception cref="IOException">Thrown when I/O error is occurred while reading from system or requesting to resource management daemon.</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when the memory is not enough to allocate.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when caller doesn't have a privilege to use this method.</exception>
+ public static IDictionary<int, ProcessCpuUsage> GetProcessCpuUsage(IEnumerable<int> pid)
+ {
+ int[] processArray = pid.ToArray<int>();
+ Interop.RuntimeInfo.ProcessCpuUsage[] processCpuUsageArray = new Interop.RuntimeInfo.ProcessCpuUsage[pid.Count<int>()];
+ Dictionary<int, ProcessCpuUsage> map = new Dictionary<int, ProcessCpuUsage>();
+ int ret = Interop.RuntimeInfo.GetProcessCpuUsage(processArray, pid.Count<int>(), out processCpuUsageArray);
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to get Process cpu usage");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+
+ int idx = 0;
+ foreach (Interop.RuntimeInfo.ProcessCpuUsage cur in processCpuUsageArray)
+ {
+ ProcessCpuUsage processUsage = new ProcessCpuUsage(cur);
+ map.Add(processArray[idx], processUsage);
+ idx++;
+ }
+
+ return map;
+ }
+
+ /// <summary>
+ /// Gets the number of processors
+ /// </summary>
+ /// <value>The number of processors</value>
+ /// <exception cref="IOException">Thrown when I/O error is occurred while reading from system.</exception>
+ public static int ProcessorCount
+ {
+ get
+ {
+ int count;
+ int ret = Interop.RuntimeInfo.GetProcessorCount(out count);
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to get Processor count");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+
+ return count;
+ }
+ }
+
+ /// <summary>
+ /// Gets the current frequency of processor
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="coreId">The index (from 0) of CPU core that you want to know the frequency</param>
+ /// <returns>The current frequency(MHz) of processor</returns>
+ /// <exception cref="ArgumentException">Thrown when the <paramref name="coreid"/> is invalid.</exception>
+ /// <exception cref="IOException">Thrown when I/O error is occurred while reading from system.</exception>
+ /// <exception cref="NotSupportedException">Thrown when this system doesn't store CPU current frequency.</exception>
+ public static int GetProcessorCurrentFrequency(int coreId)
+ {
+ int frequency;
+ int ret = Interop.RuntimeInfo.GetProcessorCurrentFrequency(coreId, out frequency);
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to get Processor current frequency");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ return frequency;
+ }
+
+ /// <summary>
+ /// Gets the max frequency of processor
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="coreId">The index (from 0) of CPU core that you want to know the frequency</param>
+ /// <returns>The max frequency(MHz) of processor</returns>
+ /// <exception cref="ArgumentException">Thrown when the <paramref name="coreid"/> is invalid.</exception>
+ /// <exception cref="IOException">Thrown when I/O error is occurred while reading from system.</exception>
+ /// <exception cref="NotSupportedException">Thrown when this system doesn't store CPU max frequency.</exception>
+ public static int GetProcessorMaxFrequency(int coreId)
+ {
+ int frequency;
+ int ret = Interop.RuntimeInfo.GetProcessorMaxFrequency(coreId, out frequency);
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to get Processor max frequency");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ return frequency;
+ }
+
+ /// <summary>
+ /// (event) BluetoothEnabled is raised when system preference for bluetooth is changed.
+ /// </summary>
+ public static event EventHandler<RuntimeKeyStatusChangedEventArgs> BluetoothEnabled
+ {
+ add
+ {
+ if (s_bluetoothEnabled == null)
+ {
+ int ret = Interop.RuntimeInfo.SetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.Bluetooth), s_runtimeInfoChangedCallback, IntPtr.Zero);
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ }
+ s_bluetoothEnabled += value;
+ }
+ remove
+ {
+ s_bluetoothEnabled -= value;
+ if (s_bluetoothEnabled == null)
+ {
+ int ret = Interop.RuntimeInfo.UnsetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.Bluetooth));
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ }
+ }
+ }
+ /// <summary>
+ /// (event) WifiHotspotEnabled is raised when system preference for Wi-Fi is changed.
+ /// </summary>
+ public static event EventHandler<RuntimeKeyStatusChangedEventArgs> WifiHotspotEnabled
+ {
+ add
+ {
+ if (s_wifiHotspotEnabled == null)
+ {
+ int ret = Interop.RuntimeInfo.SetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.WifiHotspot), s_runtimeInfoChangedCallback, IntPtr.Zero);
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ }
+ s_wifiHotspotEnabled += value;
+ }
+ remove
+ {
+ s_wifiHotspotEnabled -= value;
+ if (s_wifiHotspotEnabled == null)
+ {
+ int ret = Interop.RuntimeInfo.UnsetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.WifiHotspot));
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ }
+ }
+ }
+ /// <summary>
+ /// (event) BluetoothTetheringEnabled is raised when system preference for bluetooth tethering is changed.
+ /// </summary>
+ public static event EventHandler<RuntimeKeyStatusChangedEventArgs> BluetoothTetheringEnabled
+ {
+ add
+ {
+ if (s_bluetoothTetheringEnabled == null)
+ {
+ int ret = Interop.RuntimeInfo.SetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.BluetoothTethering), s_runtimeInfoChangedCallback, IntPtr.Zero);
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ }
+ s_bluetoothTetheringEnabled += value;
+ }
+ remove
+ {
+ s_bluetoothTetheringEnabled -= value;
+ if (s_bluetoothTetheringEnabled == null)
+ {
+ int ret = Interop.RuntimeInfo.UnsetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.BluetoothTethering));
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ }
+ }
+ }
+ /// <summary>
+ /// (event) UsbTetheringEnabled is raised when system preference for USB tethering is changed.
+ /// </summary>
+ public static event EventHandler<RuntimeKeyStatusChangedEventArgs> UsbTetheringEnabled
+ {
+ add
+ {
+ if (s_usbTetheringEnabled == null)
+ {
+ int ret = Interop.RuntimeInfo.SetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.UsbTethering), s_runtimeInfoChangedCallback, IntPtr.Zero);
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ }
+ s_usbTetheringEnabled += value;
+ }
+ remove
+ {
+ s_usbTetheringEnabled -= value;
+ if (s_usbTetheringEnabled == null)
+ {
+ int ret = Interop.RuntimeInfo.UnsetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.UsbTethering));
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ }
+ }
+ }
+ /// <summary>
+ /// (event) PacketDataEnabled is raised when system preference for package data through 3G network is changed.
+ /// </summary>
+ public static event EventHandler<RuntimeKeyStatusChangedEventArgs> PacketDataEnabled
+ {
+ add
+ {
+ if (s_packetDataEnabled == null)
+ {
+ int ret = Interop.RuntimeInfo.SetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.PacketData), s_runtimeInfoChangedCallback, IntPtr.Zero);
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ }
+ s_packetDataEnabled += value;
+ }
+ remove
+ {
+ s_packetDataEnabled -= value;
+ if (s_packetDataEnabled == null)
+ {
+ int ret = Interop.RuntimeInfo.UnsetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.PacketData));
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ }
+ }
+ }
+ /// <summary>
+ /// (event) DataRoamingEnabled is raised when system preference for data roaming is changed.
+ /// </summary>
+ public static event EventHandler<RuntimeKeyStatusChangedEventArgs> DataRoamingEnabled
+ {
+ add
+ {
+ if (s_dataRoamingEnabled == null)
+ {
+ int ret = Interop.RuntimeInfo.SetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.DataRoaming), s_runtimeInfoChangedCallback, IntPtr.Zero);
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ }
+ s_dataRoamingEnabled += value;
+ }
+ remove
+ {
+ s_dataRoamingEnabled -= value;
+ if (s_dataRoamingEnabled == null)
+ {
+ int ret = Interop.RuntimeInfo.UnsetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.DataRoaming));
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ }
+ }
+ }
+ /// <summary>
+ /// (event) VibrationEnabled is raised when system preference for vibration is changed.
+ /// </summary>
+ public static event EventHandler<RuntimeKeyStatusChangedEventArgs> VibrationEnabled
+ {
+ add
+ {
+ if (s_vibrationEnabled == null)
+ {
+ int ret = Interop.RuntimeInfo.SetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.Vibration), s_runtimeInfoChangedCallback, IntPtr.Zero);
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ }
+ s_vibrationEnabled += value;
+ }
+ remove
+ {
+ s_vibrationEnabled -= value;
+ if (s_vibrationEnabled == null)
+ {
+ int ret = Interop.RuntimeInfo.UnsetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.Vibration));
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ }
+ }
+ }
+ /// <summary>
+ /// (event) AudioJackConnected is raised when audio jack is connected/disconnected.
+ /// </summary>
+ public static event EventHandler<RuntimeKeyStatusChangedEventArgs> AudioJackConnected
+ {
+ add
+ {
+ if (s_audioJackConnected == null)
+ {
+ int ret = Interop.RuntimeInfo.SetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.AudioJack), s_runtimeInfoChangedCallback, IntPtr.Zero);
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ }
+ s_audioJackConnected += value;
+ }
+ remove
+ {
+ s_audioJackConnected -= value;
+ if (s_audioJackConnected == null)
+ {
+ int ret = Interop.RuntimeInfo.UnsetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.AudioJack));
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ }
+ }
+ }
+ /// <summary>
+ /// (event) GpsStatusChanged is raised when status of GPS is changed.
+ /// </summary>
+ public static event EventHandler<RuntimeKeyStatusChangedEventArgs> GpsStatusChanged
+ {
+ add
+ {
+ if (s_gpsStatusChanged == null)
+ {
+ int ret = Interop.RuntimeInfo.SetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.Gps), s_runtimeInfoChangedCallback, IntPtr.Zero);
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ }
+ s_gpsStatusChanged += value;
+ }
+ remove
+ {
+ s_gpsStatusChanged -= value;
+ if (s_gpsStatusChanged == null)
+ {
+ int ret = Interop.RuntimeInfo.UnsetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.Gps));
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ }
+ }
+ }
+ /// <summary>
+ /// (event) BatteryIsCharging is raised battery is currently charging.
+ /// </summary>
+ public static event EventHandler<RuntimeKeyStatusChangedEventArgs> BatteryIsCharging
+ {
+ add
+ {
+ if (s_batteryIsCharging == null)
+ {
+ int ret = Interop.RuntimeInfo.SetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.BatteryIsCharging), s_runtimeInfoChangedCallback, IntPtr.Zero);
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ }
+ s_batteryIsCharging += value;
+ }
+ remove
+ {
+ s_batteryIsCharging -= value;
+ if (s_batteryIsCharging == null)
+ {
+ int ret = Interop.RuntimeInfo.UnsetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.BatteryIsCharging));
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ }
+ }
+ }
+ /// <summary>
+ /// (event) TvOutConnected is raised when TV out is connected/disconnected.
+ /// </summary>
+ public static event EventHandler<RuntimeKeyStatusChangedEventArgs> TvOutConnected
+ {
+ add
+ {
+ if (s_tvOutConnected == null)
+ {
+ int ret = Interop.RuntimeInfo.SetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.TvOut), s_runtimeInfoChangedCallback, IntPtr.Zero);
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ }
+ s_tvOutConnected += value;
+ }
+ remove
+ {
+ s_tvOutConnected -= value;
+ if (s_tvOutConnected == null)
+ {
+ int ret = Interop.RuntimeInfo.UnsetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.TvOut));
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ }
+ }
+ }
+ /// <summary>
+ /// (event) AudioJackConnectorChanged is raised when audio jack connection changes.
+ /// </summary>
+ public static event EventHandler<RuntimeKeyStatusChangedEventArgs> AudioJackConnectorChanged
+ {
+ add
+ {
+ if (s_audioJackConnectorChanged == null)
+ {
+ int ret = Interop.RuntimeInfo.SetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.AudioJackConnector), s_runtimeInfoChangedCallback, IntPtr.Zero);
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ }
+ s_audioJackConnectorChanged += value;
+ }
+ remove
+ {
+ s_audioJackConnectorChanged -= value;
+ if (s_audioJackConnectorChanged == null)
+ {
+ int ret = Interop.RuntimeInfo.UnsetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.AudioJackConnector));
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ }
+ }
+ }
+ /// <summary>
+ /// (event) ChargerConnected is raised when charger is connected/disconnected.
+ /// </summary>
+ public static event EventHandler<RuntimeKeyStatusChangedEventArgs> ChargerConnected
+ {
+ add
+ {
+ if (s_chargerConnected == null)
+ {
+ int ret = Interop.RuntimeInfo.SetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.Charger), s_runtimeInfoChangedCallback, IntPtr.Zero);
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ }
+ s_chargerConnected += value;
+ }
+ remove
+ {
+ s_chargerConnected -= value;
+ if (s_chargerConnected == null)
+ {
+ int ret = Interop.RuntimeInfo.UnsetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.Charger));
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ }
+ }
+ }
+ /// <summary>
+ /// (event) AutoRotationEnabled is raised when system preference for auto rotation is changed.
+ /// </summary>
+ public static event EventHandler<RuntimeKeyStatusChangedEventArgs> AutoRotationEnabled
+ {
+ add
+ {
+ if (s_autoRotationEnabled == null)
+ {
+ int ret = Interop.RuntimeInfo.SetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.AutoRotation), s_runtimeInfoChangedCallback, IntPtr.Zero);
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ }
+ s_autoRotationEnabled += value;
+ }
+ remove
+ {
+ s_autoRotationEnabled -= value;
+ if (s_autoRotationEnabled == null)
+ {
+ int ret = Interop.RuntimeInfo.UnsetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.AutoRotation));
+ if (ret != (int)RuntimeInfoError.None)
+ {
+ Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
+ RuntimeInfoErrorFactory.ThrowException(ret);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/Tizen.System.Information/RuntimeInfo/RuntimeKeyStatusChangedEventArgs.cs b/src/Tizen.System.Information/RuntimeInfo/RuntimeKeyStatusChangedEventArgs.cs
new file mode 100755
index 0000000..0e1c3aa
--- /dev/null
+++ b/src/Tizen.System.Information/RuntimeInfo/RuntimeKeyStatusChangedEventArgs.cs
@@ -0,0 +1,35 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tizen.System
+{
+ /// <summary>
+ /// RuntimeInfoChangedEventArgs is an extended EventArgs class. This class contains event arguments for runtime event listeners
+ /// </summary>
+ public class RuntimeKeyStatusChangedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// The key indicating the runtime system preference which was changed.
+ /// </summary>
+ public RuntimeInformationKey Key { get; internal set; }
+ }
+}
diff --git a/src/Tizen.System.Information/SystemInfo/SystemInfo.cs b/src/Tizen.System.Information/SystemInfo/SystemInfo.cs
new file mode 100755
index 0000000..61dbef9
--- /dev/null
+++ b/src/Tizen.System.Information/SystemInfo/SystemInfo.cs
@@ -0,0 +1,272 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.ComponentModel;
+
+namespace Tizen.System
+{
+ /// <summary>
+ /// System Information class. This class has methods which can be used to obtain device information
+ /// </summary>
+ public static class SystemInfo
+ {
+ private const string LogTag = "Tizen.System";
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ private static Interop.SystemInfo.SystemInfoType GetValueType(string key, out Interop.SystemInfo.SystemInfoValueType valueType)
+ {
+ Interop.SystemInfo.ErrorCode err = Interop.SystemInfo.SystemInfoGetPlatformType(key, out valueType);
+ if (err == Interop.SystemInfo.ErrorCode.None)
+ {
+ return Interop.SystemInfo.SystemInfoType.platform;
+ }
+
+ Log.Debug(LogTag, string.Format("Key {0} not in platform system info", key));
+ err = Interop.SystemInfo.SystemInfoGetCustomType(key, out valueType);
+ if (err == Interop.SystemInfo.ErrorCode.None)
+ {
+ return Interop.SystemInfo.SystemInfoType.Custom;
+ }
+
+ Log.Debug(LogTag, string.Format("Key {0} not in custom system info", key));
+ return Interop.SystemInfo.SystemInfoType.None;
+ }
+
+ /// <summary>
+ /// Checks if type of value for given feature is T
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <typeparam name="T">Type of value for feature key</typeparam>
+ /// <param name="key">The name of the feature</param>
+ /// <returns>true if type of value for given feature is T, false otherwise</returns>
+ public static bool Is<T>(string key)
+ {
+ Interop.SystemInfo.SystemInfoValueType valueType;
+ Interop.SystemInfo.SystemInfoType keyType = GetValueType(key, out valueType);
+ if (keyType == Interop.SystemInfo.SystemInfoType.None)
+ {
+ return false;
+ }
+
+ switch (valueType)
+ {
+ case Interop.SystemInfo.SystemInfoValueType.Bool:
+ return typeof(T) == typeof(bool);
+ case Interop.SystemInfo.SystemInfoValueType.Double:
+ return typeof(T) == typeof(double);
+ case Interop.SystemInfo.SystemInfoValueType.Int:
+ return typeof(T) == typeof(int);
+ case Interop.SystemInfo.SystemInfoValueType.String:
+ return typeof(T) == typeof(string);
+ }
+ return false;
+ }
+
+ /// <summary>
+ /// Checks if given key is valid feature
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="key">The name of the feature</param>
+ /// <returns>true of key is valid, false otherwise</returns>
+ public static bool IsValidKey(string key)
+ {
+ Interop.SystemInfo.SystemInfoValueType valueType;
+ return GetValueType(key, out valueType) != Interop.SystemInfo.SystemInfoType.None;
+ }
+
+ /// <summary>
+ /// Gets the value of the feature.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <typeparam name="T">Type of key value</typeparam>
+ /// <param name="key">The name of the feature</param>
+ /// <param name="value">The value of the given feature</param>
+ /// <returns>return true on success otherwise false</returns>
+ public static bool TryGetValue<T>(string key, out T value)
+ {
+ bool res = false;
+ if (typeof(T) == typeof(bool))
+ {
+ bool val;
+ res = TryGetValue(key, out val);
+ value = (T)(object)val;
+ }
+ else if (typeof(T) == typeof(int))
+ {
+ int val;
+ res = TryGetValue(key, out val);
+ value = (T)(object)val;
+ }
+ else if (typeof(T) == typeof(double))
+ {
+ double val;
+ res = TryGetValue(key, out val);
+ value = (T)(object)val;
+ }
+ else if (typeof(T) == typeof(string))
+ {
+ string val;
+ res = TryGetValue(key, out val);
+ value = (T)(object)val;
+ }
+ else
+ {
+ value = default(T);
+ }
+ return res;
+ }
+
+ /// <summary>
+ /// Gets the bool value of the feature.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="key">The name of the feature</param>
+ /// <param name="value">The value of the given feature</param>
+ /// <returns>return true on success otherwise false</returns>
+ public static bool TryGetValue(string key, out bool value)
+ {
+ Interop.SystemInfo.SystemInfoValueType valueType;
+ Interop.SystemInfo.SystemInfoType keyType = GetValueType(key, out valueType);
+
+ Interop.SystemInfo.ErrorCode err = Interop.SystemInfo.ErrorCode.InvalidParameter;
+ if (keyType == Interop.SystemInfo.SystemInfoType.platform)
+ {
+ err = Interop.SystemInfo.SystemInfoGetPlatformBool(key, out value);
+ }
+ else if (keyType == Interop.SystemInfo.SystemInfoType.Custom)
+ {
+ err = Interop.SystemInfo.SystemInfoGetCustomBool(key, out value);
+ } else
+ {
+ value = false;
+ }
+
+ if (err != Interop.SystemInfo.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to get value for key: {0}. err = {1}", key, err));
+ return false;
+ }
+
+ return true;
+ }
+
+ /// <summary>
+ /// Gets the int value of the feature.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="key">The name of the feature</param>
+ /// <param name="value">The value of the given feature</param>
+ /// <returns>return true on success otherwise false</returns>
+ public static bool TryGetValue(string key, out int value)
+ {
+ Interop.SystemInfo.SystemInfoValueType valueType;
+ Interop.SystemInfo.SystemInfoType keyType = GetValueType(key, out valueType);
+
+ Interop.SystemInfo.ErrorCode err = Interop.SystemInfo.ErrorCode.InvalidParameter;
+ if (keyType == Interop.SystemInfo.SystemInfoType.platform)
+ {
+ err = Interop.SystemInfo.SystemInfoGetPlatformInt(key, out value);
+ }
+ else if (keyType == Interop.SystemInfo.SystemInfoType.Custom)
+ {
+ err = Interop.SystemInfo.SystemInfoGetCustomInt(key, out value);
+ }
+ else
+ {
+ value = 0;
+ }
+
+ if (err != Interop.SystemInfo.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to get value for key: {0}. err = {1}", key, err));
+ return false;
+ }
+
+ return true;
+ }
+
+ /// <summary>
+ /// Gets the double value of the feature.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="key">The name of the feature</param>
+ /// <param name="value">The value of the given feature</param>
+ /// <returns>return true on success otherwise false</returns>
+ public static bool TryGetValue(string key, out double value)
+ {
+ Interop.SystemInfo.SystemInfoValueType valueType;
+ Interop.SystemInfo.SystemInfoType keyType = GetValueType(key, out valueType);
+
+ Interop.SystemInfo.ErrorCode err = Interop.SystemInfo.ErrorCode.InvalidParameter;
+ if (keyType == Interop.SystemInfo.SystemInfoType.platform)
+ {
+ err = Interop.SystemInfo.SystemInfoGetPlatformDouble(key, out value);
+ }
+ else if (keyType == Interop.SystemInfo.SystemInfoType.Custom)
+ {
+ err = Interop.SystemInfo.SystemInfoGetCustomDouble(key, out value);
+ }
+ else
+ {
+ value = 0;
+ }
+
+ if (err != Interop.SystemInfo.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to get value for key: {0}. err = {1}", key, err));
+ return false;
+ }
+
+ return true;
+ }
+
+ /// <summary>
+ /// Gets the string value of the feature.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <param name="key">The name of the feature</param>
+ /// <param name="value">The value of the given feature</param>
+ /// <returns>return true on success otherwise false</returns>
+ public static bool TryGetValue(string key, out string value)
+ {
+ Interop.SystemInfo.SystemInfoValueType valueType;
+ Interop.SystemInfo.SystemInfoType keyType = GetValueType(key, out valueType);
+
+ Interop.SystemInfo.ErrorCode err = Interop.SystemInfo.ErrorCode.InvalidParameter;
+ if (keyType == Interop.SystemInfo.SystemInfoType.platform)
+ {
+ err = Interop.SystemInfo.SystemInfoGetPlatformString(key, out value);
+ }
+ else if (keyType == Interop.SystemInfo.SystemInfoType.Custom)
+ {
+ err = Interop.SystemInfo.SystemInfoGetCustomString(key, out value);
+ }
+ else
+ {
+ value = string.Empty;
+ }
+
+ if (err != Interop.SystemInfo.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to get value for key: {0}. err = {1}", key, err));
+ return false;
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/src/Tizen.System.Information/Tizen.System.Information.csproj b/src/Tizen.System.Information/Tizen.System.Information.csproj
new file mode 100644
index 0000000..5ed2f1f
--- /dev/null
+++ b/src/Tizen.System.Information/Tizen.System.Information.csproj
@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.System.MediaKey/Interop/Interop.Libraries.cs b/src/Tizen.System.MediaKey/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..9902c9f
--- /dev/null
+++ b/src/Tizen.System.MediaKey/Interop/Interop.Libraries.cs
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string MediaKey = "libcapi-system-media-key.so.0";
+ }
+}
diff --git a/src/Tizen.System.MediaKey/Interop/Interop.MediaKey.cs b/src/Tizen.System.MediaKey/Interop/Interop.MediaKey.cs
new file mode 100755
index 0000000..d18aa9d
--- /dev/null
+++ b/src/Tizen.System.MediaKey/Interop/Interop.MediaKey.cs
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class MediaKey
+ {
+ internal enum KeyValue
+ {
+ Play,
+ Stop,
+ Pause,
+ Previous,
+ Next,
+ FastForward,
+ Rewind,
+ PlayPause,
+ Media,
+ Unknown
+ }
+
+ internal enum KeyStatus
+ {
+ Pressed,
+ Released,
+ Unknown
+ }
+
+ internal enum ErrorCode : int
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None,
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+ OperationFailed = -0x02420000 | 0x01
+ }
+
+ internal delegate void EventCallback(KeyValue value, KeyStatus status, IntPtr userData);
+
+ [DllImport(Libraries.MediaKey, EntryPoint = "media_key_reserve")]
+ internal static extern ErrorCode Reserve(EventCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.MediaKey, EntryPoint = "media_key_release")]
+ internal static extern ErrorCode Release();
+ }
+}
diff --git a/src/Tizen.System.MediaKey/Tizen.System.MediaKey.csproj b/src/Tizen.System.MediaKey/Tizen.System.MediaKey.csproj
new file mode 100644
index 0000000..5ed2f1f
--- /dev/null
+++ b/src/Tizen.System.MediaKey/Tizen.System.MediaKey.csproj
@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.System.MediaKey/Tizen.System/MediaKey.cs b/src/Tizen.System.MediaKey/Tizen.System/MediaKey.cs
new file mode 100755
index 0000000..abe96b7
--- /dev/null
+++ b/src/Tizen.System.MediaKey/Tizen.System/MediaKey.cs
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.System
+{
+ /// <summary>
+ /// Class for event arguments of the media key.
+ /// </summary>
+ public class MediaKeyEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Enumeration for Key value.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum KeyValue
+ {
+ /// <summary>
+ /// Play key.
+ /// </summary>
+ Play,
+
+ /// <summary>
+ /// Stop key.
+ /// </summary>
+ Stop,
+
+ /// <summary>
+ /// Pause key.
+ /// </summary>
+ Pause,
+
+ /// <summary>
+ /// Previous key.
+ /// </summary>
+ Previous,
+
+ /// <summary>
+ /// Next key.
+ /// </summary>
+ Next,
+
+ /// <summary>
+ /// Fast forward key.
+ /// </summary>
+ FastForward,
+
+ /// <summary>
+ /// Rewind key.
+ /// </summary>
+ Rewind,
+
+ /// <summary>
+ /// Play-pause key.
+ /// </summary>
+ PlayPause,
+
+ /// <summary>
+ /// Media key for earjack.
+ /// </summary>
+ Media,
+
+ /// <summary>
+ /// Unknown key.
+ /// </summary>
+ Unknown
+ }
+
+ /// <summary>
+ /// Enumeration for Key status.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public enum KeyStatus
+ {
+ /// <summary>
+ /// Pressed status.
+ /// </summary>
+ Pressed,
+
+ /// <summary>
+ /// Released status.
+ /// </summary>
+ Released,
+
+ /// <summary>
+ /// Unknown status.
+ /// </summary>
+ Unknown
+ }
+
+ /// <summary>
+ /// Key value.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public KeyValue Value { get; internal set; }
+
+ /// <summary>
+ /// Key status.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ public KeyStatus Status { get; internal set; }
+ }
+
+ /// <summary>
+ /// Class for receiving events of media keys.
+ /// </summary>
+ public static class MediaKey
+ {
+ private static EventHandler<MediaKeyEventArgs> s_eventHandler;
+ private static Interop.MediaKey.EventCallback s_callback;
+
+ private static void OnEvent(Interop.MediaKey.KeyValue value, Interop.MediaKey.KeyStatus status, IntPtr userData)
+ {
+ s_eventHandler?.Invoke(null, new MediaKeyEventArgs()
+ {
+ Value = (MediaKeyEventArgs.KeyValue)value,
+ Status = (MediaKeyEventArgs.KeyStatus)status
+ });
+ }
+
+ /// <summary>
+ /// Adds or removes events for all media keys.
+ /// </summary>
+ /// <since_tizen>3</since_tizen>
+ /// <exception cref="InvalidOperationException">Failed to reserve or release key.</exception>
+ public static event EventHandler<MediaKeyEventArgs> Event
+ {
+ add
+ {
+ if (s_eventHandler == null)
+ {
+ if (s_callback == null)
+ s_callback = new Interop.MediaKey.EventCallback(OnEvent);
+ Interop.MediaKey.ErrorCode err = Interop.MediaKey.Reserve(s_callback, IntPtr.Zero);
+
+ if (err != Interop.MediaKey.ErrorCode.None)
+ {
+ throw new InvalidOperationException("Failed to reserve key. err = " + err);
+ }
+
+ }
+ s_eventHandler += value;
+
+ }
+ remove
+ {
+ s_eventHandler -= value;
+ if (s_eventHandler == null)
+ {
+ Interop.MediaKey.ErrorCode err = Interop.MediaKey.Release();
+
+ if (err != Interop.MediaKey.ErrorCode.None)
+ {
+ throw new InvalidOperationException("Failed to release key. err = " + err);
+ }
+ s_callback = null;
+ }
+ }
+ }
+ }
+}
+
diff --git a/src/Tizen.System.Storage/Interop/Interop.Libraries.cs b/src/Tizen.System.Storage/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..0180f70
--- /dev/null
+++ b/src/Tizen.System.Storage/Interop/Interop.Libraries.cs
@@ -0,0 +1,23 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ internal const string Storage = "libstorage.so.0.1";
+ }
+}
diff --git a/src/Tizen.System.Storage/Interop/Interop.Storage.cs b/src/Tizen.System.Storage/Interop/Interop.Storage.cs
new file mode 100644
index 0000000..5f04e08
--- /dev/null
+++ b/src/Tizen.System.Storage/Interop/Interop.Storage.cs
@@ -0,0 +1,96 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Storage
+ {
+ internal enum ErrorCode
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None,
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+ OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
+ NotSupported = Tizen.Internals.Errors.ErrorCode.NoSuchDevice,
+ OperationFailed = -0x00020000 | 0x12,
+ }
+
+ // Any change here might require changes in Tizen.System.StorageArea enum
+ internal enum StorageArea
+ {
+ Internal = 0,
+ External = 1,
+ }
+
+ // Any change here might require changes in Tizen.System.StorageState enum
+ internal enum StorageState
+ {
+ Unmountable = -2,
+ Removed = -1,
+ Mounted = 0,
+ MountedReadOnly = 1,
+ }
+
+ // Any change here might require changes in Tizen.System.directoryType enum
+ internal enum DirectoryType
+ {
+ Images = 0,
+ Sounds = 1,
+ Videos = 2,
+ Camera = 3,
+ Downloads = 4,
+ Music = 5,
+ Documents = 6,
+ Others = 7,
+ Ringtones = 8,
+ }
+
+ [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+ internal delegate void StorageStateChangedCallback(int id, StorageState state, IntPtr userData);
+
+ [DllImport(Libraries.Storage, EntryPoint = "storage_get_root_directory")]
+ internal static extern ErrorCode StorageGetRootDirectory(int id, out string path);
+
+ [DllImport(Libraries.Storage, EntryPoint = "storage_get_directory")]
+ internal static extern ErrorCode StorageGetAbsoluteDirectory(int id, DirectoryType type, out string path);
+
+ [DllImport(Libraries.Storage, EntryPoint = "storage_get_state")]
+ internal static extern ErrorCode StorageGetState(int id, out StorageState state);
+
+ [DllImport(Libraries.Storage, EntryPoint = "storage_get_type")]
+ internal static extern ErrorCode StorageGetType(int id, out StorageArea type);
+
+ [DllImport(Libraries.Storage, EntryPoint = "storage_set_state_changed_cb")]
+ internal static extern ErrorCode StorageSetStateChanged(int id, StorageStateChangedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Storage, EntryPoint = "storage_unset_state_changed_cb")]
+ internal static extern ErrorCode StorageUnsetStateChanged(int id, StorageStateChangedCallback callback);
+
+ [DllImport(Libraries.Storage, EntryPoint = "storage_get_total_space")]
+ internal static extern ErrorCode StorageGetTotalSpace(int id, out ulong bytes);
+
+ [DllImport(Libraries.Storage, EntryPoint = "storage_get_available_space")]
+ internal static extern ErrorCode StorageGetAvailableSpace(int id, out ulong bytes);
+
+ [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+ internal delegate bool StorageDeviceSupportedCallback(int storageID, StorageArea type, StorageState state, string rootDirectory, IntPtr userData);
+
+ [DllImport(Libraries.Storage, EntryPoint = "storage_foreach_device_supported")]
+ public static extern ErrorCode StorageManagerGetForeachDeviceSupported(StorageDeviceSupportedCallback callback, IntPtr userData);
+ }
+}
diff --git a/src/Tizen.System.Storage/Storage/DirectoryType.cs b/src/Tizen.System.Storage/Storage/DirectoryType.cs
new file mode 100644
index 0000000..ed4cb2b
--- /dev/null
+++ b/src/Tizen.System.Storage/Storage/DirectoryType.cs
@@ -0,0 +1,71 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+namespace Tizen.System
+{
+ /// <summary>
+ /// Enumeration of the storage directory types.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum DirectoryType
+ {
+ /// <summary>
+ /// Image directory
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Images = Interop.Storage.DirectoryType.Images,
+ /// <summary>
+ /// Sounds directory
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Sounds = Interop.Storage.DirectoryType.Sounds,
+ /// <summary>
+ /// Videos directory
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Videos = Interop.Storage.DirectoryType.Videos,
+ /// <summary>
+ /// Camera directory
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Camera = Interop.Storage.DirectoryType.Camera,
+ /// <summary>
+ /// Downloads directory
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Downloads = Interop.Storage.DirectoryType.Downloads,
+ /// <summary>
+ /// Music directory
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Music = Interop.Storage.DirectoryType.Music,
+ /// <summary>
+ /// Documents directory
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Documents = Interop.Storage.DirectoryType.Documents,
+ /// <summary>
+ /// Others directory
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Others = Interop.Storage.DirectoryType.Others,
+ /// <summary>
+ /// System ringtones directory. Only available for internal storage.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Ringtones = Interop.Storage.DirectoryType.Ringtones,
+ }
+}
diff --git a/src/Tizen.System.Storage/Storage/Storage.cs b/src/Tizen.System.Storage/Storage/Storage.cs
new file mode 100644
index 0000000..ce70b88
--- /dev/null
+++ b/src/Tizen.System.Storage/Storage/Storage.cs
@@ -0,0 +1,224 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+
+namespace Tizen.System
+{
+ /// <summary>
+ /// class to access storage device information
+ /// </summary>
+ public class Storage
+ {
+ private const string LogTag = "Tizen.System";
+ private Interop.Storage.StorageState _state;
+ private ulong _totalSpace;
+
+ internal Storage(int storageID, Interop.Storage.StorageArea storageType, Interop.Storage.StorageState storagestate, string rootDirectory)
+ {
+ Id = storageID;
+ StorageType = (StorageArea)storageType;
+ RootDirectory = rootDirectory;
+ _state = storagestate;
+
+ Interop.Storage.ErrorCode err = Interop.Storage.StorageGetTotalSpace(Id, out _totalSpace);
+ if (err != Interop.Storage.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to get total storage space for storage Id: {0}. err = {1}", Id, err));
+ }
+
+ s_stateChangedEventCallback = (id, state, userData) =>
+ {
+ if (id == Id)
+ {
+ _state = state;
+ s_stateChangedEventHandler?.Invoke(this, EventArgs.Empty);
+ }
+ };
+ }
+
+ private EventHandler s_stateChangedEventHandler;
+ private Interop.Storage.StorageStateChangedCallback s_stateChangedEventCallback;
+
+ private void RegisterStateChangedEvent()
+ {
+ Interop.Storage.ErrorCode err = Interop.Storage.StorageSetStateChanged(Id, s_stateChangedEventCallback, IntPtr.Zero);
+ if (err != Interop.Storage.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to Register state changed event callback for storage Id: {0}. err = {1}", Id, err));
+ }
+ }
+
+ private void UnregisterStateChangedEvent()
+ {
+ Interop.Storage.ErrorCode err = Interop.Storage.StorageUnsetStateChanged(Id, s_stateChangedEventCallback);
+ if (err != Interop.Storage.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to Register state changed event callback for storage Id: {0}. err = {1}", Id, err));
+ }
+ }
+
+ /// <summary>
+ /// StorageStateChanged event. This event is occurred when a storage state changes.
+ /// </summary>
+ /// <remarks>
+ /// Storage state will be updated before calling event handler.
+ /// </remarks>
+ /// <since_tizen> 3 </since_tizen>
+ /// <example>
+ /// <code>
+ /// myStorage.StorageStateChanged += (s, e) =>
+ /// {
+ /// var storage = s as Storage;
+ /// Console.WriteLine(string.Format("State Changed to {0}", storage.State));
+ /// }
+ /// </code>
+ /// </example>
+ public event EventHandler StorageStateChanged
+ {
+ add
+ {
+ if (s_stateChangedEventHandler == null)
+ {
+ _state = (Interop.Storage.StorageState)State;
+ RegisterStateChangedEvent();
+ }
+ s_stateChangedEventHandler += value;
+ }
+ remove
+ {
+ if (s_stateChangedEventHandler != null)
+ {
+ s_stateChangedEventHandler -= value;
+ if (s_stateChangedEventHandler == null)
+ {
+ UnregisterStateChangedEvent();
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Storage ID
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Id { get; }
+ /// <summary>
+ /// Type of the storage
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public StorageArea StorageType { get; }
+ /// <summary>
+ /// Root directory for the storage
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string RootDirectory { get; }
+ /// <summary>
+ /// Total storage size in bytes
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ulong TotalSpace { get { return _totalSpace; } }
+
+ /// <summary>
+ /// Storage state
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public StorageState State
+ {
+ get
+ {
+ if (s_stateChangedEventHandler == null)
+ {
+ Interop.Storage.ErrorCode err = Interop.Storage.StorageGetState(Id, out _state);
+ if (err != Interop.Storage.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to get storage state for storage Id: {0}. err = {1}", Id, err));
+ }
+ }
+ return (StorageState)_state;
+ }
+ }
+
+ /// <summary>
+ /// Available storage size in bytes
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ulong AvaliableSpace
+ {
+ get
+ {
+ ulong available;
+ Interop.Storage.ErrorCode err = Interop.Storage.StorageGetAvailableSpace(Id, out available);
+ if (err != Interop.Storage.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to get available storage stace for storage Id: {0}. err = {1}", Id, err));
+ }
+
+ return available;
+ }
+ }
+
+ /// <summary>
+ /// Absolute path for given directory type in storage
+ /// </summary>
+ /// <remarks>
+ /// returned directory path may not exist, so you must make sure that it exists before using it.
+ /// For accessing internal storage except Ringtones directory, app should have http://tizen.org/privilege/mediastorage privilege.
+ /// For accessing Ringtones directory, app should have http://tizen.org/privilege/systemsettings privilege.
+ /// For accessing external storage, app should have http://tizen.org/privilege/externalstorage privilege.
+ /// </remarks>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="dirType">Directory type</param>
+ /// <returns>Absolute path for given directory type in storage</returns>
+ /// <exception cref="ArgumentException">Thrown when failed because of a invalid arguament</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory exception</exception>
+ /// <exception cref="NotSupportedException">Thrown when failed if storage is not supported or app does not have permission to access directory path</exception>
+ /// <privilege>http://tizen.org/privilege/mediastorage</privilege>
+ /// <privilege>http://tizen.org/privilege/systemsettings</privilege>
+ /// <privilege>http://tizen.org/privilege/externalstorage</privilege>
+ /// <example>
+ /// <code>
+ /// // To get video directories for all supported storage,
+ /// var storageList = StorageManager.Storages as List&lt;Storage&gt;;
+ /// foreach (var storage in storageList)
+ /// {
+ /// string pathForVideoDir = storage.GetAbsolutePath(DirectoryType.Videos);
+ /// }
+ /// </code>
+ /// </example>
+ public string GetAbsolutePath(DirectoryType dirType)
+ {
+ string path;
+ Interop.Storage.ErrorCode err = Interop.Storage.StorageGetAbsoluteDirectory(Id, (Interop.Storage.DirectoryType)dirType, out path);
+ if (err != Interop.Storage.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to get package Id. err = {0}", err));
+ switch (err)
+ {
+ case Interop.Storage.ErrorCode.InvalidParameter:
+ throw new ArgumentException("Invalid Arguments");
+ case Interop.Storage.ErrorCode.OutOfMemory:
+ throw new OutOfMemoryException("Out of Memory");
+ case Interop.Storage.ErrorCode.NotSupported:
+ throw new NotSupportedException("Operation Not Supported");
+ default:
+ throw new InvalidOperationException("Error = " + err);
+ }
+ }
+ return path;
+ }
+ }
+}
diff --git a/src/Tizen.System.Storage/Storage/StorageArea.cs b/src/Tizen.System.Storage/Storage/StorageArea.cs
new file mode 100644
index 0000000..7a0e80d
--- /dev/null
+++ b/src/Tizen.System.Storage/Storage/StorageArea.cs
@@ -0,0 +1,36 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+namespace Tizen.System
+{
+ /// <summary>
+ /// Enumeration for storage area types.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum StorageArea
+ {
+ /// <summary>
+ /// Internal device storage (built-in storage in a device, non-removable)
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Internal = Interop.Storage.StorageArea.Internal,
+ /// <summary>
+ /// External storage
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ External = Interop.Storage.StorageArea.External,
+ }
+}
diff --git a/src/Tizen.System.Storage/Storage/StorageManager.cs b/src/Tizen.System.Storage/Storage/StorageManager.cs
new file mode 100644
index 0000000..dc16470
--- /dev/null
+++ b/src/Tizen.System.Storage/Storage/StorageManager.cs
@@ -0,0 +1,53 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.System
+{
+ /// <summary>
+ /// Storage Manager, provides properties/ methods to access storage in the device.
+ /// </summary>
+ public static class StorageManager
+ {
+ private const string LogTag = "Tizen.System";
+
+ /// <summary>
+ /// List of all storage in the device
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static IEnumerable<Storage> Storages
+ {
+ get
+ {
+ List<Storage> storageList = new List<Storage>();
+ Interop.Storage.StorageDeviceSupportedCallback cb = (int storageID, Interop.Storage.StorageArea type, Interop.Storage.StorageState state, string rootDirectory, IntPtr userData) =>
+ {
+ storageList.Add(new Storage(storageID, type, state, rootDirectory));
+ return true;
+ };
+
+ Interop.Storage.ErrorCode err = Interop.Storage.StorageManagerGetForeachDeviceSupported(cb, IntPtr.Zero);
+ if (err != Interop.Storage.ErrorCode.None)
+ {
+ Log.Warn(LogTag, string.Format("Failed to get storage list. err = {0}", err));
+ }
+ return storageList;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.System.Storage/Storage/StorageState.cs b/src/Tizen.System.Storage/Storage/StorageState.cs
new file mode 100644
index 0000000..49151b6
--- /dev/null
+++ b/src/Tizen.System.Storage/Storage/StorageState.cs
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+namespace Tizen.System
+{
+ /// <summary>
+ /// Enumeration for the state of storage devices.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum StorageState
+ {
+ /// <summary>
+ /// Storage is present but cannot be mounted. Typically it happens if the file system of the storage is corrupted
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Unmountable = Interop.Storage.StorageState.Unmountable,
+ /// <summary>
+ /// Storage is not present or removed
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Removed = Interop.Storage.StorageState.Removed,
+ /// <summary>
+ /// Storage is mounted with read/write access
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Mounted = Interop.Storage.StorageState.Mounted,
+ /// <summary>
+ /// Storage is mounted with read only access
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ MountedReadOnly = Interop.Storage.StorageState.MountedReadOnly,
+ }
+}
diff --git a/src/Tizen.System.Storage/Tizen.System.Storage.csproj b/src/Tizen.System.Storage/Tizen.System.Storage.csproj
new file mode 100644
index 0000000..5ed2f1f
--- /dev/null
+++ b/src/Tizen.System.Storage/Tizen.System.Storage.csproj
@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.System.SystemSettings/Interop/Interop.SystemSettings.cs b/src/Tizen.System.SystemSettings/Interop/Interop.SystemSettings.cs
new file mode 100644
index 0000000..3925cd5
--- /dev/null
+++ b/src/Tizen.System.SystemSettings/Interop/Interop.SystemSettings.cs
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.System;
+
+internal static partial class Interop
+{
+ internal static partial class Settings
+ {
+ [DllImport("capi-system-system-settings.so.0", EntryPoint = "system_settings_set_value_int", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int SystemSettingsSetValueInt(SystemSettingsKeys key, int value);
+
+ [DllImport("capi-system-system-settings.so.0", EntryPoint = "system_settings_set_value_bool", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int SystemSettingsSetValueBool(SystemSettingsKeys key, bool value);
+
+ [DllImport("capi-system-system-settings.so.0", EntryPoint = "system_settings_set_value_string", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int SystemSettingsSetValueString(SystemSettingsKeys key, string value);
+
+
+ [DllImport("capi-system-system-settings.so.0", EntryPoint = "system_settings_get_value_int", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int SystemSettingsGetValueInt(SystemSettingsKeys key, out int value);
+
+ [DllImport("capi-system-system-settings.so.0", EntryPoint = "system_settings_get_value_bool", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int SystemSettingsGetValueBool(SystemSettingsKeys key, out bool value);
+
+ [DllImport("capi-system-system-settings.so.0", EntryPoint = "system_settings_get_value_string", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int SystemSettingsGetValueString(SystemSettingsKeys key, out string value);
+
+ // Callback
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void SystemSettingsChangedCallback(SystemSettingsKeys key, IntPtr data);
+ [DllImport("capi-system-system-settings.so.0", EntryPoint = "system_settings_set_changed_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int SystemSettingsSetCallback(SystemSettingsKeys systemSettingsKey, SystemSettingsChangedCallback cb, IntPtr data);
+ [DllImport("capi-system-system-settings.so.0", EntryPoint = "system_settings_unset_changed_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int SystemSettingsRemoveCallback(SystemSettingsKeys systemSettingsKey);
+ }
+}
diff --git a/src/Tizen.System.SystemSettings/Tizen.System.SystemSettings.csproj b/src/Tizen.System.SystemSettings/Tizen.System.SystemSettings.csproj
new file mode 100644
index 0000000..5ed2f1f
--- /dev/null
+++ b/src/Tizen.System.SystemSettings/Tizen.System.SystemSettings.csproj
@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.System.SystemSettings/Tizen.System.SystemSettings/SystemSettings.cs b/src/Tizen.System.SystemSettings/Tizen.System.SystemSettings/SystemSettings.cs
new file mode 100755
index 0000000..1b4398f
--- /dev/null
+++ b/src/Tizen.System.SystemSettings/Tizen.System.SystemSettings/SystemSettings.cs
@@ -0,0 +1,1929 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.System
+{
+ /// <summary>
+ /// The System Settings API provides APIs for sharing configuration over a system
+ /// </summary>
+ /// <remarks>
+ /// System Settings API provides functions for getting the system configuration related to user preferences.
+ /// The main features of the System Settings API include accessing system-wide configurations, such as ringtones, wallpapers, and etc
+ /// </remarks>
+ public static class SystemSettings
+ {
+ /// <summary>
+ /// The file path of the current ringtone
+ /// </summary>
+ public static string IncomingCallRingtone
+ {
+ get
+ {
+ string filePath;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueString(SystemSettingsKeys.IncomingCallRingtone, out filePath);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get IncomingCallRingtone system setting.");
+ }
+ return filePath;
+ }
+ set
+ {
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsSetValueString(SystemSettingsKeys.IncomingCallRingtone, value);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to set IncomingCallRingtone system setting.");
+ }
+ }
+ }
+
+ /// <summary>
+ /// The file path of the current home screen wallpaper
+ /// </summary>
+ public static string WallpaperHomeScreen
+ {
+ get
+ {
+ string filePath;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueString(SystemSettingsKeys.WallpaperHomeScreen, out filePath);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get WallpaperHomeScreen system setting.");
+ }
+ return filePath;
+ }
+ set
+ {
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsSetValueString(SystemSettingsKeys.WallpaperHomeScreen, value);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to set WallpaperHomeScreen system setting.");
+ }
+ }
+ }
+
+ /// <summary>
+ /// The file path of the current lock screen wallpaper
+ /// </summary>
+ public static string WallpaperLockScreen
+ {
+ get
+ {
+ string filePath;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueString(SystemSettingsKeys.WallpaperLockScreen, out filePath);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get WallpaperLockScreen system setting.");
+ }
+ return filePath;
+ }
+ set
+ {
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsSetValueString(SystemSettingsKeys.WallpaperLockScreen, value);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to set WallpaperLockScreen system setting.");
+ }
+ }
+ }
+
+ /// <summary>
+ /// The current system font size
+ /// </summary>
+ public static SystemSettingsFontSize FontSize
+ {
+ get
+ {
+ int fontSize;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueInt(SystemSettingsKeys.FontSize, out fontSize);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get FontSize system setting.");
+ }
+ return (SystemSettingsFontSize)fontSize;
+ }
+ set
+ {
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsSetValueInt(SystemSettingsKeys.FontSize, (int)value);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to set FontSize system setting.");
+ }
+ }
+ }
+
+ /// <summary>
+ /// The current system font type
+ /// </summary>
+ public static string FontType
+ {
+ get
+ {
+ string fontType;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueString(SystemSettingsKeys.FontType, out fontType);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get FontType system setting.");
+ }
+ return fontType;
+ }
+ set
+ {
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsSetValueString(SystemSettingsKeys.FontType, value);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to set FontType system setting.");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Indicates whether the motion service is activated
+ /// </summary>
+ public static bool MotionActivationEnabled
+ {
+ get
+ {
+ bool isMotionServiceActivated;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueBool(SystemSettingsKeys.MotionActivationEnabled, out isMotionServiceActivated);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get MotionActivation system setting.");
+ }
+ return isMotionServiceActivated;
+ }
+ set
+ {
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsSetValueBool(SystemSettingsKeys.MotionActivationEnabled, value);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to set MotionActivation system setting.");
+ }
+ }
+ }
+
+ /// <summary>
+ /// The file path of the current email alert ringtone
+ /// </summary>
+ public static string EmailAlertRingtone
+ {
+ get
+ {
+ string filePath;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueString(SystemSettingsKeys.EmailAlertRingtone, out filePath);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get EmailAlertRingtone system setting.");
+ }
+ return filePath;
+ }
+ set
+ {
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsSetValueString(SystemSettingsKeys.EmailAlertRingtone, value);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to set EmailAlertRingtone system setting.");
+ }
+ }
+ }
+ /// <summary>
+ /// Indicates whether the USB debugging is enabled
+ /// </summary>
+ public static bool UsbDebuggingEnabled
+ {
+ get
+ {
+ bool isusbDebuggingEnabled;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueBool(SystemSettingsKeys.UsbDebuggingEnabled, out isusbDebuggingEnabled);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get UsbDebuggingEnabled system setting.");
+ }
+ return isusbDebuggingEnabled;
+ }
+ set
+ {
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsSetValueBool(SystemSettingsKeys.UsbDebuggingEnabled, value);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to set UsbDebuggingEnabled system setting.");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Indicates whether the 3G data network is enabled
+ /// </summary>
+ public static bool Data3GNetworkEnabled
+ {
+ get
+ {
+ bool is3GDataEnabled;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueBool(SystemSettingsKeys.Data3GNetworkEnabled, out is3GDataEnabled);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get Data3GNetworkEnabled system setting.");
+ }
+ return is3GDataEnabled;
+ }
+ set
+ {
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsSetValueBool(SystemSettingsKeys.Data3GNetworkEnabled, value);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to set Data3GNetworkEnabled system setting.");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Indicates lockscreen app pkg name
+ /// </summary>
+ public static string LockscreenApp
+ {
+ get
+ {
+ string pkgName;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueString(SystemSettingsKeys.LockscreenApp, out pkgName);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get LockscreenApp system setting.");
+ }
+ return pkgName;
+ }
+ set
+ {
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsSetValueString(SystemSettingsKeys.LockscreenApp, value);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to set LockscreenApp system setting.");
+ }
+ }
+ }
+
+ /// <summary>
+ /// The current system default font type (only support Get)
+ /// </summary>
+ public static string DefaultFontType
+ {
+ get
+ {
+ string defaultFontType;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueString(SystemSettingsKeys.DefaultFontType, out defaultFontType);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get DefaultFontType system setting value.");
+ }
+ return defaultFontType;
+ }
+ }
+
+ /// <summary>
+ /// Indicates the current country setting in the &lt;LANGUAGE&gt;_&lt;REGION&gt; syntax.
+ /// The country setting is in the ISO 639-2 format,
+ /// and the region setting is in the ISO 3166-1 alpha-2 format
+ /// </summary>
+ public static string LocaleCountry
+ {
+ get
+ {
+ string countrySetting;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueString(SystemSettingsKeys.LocaleCountry, out countrySetting);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get LocaleCountry system setting.");
+ }
+ return countrySetting;
+ }
+ set
+ {
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsSetValueString(SystemSettingsKeys.LocaleCountry, value);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to set LocaleCountry system setting.");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Indicates the current language setting in the &lt;LANGUAGE&gt;_&lt;REGION&gt; syntax.
+ /// The language setting is in the ISO 639-2 format
+ /// and the region setting is in the ISO 3166-1 alpha-2 format.
+ /// </summary>
+ public static string LocaleLanguage
+ {
+ get
+ {
+ string languageSetting;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueString(SystemSettingsKeys.LocaleLanguage, out languageSetting);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get LocaleLanguage system setting.");
+ }
+ return languageSetting;
+ }
+ set
+ {
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsSetValueString(SystemSettingsKeys.LocaleLanguage, value);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to set LocaleLanguage system setting.");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Indicates whether the 24-hour clock is used.
+ /// If the value is false, the 12-hour clock is used.
+ /// </summary>
+ public static bool LocaleTimeFormat24HourEnabled
+ {
+ get
+ {
+ bool is24HrFormat;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueBool(SystemSettingsKeys.LocaleTimeFormat24HourEnabled, out is24HrFormat);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get LocaleTimeFormat24Hour system setting.");
+ }
+ return is24HrFormat;
+ }
+ set
+ {
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsSetValueBool(SystemSettingsKeys.LocaleTimeFormat24HourEnabled, value);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to set LocaleTimeFormat24Hour system setting.");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Indicates the current time zone. Eg. "Pacific/Tahiti"
+ /// </summary>
+ public static string LocaleTimeZone
+ {
+ get
+ {
+ string timeZone;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueString(SystemSettingsKeys.LocaleTimeZone, out timeZone);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get LocaleTimeZone system setting.");
+ }
+ return timeZone;
+ }
+ set
+ {
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsSetValueString(SystemSettingsKeys.LocaleTimeZone, value);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to set LocaleTimeZone system setting.");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Once System changes time, this event occurs to notify time change.
+ /// </summary>
+ public static int Time
+ {
+ get
+ {
+ int time;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueInt(SystemSettingsKeys.Time, out time);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get Time system setting.");
+ }
+ return time;
+ }
+ }
+ /// <summary>
+ /// Indicates whether the screen lock sound is enabled on the device. ex) LCD on/off sound
+ /// </summary>
+ public static bool SoundLockEnabled
+ {
+ get
+ {
+ bool isSoundLockEnabled;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueBool(SystemSettingsKeys.SoundLockEnabled, out isSoundLockEnabled);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get SoundLock system setting.");
+ }
+ return isSoundLockEnabled;
+ }
+ }
+
+ /// <summary>
+ /// Indicates whether the device is in the silent mode.
+ /// </summary>
+ public static bool SoundSilentModeEnabled
+ {
+ get
+ {
+ bool isSilent;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueBool(SystemSettingsKeys.SoundSilentModeEnabled, out isSilent);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get SoundSilentMode system setting.");
+ }
+ return isSilent;
+ }
+ }
+
+ /// <summary>
+ /// Indicates whether the screen touch sound is enabled on the device.
+ /// </summary>
+ public static bool SoundTouchEnabled
+ {
+ get
+ {
+ bool isTouchSoundEnabled;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueBool(SystemSettingsKeys.SoundTouchEnabled, out isTouchSoundEnabled);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get SoundTouch system setting value.");
+ }
+ return isTouchSoundEnabled;
+ }
+ }
+
+ /// <summary>
+ /// Indicates whether rotation control is automatic.
+ /// </summary>
+ public static bool DisplayScreenRotationAutoEnabled
+ {
+ get
+ {
+ bool isRotationAutomatic;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueBool(SystemSettingsKeys.DisplayScreenRotationAutoEnabled, out isRotationAutomatic);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get DisplayScreenRotationAuto system setting.");
+ }
+ return isRotationAutomatic;
+ }
+ }
+
+ /// <summary>
+ /// Indicates device name.
+ /// </summary>
+ public static string DeviceName
+ {
+ get
+ {
+ string deviceName;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueString(SystemSettingsKeys.DeviceName, out deviceName);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get DeviceName system setting value.");
+ }
+ return deviceName;
+ }
+ }
+ /// <summary>
+ /// Indicates whether the device user has enabled motion feature.
+ /// </summary>
+ public static bool MotionEnabled
+ {
+ get
+ {
+ bool isMotionEnabled;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueBool(SystemSettingsKeys.MotionEnabled, out isMotionEnabled);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get MotionEnabled system setting value.");
+ }
+ return isMotionEnabled;
+ }
+ }
+
+ /// <summary>
+ /// Indicates whether Wi-Fi-related notifications are enabled on the device.
+ /// </summary>
+ public static bool NetworkWifiNotificationEnabled
+ {
+ get
+ {
+ bool isWifiNotificationEnabled;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueBool(SystemSettingsKeys.NetworkWifiNotificationEnabled, out isWifiNotificationEnabled);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get NetworkWifiNotification system setting.");
+ }
+ return isWifiNotificationEnabled;
+ }
+ }
+
+ /// <summary>
+ /// Indicates whether the device is in the flight mode.
+ /// </summary>
+ public static bool NetworkFlightModeEnabled
+ {
+ get
+ {
+ bool isFlightModeEnabled;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueBool(SystemSettingsKeys.NetworkFlightModeEnabled, out isFlightModeEnabled);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get NetworkFlightMode system setting.");
+ }
+ return isFlightModeEnabled;
+ }
+ }
+
+ /// <summary>
+ /// Indicates the backlight time (in seconds). The following values can be used: 15, 30, 60, 120, 300, and 600.
+ /// </summary>
+ public static int ScreenBacklightTime
+ {
+ get
+ {
+ int backlightTime;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueInt(SystemSettingsKeys.ScreenBacklightTime, out backlightTime);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get ScreenBacklightTime system setting.");
+ }
+ return backlightTime;
+ }
+ set
+ {
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsSetValueInt(SystemSettingsKeys.ScreenBacklightTime, value);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to set ScreenBacklightTime system setting.");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Indicates the file path of the current notification tone set by the user.
+ /// </summary>
+ public static string SoundNotification
+ {
+ get
+ {
+ string filePath;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueString(SystemSettingsKeys.SoundNotification, out filePath);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get SoundNotification system setting.");
+ }
+ return filePath;
+ }
+ set
+ {
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsSetValueString(SystemSettingsKeys.SoundNotification, value);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to set SoundNotification system setting.");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Indicates the time period for notification repetitions.
+ /// </summary>
+ public static int SoundNotificationRepetitionPeriod
+ {
+ get
+ {
+ int notificationRepetitionPeriod;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueInt(SystemSettingsKeys.SoundNotificationRepetitionPeriod, out notificationRepetitionPeriod);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get SoundNotificationRepetitionPeriod system setting.");
+ }
+ return notificationRepetitionPeriod;
+ }
+ set
+ {
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsSetValueInt(SystemSettingsKeys.SoundNotificationRepetitionPeriod, value);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to set SoundNotificationRepetitionPeriod system setting.");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Indicates the current lock state
+ /// </summary>
+ public static SystemSettingsIdleLockState LockState
+ {
+ get
+ {
+ int LockState;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueInt(SystemSettingsKeys.LockState, out LockState);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get LockState system setting.");
+ }
+ return (SystemSettingsIdleLockState)LockState;
+ }
+ set
+ {
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsSetValueInt(SystemSettingsKeys.LockState, (int)value);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to set LockState system setting.");
+ }
+ }
+ }
+
+ /// <summary>
+ /// The current system ADS ID
+ /// </summary>
+ public static string AdsId
+ {
+ get
+ {
+ string adsId;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueString(SystemSettingsKeys.AdsId, out adsId);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get AdsId system setting.");
+ }
+ return adsId;
+ }
+ set
+ {
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsSetValueString(SystemSettingsKeys.AdsId, value);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to set AdsId system setting.");
+ }
+ }
+ }
+
+
+ /// <summary>
+ /// Indicates the time period for notification repetitions.
+ /// </summary>
+ public static SystemSettingsUdsState UltraDataSave
+ {
+ get
+ {
+ int UltraDataSave;
+ SystemSettingsError res = (SystemSettingsError)Interop.Settings.SystemSettingsGetValueInt(SystemSettingsKeys.UltraDataSave, out UltraDataSave);
+ if (res != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(res, "unable to get UltraDataSave system setting.");
+ }
+ return (SystemSettingsUdsState)UltraDataSave;
+ }
+ }
+
+
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_incomingCallRingtoneChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+ string path = SystemSettings.IncomingCallRingtone;
+ IncomingCallRingtoneChangedEventArgs eventArgs = new IncomingCallRingtoneChangedEventArgs(path);
+ s_incomingCallRingtoneChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<IncomingCallRingtoneChangedEventArgs> s_incomingCallRingtoneChanged;
+ /// <summary>
+ /// IncomingCallRingtoneChanged event is triggered when the file path of the incoming ringtone is changed
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A IncomingCallRingtoneChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<IncomingCallRingtoneChangedEventArgs> IncomingCallRingtoneChanged
+ {
+ add
+ {
+ if (s_incomingCallRingtoneChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.IncomingCallRingtone, s_incomingCallRingtoneChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_incomingCallRingtoneChanged += value;
+ }
+
+ remove
+ {
+ s_incomingCallRingtoneChanged -= value;
+ if (s_incomingCallRingtoneChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.IncomingCallRingtone);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_wallpaperHomeScreenChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+ string path = SystemSettings.WallpaperHomeScreen;
+ WallpaperHomeScreenChangedEventArgs eventArgs = new WallpaperHomeScreenChangedEventArgs(path);
+ s_wallpaperHomeScreenChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<WallpaperHomeScreenChangedEventArgs> s_wallpaperHomeScreenChanged;
+ /// <summary>
+ /// WallpaperHomeScreenChanged event is triggered when the file path of the current home screen wallpaper is changed
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A WallpaperHomeScreenChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<WallpaperHomeScreenChangedEventArgs> WallpaperHomeScreenChanged
+ {
+ add
+ {
+ if (s_wallpaperHomeScreenChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.WallpaperHomeScreen, s_wallpaperHomeScreenChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_wallpaperHomeScreenChanged += value;
+ }
+
+ remove
+ {
+ s_wallpaperHomeScreenChanged -= value;
+ if (s_wallpaperHomeScreenChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.WallpaperHomeScreen);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_wallpaperLockScreenChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+ string path = SystemSettings.WallpaperLockScreen;
+ WallpaperLockScreenChangedEventArgs eventArgs = new WallpaperLockScreenChangedEventArgs(path);
+ s_wallpaperLockScreenChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<WallpaperLockScreenChangedEventArgs> s_wallpaperLockScreenChanged;
+ /// <summary>
+ /// WallpaperLockScreenChanged event is triggered when the file path of the current lock screen wallpaper is changed
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A WallpaperLockScreenChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<WallpaperLockScreenChangedEventArgs> WallpaperLockScreenChanged
+ {
+ add
+ {
+ if (s_wallpaperLockScreenChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.WallpaperLockScreen, s_wallpaperLockScreenChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_wallpaperLockScreenChanged += value;
+ }
+
+ remove
+ {
+ s_wallpaperLockScreenChanged -= value;
+ if (s_wallpaperLockScreenChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.WallpaperLockScreen);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_fontSizeChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+ SystemSettingsFontSize fontSize = SystemSettings.FontSize;
+ FontSizeChangedEventArgs eventArgs = new FontSizeChangedEventArgs(fontSize);
+ s_fontSizeChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<FontSizeChangedEventArgs> s_fontSizeChanged;
+ /// <summary>
+ /// FontSizeChanged event is triggered when the current system font size is changed
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A FontSizeChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<FontSizeChangedEventArgs> FontSizeChanged
+ {
+ add
+ {
+ if (s_fontSizeChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.FontSize, s_fontSizeChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_fontSizeChanged += value;
+ }
+
+ remove
+ {
+ s_fontSizeChanged -= value;
+ if (s_fontSizeChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.FontSize);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_fontTypeChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+ string fontType = SystemSettings.FontType;
+ FontTypeChangedEventArgs eventArgs = new FontTypeChangedEventArgs(fontType);
+ s_fontTypeChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<FontTypeChangedEventArgs> s_fontTypeChanged;
+ /// <summary>
+ /// FontTypeChanged event is triggered when the current system font type is changed
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A FontTypeChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<FontTypeChangedEventArgs> FontTypeChanged
+ {
+ add
+ {
+ if (s_fontTypeChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.FontType, s_fontTypeChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_fontTypeChanged += value;
+ }
+
+ remove
+ {
+ s_fontTypeChanged -= value;
+ if (s_fontTypeChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.FontType);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_motionActivationChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+ bool motionActivation = SystemSettings.MotionActivationEnabled;
+ MotionActivationSettingChangedEventArgs eventArgs = new MotionActivationSettingChangedEventArgs(motionActivation);
+ s_motionActivationChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<MotionActivationSettingChangedEventArgs> s_motionActivationChanged;
+ /// <summary>
+ /// MotionActivationChanged event is triggered when the motion service status is changed
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A MotionActivationChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<MotionActivationSettingChangedEventArgs> MotionActivationSettingChanged
+ {
+ add
+ {
+ if (s_motionActivationChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.MotionActivationEnabled, s_motionActivationChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_motionActivationChanged += value;
+ }
+
+ remove
+ {
+ s_motionActivationChanged -= value;
+ if (s_motionActivationChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.MotionActivationEnabled);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_emailAlertRingtoneChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+ string emailAlertRingtone = SystemSettings.EmailAlertRingtone;
+ EmailAlertRingtoneChangedEventArgs eventArgs = new EmailAlertRingtoneChangedEventArgs(emailAlertRingtone);
+ s_emailAlertRingtoneChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<EmailAlertRingtoneChangedEventArgs> s_emailAlertRingtoneChanged;
+ /// <summary>
+ /// EmailAlertRingtoneChanged event is triggered when the file path of the current email alert ringtone is changed
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A EmailAlertRingtoneChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<EmailAlertRingtoneChangedEventArgs> EmailAlertRingtoneChanged
+ {
+ add
+ {
+ if (s_emailAlertRingtoneChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.EmailAlertRingtone, s_emailAlertRingtoneChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_emailAlertRingtoneChanged += value;
+ }
+
+ remove
+ {
+ s_emailAlertRingtoneChanged -= value;
+ if (s_emailAlertRingtoneChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.EmailAlertRingtone);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_usbDebuggingSettingChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+ bool usbDebuggingEnabled = SystemSettings.UsbDebuggingEnabled;
+ UsbDebuggingSettingChangedEventArgs eventArgs = new UsbDebuggingSettingChangedEventArgs(usbDebuggingEnabled);
+ s_usbDebuggingSettingChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<UsbDebuggingSettingChangedEventArgs> s_usbDebuggingSettingChanged;
+ /// <summary>
+ /// UsbDebuggingSettingChangedEventArgs event is triggered when the USB debugging status is changed
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A UsbDebuggingSettingChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<UsbDebuggingSettingChangedEventArgs> UsbDebuggingSettingChanged
+ {
+ add
+ {
+ if (s_usbDebuggingSettingChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.UsbDebuggingEnabled, s_usbDebuggingSettingChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_usbDebuggingSettingChanged += value;
+ }
+
+ remove
+ {
+ s_usbDebuggingSettingChanged -= value;
+ if (s_usbDebuggingSettingChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.UsbDebuggingEnabled);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_data3GNetworkSettingChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+ bool data3GEnabled = SystemSettings.Data3GNetworkEnabled;
+ Data3GNetworkSettingChangedEventArgs eventArgs = new Data3GNetworkSettingChangedEventArgs(data3GEnabled);
+ s_data3GNetworkSettingChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<Data3GNetworkSettingChangedEventArgs> s_data3GNetworkSettingChanged;
+ /// <summary>
+ /// Data3GNetworkSettingChanged event is triggered when the 3G data network status is changed
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A Data3GNetworkSettingChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<Data3GNetworkSettingChangedEventArgs> Data3GNetworkSettingChanged
+ {
+ add
+ {
+ if (s_data3GNetworkSettingChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.Data3GNetworkEnabled, s_data3GNetworkSettingChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_data3GNetworkSettingChanged += value;
+ }
+
+ remove
+ {
+ s_data3GNetworkSettingChanged -= value;
+ if (s_data3GNetworkSettingChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.Data3GNetworkEnabled);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_lockscreenAppChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+ string lockScreenApp = SystemSettings.LockscreenApp;
+ LockscreenAppChangedEventArgs eventArgs = new LockscreenAppChangedEventArgs(lockScreenApp);
+ s_lockscreenAppChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<LockscreenAppChangedEventArgs> s_lockscreenAppChanged;
+ /// <summary>
+ /// LockscreenAppChanged event is triggered when the lockscreen app pkg name is changed
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A LockscreenAppChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<LockscreenAppChangedEventArgs> LockscreenAppChanged
+ {
+ add
+ {
+ if (s_lockscreenAppChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.LockscreenApp, s_lockscreenAppChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_lockscreenAppChanged += value;
+ }
+
+ remove
+ {
+ s_lockscreenAppChanged -= value;
+ if (s_lockscreenAppChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.LockscreenApp);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_localeCountryChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+ string localeCountry = SystemSettings.LocaleCountry;
+ LocaleCountryChangedEventArgs eventArgs = new LocaleCountryChangedEventArgs(localeCountry);
+ s_localeCountryChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<LocaleCountryChangedEventArgs> s_localeCountryChanged;
+ /// <summary>
+ /// LocaleCountryChanged event is triggered when the current country setting in the &lt;LANGUAGE&gt;_&lt;REGION&gt; syntax, is changed
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A LocaleCountryChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<LocaleCountryChangedEventArgs> LocaleCountryChanged
+ {
+ add
+ {
+ if (s_localeCountryChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.LocaleCountry, s_localeCountryChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_localeCountryChanged += value;
+ }
+
+ remove
+ {
+ s_localeCountryChanged -= value;
+ if (s_localeCountryChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.LocaleCountry);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_localeLanguageChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+ string localeLanguage = SystemSettings.LocaleLanguage;
+ LocaleLanguageChangedEventArgs eventArgs = new LocaleLanguageChangedEventArgs(localeLanguage);
+ s_localeLanguageChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<LocaleLanguageChangedEventArgs> s_localeLanguageChanged;
+ /// <summary>
+ /// LocaleLanguageChanged event is triggered when the current language setting in the &lt;LANGUAGE&gt;_&lt;REGION&gt; syntax, is changed
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A LocaleLanguageChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<LocaleLanguageChangedEventArgs> LocaleLanguageChanged
+ {
+ add
+ {
+ if (s_localeLanguageChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.LocaleLanguage, s_localeLanguageChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_localeLanguageChanged += value;
+ }
+
+ remove
+ {
+ s_localeLanguageChanged -= value;
+ if (s_localeLanguageChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.LocaleLanguage);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_localeTimeFormat24HourChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+ bool localeTimeFormat24Hour = SystemSettings.LocaleTimeFormat24HourEnabled;
+ LocaleTimeFormat24HourSettingChangedEventArgs eventArgs = new LocaleTimeFormat24HourSettingChangedEventArgs(localeTimeFormat24Hour);
+ s_localeTimeFormat24HourChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<LocaleTimeFormat24HourSettingChangedEventArgs> s_localeTimeFormat24HourChanged;
+ /// <summary>
+ /// LocaleTimeFormat24HourChanged event is triggered when the time format is changed
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A LocaleTimeFormat24HourChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<LocaleTimeFormat24HourSettingChangedEventArgs> LocaleTimeFormat24HourSettingChanged
+ {
+ add
+ {
+ if (s_localeTimeFormat24HourChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.LocaleTimeFormat24HourEnabled, s_localeTimeFormat24HourChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_localeTimeFormat24HourChanged += value;
+ }
+
+ remove
+ {
+ s_localeTimeFormat24HourChanged -= value;
+ if (s_localeTimeFormat24HourChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.LocaleTimeFormat24HourEnabled);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_localeTimeZoneChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+ string localeTimeZone = SystemSettings.LocaleTimeZone;
+ LocaleTimeZoneChangedEventArgs eventArgs = new LocaleTimeZoneChangedEventArgs(localeTimeZone);
+ s_localeTimeZoneChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<LocaleTimeZoneChangedEventArgs> s_localeTimeZoneChanged;
+ /// <summary>
+ /// LocaleTimeZoneChanged event is triggered when the current time zone is changed
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A LocaleTimeZoneChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<LocaleTimeZoneChangedEventArgs> LocaleTimeZoneChanged
+ {
+ add
+ {
+ if (s_localeTimeZoneChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.LocaleTimeZone, s_localeTimeZoneChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_localeTimeZoneChanged += value;
+ }
+
+ remove
+ {
+ s_localeTimeZoneChanged -= value;
+ if (s_localeTimeZoneChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.LocaleTimeZone);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_timeChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+
+ int time = SystemSettings.Time;
+ TimeChangedEventArgs eventArgs = new TimeChangedEventArgs(time);
+ s_timeChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<TimeChangedEventArgs> s_timeChanged;
+ /// <summary>
+ /// TimeChanged event is triggered when the system time is changed
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A TimeChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<TimeChangedEventArgs> TimeChanged
+ {
+ add
+ {
+ if (s_timeChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.Time, s_timeChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_timeChanged += value;
+ }
+
+ remove
+ {
+ s_timeChanged -= value;
+ if (s_timeChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.Time);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_soundLockChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+ bool soundLock = SystemSettings.SoundLockEnabled;
+ SoundLockSettingChangedEventArgs eventArgs = new SoundLockSettingChangedEventArgs(soundLock);
+ s_soundLockChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<SoundLockSettingChangedEventArgs> s_soundLockChanged;
+ /// <summary>
+ /// SoundLockChanged event is triggered when the screen lock sound enabled status is changed
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A SoundLockChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<SoundLockSettingChangedEventArgs> SoundLockSettingChanged
+ {
+ add
+ {
+ if (s_soundLockChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.SoundLockEnabled, s_soundLockChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_soundLockChanged += value;
+ }
+
+ remove
+ {
+ s_soundLockChanged -= value;
+ if (s_soundLockChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.SoundLockEnabled);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_soundSilentModeChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+ bool soundSilentMode = SystemSettings.SoundSilentModeEnabled;
+ SoundSilentModeSettingChangedEventArgs eventArgs = new SoundSilentModeSettingChangedEventArgs(soundSilentMode);
+ s_soundSilentModeChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<SoundSilentModeSettingChangedEventArgs> s_soundSilentModeChanged;
+ /// <summary>
+ /// SoundSilentModeChanged event is triggered when the silent mode status is changed
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A SoundSilentModeChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<SoundSilentModeSettingChangedEventArgs> SoundSilentModeSettingChanged
+ {
+ add
+ {
+ if (s_soundSilentModeChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.SoundSilentModeEnabled, s_soundSilentModeChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_soundSilentModeChanged += value;
+ }
+
+ remove
+ {
+ s_soundSilentModeChanged -= value;
+ if (s_soundSilentModeChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.SoundSilentModeEnabled);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_soundTouchChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+ bool soundTouch = SystemSettings.SoundTouchEnabled;
+ SoundTouchSettingChangedEventArgs eventArgs = new SoundTouchSettingChangedEventArgs(soundTouch);
+ s_soundTouchChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<SoundTouchSettingChangedEventArgs> s_soundTouchChanged;
+ /// <summary>
+ /// SoundTouchChanged event is triggered when the screen touch sound enabled status is changed
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A SoundTouchChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<SoundTouchSettingChangedEventArgs> SoundTouchSettingChanged
+ {
+ add
+ {
+ if (s_soundTouchChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.SoundTouchEnabled, s_soundTouchChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_soundTouchChanged += value;
+ }
+
+ remove
+ {
+ s_soundTouchChanged -= value;
+ if (s_soundTouchChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.SoundTouchEnabled);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_displayScreenRotationAutoChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+ bool displayScreenRotationAuto = SystemSettings.DisplayScreenRotationAutoEnabled;
+ DisplayScreenRotationAutoSettingChangedEventArgs eventArgs = new DisplayScreenRotationAutoSettingChangedEventArgs(displayScreenRotationAuto);
+ s_displayScreenRotationAutoChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<DisplayScreenRotationAutoSettingChangedEventArgs> s_displayScreenRotationAutoChanged;
+ /// <summary>
+ /// DisplayScreenRotationAutoChanged event is triggered when the automatic rotation control status is changed
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A DisplayScreenRotationAutoChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<DisplayScreenRotationAutoSettingChangedEventArgs> DisplayScreenRotationAutoSettingChanged
+ {
+ add
+ {
+ if (s_displayScreenRotationAutoChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.DisplayScreenRotationAutoEnabled, s_displayScreenRotationAutoChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_displayScreenRotationAutoChanged += value;
+ }
+
+ remove
+ {
+ s_displayScreenRotationAutoChanged -= value;
+ if (s_displayScreenRotationAutoChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.DisplayScreenRotationAutoEnabled);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_deviceNameChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+ string deviceName = SystemSettings.DeviceName;
+ DeviceNameChangedEventArgs eventArgs = new DeviceNameChangedEventArgs(deviceName);
+ s_deviceNameChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<DeviceNameChangedEventArgs> s_deviceNameChanged;
+ /// <summary>
+ /// DeviceNameChanged event is triggered when the device name is changed
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A DeviceNameChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<DeviceNameChangedEventArgs> DeviceNameChanged
+ {
+ add
+ {
+ if (s_deviceNameChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.DeviceName, s_deviceNameChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_deviceNameChanged += value;
+ }
+
+ remove
+ {
+ s_deviceNameChanged -= value;
+ if (s_deviceNameChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.DeviceName);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_motionSettingChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+ bool motionEnabled = SystemSettings.MotionEnabled;
+ MotionSettingChangedEventArgs eventArgs = new MotionSettingChangedEventArgs(motionEnabled);
+ s_motionSettingChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<MotionSettingChangedEventArgs> s_motionSettingChanged;
+ /// <summary>
+ /// MotionSettingChanged event is triggered when the motion feature enabled status is changed
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A MotionSettingChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<MotionSettingChangedEventArgs> MotionSettingChanged
+ {
+ add
+ {
+ if (s_motionSettingChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.MotionEnabled, s_motionSettingChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_motionSettingChanged += value;
+ }
+
+ remove
+ {
+ s_motionSettingChanged -= value;
+ if (s_motionSettingChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.MotionEnabled);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_networkWifiNotificationChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+ bool networkWifiNotification = SystemSettings.NetworkWifiNotificationEnabled;
+ NetworkWifiNotificationSettingChangedEventArgs eventArgs = new NetworkWifiNotificationSettingChangedEventArgs(networkWifiNotification);
+ s_networkWifiNotificationChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<NetworkWifiNotificationSettingChangedEventArgs> s_networkWifiNotificationChanged;
+ /// <summary>
+ /// NetworkWifiNotificationChanged event is triggered when the Wi-Fi-related notifications enabled status is changed
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A NetworkWifiNotificationChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<NetworkWifiNotificationSettingChangedEventArgs> NetworkWifiNotificationSettingChanged
+ {
+ add
+ {
+ if (s_networkWifiNotificationChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.NetworkWifiNotificationEnabled, s_networkWifiNotificationChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_networkWifiNotificationChanged += value;
+ }
+
+ remove
+ {
+ s_networkWifiNotificationChanged -= value;
+ if (s_networkWifiNotificationChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.NetworkWifiNotificationEnabled);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_networkFlightModeChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+ bool networkFlightMode = SystemSettings.NetworkFlightModeEnabled;
+ NetworkFlightModeSettingChangedEventArgs eventArgs = new NetworkFlightModeSettingChangedEventArgs(networkFlightMode);
+ s_networkFlightModeChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<NetworkFlightModeSettingChangedEventArgs> s_networkFlightModeChanged;
+ /// <summary>
+ /// NetworkFlightModeChanged event is triggered when the flight mode status is changed
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A NetworkFlightModeChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<NetworkFlightModeSettingChangedEventArgs> NetworkFlightModeSettingChanged
+ {
+ add
+ {
+ if (s_networkFlightModeChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.NetworkFlightModeEnabled, s_networkFlightModeChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_networkFlightModeChanged += value;
+ }
+
+ remove
+ {
+ s_networkFlightModeChanged -= value;
+ if (s_networkFlightModeChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.NetworkFlightModeEnabled);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_screenBacklightTimeChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+ int screenBacklightTime = SystemSettings.ScreenBacklightTime;
+ ScreenBacklightTimeChangedEventArgs eventArgs = new ScreenBacklightTimeChangedEventArgs(screenBacklightTime);
+ s_screenBacklightTimeChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<ScreenBacklightTimeChangedEventArgs> s_screenBacklightTimeChanged;
+ /// <summary>
+ /// ScreenBacklightTimeChanged event is triggered when the backlight time is changed.
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A ScreenBacklightTimeChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<ScreenBacklightTimeChangedEventArgs> ScreenBacklightTimeChanged
+ {
+ add
+ {
+ if (s_screenBacklightTimeChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.ScreenBacklightTime, s_screenBacklightTimeChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_screenBacklightTimeChanged += value;
+ }
+
+ remove
+ {
+ s_screenBacklightTimeChanged -= value;
+ if (s_screenBacklightTimeChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.ScreenBacklightTime);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_soundNotificationChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+ string soundNotification = SystemSettings.SoundNotification;
+ SoundNotificationChangedEventArgs eventArgs = new SoundNotificationChangedEventArgs(soundNotification);
+ s_soundNotificationChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<SoundNotificationChangedEventArgs> s_soundNotificationChanged;
+ /// <summary>
+ /// SoundNotificationChanged event is triggered when the file path of the current notification tone set by the user is changed
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A SoundNotificationChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<SoundNotificationChangedEventArgs> SoundNotificationChanged
+ {
+ add
+ {
+ if (s_soundNotificationChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.SoundNotification, s_soundNotificationChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_soundNotificationChanged += value;
+ }
+
+ remove
+ {
+ s_soundNotificationChanged -= value;
+ if (s_soundNotificationChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.SoundNotification);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_soundNotificationRepetitionPeriodChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+ int soundNotificationRepetitionPeriod = SystemSettings.SoundNotificationRepetitionPeriod;
+ SoundNotificationRepetitionPeriodChangedEventArgs eventArgs = new SoundNotificationRepetitionPeriodChangedEventArgs(soundNotificationRepetitionPeriod);
+ s_soundNotificationRepetitionPeriodChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<SoundNotificationRepetitionPeriodChangedEventArgs> s_soundNotificationRepetitionPeriodChanged;
+ /// <summary>
+ /// SoundNotificationRepetitionPeriodChanged event is triggered when the time period for notification repetitions is changed
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A SoundNotificationRepetitionPeriodChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<SoundNotificationRepetitionPeriodChangedEventArgs> SoundNotificationRepetitionPeriodChanged
+ {
+ add
+ {
+ if (s_soundNotificationRepetitionPeriodChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.SoundNotificationRepetitionPeriod, s_soundNotificationRepetitionPeriodChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_soundNotificationRepetitionPeriodChanged += value;
+ }
+
+ remove
+ {
+ s_soundNotificationRepetitionPeriodChanged -= value;
+ if (s_soundNotificationRepetitionPeriodChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.SoundNotificationRepetitionPeriod);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_lockStateChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+ SystemSettingsIdleLockState lockState = SystemSettings.LockState;
+ LockStateChangedEventArgs eventArgs = new LockStateChangedEventArgs(lockState);
+ s_lockStateChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<LockStateChangedEventArgs> s_lockStateChanged;
+ /// <summary>
+ /// LockStateChanged event is triggered when the current lock state is changed
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A LockStateChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<LockStateChangedEventArgs> LockStateChanged
+ {
+ add
+ {
+ if (s_lockStateChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.LockState, s_lockStateChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_lockStateChanged += value;
+ }
+
+ remove
+ {
+ s_lockStateChanged -= value;
+ if (s_lockStateChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.LockState);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_adsIdChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+ string adsId = SystemSettings.AdsId;
+ AdsIdChangedEventArgs eventArgs = new AdsIdChangedEventArgs(adsId);
+ s_adsIdChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<AdsIdChangedEventArgs> s_adsIdChanged;
+ /// <summary>
+ /// AdsIdChanged event is triggered when the current ADS ID state is changed
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A AdsIdChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<AdsIdChangedEventArgs> AdsIdChanged
+ {
+ add
+ {
+ if (s_adsIdChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.AdsId, s_adsIdChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_adsIdChanged += value;
+ }
+
+ remove
+ {
+ s_adsIdChanged -= value;
+ if (s_adsIdChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.AdsId);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_ultraDataSaveChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+ SystemSettingsUdsState ultraDataSave = SystemSettings.UltraDataSave;
+ UltraDataSaveChangedEventArgs eventArgs = new UltraDataSaveChangedEventArgs(ultraDataSave);
+ s_ultraDataSaveChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<UltraDataSaveChangedEventArgs> s_ultraDataSaveChanged;
+ /// <summary>
+ /// UltraDataSaveChanged event is triggered when the current Ultra Data Save state is changed
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A UltraDataSaveChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<UltraDataSaveChangedEventArgs> UltraDataSaveChanged
+ {
+ add
+ {
+ if (s_ultraDataSaveChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.UltraDataSave, s_ultraDataSaveChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_ultraDataSaveChanged += value;
+ }
+
+ remove
+ {
+ s_ultraDataSaveChanged -= value;
+ if (s_ultraDataSaveChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.UltraDataSave);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+
+ private static readonly Interop.Settings.SystemSettingsChangedCallback s_ultraDataSavePackageListChangedCallback = (SystemSettingsKeys key, IntPtr userData) =>
+ {
+ string ultraDataSavePackageList = "None";
+ UltraDataSavePackageListChangedEventArgs eventArgs = new UltraDataSavePackageListChangedEventArgs(ultraDataSavePackageList);
+ s_ultraDataSavePackageListChanged?.Invoke(null, eventArgs);
+ };
+ private static event EventHandler<UltraDataSavePackageListChangedEventArgs> s_ultraDataSavePackageListChanged;
+ /// <summary>
+ /// UltraDataSavePackageListChanged event is triggered when the current ADS ID state is changed
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">A UltraDataSavePackageListChangedEventArgs object that contains the key & changed value</param>
+ public static event EventHandler<UltraDataSavePackageListChangedEventArgs> UltraDataSavePackageListChanged
+ {
+ add
+ {
+ if (s_ultraDataSavePackageListChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsSetCallback(SystemSettingsKeys.UltraDataSavePackageList, s_ultraDataSavePackageListChangedCallback, IntPtr.Zero);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ s_ultraDataSavePackageListChanged += value;
+ }
+
+ remove
+ {
+ s_ultraDataSavePackageListChanged -= value;
+ if (s_ultraDataSavePackageListChanged == null)
+ {
+ SystemSettingsError ret = (SystemSettingsError)Interop.Settings.SystemSettingsRemoveCallback(SystemSettingsKeys.UltraDataSavePackageList);
+ if (ret != SystemSettingsError.None)
+ {
+ throw SystemSettingsExceptionFactory.CreateException(ret, "Error in callback handling");
+ }
+ }
+ }
+ }
+ }
+}
+
diff --git a/src/Tizen.System.SystemSettings/Tizen.System.SystemSettings/SystemSettingsEnums.cs b/src/Tizen.System.SystemSettings/Tizen.System.SystemSettings/SystemSettingsEnums.cs
new file mode 100755
index 0000000..e935db5
--- /dev/null
+++ b/src/Tizen.System.SystemSettings/Tizen.System.SystemSettings/SystemSettingsEnums.cs
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.System
+{
+ /// <summary>
+ /// Enumeration for all available system settings
+ /// </summary>
+ public enum SystemSettingsKeys : int
+ {
+ /// <summary>
+ /// (string) The file path of the current ringtone
+ /// </summary>
+ IncomingCallRingtone = 0,
+ /// <summary>
+ /// (string) The file path of the current home screen wallpaper
+ /// </summary>
+ WallpaperHomeScreen,
+ /// <summary>
+ /// (string) The file path of the current lock screen wallpaper
+ /// </summary>
+ WallpaperLockScreen,
+ /// <summary>
+ /// (int) The current system font size
+ /// </summary>
+ FontSize,
+ /// <summary>
+ /// (string) The current system font type
+ /// </summary>
+ FontType,
+ /// <summary>
+ /// (bool) Indicates whether the motion service is activated
+ /// </summary>
+ MotionActivationEnabled,
+ /// <summary>
+ /// (string) The file path of the current email alert ringtone
+ /// </summary>
+ EmailAlertRingtone,
+ /// <summary>
+ /// (bool) Indicates whether the USB debugging is enabled
+ /// </summary>
+ UsbDebuggingEnabled,
+ /// <summary>
+ /// (bool) Indicates whether the 3G data network is enabled
+ /// </summary>
+ Data3GNetworkEnabled,
+ /// <summary>
+ /// (string) Indicates lockscreen app pkg name
+ /// </summary>
+ LockscreenApp = Data3GNetworkEnabled + 2,
+ /// <summary>
+ /// (string) The current system default font type (only support Get)
+ /// </summary>
+ DefaultFontType,
+ /// <summary>
+ /// (string) Indicates the current country setting in the &lt;LANGUAGE&gt;_&lt;REGION&gt; syntax.
+ /// The country setting is in the ISO 639-2 format,
+ /// and the region setting is in the ISO 3166-1 alpha-2 format
+ /// </summary>
+ LocaleCountry,
+ /// <summary>
+ /// (string) Indicates the current language setting in the &lt;LANGUAGE&gt;_&lt;REGION&gt; syntax.
+ /// The language setting is in the ISO 639-2 format
+ /// and the region setting is in the ISO 3166-1 alpha-2 format.
+ /// </summary>
+ LocaleLanguage,
+ /// <summary>
+ /// (bool) Indicates whether the 24-hour clock is used.
+ /// If the value is false, the 12-hour clock is used.
+ /// </summary>
+ LocaleTimeFormat24HourEnabled,
+ /// <summary>
+ /// (string) Indicates the current time zone. Eg. Pacific/Tahiti
+ /// </summary>
+ LocaleTimeZone,
+ /// <summary>
+ /// (int) Once System changes time, this event occurs to notify time change.
+ /// </summary>
+ Time,
+ /// <summary>
+ /// GET (bool) Indicates whether the screen lock sound is enabled on the device. ex) LCD on/off sound
+ /// </summary>
+ SoundLockEnabled,
+ /// <summary>
+ /// GET (bool) Indicates whether the device is in the silent mode.
+ /// </summary>
+ SoundSilentModeEnabled,
+ /// <summary>
+ /// GET (bool) Indicates whether the screen touch sound is enabled on the device.
+ /// </summary>
+ SoundTouchEnabled,
+ /// <summary>
+ /// GET (bool) Indicates whether rotation control is automatic.
+ /// </summary>
+ DisplayScreenRotationAutoEnabled,
+ /// <summary>
+ /// GET (string) Indicates device name.
+ /// </summary>
+ DeviceName,
+ /// <summary>
+ /// GET (bool) Indicates whether the device user has enabled motion feature.
+ /// </summary>
+ MotionEnabled,
+ /// <summary>
+ /// GET (bool) Indicates whether Wi-Fi-related notifications are enabled on the device.
+ /// </summary>
+ NetworkWifiNotificationEnabled,
+ /// <summary>
+ /// GET (bool) Indicates whether the device is in the flight mode.
+ /// </summary>
+ NetworkFlightModeEnabled,
+ /// <summary>
+ /// (int) Indicates the backlight time (in seconds). The following values can be used: 15, 30, 60, 120, 300, and 600.
+ /// </summary>
+ ScreenBacklightTime,
+ /// <summary>
+ /// (string) Indicates the file path of the current notification tone set by the user.
+ /// </summary>
+ SoundNotification,
+ /// <summary>
+ /// (int) Indicates the time period for notification repetitions.
+ /// </summary>
+ SoundNotificationRepetitionPeriod,
+ /// <summary>
+ /// (int) Indicates the current lock state
+ /// </summary>
+ LockState,
+ /// <summary>
+ /// (string) Indicates Ads ID for each device
+ /// </summary>
+ AdsId,
+ /// <summary>
+ /// (int) Indicates Ultra Data Save status, one of #SystemSettingsUdsState values
+ /// </summary>
+ UltraDataSave,
+ /// <summary>
+ /// (string) Indicates Ultra Data Save Package List (Since 4.0), the list is a string containing whitelisted package names separated with semicolons (;)
+ /// </summary>
+ UltraDataSavePackageList
+ }
+ /// <summary>
+ /// Enumeration for Idle Lock State.
+ /// </summary>
+ public enum SystemSettingsIdleLockState : int
+ {
+ /// <summary>
+ /// Device is unlocked
+ /// </summary>
+ Unlock = 0,
+ /// <summary>
+ /// Device is locked
+ /// </summary>
+ Lock,
+ /// <summary>
+ /// Device is being locked
+ /// </summary>
+ LaunchingLock
+ }
+ /// <summary>
+ /// Enumeration for font size.
+ /// </summary>
+ public enum SystemSettingsFontSize : int
+ {
+ /// <summary>
+ /// A small size
+ /// </summary>
+ Small = 0,
+ /// <summary>
+ /// A normal size
+ /// </summary>
+ Normal,
+ /// <summary>
+ /// A large size
+ /// </summary>
+ Large,
+ /// <summary>
+ /// A huge size
+ /// </summary>
+ Huge,
+ /// <summary>
+ /// A giant size
+ /// </summary>
+ Giant
+ }
+ /// <summary>
+ /// Enumeration for ultra data save
+ /// </summary>
+ public enum SystemSettingsUdsState : int
+ {
+ /// <summary>
+ /// UDS Off
+ /// </summary>
+ UdsOff = 0,
+ /// <summary>
+ /// UDS On
+ /// </summary>
+ UdsOn,
+ /// <summary>
+ /// UDS On and the app is whitelisted
+ /// </summary>
+ UdsOnWhitelisted,
+ }
+}
diff --git a/src/Tizen.System.SystemSettings/Tizen.System.SystemSettings/SystemSettingsEventArgs.cs b/src/Tizen.System.SystemSettings/Tizen.System.SystemSettings/SystemSettingsEventArgs.cs
new file mode 100755
index 0000000..0cdd7ae
--- /dev/null
+++ b/src/Tizen.System.SystemSettings/Tizen.System.SystemSettings/SystemSettingsEventArgs.cs
@@ -0,0 +1,712 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.System
+{
+ /// <summary>
+ /// EventArgs type for the event IncomingCallRingtoneChanged
+ /// </summary>
+ public class IncomingCallRingtoneChangedEventArgs : EventArgs
+ {
+ private readonly string _incomingCallRingtone = null;
+ internal IncomingCallRingtoneChangedEventArgs(string val)
+ {
+ _incomingCallRingtone = val;
+ }
+
+ /// <summary>
+ /// The file path of the current ringtone
+ /// </summary>
+ public string Value
+ {
+ get
+ {
+ return _incomingCallRingtone;
+ }
+ }
+ }
+
+ /// <summary>
+ /// EventArgs type for the event WallpaperHomeScreenChanged
+ /// </summary>
+ public class WallpaperHomeScreenChangedEventArgs : EventArgs
+ {
+ private readonly string _wallpaperHomeScreen = null;
+ internal WallpaperHomeScreenChangedEventArgs(string val)
+ {
+ _wallpaperHomeScreen = val;
+ }
+
+ /// <summary>
+ /// The file path of the current home screen wallpaper
+ /// </summary>
+ public string Value
+ {
+ get
+ {
+ return _wallpaperHomeScreen;
+ }
+ }
+ }
+
+ /// <summary>
+ /// EventArgs type for the event WallpaperLockScreenChanged
+ /// </summary>
+ public class WallpaperLockScreenChangedEventArgs : EventArgs
+ {
+ private readonly string _wallpaperLockScreen = null;
+ internal WallpaperLockScreenChangedEventArgs(string val)
+ {
+ _wallpaperLockScreen = val;
+ }
+
+ /// <summary>
+ /// The file path of the current lock screen wallpaper
+ /// </summary>
+ public string Value
+ {
+ get
+ {
+ return _wallpaperLockScreen;
+ }
+ }
+ }
+
+ /// <summary>
+ /// EventArgs type for the event FontSizeChanged
+ /// </summary>
+ public class FontSizeChangedEventArgs : EventArgs
+ {
+ private readonly SystemSettingsFontSize _fontSize;
+ internal FontSizeChangedEventArgs(SystemSettingsFontSize val)
+ {
+ _fontSize = val;
+ }
+
+ /// <summary>
+ /// The current system font size
+ /// </summary>
+ public SystemSettingsFontSize Value
+ {
+ get
+ {
+ return _fontSize;
+ }
+ }
+ }
+
+ /// <summary>
+ /// EventArgs type for the event FontTypeChanged
+ /// </summary>
+ public class FontTypeChangedEventArgs : EventArgs
+ {
+ private readonly string _fontType = null;
+ internal FontTypeChangedEventArgs(string val)
+ {
+ _fontType = val;
+ }
+
+ /// <summary>
+ /// The current system font type
+ /// </summary>
+ public string Value
+ {
+ get
+ {
+ return _fontType;
+ }
+ }
+ }
+
+ /// <summary>
+ /// EventArgs type for the event MotionActivationChanged
+ /// </summary>
+ public class MotionActivationSettingChangedEventArgs : EventArgs
+ {
+ private readonly bool _motionActivation;
+ internal MotionActivationSettingChangedEventArgs(bool val)
+ {
+ _motionActivation = val;
+ }
+
+ /// <summary>
+ /// Indicates whether the motion service is activated
+ /// </summary>
+ public bool Value
+ {
+ get
+ {
+ return _motionActivation;
+ }
+ }
+ }
+
+ /// <summary>
+ /// EventArgs type for the event EmailAlertRingtoneChanged
+ /// </summary>
+ public class EmailAlertRingtoneChangedEventArgs : EventArgs
+ {
+ private readonly string _emailAlertRingtone = null;
+ internal EmailAlertRingtoneChangedEventArgs(string val)
+ {
+ _emailAlertRingtone = val;
+ }
+
+ /// <summary>
+ /// The file path of the current email alert ringtone
+ /// </summary>
+ public string Value
+ {
+ get
+ {
+ return _emailAlertRingtone;
+ }
+ }
+ }
+
+ /// <summary>
+ /// EventArgs type for the event UsbDebuggingSettingChanged
+ /// </summary>
+ public class UsbDebuggingSettingChangedEventArgs : EventArgs
+ {
+ private readonly bool _usbDebuggingEnabled;
+ internal UsbDebuggingSettingChangedEventArgs(bool val)
+ {
+ _usbDebuggingEnabled = val;
+ }
+
+ /// <summary>
+ /// Indicates whether the USB debugging is enabled
+ /// </summary>
+ public bool Value
+ {
+ get
+ {
+ return _usbDebuggingEnabled;
+ }
+ }
+ }
+
+ /// <summary>
+ /// EventArgs type for the event Data3GNetworkSettingChanged
+ /// </summary>
+ public class Data3GNetworkSettingChangedEventArgs : EventArgs
+ {
+ private readonly bool _data3GNetworkEnabled;
+ internal Data3GNetworkSettingChangedEventArgs(bool val)
+ {
+ _data3GNetworkEnabled = val;
+ }
+
+ /// <summary>
+ /// Indicates whether the 3G data network is enabled
+ /// </summary>
+ public bool Value
+ {
+ get
+ {
+ return _data3GNetworkEnabled;
+ }
+ }
+ }
+
+ /// <summary>
+ /// EventArgs type for the event LockscreenAppChanged
+ /// </summary>
+ public class LockscreenAppChangedEventArgs : EventArgs
+ {
+ private readonly string _lockscreenApp = null;
+ internal LockscreenAppChangedEventArgs(string val)
+ {
+ _lockscreenApp = val;
+ }
+
+ /// <summary>
+ /// Indicates lockscreen app pkg name
+ /// </summary>
+ public string Value
+ {
+ get
+ {
+ return _lockscreenApp;
+ }
+ }
+ }
+
+ /// <summary>
+ /// EventArgs type for the event LocaleCountryChanged
+ /// </summary>
+ public class LocaleCountryChangedEventArgs : EventArgs
+ {
+ private readonly string _localeCountry = null;
+ internal LocaleCountryChangedEventArgs(string val)
+ {
+ _localeCountry = val;
+ }
+
+ /// <summary>
+ /// Indicates the current country setting in the &lt;LANGUAGE&gt;_&lt;REGION&gt; syntax.
+ /// The country setting is in the ISO 639-2 format, and the region setting is in the ISO 3166-1 alpha-2 format
+ /// </summary>
+ public string Value
+ {
+ get
+ {
+ return _localeCountry;
+ }
+ }
+ }
+
+ /// <summary>
+ /// EventArgs type for the event LocaleLanguageChanged
+ /// </summary>
+ public class LocaleLanguageChangedEventArgs : EventArgs
+ {
+ private readonly string _localeLanguage = null;
+ internal LocaleLanguageChangedEventArgs(string val)
+ {
+ _localeLanguage = val;
+ }
+
+ /// <summary>
+ /// Indicates the current language setting in the &lt;LANGUAGE&gt;_&lt;REGION&gt; syntax.
+ /// The language setting is in the ISO 639-2 format and the region setting is in the ISO 3166-1 alpha-2 format
+ /// </summary>
+ public string Value
+ {
+ get
+ {
+ return _localeLanguage;
+ }
+ }
+ }
+
+ /// <summary>
+ /// EventArgs type for the event LocaleTimeFormat24HourChanged
+ /// </summary>
+ public class LocaleTimeFormat24HourSettingChangedEventArgs : EventArgs
+ {
+ private readonly bool _localeTimeFormat24Hour;
+ internal LocaleTimeFormat24HourSettingChangedEventArgs(bool val)
+ {
+ _localeTimeFormat24Hour = val;
+ }
+
+ /// <summary>
+ /// Indicates whether the 24-hour clock is used. If the value is false, the 12-hour clock is used.
+ /// </summary>
+ public bool Value
+ {
+ get
+ {
+ return _localeTimeFormat24Hour;
+ }
+ }
+ }
+
+ /// <summary>
+ /// EventArgs type for the event LocaleTimeZoneChanged
+ /// </summary>
+ public class LocaleTimeZoneChangedEventArgs : EventArgs
+ {
+ private readonly string _localeTimeZone = null;
+ internal LocaleTimeZoneChangedEventArgs(string val)
+ {
+ _localeTimeZone = val;
+ }
+
+ /// <summary>
+ /// Indicates the current time zone
+ /// </summary>
+ public string Value
+ {
+ get
+ {
+ return _localeTimeZone;
+ }
+ }
+ }
+
+ /// <summary>
+ /// EventArgs type for the event TimeChanged
+ /// </summary>
+ public class TimeChangedEventArgs : EventArgs
+ {
+ private readonly int _time;
+ internal TimeChangedEventArgs(int val)
+ {
+ _time = val;
+ }
+
+ /// <summary>
+ /// Indicates the current time
+ /// </summary>
+ public int Value
+ {
+ get
+ {
+ return _time;
+ }
+ }
+ }
+
+ /// <summary>
+ /// EventArgs type for the event SoundLockChanged
+ /// </summary>
+ public class SoundLockSettingChangedEventArgs : EventArgs
+ {
+ private readonly bool _soundLock;
+ internal SoundLockSettingChangedEventArgs(bool val)
+ {
+ _soundLock = val;
+ }
+
+ /// <summary>
+ /// Indicates whether the screen lock sound is enabled on the device. ex) LCD on/off sound
+ /// </summary>
+ public bool Value
+ {
+ get
+ {
+ return _soundLock;
+ }
+ }
+ }
+
+ /// <summary>
+ /// EventArgs type for the event SoundSilentModeChanged
+ /// </summary>
+ public class SoundSilentModeSettingChangedEventArgs : EventArgs
+ {
+ private readonly bool _soundSilentMode;
+ internal SoundSilentModeSettingChangedEventArgs(bool val)
+ {
+ _soundSilentMode = val;
+ }
+
+ /// <summary>
+ /// Indicates whether the device is in the silent mode.
+ /// </summary>
+ public bool Value
+ {
+ get
+ {
+ return _soundSilentMode;
+ }
+ }
+ }
+
+ /// <summary>
+ /// EventArgs type for the event SoundTouchChanged
+ /// </summary>
+ public class SoundTouchSettingChangedEventArgs : EventArgs
+ {
+ private readonly bool _soundTouch;
+ internal SoundTouchSettingChangedEventArgs(bool val)
+ {
+ _soundTouch = val;
+ }
+
+ /// <summary>
+ /// Indicates whether the screen touch sound is enabled on the device.
+ /// </summary>
+ public bool Value
+ {
+ get
+ {
+ return _soundTouch;
+ }
+ }
+ }
+
+ /// <summary>
+ /// EventArgs type for the event DisplayScreenRotationAutoChanged
+ /// </summary>
+ public class DisplayScreenRotationAutoSettingChangedEventArgs : EventArgs
+ {
+ private readonly bool _displayScreenRotationAuto;
+ internal DisplayScreenRotationAutoSettingChangedEventArgs(bool val)
+ {
+ _displayScreenRotationAuto = val;
+ }
+
+ /// <summary>
+ /// Indicates whether rotation control is automatic
+ /// </summary>
+ public bool Value
+ {
+ get
+ {
+ return _displayScreenRotationAuto;
+ }
+ }
+ }
+
+ /// <summary>
+ /// EventArgs type for the event DeviceNameChanged
+ /// </summary>
+ public class DeviceNameChangedEventArgs : EventArgs
+ {
+ private readonly string _deviceName = null;
+ internal DeviceNameChangedEventArgs(string val)
+ {
+ _deviceName = val;
+ }
+
+ /// <summary>
+ /// Indicates device name
+ /// </summary>
+ public string Value
+ {
+ get
+ {
+ return _deviceName;
+ }
+ }
+ }
+
+ /// <summary>
+ /// EventArgs type for the event MotionSettingChanged
+ /// </summary>
+ public class MotionSettingChangedEventArgs : EventArgs
+ {
+ private readonly bool _motionEnabled;
+ internal MotionSettingChangedEventArgs(bool val)
+ {
+ _motionEnabled = val;
+ }
+
+ /// <summary>
+ /// Indicates whether the device user has enabled motion feature
+ /// </summary>
+ public bool Value
+ {
+ get
+ {
+ return _motionEnabled;
+ }
+ }
+ }
+
+ /// <summary>
+ /// EventArgs type for the event NetworkWifiNotificationChanged
+ /// </summary>
+ public class NetworkWifiNotificationSettingChangedEventArgs : EventArgs
+ {
+ private readonly bool _networkWifiNotification;
+ internal NetworkWifiNotificationSettingChangedEventArgs(bool val)
+ {
+ _networkWifiNotification = val;
+ }
+
+ /// <summary>
+ /// Indicates whether Wi-Fi-related notifications are enabled on the device
+ /// </summary>
+ public bool Value
+ {
+ get
+ {
+ return _networkWifiNotification;
+ }
+ }
+ }
+
+ /// <summary>
+ /// EventArgs type for the event NetworkFlightModeChanged
+ /// </summary>
+ public class NetworkFlightModeSettingChangedEventArgs : EventArgs
+ {
+ private readonly bool _networkFlightMode;
+ internal NetworkFlightModeSettingChangedEventArgs(bool val)
+ {
+ _networkFlightMode = val;
+ }
+
+ /// <summary>
+ /// Indicates whether the device is in the flight mode
+ /// </summary>
+ public bool Value
+ {
+ get
+ {
+ return _networkFlightMode;
+ }
+ }
+ }
+
+ /// <summary>
+ /// EventArgs type for the event ScreenBacklightTimeChanged
+ /// </summary>
+ public class ScreenBacklightTimeChangedEventArgs : EventArgs
+ {
+ private readonly int _screenBacklightTime;
+ internal ScreenBacklightTimeChangedEventArgs(int val)
+ {
+ _screenBacklightTime = val;
+ }
+
+ /// <summary>
+ /// Indicates the backlight time (in seconds)
+ /// </summary>
+ public int Value
+ {
+ get
+ {
+ return _screenBacklightTime;
+ }
+ }
+ }
+
+ /// <summary>
+ /// EventArgs type for the event SoundNotificationChanged
+ /// </summary>
+ public class SoundNotificationChangedEventArgs : EventArgs
+ {
+ private readonly string _soundNotification = null;
+ internal SoundNotificationChangedEventArgs(string val)
+ {
+ _soundNotification = val;
+ }
+
+ /// <summary>
+ /// Indicates the file path of the current notification tone set by the user
+ /// </summary>
+ public string Value
+ {
+ get
+ {
+ return _soundNotification;
+ }
+ }
+ }
+
+ /// <summary>
+ /// EventArgs type for the event SoundNotificationRepetitionPeriodChanged
+ /// </summary>
+ public class SoundNotificationRepetitionPeriodChangedEventArgs : EventArgs
+ {
+ private readonly int _soundNotificationRepetitionPeriod;
+ internal SoundNotificationRepetitionPeriodChangedEventArgs(int val)
+ {
+ _soundNotificationRepetitionPeriod = val;
+ }
+
+ /// <summary>
+ /// Indicates the time period for notification repetitions
+ /// </summary>
+ public int Value
+ {
+ get
+ {
+ return _soundNotificationRepetitionPeriod;
+ }
+ }
+ }
+
+ /// <summary>
+ /// EventArgs type for the event LockStateChanged
+ /// </summary>
+ public class LockStateChangedEventArgs : EventArgs
+ {
+ private readonly SystemSettingsIdleLockState _lockState;
+ internal LockStateChangedEventArgs(SystemSettingsIdleLockState val)
+ {
+ _lockState = val;
+ }
+
+ /// <summary>
+ /// Indicates the current lock state
+ /// </summary>
+ public SystemSettingsIdleLockState Value
+ {
+ get
+ {
+ return _lockState;
+ }
+ }
+ }
+
+ /// <summary>
+ /// EventArgs type for the event AdsIdChanged
+ /// </summary>
+ public class AdsIdChangedEventArgs : EventArgs
+ {
+ private readonly string _adsId = null;
+ internal AdsIdChangedEventArgs(string val)
+ {
+ _adsId = val;
+ }
+
+ /// <summary>
+ /// Indicates the current lock state
+ /// </summary>
+ public string Value
+ {
+ get
+ {
+ return _adsId;
+ }
+ }
+ }
+
+ /// <summary>
+ /// EventArgs type for the event UltraDataSaveChanged
+ /// </summary>
+ public class UltraDataSaveChangedEventArgs : EventArgs
+ {
+ private readonly SystemSettingsUdsState _ultraDataSave = SystemSettingsUdsState.UdsOff;
+ internal UltraDataSaveChangedEventArgs(SystemSettingsUdsState val)
+ {
+ _ultraDataSave = val;
+ }
+
+ /// <summary>
+ /// Indicates the current lock state
+ /// </summary>
+ public SystemSettingsUdsState Value
+ {
+ get
+ {
+ return _ultraDataSave;
+ }
+ }
+ }
+
+ /// <summary>
+ /// EventArgs type for the event UltraDataSavePackageListChanged
+ /// </summary>
+ public class UltraDataSavePackageListChangedEventArgs : EventArgs
+ {
+ private readonly string _ultraDataSavePackageList = null;
+ internal UltraDataSavePackageListChangedEventArgs(string val)
+ {
+ _ultraDataSavePackageList = val;
+ }
+
+ /// <summary>
+ /// Indicates the current lock state
+ /// </summary>
+ public string Value
+ {
+ get
+ {
+ return _ultraDataSavePackageList;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.System.SystemSettings/Tizen.System.SystemSettings/SystemSettingsExceptionFactory.cs b/src/Tizen.System.SystemSettings/Tizen.System.SystemSettings/SystemSettingsExceptionFactory.cs
new file mode 100644
index 0000000..039ff41
--- /dev/null
+++ b/src/Tizen.System.SystemSettings/Tizen.System.SystemSettings/SystemSettingsExceptionFactory.cs
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.System
+{
+ internal enum SystemSettingsError
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None,
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+ OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
+ IoError = Tizen.Internals.Errors.ErrorCode.IoError,
+ PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied,
+ NotSupported = Tizen.Internals.Errors.ErrorCode.NotSupported,
+ LockScreenAppPasswordMode = -0x01140000 | 0x01
+ };
+ internal class SystemSettingsExceptionFactory
+ {
+ internal const string LogTag = "Tizen.System.SystemSettings";
+
+ internal static Exception CreateException(SystemSettingsError err, string msg)
+ {
+ Exception exp;
+ switch (err)
+ {
+ case SystemSettingsError.InvalidParameter:
+ exp = new ArgumentException(msg);
+ break;
+ case SystemSettingsError.NotSupported:
+ exp = new NotSupportedException(msg);
+ break;
+ case SystemSettingsError.OutOfMemory:
+ //fall through
+ case SystemSettingsError.IoError:
+ //fall through
+ case SystemSettingsError.PermissionDenied:
+ //fall through
+ case SystemSettingsError.LockScreenAppPasswordMode:
+ //fall through
+ default:
+ exp = new InvalidOperationException(msg);
+ break;
+ }
+ return exp;
+ }
+ }
+}
diff --git a/src/Tizen.System/Device/Battery.cs b/src/Tizen.System/Device/Battery.cs
new file mode 100755
index 0000000..e622284
--- /dev/null
+++ b/src/Tizen.System/Device/Battery.cs
@@ -0,0 +1,339 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+
+namespace Tizen.System
+{
+ /// <summary>
+ /// Enumeration for the Battery level.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum BatteryLevelStatus
+ {
+ /// <summary>
+ /// The battery goes empty.
+ /// Prepare for the safe termination of the application,
+ /// because the device starts a shutdown process soon
+ /// after entering this level.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Empty = 0,
+ /// <summary>
+ /// The battery charge is at a critical state.
+ /// You may have to stop using multimedia features,
+ /// because they are not guaranteed to work correctly
+ /// at this battery status.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Critical,
+ /// <summary>
+ /// The battery has little charge left.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Low,
+ /// <summary>
+ /// The battery status is not to be careful.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ High,
+ /// <summary>
+ /// The battery status is full.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Full
+ }
+
+ /// <summary>
+ /// The Battery class provides the Properties and Events for device battery.
+ /// </summary>
+ /// <remarks>
+ /// The Battery API provides the way to get the current battery capacity value (Percent),
+ /// battery state and charging state. It also provides Events for an application
+ /// to receive the battery status change events from the device.
+ /// To receive the battery event, application should register with respective EventHandler.
+ /// </remarks>
+ /// <code>
+ /// Console.WriteLine("battery Charging state is: {0}", Tizen.System.Battery.IsCharging);
+ /// Console.WriteLine("battery Percent is: {0}", Tizen.System.Battery.Percent);
+ /// </code>
+ public static class Battery
+ {
+ private static readonly object s_lock = new object();
+ /// <summary>
+ /// Gets the battery charge percentage.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>It returns an integer value from 0 to 100 that indicates remaining
+ /// battery charge as a percentage of the maximum level.</value>
+ public static int Percent
+ {
+ get
+ {
+ int percent = 0;
+ DeviceError res = (DeviceError)Interop.Device.DeviceBatteryGetPercent(out percent);
+ if (res != DeviceError.None)
+ {
+ Log.Warn(DeviceExceptionFactory.LogTag, "unable to get battery percentage.");
+ }
+ return percent;
+ }
+ }
+ /// <summary>
+ /// Gets the current Battery level.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static BatteryLevelStatus Level
+ {
+ get
+ {
+ int level = 0;
+ DeviceError res = (DeviceError)Interop.Device.DeviceBatteryGetLevelStatus(out level);
+ if (res != DeviceError.None)
+ {
+ Log.Warn(DeviceExceptionFactory.LogTag, "unable to get battery status.");
+ }
+ return (BatteryLevelStatus)level;
+ }
+ }
+ /// <summary>
+ /// Gets the current charging state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static bool IsCharging
+ {
+ get
+ {
+ bool charging;
+ DeviceError res = (DeviceError)Interop.Device.DeviceBatteryIsCharging(out charging);
+ if (res != DeviceError.None)
+ {
+ Log.Warn(DeviceExceptionFactory.LogTag, "unable to get battery charging state.");
+ }
+ return charging;
+ }
+ }
+
+ private static EventHandler<BatteryPercentChangedEventArgs> s_capacityChanged;
+ /// <summary>
+ /// CapacityChanged is triggered when the battery charge percentage is changed
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="sender"></param>
+ /// <param name="e">A BatteryCapacityChangedEventArgs object that contains changed battery capacity (Percent)</param>
+ /// <code>
+ /// public static async Task BatteryEventHandler()
+ /// {
+ /// EventHandler<BatteryPercentChangedEventArgs> handler = null;
+ /// handler = (object sender, BatteryChargingStateChangedEventArgs args) =>
+ /// {
+ /// Console.WriteLine("battery Percent is: {0}", args.Percent);
+ /// }
+ /// Battery.PercentChanged += handler;
+ /// await Task.Delay(20000);
+ /// }
+ /// </code>
+ public static event EventHandler<BatteryPercentChangedEventArgs> PercentChanged
+ {
+ add
+ {
+ lock (s_lock)
+ {
+ if (s_capacityChanged == null)
+ {
+ EventListenerStart(EventType.BatteryPercent);
+ }
+ s_capacityChanged += value;
+ }
+ }
+ remove
+ {
+ lock (s_lock)
+ {
+ s_capacityChanged -= value;
+ if (s_capacityChanged == null)
+ {
+ EventListenerStop(EventType.BatteryPercent);
+ }
+ }
+ }
+ }
+
+ private static event EventHandler<BatteryLevelChangedEventArgs> s_levelChanged;
+
+ /// <summary>
+ /// LevelChanged is triggered when the battery level is changed
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="sender"></param>
+ /// <param name="e">A BatteryLevelChangedEventArgs object that contains changed battery level </param>
+ /// <code>
+ /// public static async Task BatteryEventHandler()
+ /// {
+ /// EventHandler<BatteryLevelChangedEventArgs> handler = null;
+ /// handler = (object sender, BatteryLevelChangedEventArgs args) =>
+ /// {
+ /// Console.WriteLine("battery Level is: {0}", args.Level);
+ /// }
+ /// Battery.LevelChanged += handler;
+ /// await Task.Delay(20000);
+ /// }
+ /// </code>
+ public static event EventHandler<BatteryLevelChangedEventArgs> LevelChanged
+ {
+ add
+ {
+ lock (s_lock)
+ {
+ if (s_levelChanged == null)
+ {
+ EventListenerStart(EventType.BatteryLevel);
+ }
+ s_levelChanged += value;
+ }
+ }
+ remove
+ {
+ lock (s_lock)
+ {
+ s_levelChanged -= value;
+ if (s_levelChanged == null)
+ {
+ EventListenerStop(EventType.BatteryLevel);
+ }
+ }
+ }
+ }
+
+ private static event EventHandler<BatteryChargingStateChangedEventArgs> s_chargingStateChanged;
+ /// <summary>
+ /// ChargingStatusChanged is triggered when the Battery charging status is changed.
+ /// This event is triggered when Charger is connected/Disconnected.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="sender"></param>
+ /// <param name="e">A BatteryChargingStateChangedEventArgs object that contains changed battery charging state</param>
+ /// <code>
+ /// public static async Task BatteryEventHandler()
+ /// {
+ /// EventHandler<BatteryChargingStateChangedEventArgs> handler = null;
+ /// handler = (object sender, BatteryChargingStateChangedEventArgs args) =>
+ /// {
+ /// Console.WriteLine("battery Level is: {0}", args.IsCharging);
+ /// }
+ /// Battery.ChargingStateChanged += handler;
+ /// await Task.Delay(20000);
+ /// }
+ /// </code>
+ public static event EventHandler<BatteryChargingStateChangedEventArgs> ChargingStateChanged
+ {
+ add
+ {
+ lock (s_lock)
+ {
+ if (s_chargingStateChanged == null)
+ {
+ EventListenerStart(EventType.BatteryCharging);
+ }
+ s_chargingStateChanged += value;
+ }
+ }
+ remove
+ {
+ lock (s_lock)
+ {
+ s_chargingStateChanged -= value;
+ if (s_chargingStateChanged == null)
+ {
+ EventListenerStop(EventType.BatteryCharging);
+ }
+ }
+ }
+ }
+
+ private static Interop.Device.deviceCallback s_cpacityHandler;
+ private static Interop.Device.deviceCallback s_levelHandler;
+ private static Interop.Device.deviceCallback s_chargingHandler;
+
+ private static void EventListenerStart(EventType eventType)
+ {
+ switch (eventType)
+ {
+ case EventType.BatteryPercent:
+ s_cpacityHandler = (int type, IntPtr value, IntPtr data) =>
+ {
+ int val = value.ToInt32();
+ BatteryPercentChangedEventArgs e = new BatteryPercentChangedEventArgs()
+ {
+ Percent = val
+ };
+ s_capacityChanged?.Invoke(null, e);
+ return true;
+ };
+
+ Interop.Device.DeviceAddCallback(eventType, s_cpacityHandler, IntPtr.Zero);
+ break;
+
+ case EventType.BatteryLevel:
+ s_levelHandler = (int type, IntPtr value, IntPtr data) =>
+ {
+ int val = value.ToInt32();
+ BatteryLevelChangedEventArgs e = new BatteryLevelChangedEventArgs()
+ {
+ Level = (BatteryLevelStatus)val
+ };
+ s_levelChanged?.Invoke(null, e);
+ return true;
+ };
+
+ Interop.Device.DeviceAddCallback(eventType, s_levelHandler, IntPtr.Zero);
+ break;
+
+ case EventType.BatteryCharging:
+ s_chargingHandler = (int type, IntPtr value, IntPtr data) =>
+ {
+ bool val = (value.ToInt32() == 1);
+ BatteryChargingStateChangedEventArgs e = new BatteryChargingStateChangedEventArgs()
+ {
+ IsCharging = val
+ };
+ s_chargingStateChanged?.Invoke(null, e);
+ return true;
+ };
+ Interop.Device.DeviceAddCallback(eventType, s_chargingHandler, IntPtr.Zero);
+ break;
+ }
+ }
+
+ private static void EventListenerStop(EventType eventType)
+ {
+ switch (eventType)
+ {
+ case EventType.BatteryPercent:
+ Interop.Device.DeviceRemoveCallback(eventType, s_cpacityHandler);
+ break;
+
+ case EventType.BatteryLevel:
+ Interop.Device.DeviceRemoveCallback(eventType, s_levelHandler);
+ break;
+
+ case EventType.BatteryCharging:
+ Interop.Device.DeviceRemoveCallback(eventType, s_chargingHandler);
+ break;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.System/Device/DeviceEventArgs.cs b/src/Tizen.System/Device/DeviceEventArgs.cs
new file mode 100644
index 0000000..829e8de
--- /dev/null
+++ b/src/Tizen.System/Device/DeviceEventArgs.cs
@@ -0,0 +1,86 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+
+namespace Tizen.System
+{
+ /// <summary>
+ /// BatteryPercentChangedEventArgs is an extended EventArgs class. This class contains event arguments for BatteryPercentChanged event from Battery class.
+ /// </summary>
+ public class BatteryPercentChangedEventArgs : EventArgs
+ {
+ internal BatteryPercentChangedEventArgs(){}
+ /// <summary>
+ /// The current capacity of the battery.
+ /// Capacity is an integer value from 0 to 100, that indicates remaining battery charge as a percentage of the maximum level.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Percent { get; internal set; }
+ }
+
+ /// <summary>
+ /// BatteryLevelChangedEventArgs is an extended EventArgs class. This class contains event arguments for BatteryLevelChanged event from Battery class.
+ /// </summary>
+ public class BatteryLevelChangedEventArgs : EventArgs
+ {
+ internal BatteryLevelChangedEventArgs(){}
+ /// <summary>
+ /// Level indicates the Current battery level status which is of type BatteryLevelStatus.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public BatteryLevelStatus Level { get; internal set; }
+ }
+
+ /// <summary>
+ /// BatteryChargingStateChangedEventArgs is an extended EventArgs class. This class contains event arguments for BatteryChargingStateChanged event from Battery class.
+ /// </summary>
+ public class BatteryChargingStateChangedEventArgs : EventArgs
+ {
+ internal BatteryChargingStateChangedEventArgs() {}
+ /// <summary>
+ /// The charging state of the battery. Charging is of type boolean which indicates true/false based on currrent charging status.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool IsCharging { get; internal set; }
+ }
+
+ /// <summary>
+ /// DisplayStateChangedEventArgs is an extended EventArgs class. This class contains event arguments for DisplayStateChanged event from Display class.
+ /// </summary>
+ public class DisplayStateChangedEventArgs : EventArgs
+ {
+ internal DisplayStateChangedEventArgs() {}
+ /// <summary>
+ /// State indicates the current display state of the device which is an enum of type DisplayState.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public DisplayState State { get; internal set; }
+ }
+
+ /// <summary>
+ /// LedBrightnessChangedEventArgs is an extended EventArgs class. This class contains event arguments for LedBrightnessChanged event from Led class.
+ /// </summary>
+ public class LedBrightnessChangedEventArgs : EventArgs
+ {
+ internal LedBrightnessChangedEventArgs() {}
+ /// <summary>
+ /// Brightness indicates the current brightness level of the display as an integer.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Brightness { get; internal set; }
+ }
+}
diff --git a/src/Tizen.System/Device/DeviceExceptionFactory.cs b/src/Tizen.System/Device/DeviceExceptionFactory.cs
new file mode 100644
index 0000000..96c1eeb
--- /dev/null
+++ b/src/Tizen.System/Device/DeviceExceptionFactory.cs
@@ -0,0 +1,73 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Tizen.System
+{
+ internal enum DeviceError
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None,
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+ PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied,
+ InvalidOperation = Tizen.Internals.Errors.ErrorCode.InvalidOperation,
+ AlreadyInProgress = Tizen.Internals.Errors.ErrorCode.NowInProgress,
+ NotSupported = Tizen.Internals.Errors.ErrorCode.NotSupported,
+ ResourceBusy = Tizen.Internals.Errors.ErrorCode.ResourceBusy,
+ OperationFailed = -0x01140000 | 0x01,
+ NotInitialized = -0x01140000 | 0x02
+ };
+
+ class DeviceExceptionFactory
+ {
+ internal const string LogTag = "Tizen.System.Device";
+
+ internal static Exception CreateException(DeviceError err, string msg)
+ {
+ Exception exp;
+ switch (err)
+ {
+ case DeviceError.InvalidParameter:
+ case DeviceError.NotInitialized:
+ //fall through
+ exp = new ArgumentException(msg);
+ break;
+ case DeviceError.NotSupported:
+ exp = new NotSupportedException(msg +" : Device does not support the Operation.");
+ break;
+ case DeviceError.AlreadyInProgress:
+ //fall through
+ case DeviceError.ResourceBusy:
+ //fall through
+ case DeviceError.OperationFailed:
+ //fall through
+ case DeviceError.InvalidOperation:
+ exp = new InvalidOperationException(msg);
+ break;
+ case DeviceError.PermissionDenied:
+ exp = new UnauthorizedAccessException(msg);
+ break;
+ default:
+ exp = new InvalidOperationException("Unknown error occured.");
+ break;
+ }
+ return exp;
+ }
+ }
+}
diff --git a/src/Tizen.System/Device/Display.cs b/src/Tizen.System/Device/Display.cs
new file mode 100644
index 0000000..4588001
--- /dev/null
+++ b/src/Tizen.System/Device/Display.cs
@@ -0,0 +1,255 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Collections.Generic;
+namespace Tizen.System
+{
+ /// <summary>
+ /// Enumeration for the available Display states.
+ /// An application cannot put the device into the power off state or the suspend state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum DisplayState
+ {
+ /// <summary>
+ /// Normal state
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Normal = 0,
+ /// <summary>
+ /// Screen dim state
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Dim,
+ /// <summary>
+ /// Screen off state
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Off
+ }
+
+ /// <summary>
+ /// The Display class provides Properties and Events to control the display status and brightness.
+ /// </summary>
+ /// <remarks>
+ /// The Display API provides the way to get the current Display brightness value,
+ /// display state and toal number of available displayes.
+ /// It also provides Events for an application to receive the Display state change events from the device.
+ /// To receive the Display event, application should register with assocated EventHandler.
+ /// </remarks>
+ /// <privilege>
+ /// http://tizen.org/privilege/display
+ /// </privilege>
+ /// <code>
+ /// Console.WriteLine("Display current state is: {0}", Tizen.System.Display.State);
+ /// Console.WriteLine("Total number of Displays are: {0}", Tizen.System.Display.NumberOfDisplays);
+ /// </code>
+ public class Display
+ {
+ private readonly int _displayId;
+ private static readonly object s_lock = new object();
+ private static Lazy<IReadOnlyList<Display>> _lazyDisplays;
+ private Display(int deviceNumber)
+ {
+ _displayId = deviceNumber;
+ }
+
+ /// <summary>
+ /// The number of available display devices.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static int NumberOfDisplays
+ {
+ get
+ {
+ int number = 0;
+ DeviceError res = (DeviceError)Interop.Device.DeviceDisplayGetNumbers(out number);
+ if (res != DeviceError.None)
+ {
+ Log.Warn(DeviceExceptionFactory.LogTag, "unable to get number of displays.");
+ }
+ return number;
+ }
+ }
+ /// <summary>
+ /// Get all the avaialble Displays.
+ /// The Display at index zero is always assigned to the main display.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static IReadOnlyList<Display> Displays
+ {
+ get
+ {
+ _lazyDisplays = new Lazy<IReadOnlyList<Display>>(() => GetAllDisplayes());
+ return _lazyDisplays.Value;
+ }
+ }
+
+
+ private static IReadOnlyList<Display> GetAllDisplayes()
+ {
+ List<Display> displays = new List<Display>();
+
+ for (int i = 0; i < NumberOfDisplays; i++)
+ {
+ displays.Add(new Display(i));
+ }
+ return displays;
+
+ }
+ /// <summary>
+ /// The maximum brightness value that can be set for the specific Display.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <code>
+ /// Display display = Display.Displays[0];
+ /// Console.WriteLine("Display MaxBrightness is: {0}", display.MaxBrightness);
+ /// </code>
+ public int MaxBrightness
+ {
+ get
+ {
+ int max = 0;
+ DeviceError res = (DeviceError)Interop.Device.DeviceDisplayGetMaxBrightness(_displayId, out max);
+ if (res != DeviceError.None)
+ {
+ Log.Warn(DeviceExceptionFactory.LogTag, "unable to get max brightness.");
+ }
+ return max;
+ }
+ }
+
+ /// <summary>
+ /// The display brightness valu of the Display.
+ /// </summary>
+ /// <remarks>
+ /// Brightness value should be less than are equal to MaxBrightness value.
+ /// </remarks>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ArgumentException"> When the invalid parameter value is set.</exception>
+ /// <exception cref = "UnauthorizedAccessException"> If the privilege is not set.</exception>
+ /// <code>
+ /// Display display = Display.Displays[0];
+ /// Console.WriteLine("Display current Brightness is: {0}", display.Brightness);
+ /// </code>
+ public int Brightness
+ {
+ get
+ {
+ int brightness = 0;
+ DeviceError res = (DeviceError)Interop.Device.DeviceDisplayGetBrightness(_displayId, out brightness);
+ if (res != DeviceError.None)
+ {
+ Log.Warn(DeviceExceptionFactory.LogTag, "unable to get brightness.");
+ }
+ return brightness;
+ }
+ set
+ {
+ //TODO: Check for maximum throw exception..
+ DeviceError res = (DeviceError)Interop.Device.DeviceDisplaySetBrightness(_displayId, value);
+ if (res != DeviceError.None)
+ {
+ throw DeviceExceptionFactory.CreateException(res, "unable to set brightness value");
+ }
+ }
+ }
+ /// <summary>
+ /// The current device display state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static DisplayState State
+ {
+ get
+ {
+ int state = 0;
+ DeviceError res = (DeviceError)Interop.Device.DeviceDisplayGetState(out state);
+ if (res != DeviceError.None)
+ {
+ Log.Warn(DeviceExceptionFactory.LogTag, "unable to get Display state.");
+ }
+ return (DisplayState)state;
+ }
+ }
+
+ private static event EventHandler<DisplayStateChangedEventArgs> s_stateChanged;
+ /// <summary>
+ /// StateChanged is raised when the state of the display is changed
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="sender"></param>
+ /// <param name="e">An DisplayStateChangedEventArgs object that contains the changed state</param>
+ /// <code>
+ /// public static async Task DisplayEventHandler()
+ /// {
+ /// EventHandler<DisplayStateChangedEventArgs> handler = null;
+ /// handler = (object sender, DisplayStateChangedEventArgs args) =>
+ /// {
+ /// Console.WriteLine("Display State is: {0}", args.State);
+ /// }
+ /// Battery.StateChanged += handler;
+ /// await Task.Delay(20000);
+ /// }
+ /// </code>
+ public static event EventHandler<DisplayStateChangedEventArgs> StateChanged
+ {
+ add
+ {
+ lock (s_lock)
+ {
+ if (s_stateChanged == null)
+ {
+ EventListenerStart();
+ }
+ s_stateChanged += value;
+ }
+ }
+ remove
+ {
+ lock (s_lock)
+ {
+ s_stateChanged -= value;
+ if (s_stateChanged == null)
+ {
+ EventListenerStop();
+ }
+ }
+ }
+ }
+
+ private static Interop.Device.deviceCallback s_handler;
+ private static void EventListenerStart()
+ {
+ s_handler = (int type, IntPtr value, IntPtr data) =>
+ {
+ int val = value.ToInt32();
+ DisplayStateChangedEventArgs e = new DisplayStateChangedEventArgs()
+ {
+ State = (DisplayState)val
+ };
+ s_stateChanged?.Invoke(null, e);
+ return true;
+ };
+ Interop.Device.DeviceAddCallback(EventType.DisplayState, s_handler, IntPtr.Zero);
+ }
+
+ private static void EventListenerStop()
+ {
+ Interop.Device.DeviceRemoveCallback(EventType.DisplayState, s_handler);
+ }
+ }
+}
diff --git a/src/Tizen.System/Device/Haptic.cs b/src/Tizen.System/Device/Haptic.cs
new file mode 100644
index 0000000..b451f33
--- /dev/null
+++ b/src/Tizen.System/Device/Haptic.cs
@@ -0,0 +1,202 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Collections.Generic;
+namespace Tizen.System
+{
+ /// <summary>
+ /// The Vibrator class provides properties and methods to control a vibrator.
+ /// </summary>
+ /// <remarks>
+ /// The Vibrator API provides the way to access the Vibrators in the device.
+ /// It allows the management of the device's vibrator parameters, such as the vibration count and level.
+ /// It provides methods to Vibrate and Stop the vibration.
+ /// </remarks>
+ /// <privilege>
+ /// http://tizen.org/privilege/haptic
+ /// </privilege>
+ /// <code>
+ /// Console.WriteLine("Total number of Vibrators are: {0}", Tizen.System.Vibrator.NumberOfVibrators);
+ /// </code>
+ public class Vibrator : IDisposable
+ {
+ private readonly int _vibratorId;
+ private IntPtr _hapticHandle = IntPtr.Zero;
+ private bool _disposedValue = false;
+ private static Lazy<IReadOnlyList<Vibrator>> _lazyVibrators;
+ private static int _maxcount = 0;
+ private Vibrator(int id)
+ {
+ _vibratorId = id;
+ DeviceError res = (DeviceError)Interop.Device.DeviceHapticOpen(_vibratorId, out _hapticHandle);
+ if (res != DeviceError.None)
+ {
+ throw DeviceExceptionFactory.CreateException(res, "unable to create Vibrator for given Id");
+ }
+ res = (DeviceError)Interop.Device.DeviceHapticGetCount(out _maxcount);
+ if (res != DeviceError.None)
+ {
+ Log.Warn(DeviceExceptionFactory.LogTag, "unable to get Vibrators count.");
+ }
+
+ }
+
+ ~Vibrator()
+ {
+ Dispose(false);
+ }
+ /// <summary>
+ /// Get the number of avaialble vibrators.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static int NumberOfVibrators
+ {
+ get
+ {
+ int count = 0;
+ DeviceError res = (DeviceError)Interop.Device.DeviceHapticGetCount(out count);
+ if (res != DeviceError.None)
+ {
+ Log.Warn(DeviceExceptionFactory.LogTag, "unable to get Vibrators count.");
+ }
+ return count;
+ }
+ }
+ /// <summary>
+ /// Get all the avaialble vibrators.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static IReadOnlyList<Vibrator> Vibrators
+ {
+ get
+ {
+ _lazyVibrators = new Lazy<IReadOnlyList<Vibrator>>(() => GetAllVibrators());
+ return _lazyVibrators.Value;
+ }
+ }
+ private static IReadOnlyList<Vibrator> GetAllVibrators()
+ {
+ int count = 0;
+ List<Vibrator> vibrators = new List<Vibrator>();
+ DeviceError res = (DeviceError)Interop.Device.DeviceHapticGetCount(out count);
+ if (res != DeviceError.None)
+ {
+ throw DeviceExceptionFactory.CreateException(res, "unable to get Vibrators count.");
+ }
+ for (int i = 0; i < NumberOfVibrators; i++)
+ {
+ vibrators.Add(new Vibrator(i));
+ }
+ return vibrators;
+
+ }
+ /// <summary>
+ /// Vibrates during the specified time with a constant intensity.
+ /// This function can be used to start monotonous vibration for the specified time.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="duration">The play duration in milliseconds </param>
+ /// <param name="feedback">The amount of the intensity variation (0 ~ 100) </param>
+ /// <exception cref="ArgumentException"> When the invalid parameter value is set.</exception>
+ /// <exception cref = "UnauthorizedAccessException"> If the privilege is not set.</exception>
+ /// <exception cref = "InvalidOperationException"> In case of any system error.</exception>
+ /// <exception cref = "NotSupportedException"> In case of device does not support this behavior.</exception>
+ /// <code>
+ /// Vibrator vibrator = Vibrator.Vibrators[0];
+ /// try
+ /// {
+ /// vibrator.Vibrate(2000, 70);
+ /// }
+ /// Catch(Exception e)
+ /// {
+ /// }
+ /// </code>
+
+ public void Vibrate(int duration, int feedback)
+ {
+ IntPtr effect;
+ DeviceError res = DeviceError.None;
+ if (_hapticHandle == IntPtr.Zero)
+ {
+ res = (DeviceError)Interop.Device.DeviceHapticOpen(_vibratorId, out _hapticHandle);
+ if (res != DeviceError.None)
+ {
+ throw DeviceExceptionFactory.CreateException(res, "unable to get vibrator.");
+ }
+ }
+
+ res = (DeviceError)Interop.Device.DeviceHapticVibrate(_hapticHandle, duration, feedback, out effect);
+ if (res != DeviceError.None)
+ {
+ throw DeviceExceptionFactory.CreateException(res, "unable to vibrate the current vibrator.");
+ }
+ }
+ /// <summary>
+ /// Stops all vibration effects which are being played.
+ /// This function can be used to stop all effects started by Vibrate().
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ArgumentException"> In case of invalid vibrator instance is used.</exception>
+ /// <exception cref = "UnauthorizedAccessException"> If the privilege is not set.</exception>
+ /// <exception cref = "InvalidOperationException"> In case of any system error.</exception>
+ /// <exception cref = "NotSupportedException"> In case of device does not support this behavior.</exception>
+ /// <code>
+ /// Vibrator vibrator = Vibrator.Vibrators[0];
+ /// try
+ /// {
+ /// vibrator.Stop();
+ /// }
+ /// Catch(Exception e)
+ /// {
+ /// }
+ /// </code>
+ public void Stop()
+ {
+ if (_hapticHandle != IntPtr.Zero)
+ {
+ DeviceError res = (DeviceError)Interop.Device.DeviceHapticStop(_hapticHandle, IntPtr.Zero);
+ if (res != DeviceError.None)
+ {
+ throw DeviceExceptionFactory.CreateException(res, "unable to stop the current vibrator.");
+ }
+ }
+ }
+ /// <summary>
+ /// Dispose API for closing the internal resources.
+ /// This function can be used to stop all effects started by Vibrate().
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ if (_hapticHandle != IntPtr.Zero)
+ {
+ Interop.Device.DeviceHapticClose(_hapticHandle);
+ _hapticHandle = IntPtr.Zero;
+ }
+ _disposedValue = true;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.System/Device/IR.cs b/src/Tizen.System/Device/IR.cs
new file mode 100644
index 0000000..c2631bf
--- /dev/null
+++ b/src/Tizen.System/Device/IR.cs
@@ -0,0 +1,89 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Tizen.System
+{
+ /// <summary>
+ /// The IR API provides functions to control a IR transmitter.
+ /// The IR API provides the way to get the information whether IR is available and transmit IR command.
+ /// </summary>
+ /// <privilege>
+ /// http://tizen.org/privilege/use_ir
+ /// </privilege>
+ /// <code>
+ /// Console.WriteLine("IR availablity for this device is: {0}", IR.IsAvailable);
+ /// </code>
+ public static class IR
+ {
+ /// <summary>
+ /// Gets the information whether IR module is available.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static bool IsAvailable
+ {
+ get
+ {
+ bool available = false;
+ DeviceError res = (DeviceError)Interop.Device.DeviceIRIsAvailable(out available);
+ if (res != DeviceError.None)
+ {
+ Log.Warn(DeviceExceptionFactory.LogTag, "unable to get ir status.");
+ }
+ return available;
+ }
+ }
+
+ /// <summary>
+ /// Transmits IR command.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="carrierFreequency">
+ /// Carrier frequency to transmit IR command (Hertz).
+ /// </param>
+ /// <param name="pattern">
+ /// IR command list of type interger.
+ /// </param>
+ /// <exception cref="ArgumentException"> When the invalid parameter value is set.</exception>
+ /// <exception cref = "UnauthorizedAccessException"> If the privilege is not set.</exception>
+ /// <exception cref = "InvalidOperationException"> In case of any system error.</exception>
+ /// <exception cref = "NotSupportedException"> In case of device does not support this behavior.</exception>
+ /// <code>
+ /// try
+ /// {
+ /// List<int> pattern = new List<int>();
+ /// pattern.Add(10);
+ /// pattern.Add(50);
+ /// IR.Transmit(60657, pattern);
+ /// }
+ /// catch(Exception e)
+ /// {
+ /// }
+ /// </code>
+ public static void Transmit(int carrierFreequency, IList<int> pattern)
+ {
+ int[] patternArray = pattern.ToArray();
+ DeviceError res = (DeviceError)Interop.Device.DeviceIRTransmit(carrierFreequency, patternArray, pattern.Count());
+ if (res != DeviceError.None)
+ {
+ throw DeviceExceptionFactory.CreateException(res, "unable to trasmit IR command.");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.System/Device/Led.cs b/src/Tizen.System/Device/Led.cs
new file mode 100644
index 0000000..fbf2fa1
--- /dev/null
+++ b/src/Tizen.System/Device/Led.cs
@@ -0,0 +1,220 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+
+using Tizen.Common;
+
+namespace Tizen.System
+{
+ /// <summary>
+ /// The Led class provides properties and methods to control the attached led device.
+ /// </summary>
+ /// <remarks>
+ /// The Led API provides the way to control the attached LED device such as the camera flash and service LED.It supports to turn on the camera flash and set the pattern to the service LED which is located to the front of a device.
+ /// Related Features
+ /// http://tizen.org/feature/led
+ /// http://tizen.org/feature/camera.back.flash
+ /// It is recommended to design feature related codes in your application for reliability.
+ /// You can check if a device supports the related features for this API by using System Information, thereby controlling the procedure of your application.
+ /// </remarks>
+ /// <privilege>
+ /// http://tizen.org/privilege/led
+ /// </privilege>
+ /// <code>
+ /// Console.WriteLine("Led MaxBrightness is: {0}", Tizen.System.Led.MaxBrightness);
+ /// Console.WriteLine("Led current Brightness is: {0}", Tizen.System.Led.Brightness);
+ /// </code>
+ public static class Led
+ {
+ /// <summary>
+ /// Gets the max brightness value of a LED that is located next to the camera.
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ArgumentException"> When the invalid parameter value is set.</exception>
+ /// <exception cref = "UnauthorizedAccessException"> If the privilege is not set.</exception>
+ /// <exception cref = "NotSupportedException"> In case of device does not support this behavior.</exception>
+ /// </summary>
+ public static int MaxBrightness
+ {
+ get
+ {
+ int max = 0;
+ DeviceError res = (DeviceError)Interop.Device.DeviceFlashGetMaxBrightness(out max);
+ if (res != DeviceError.None)
+ {
+ Log.Warn(DeviceExceptionFactory.LogTag, "unable to get max brightness value.");
+ }
+ return max;
+ }
+ }
+
+ private static readonly object s_lock = new object();
+
+ /// <summary>
+ /// Gets the brightness value of a LED that is located next to the camera.
+ /// </summary>
+ /// <remarks>The brightness value range of LED is 0 to Tizen.System.Led.MaxBrightness value.
+ /// Changing the brightness value will invoke the registered EventHandler for led BrightnessChanged (If any).
+ /// </remarks>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="ArgumentException"> When the invalid parameter value is set.</exception>
+ /// <exception cref = "UnauthorizedAccessException"> If the privilege is not set.</exception>
+ /// <exception cref = "NotSupportedException"> In case of device does not support this behavior.</exception>
+ /// <code>
+ /// Console.WriteLine("Led current Brightness is: {0}", Tizen.System.Led.Brightness);
+ /// Tizen.System.Led.Brightness = 50;
+ /// Console.WriteLine("Led current Brightness is: {0}", Tizen.System.Led.Brightness);
+ /// </code>
+
+ public static int Brightness
+ {
+ get
+ {
+ int brightness = 0;
+ DeviceError res = (DeviceError)Interop.Device.DeviceFlashGetBrightness(out brightness);
+ if (res != DeviceError.None)
+ {
+ Log.Warn(DeviceExceptionFactory.LogTag, "unable to get brightness value.");
+ }
+ return brightness;
+ }
+ set
+ {
+ DeviceError res = (DeviceError) Interop.Device.DeviceFlashSetBrightness(value);
+ if (res != DeviceError.None)
+ {
+ throw DeviceExceptionFactory.CreateException(res, "unable to set brightness value");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Plays the LED that is located to the front of a device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="on">Turn on time in milliseconds </param>
+ /// <param name="off">Turn off time in milliseconds </param>
+ /// <param name="color">
+ /// The Color value
+ /// The first byte means opaque and the other 3 bytes are RGB values.
+ /// </param>
+ /// <exception cref="ArgumentException"> When the invalid parameter value is set.</exception>
+ /// <exception cref = "UnauthorizedAccessException"> If the privilege is not set.</exception>
+ /// <exception cref = "InvalidOperationException"> In case of any system error.</exception>
+ /// <exception cref = "NotSupportedException"> In case of device does not support this behavior.</exception>
+ /// <code>
+ /// try
+ /// {
+ /// Led.Play(500, 200, Color.FromRgba(255, 255, 255, 1));
+ /// }
+ /// Catch(Exception e)
+ /// {
+ /// }
+ /// </code>
+ public static void Play(int on, int off, Color color)
+ {
+ //looks like only blink option is supported. So hard coded to default blink option.
+ DeviceError res = (DeviceError)Interop.Device.DeviceLedPlayCustom(on, off, Convert.ToUInt32(color.GetArgb()), 1);
+ if (res != DeviceError.None)
+ {
+ throw DeviceExceptionFactory.CreateException(res, "failed to play Led.");
+ }
+ }
+
+ /// <summary>
+ /// Stops the LED that is located to the front of a device.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref = "UnauthorizedAccessException"> If the privilege is not set.</exception>
+ /// <exception cref = "InvalidOperationException"> In case of any system error.</exception>
+ /// <exception cref = "NotSupportedException"> In case of device does not support this behavior.</exception>
+ /// <code>
+ /// try
+ /// {
+ /// Led.Play(500, 200, Color.FromRgba(255, 255, 255, 1));
+ /// //wait for a while and stop...
+ /// Led.Stop();
+ /// }
+ /// Catch(Exception e)
+ /// {
+ /// }
+ /// </code>
+
+ public static void Stop()
+ {
+ DeviceError res = (DeviceError)Interop.Device.DeviceLedStopCustom();
+ if (res != DeviceError.None)
+ {
+ throw DeviceExceptionFactory.CreateException(res, "failed to stop Led.");
+ }
+ }
+
+
+ private static EventHandler<LedBrightnessChangedEventArgs> s_brightnessChanged;
+ /// <summary>
+ /// StateChanged is raised when the LED state is changed
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="e">An LedBrightnessChangedEventArgs object that contains the changed brightness.</param>
+ public static event EventHandler<LedBrightnessChangedEventArgs> BrightnessChanged
+ {
+ add
+ {
+ lock (s_lock)
+ {
+ if (s_brightnessChanged == null)
+ {
+ EventListenerStart();
+ }
+ s_brightnessChanged += value;
+ }
+ }
+ remove
+ {
+ lock (s_lock)
+ {
+ s_brightnessChanged -= value;
+ if (s_brightnessChanged == null)
+ {
+ EventListenerStop();
+ }
+ }
+ }
+ }
+
+ private static Interop.Device.deviceCallback s_handler;
+ private static void EventListenerStart()
+ {
+ s_handler = (int type, IntPtr value, IntPtr data) =>
+ {
+ int val = value.ToInt32();
+ LedBrightnessChangedEventArgs e = new LedBrightnessChangedEventArgs()
+ {
+ Brightness = val
+ };
+ s_brightnessChanged?.Invoke(null, e);
+ return true;
+ };
+ Interop.Device.DeviceAddCallback(EventType.FlashBrightness, s_handler, IntPtr.Zero);
+ }
+
+ private static void EventListenerStop()
+ {
+ Interop.Device.DeviceRemoveCallback(EventType.FlashBrightness, s_handler);
+ }
+ }
+}
diff --git a/src/Tizen.System/Device/Power.cs b/src/Tizen.System/Device/Power.cs
new file mode 100644
index 0000000..50c7dcc
--- /dev/null
+++ b/src/Tizen.System/Device/Power.cs
@@ -0,0 +1,78 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+
+namespace Tizen.System
+{
+ /// <summary>
+ /// The Power class provides methods to control the power service.
+ /// </summary>
+ /// <remarks>
+ /// The Power API provides the way to control the power service.
+ /// It can be made to hold the specific state to avoid CPU state internally.
+ /// </remarks>
+ /// <privilege>
+ /// http://tizen.org/privilege/display
+ /// </privilege>
+ public static class Power
+ {
+ /// <summary>
+ /// Locks the CPU for a specified time.
+ /// After the given timeout (in milliseconds), unlock the given lock state automatically.
+ /// </summary>
+ /// <remarks>
+ /// If the process dies, then every lock will be removed.
+ /// </remarks>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="timeout">
+ /// The positive number in milliseconds or 0 for permanent lock
+ /// So you must release the permanent lock of power state with ReleaseCpuLock() if timeout_ms is zero.
+ /// </param>
+ /// <exception cref="ArgumentException"> When the invalid parameter value is set.</exception>
+ /// <exception cref = "UnauthorizedAccessException"> If the privilege is not set.</exception>
+ /// <exception cref = "InvalidOperationException"> In case of any system error.</exception>
+ /// <code>
+ /// Tizen.System.Power.RequestCpuLock(2000);
+ /// </code>
+
+ public static void RequestCpuLock(int timeout)
+ {
+ DeviceError res = (DeviceError)Interop.Device.DevicePowerRequestLock(0, timeout);
+ if (res != DeviceError.None)
+ {
+ throw DeviceExceptionFactory.CreateException(res, "unable to acquire power lock.");
+ }
+ }
+ /// <summary>
+ /// Releases the CPU lock state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref = "UnauthorizedAccessException"> If the privilege is not set.</exception>
+ /// <exception cref = "InvalidOperationException"> In case of any system error.</exception>
+ /// <code>
+ /// Tizen.System.Power.ReleaseCpuLock();
+ /// </code>
+ public static void ReleaseCpuLock()
+ {
+ DeviceError res = (DeviceError)Interop.Device.DevicePowerReleaseLock(0);
+ if (res != DeviceError.None)
+ {
+ throw DeviceExceptionFactory.CreateException(res, "unable to release power lock.");
+ }
+ }
+ }
+}
diff --git a/src/Tizen.System/Interop/Interop.Device.cs b/src/Tizen.System/Interop/Interop.Device.cs
new file mode 100644
index 0000000..3862edd
--- /dev/null
+++ b/src/Tizen.System/Interop/Interop.Device.cs
@@ -0,0 +1,101 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.System
+{
+ internal enum EventType
+ {
+ BatteryPercent,
+ BatteryLevel,
+ BatteryCharging,
+ DisplayState,
+ FlashBrightness
+ }
+}
+internal static partial class Interop
+{
+ internal static partial class Device
+ {
+ // Battery
+ [DllImport(Libraries.Device, EntryPoint = "device_battery_get_percent", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int DeviceBatteryGetPercent(out int percent);
+ [DllImport(Libraries.Device, EntryPoint = "device_battery_is_charging", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int DeviceBatteryIsCharging(out bool charging);
+ [DllImport(Libraries.Device, EntryPoint = "device_battery_get_level_status", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int DeviceBatteryGetLevelStatus(out int status);
+
+ // Display
+ [DllImport(Libraries.Device, EntryPoint = "device_display_get_numbers", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int DeviceDisplayGetNumbers(out int device_number);
+ [DllImport(Libraries.Device, EntryPoint = "device_display_get_max_brightness", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int DeviceDisplayGetMaxBrightness(int index, out int max_brightness);
+ [DllImport(Libraries.Device, EntryPoint = "device_display_get_brightness", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int DeviceDisplayGetBrightness(int index, out int status);
+ [DllImport(Libraries.Device, EntryPoint = "device_display_set_brightness", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int DeviceDisplaySetBrightness(int index, int brightness);
+ [DllImport(Libraries.Device, EntryPoint = "device_display_get_state", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int DeviceDisplayGetState(out int state);
+ [DllImport(Libraries.Device, EntryPoint = "device_display_change_state", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int DeviceDisplayChangeState(int state);
+
+ // Haptic
+ [DllImport(Libraries.Device, EntryPoint = "device_haptic_get_count", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int DeviceHapticGetCount(out int device_number);
+ [DllImport(Libraries.Device, EntryPoint = "device_haptic_open", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int DeviceHapticOpen(int index, out IntPtr handle);
+ [DllImport(Libraries.Device, EntryPoint = "device_haptic_close", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int DeviceHapticClose(IntPtr handle);
+ [DllImport(Libraries.Device, EntryPoint = "device_haptic_vibrate", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int DeviceHapticVibrate(IntPtr handle, int duration, int feedback, out IntPtr effect);
+ [DllImport(Libraries.Device, EntryPoint = "device_haptic_stop", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int DeviceHapticStop(IntPtr handle, IntPtr effect);
+
+ // Led
+ [DllImport(Libraries.Device, EntryPoint = "device_flash_get_max_brightness", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int DeviceFlashGetMaxBrightness(out int max_brightness);
+ [DllImport(Libraries.Device, EntryPoint = "device_flash_get_brightness", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int DeviceFlashGetBrightness(out int brightness);
+ [DllImport(Libraries.Device, EntryPoint = "device_flash_set_brightness", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int DeviceFlashSetBrightness(int brightness);
+ [DllImport(Libraries.Device, EntryPoint = "device_led_play_custom", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int DeviceLedPlayCustom(int on, int off, uint color, uint flags);
+ [DllImport(Libraries.Device, EntryPoint = "device_led_stop_custom", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int DeviceLedStopCustom();
+
+ // Power
+ [DllImport(Libraries.Device, EntryPoint = "device_power_request_lock", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int DevicePowerRequestLock(int type, int timeout_ms);
+ [DllImport(Libraries.Device, EntryPoint = "device_power_release_lock", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int DevicePowerReleaseLock(int type);
+
+ //IR
+ [DllImport(Libraries.Device, EntryPoint = "device_ir_is_available", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int DeviceIRIsAvailable(out bool available);
+ [DllImport(Libraries.Device, EntryPoint = "device_ir_transmit", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int DeviceIRTransmit(int carrierFreequency, int[] pattern, int size);
+
+ // Callback
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool deviceCallback(int type, IntPtr value, IntPtr data);
+ [DllImport(Libraries.Device, EntryPoint = "device_add_callback", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int DeviceAddCallback(Tizen.System.EventType type, deviceCallback cb, IntPtr data);
+ [DllImport(Libraries.Device, EntryPoint = "device_remove_callback", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int DeviceRemoveCallback(Tizen.System.EventType type, deviceCallback cb);
+ }
+}
diff --git a/src/Tizen.System/Interop/Interop.Libraries.cs b/src/Tizen.System/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..a2252c4
--- /dev/null
+++ b/src/Tizen.System/Interop/Interop.Libraries.cs
@@ -0,0 +1,23 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ internal const string Device = "libcapi-system-device.so.0";
+ }
+}
diff --git a/src/Tizen.System/Tizen.System.csproj b/src/Tizen.System/Tizen.System.csproj
new file mode 100644
index 0000000..d5717a4
--- /dev/null
+++ b/src/Tizen.System/Tizen.System.csproj
@@ -0,0 +1,15 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
+
diff --git a/src/Tizen.Telephony/Interop/Interop.Call.cs b/src/Tizen.Telephony/Interop/Interop.Call.cs
new file mode 100755
index 0000000..c5cf929
--- /dev/null
+++ b/src/Tizen.Telephony/Interop/Interop.Call.cs
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Telephony;
+using static Tizen.Telephony.CallHandle;
+
+/// <summary>
+/// Partial Interop Class
+/// </summary>
+internal static partial class Interop
+{
+ /// <summary>
+ /// Call Interop Class
+ /// </summary>
+ internal static partial class Call
+ {
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_call_get_preferred_voice_subscription")]
+ internal static extern Telephony.TelephonyError GetPreferredVoiceSubscription(IntPtr handle, out CallPreferredVoiceSubscription callSub);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_call_get_call_list")]
+ internal static extern Telephony.TelephonyError GetCallList(IntPtr handle, out uint count, out IntPtr callList);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_call_release_call_list")]
+ internal static extern Telephony.TelephonyError ReleaseCallList(uint count, IntPtr callList);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_call_get_handle_id")]
+ internal static extern Telephony.TelephonyError GetHandleId(IntPtr callHandle, out uint handleId);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_call_get_number")]
+ internal static extern Telephony.TelephonyError GetNumber(IntPtr callHandle, out string number);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_call_get_type")]
+ internal static extern Telephony.TelephonyError GetType(IntPtr callHandle, out CallType type);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_call_get_status")]
+ internal static extern Telephony.TelephonyError GetStatus(IntPtr callHandle, out CallStatus status);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_call_get_direction")]
+ internal static extern Telephony.TelephonyError GetDirection(IntPtr callHandle, out CallDirection direction);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_call_get_conference_status")]
+ internal static extern Telephony.TelephonyError GetConferenceStatus(IntPtr callHandle, out bool conferenceStatus);
+
+ internal sealed class SafeCallList : SafeHandle
+ {
+ public SafeCallList()
+ : base(IntPtr.Zero, true)
+ {
+ }
+
+ public SafeCallList(IntPtr handle, uint count)
+ : base(handle, true)
+ {
+ Count = count;
+ }
+
+ public override bool IsInvalid
+ {
+ get { return this.handle == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ ReleaseCallList(Count, this.handle);
+ this.SetHandle(IntPtr.Zero);
+ return true;
+ }
+
+ internal uint Count;
+ }
+ }
+}
diff --git a/src/Tizen.Telephony/Interop/Interop.Libraries.cs b/src/Tizen.Telephony/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..b98e7d0
--- /dev/null
+++ b/src/Tizen.Telephony/Interop/Interop.Libraries.cs
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/// <summary>
+/// Partial Interop Class
+/// </summary>
+internal static partial class Interop
+{
+ /// <summary>
+ /// Libraries Interop Class
+ /// </summary>
+ internal static partial class Libraries
+ {
+ public const string Telephony = "libcapi-telephony.so.0";
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Telephony/Interop/Interop.Modem.cs b/src/Tizen.Telephony/Interop/Interop.Modem.cs
new file mode 100755
index 0000000..19034b0
--- /dev/null
+++ b/src/Tizen.Telephony/Interop/Interop.Modem.cs
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+/// <summary>
+/// Partial Interop Class
+/// </summary>
+internal static partial class Interop
+{
+ /// <summary>
+ /// Modem Interop Class
+ /// </summary>
+ internal static partial class Modem
+ {
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_modem_get_imei")]
+ internal static extern Telephony.TelephonyError GetImei(IntPtr handle, out string imei);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_modem_get_power_status")]
+ internal static extern Telephony.TelephonyError GetPowerStatus(IntPtr handle, out Tizen.Telephony.Modem.PowerStatus status);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_modem_get_meid")]
+ internal static extern Telephony.TelephonyError GetMeid(IntPtr handle, out string meid);
+ }
+}
diff --git a/src/Tizen.Telephony/Interop/Interop.Network.cs b/src/Tizen.Telephony/Interop/Interop.Network.cs
new file mode 100755
index 0000000..e8bbaf0
--- /dev/null
+++ b/src/Tizen.Telephony/Interop/Interop.Network.cs
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+/// <summary>
+/// Partial Interop Class
+/// </summary>
+internal static partial class Interop
+{
+ /// <summary>
+ /// Network Interop Class
+ /// </summary>
+ internal static partial class Network
+ {
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_network_get_lac")]
+ internal static extern Telephony.TelephonyError GetLac(IntPtr handle, out int lac);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_network_get_cell_id")]
+ internal static extern Telephony.TelephonyError GetCellId(IntPtr handle, out int cellId);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_network_get_rssi")]
+ internal static extern Telephony.TelephonyError GetRssi(IntPtr handle, out Tizen.Telephony.Network.Rssi rssi);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_network_get_roaming_status")]
+ internal static extern Telephony.TelephonyError GetRoamingStatus(IntPtr handle, out bool status);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_network_get_mcc")]
+ internal static extern Telephony.TelephonyError GetMcc(IntPtr handle, out string mcc);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_network_get_mnc")]
+ internal static extern Telephony.TelephonyError GetMnc(IntPtr handle, out string mnc);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_network_get_network_name")]
+ internal static extern Telephony.TelephonyError GetNetworkName(IntPtr handle, out string networkName);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_network_get_type")]
+ internal static extern Telephony.TelephonyError GetType(IntPtr handle, out Tizen.Telephony.Network.Type networkType);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_network_get_ps_type")]
+ internal static extern Telephony.TelephonyError GetPsType(IntPtr handle, out Tizen.Telephony.Network.PsType psType);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_network_get_network_name_option")]
+ internal static extern Telephony.TelephonyError GetNetworkNameOption(IntPtr handle, out Tizen.Telephony.Network.NameOption networkNameOption);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_network_get_service_state")]
+ internal static extern Telephony.TelephonyError GetServiceState(IntPtr handle, out Tizen.Telephony.Network.ServiceState networkServiceState);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_network_get_default_data_subscription")]
+ internal static extern Telephony.TelephonyError GetDefaultDataSubscription(IntPtr handle, out Tizen.Telephony.Network.DefaultDataSubscription defaultSub);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_network_get_default_subscription")]
+ internal static extern Telephony.TelephonyError GetDefaultSubscription(IntPtr handle, out Tizen.Telephony.Network.DefaultSubscription defaultSub);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_network_get_selection_mode")]
+ internal static extern Telephony.TelephonyError GetSelectionMode(IntPtr handle, out Tizen.Telephony.Network.SelectionMode mode);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_network_get_tac")]
+ internal static extern Telephony.TelephonyError GetTac(IntPtr handle, out int tac);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_network_get_system_id")]
+ internal static extern Telephony.TelephonyError GetSystemId(IntPtr handle, out int sid);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_network_get_network_id")]
+ internal static extern Telephony.TelephonyError GetNetworkId(IntPtr handle, out int nid);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_network_get_base_station_id")]
+ internal static extern Telephony.TelephonyError GetBaseStationId(IntPtr handle, out int bsId);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_network_get_base_station_latitude")]
+ internal static extern Telephony.TelephonyError GetBaseStationLatitude(IntPtr handle, out int bsLatitude);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_network_get_base_station_longitude")]
+ internal static extern Telephony.TelephonyError GetBaseStationLongitude(IntPtr handle, out int bsLongitude);
+ }
+}
diff --git a/src/Tizen.Telephony/Interop/Interop.Sim.cs b/src/Tizen.Telephony/Interop/Interop.Sim.cs
new file mode 100755
index 0000000..7e8c9f2
--- /dev/null
+++ b/src/Tizen.Telephony/Interop/Interop.Sim.cs
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+/// <summary>
+/// Partial Interop Class
+/// </summary>
+internal static partial class Interop
+{
+ /// <summary>
+ /// Sim Interop Class
+ /// </summary>
+ internal static partial class Sim
+ {
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_sim_get_icc_id")]
+ internal static extern Telephony.TelephonyError GetIccId(IntPtr handle, out string iccId);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_sim_get_operator")]
+ internal static extern Telephony.TelephonyError GetOperator(IntPtr handle, out string simOperator);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_sim_get_msin")]
+ internal static extern Telephony.TelephonyError GetMsin(IntPtr handle, out string msin);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_sim_get_spn")]
+ internal static extern Telephony.TelephonyError GetSpn(IntPtr handle, out string spn);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_sim_is_changed")]
+ internal static extern Telephony.TelephonyError IsChanged(IntPtr handle, out int isChanged);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_sim_get_state")]
+ internal static extern Telephony.TelephonyError GetState(IntPtr handle, out Tizen.Telephony.Sim.State simState);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_sim_get_application_list")]
+ internal static extern Telephony.TelephonyError GetApplicationList(IntPtr handle, out uint appList);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_sim_get_subscriber_number")]
+ internal static extern Telephony.TelephonyError GetSubscriberNumber(IntPtr handle, out string subscriberNumber);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_sim_get_subscriber_id")]
+ internal static extern Telephony.TelephonyError GetSubscriberId(IntPtr handle, out string subscriberId);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_sim_get_lock_state")]
+ internal static extern Telephony.TelephonyError GetLockState(IntPtr handle, out Tizen.Telephony.Sim.LockState lockState);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_sim_get_group_id1")]
+ internal static extern Telephony.TelephonyError GetGroupId1(IntPtr handle, out string gid1);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_sim_get_call_forwarding_indicator_state")]
+ internal static extern Telephony.TelephonyError GetCallForwardingIndicatorState(IntPtr handle, out bool state);
+ }
+}
diff --git a/src/Tizen.Telephony/Interop/Interop.Telephony.cs b/src/Tizen.Telephony/Interop/Interop.Telephony.cs
new file mode 100755
index 0000000..446703d
--- /dev/null
+++ b/src/Tizen.Telephony/Interop/Interop.Telephony.cs
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Telephony;
+
+/// <summary>
+/// Partial Interop Class
+/// </summary>
+internal static partial class Interop
+{
+ /// <summary>
+ /// Telephony Interop Class
+ /// </summary>
+ internal static class Telephony
+ {
+ private const int TIZEN_ERROR_TELEPHONY = -0x02600000;
+ internal static string LogTag = "Tizen.Telephony";
+ internal enum TelephonyError
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None,
+ OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+ PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied,
+ NotSupported = Tizen.Internals.Errors.ErrorCode.NotSupported,
+ OperationFailed = TIZEN_ERROR_TELEPHONY | 0x0001,
+ SIMNotAvailable = TIZEN_ERROR_TELEPHONY | 0x1001
+ };
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct HandleList
+ {
+ internal uint Count;
+ internal IntPtr HandleArrayPointer;
+ };
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_set_noti_cb")]
+ internal static extern TelephonyError TelephonySetNotiCb(IntPtr handle, Tizen.Telephony.ChangeNotificationEventArgs.Notification notiId, NotificationCallback cb, IntPtr userData);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_unset_noti_cb")]
+ internal static extern TelephonyError TelephonyUnsetNotiCb(IntPtr handle, Tizen.Telephony.ChangeNotificationEventArgs.Notification notiId);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_init")]
+ internal static extern TelephonyError TelephonyInit(out HandleList list);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_deinit")]
+ internal static extern TelephonyError TelephonyDeinit(ref HandleList list);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_get_state")]
+ internal static extern TelephonyError TelephonyGetState(out State state);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_set_state_changed_cb")]
+ internal static extern TelephonyError TelephonySetStateChangedCb(StateChangedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Telephony, EntryPoint = "telephony_unset_state_changed_cb")]
+ internal static extern TelephonyError TelephonyUnsetStateChangedCb(StateChangedCallback callback);
+
+ [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+ internal delegate void NotificationCallback(IntPtr handle, ChangeNotificationEventArgs.Notification notiId, IntPtr data, IntPtr userData);
+
+ [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+ internal delegate void StateChangedCallback(State state, IntPtr userData);
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Telephony/Tizen.Telephony.csproj b/src/Tizen.Telephony/Tizen.Telephony.csproj
new file mode 100644
index 0000000..5ed2f1f
--- /dev/null
+++ b/src/Tizen.Telephony/Tizen.Telephony.csproj
@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Telephony/Tizen.Telephony/Call.cs b/src/Tizen.Telephony/Tizen.Telephony/Call.cs
new file mode 100644
index 0000000..3171005
--- /dev/null
+++ b/src/Tizen.Telephony/Tizen.Telephony/Call.cs
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using static Interop.Telephony;
+
+namespace Tizen.Telephony
+{
+ /// <summary>
+ /// The Call API's allows you to get the voice and video call states.
+ /// It provides the List of CallHandle which can be used to get the information about call related actions.
+ /// </summary>
+ public class Call
+ {
+ internal IntPtr _handle;
+ private List<IntPtr> _callHandle = new List<IntPtr>();
+ private List<CallHandle> _list = new List<CallHandle>();
+ private IntPtr _callList;
+ private Interop.Call.SafeCallList _safeCallList;
+
+ /// <summary>
+ /// Public Constructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="handle">
+ /// SlotHandle received in the Manager.Init API
+ /// </param>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="ArgumentNullException">
+ /// This exception occurs if handle provided is null
+ /// </exception>
+ public Call(SlotHandle handle)
+ {
+ if (handle == null)
+ {
+ throw new ArgumentNullException();
+ }
+
+ _handle = handle._handle;
+ }
+
+ /// <summary>
+ /// Gets the current value for the preferred voice call subscription.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/telephony</privilege>
+ /// <value>
+ /// The currently set preferred voicecall subscription value.
+ /// </value>
+ public CallPreferredVoiceSubscription PreferredVoiceSubscription
+ {
+ get
+ {
+ CallPreferredVoiceSubscription subs = CallPreferredVoiceSubscription.Unknown;
+ TelephonyError error = Interop.Call.GetPreferredVoiceSubscription(_handle, out subs);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetPreferredVoiceSubscription Failed with error " + error);
+ return CallPreferredVoiceSubscription.Unknown;
+ }
+
+ return subs;
+ }
+ }
+
+ /// <summary>
+ /// Gets the list of the current call.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// List of CallHandle for existing calls.
+ /// </returns>
+ /// <privilege>http://tizen.org/privilege/telephony</privilege>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="ArgumentException">Incase of Invalid parameter</exception>
+ /// <exception cref="InvalidOperationException">Incase of any System error</exception>
+ /// <exception cref="UnauthorizedAccessException">Incase of Privileges are not defined</exception>
+ /// <exception cref="OutOfMemoryException">Incase of Out of Memory</exception>
+ public IEnumerable<CallHandle> GetCallHandleList()
+ {
+ uint count;
+ _callList = new IntPtr();
+ _list.Clear();
+ TelephonyError error = Interop.Call.GetCallList(_handle, out count, out _callList);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetCallList Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+
+ _callHandle.Clear();
+ if (count > 0)
+ {
+ IntPtr[] handleArray = new IntPtr[count];
+ Marshal.Copy(_callList, handleArray, 0, (int)count);
+ foreach (IntPtr handle in handleArray)
+ {
+ CallHandle info = new CallHandle(handle);
+ _list.Add(info);
+ }
+
+ _safeCallList = new Interop.Call.SafeCallList(_callList, count);
+ }
+ return _list;
+ }
+ }
+}
diff --git a/src/Tizen.Telephony/Tizen.Telephony/CallHandle.cs b/src/Tizen.Telephony/Tizen.Telephony/CallHandle.cs
new file mode 100644
index 0000000..7d6de9c
--- /dev/null
+++ b/src/Tizen.Telephony/Tizen.Telephony/CallHandle.cs
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using static Interop.Telephony;
+
+namespace Tizen.Telephony
+{
+ /// <summary>
+ /// This Class provides API's to get the information about calls.
+ /// </summary>
+ public class CallHandle
+ {
+ private IntPtr _callHandle;
+
+ /// <summary>
+ /// Enumeration for the call status.
+ /// </summary>
+ public enum CallStatus
+ {
+ /// <summary>
+ /// Idle status
+ /// </summary>
+ Idle,
+ /// <summary>
+ /// Active status
+ /// </summary>
+ Active,
+ /// <summary>
+ /// Held status
+ /// </summary>
+ Held,
+ /// <summary>
+ /// Dialing status
+ /// </summary>
+ Dialing,
+ /// <summary>
+ /// Alerting status
+ /// </summary>
+ Alerting,
+ /// <summary>
+ /// Incoming status
+ /// </summary>
+ Incoming,
+ /// <summary>
+ /// Unavailable
+ /// </summary>
+ Unavailable
+ };
+
+ /// <summary>
+ /// Enumeration for the call type.
+ /// </summary>
+ public enum CallType
+ {
+ /// <summary>
+ /// Voice call
+ /// </summary>
+ Voice,
+ /// <summary>
+ /// Video call
+ /// </summary>
+ Video,
+ /// <summary>
+ /// Emergency call
+ /// </summary>
+ E911,
+ /// <summary>
+ /// Unavailable
+ /// </summary>
+ Unavailable
+ };
+
+ /// <summary>
+ /// Enumeration for the call direction.
+ /// </summary>
+ public enum CallDirection
+ {
+ /// <summary>
+ /// MO(Mobile Originated) call
+ /// </summary>
+ Mo,
+ /// <summary>
+ /// MT(Mobile Terminated) call
+ /// </summary>
+ Mt,
+ /// <summary>
+ /// Unavailable
+ /// </summary>
+ Unavailable
+ };
+
+ /// <summary>
+ /// Gets the call handle ID.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// The id of the call handle
+ /// 0 if unable to complete the operation
+ /// </value>
+ public uint HandleId
+ {
+ get
+ {
+ uint handleId;
+ TelephonyError error = Interop.Call.GetHandleId(_callHandle, out handleId);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetHandleId Failed with Error " + error);
+ return 0;
+ }
+
+ return handleId;
+ }
+ }
+
+ /// <summary>
+ /// Gets the call number.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// The number of the call
+ /// empty string if unable to complete the operation
+ /// </value>
+ public string Number
+ {
+ get
+ {
+ string number;
+ TelephonyError error = Interop.Call.GetNumber(_callHandle, out number);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetNumber Failed with Error " + error);
+ return "";
+ }
+
+ return number;
+ }
+ }
+
+ /// <summary>
+ /// Gets the call type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// The type of the call
+ /// </value>
+ public CallType Type
+ {
+ get
+ {
+ CallType callType;
+ TelephonyError error = Interop.Call.GetType(_callHandle, out callType);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetType Failed with Error " + error);
+ return CallType.Unavailable;
+ }
+
+ return callType;
+ }
+ }
+
+ /// <summary>
+ /// Gets the call status.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// The status of the call
+ /// </value>
+ public CallStatus Status
+ {
+ get
+ {
+ CallStatus callStatus;
+ TelephonyError error = Interop.Call.GetStatus(_callHandle, out callStatus);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetStatus Failed with Error " + error);
+ return CallStatus.Unavailable;
+ }
+
+ return callStatus;
+ }
+ }
+
+ /// <summary>
+ /// Gets whether the call is MO(Mobile Originated) call or MT(Mobile Terminated).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// The direction of the call
+ /// </value>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can occur due to:
+ /// 1. Operation Not Supported
+ /// </exception>
+ public CallDirection Direction
+ {
+ get
+ {
+ CallDirection callDirection;
+ TelephonyError error = Interop.Call.GetDirection(_callHandle, out callDirection);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetDirection Failed with Error " + error);
+ return CallDirection.Unavailable;
+ }
+
+ return callDirection;
+ }
+
+ }
+
+ /// <summary>
+ /// Gets whether the call is conference call or not.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// The value whether the call is conference call or not. (true: Conference call, false: Single call)
+ /// </value>
+ public bool ConferenceStatus
+ {
+ get
+ {
+ bool callConfStatus;
+ TelephonyError error = Interop.Call.GetConferenceStatus(_callHandle, out callConfStatus);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetConferenceStatus Failed with Error " + error);
+ return false;
+ }
+
+ return callConfStatus;
+ }
+
+ }
+
+ internal CallHandle(IntPtr handle)
+ {
+ _callHandle = handle;
+ }
+ }
+}
diff --git a/src/Tizen.Telephony/Tizen.Telephony/ChangeNotificationEventArgs.cs b/src/Tizen.Telephony/Tizen.Telephony/ChangeNotificationEventArgs.cs
new file mode 100644
index 0000000..da04afe
--- /dev/null
+++ b/src/Tizen.Telephony/Tizen.Telephony/ChangeNotificationEventArgs.cs
@@ -0,0 +1,319 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+namespace Tizen.Telephony
+{
+ /// <summary>
+ /// This Class contains the data related to the Notification event
+ /// </summary>
+ public class ChangeNotificationEventArgs : EventArgs
+ {
+ internal ChangeNotificationEventArgs(Notification noti, object data)
+ {
+ NotificationType = noti;
+ NotificationData = data;
+ }
+
+ /// <summary>
+ /// Enumeration for Telephony notification.
+ /// </summary>
+ public enum Notification
+ {
+ /// <summary>
+ /// Notification to be invoked when the SIM card state changes.
+ /// SIM.State will be delivered in notification data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/telephony
+ /// </privilege>
+ SimStatus = 0x10,
+ /// <summary>
+ /// Notification to be invoked when the SIM call forwarding indicator state changes.
+ /// 'state(bool)' will be delivered in notification data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/telephony
+ /// </privilege>
+ SimCallForwardingIndicatorState,
+ /// <summary>
+ /// Notification to be invoked when the network service state changes.
+ /// Network.ServiceState will be delivered in notification data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/telephony
+ /// </privilege>
+ NetworkServiceState = 0x20,
+ /// <summary>
+ /// Notification to be invoked when the cell ID changes.
+ /// 'cell_id(int)' will be delivered in notification data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/location.coarse
+ /// </privilege>
+ NetworkCellid,
+ /// <summary>
+ /// Notification to be invoked when the roaming status changes.
+ /// 'roaming_status(bool)' will be delivered in notification data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/telephony
+ /// </privilege>
+ NetworkRoamingStatus,
+ /// <summary>
+ /// Notification to be invoked when the signal strength changes.
+ /// Network.Rssi will be delivered in notification data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/telephony
+ /// </privilege>
+ NetworkSignalstrengthLevel,
+ /// <summary>
+ /// Notification to be invoked when the network name changes.
+ /// 'network_name(string)' will be delivered in notification data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/telephony
+ /// </privilege>
+ NetworkNetworkName,
+ /// <summary>
+ /// Notification to be invoked when the ps type changes.
+ /// Network.PSType will be delivered in notification data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/telephony
+ /// </privilege>
+ NetworkPsType,
+ /// <summary>
+ /// Notification to be invoked when the default data subscription changes.
+ /// Network.DefaultDataSubscription will be delivered in notification data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/telephony
+ /// </privilege>
+ NetworkDefaultDataSubscription,
+ /// <summary>
+ /// Notification to be invoked when the default subscription changes.
+ /// Network.DefaultSubscription will be delivered in notification data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/telephony
+ /// </privilege>
+ NetworkDefaultSubscription,
+ /// <summary>
+ /// Notification to be invoked when the LAC (Location Area Code) changes.
+ /// 'lac(int)' will be delivered in notification data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/location.coarse
+ /// </privilege>
+ NetworkLac,
+ /// <summary>
+ /// Notification to be invoked when the TAC (Tracking Area Code) changes.
+ /// 'tac(int)' will be delivered in notification data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/location.coarse
+ /// </privilege>
+ NetworkTac,
+ /// <summary>
+ /// Notification to be invoked when the system ID changes.
+ /// 'sid(int)' will be delivered in notification data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/location.coarse
+ /// </privilege>
+ NetworkSystemId,
+ /// <summary>
+ /// Notification to be invoked when the network ID changes.
+ /// 'nid(int)' will be delivered in notification data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/location.coarse
+ /// </privilege>
+ NetworkId,
+ /// <summary>
+ /// Notification to be invoked when the base station ID changes.
+ /// 'id(int)' will be delivered in notification data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/location.coarse
+ /// </privilege>
+ NetworkBsId,
+ /// <summary>
+ /// Notification to be invoked when the base station latitude changes.
+ /// 'latitude(int)' will be delivered in notification data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/location.coarse
+ /// </privilege>
+ NetworkBsLatitude,
+ /// <summary>
+ /// Notification to be invoked when the base station longitude changes.
+ /// 'longitue(int)' will be delivered in notification data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/location.coarse
+ /// </privilege>
+ NetworkBsLongitude,
+ /// <summary>
+ /// Notification to be invoked when a voice call is in idle status.
+ /// 'handle id(uint)' will be delivered in notification data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/telephony
+ /// </privilege>
+ VoiceCallStatusIdle,
+ /// <summary>
+ /// Notification to be invoked when a voice call is in active status.
+ /// 'handle id(uint)' will be delivered in notification data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/telephony
+ /// </privilege>
+ VoiceCallStatusActive,
+ /// <summary>
+ /// Notification to be invoked when a voice call is in held status.
+ /// 'handle id(uint)' will be delivered in notification data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/telephony
+ /// </privilege>
+ VoiceCallStatusHeld,
+ /// <summary>
+ /// Notification to be invoked when a voice call is in dialing status.
+ /// 'handle id(uint)' will be delivered in notification data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/telephony
+ /// </privilege>
+ VoiceCallStatusDialing,
+ /// <summary>
+ /// Notification to be invoked when a voice call is in alertingstatus.
+ /// 'handle id(uint)' will be delivered in notification data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/telephony
+ /// </privilege>
+ VoiceCallStatusAlerting,
+ /// <summary>
+ /// Notification to be invoked when a voice call is in incoming status.
+ /// 'handle id(uint)' will be delivered in notification data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/telephony
+ /// </privilege>
+ VoiceCallStatusIncoming,
+ /// <summary>
+ /// Notification to be invoked when a video call is in idle status.
+ /// 'handle id(uint)' will be delivered in notification data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/telephony
+ /// </privilege>
+ VideoCallStatusIdle,
+ /// <summary>
+ /// Notification to be invoked when a video call is in active status.
+ /// 'handle id(uint)' will be delivered in notification data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/telephony
+ /// </privilege>
+ VideoCallStatusActive,
+ /// <summary>
+ /// Notification to be invoked when a video call is in dialing status.
+ /// 'handle id(uint)' will be delivered in notification data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/telephony
+ /// </privilege>
+ VideoCallStatusDialing,
+ /// <summary>
+ /// Notification to be invoked when a video call is in alerting status.
+ /// 'handle id(uint)' will be delivered in notification data
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/telephony
+ /// </privilege>
+ VideoCallStatusAlerting,
+ /// <summary>
+ /// Notification to be invoked when a video call is in incoming status.
+ /// 'handle id(uint)' will be delivered in notification data
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/telephony
+ /// </privilege>
+ VideoCallStatusIncoming,
+ /// <summary>
+ /// Notification to be invoked when the preferred voice subscription changes.
+ /// CallPreferredVoiceSubscription will be delivered in notification data
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/telephony
+ /// </privilege>
+ CallPreferredVoiceSubscription
+ };
+
+ /// <summary>
+ /// Telephony notification type
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public Notification NotificationType
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// Data as per the Notification type
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public object NotificationData
+ {
+ get;
+ internal set;
+ }
+ }
+}
diff --git a/src/Tizen.Telephony/Tizen.Telephony/ExceptionFactory.cs b/src/Tizen.Telephony/Tizen.Telephony/ExceptionFactory.cs
new file mode 100644
index 0000000..885b138
--- /dev/null
+++ b/src/Tizen.Telephony/Tizen.Telephony/ExceptionFactory.cs
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Telephony
+{
+ internal static class ExceptionFactory
+ {
+ internal static Exception CreateException(Interop.Telephony.TelephonyError err)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "Error " + err);
+ Exception exp;
+ switch (err)
+ {
+ case Interop.Telephony.TelephonyError.InvalidParameter:
+ {
+ exp = new ArgumentException("Invalid Parameters Provided");
+ break;
+ }
+
+ case Interop.Telephony.TelephonyError.NotSupported:
+ {
+ exp = new NotSupportedException("Not Supported");
+ break;
+ }
+
+ case Interop.Telephony.TelephonyError.OperationFailed:
+ {
+ exp = new InvalidOperationException("Operation Failed");
+ break;
+ }
+
+ case Interop.Telephony.TelephonyError.OutOfMemory:
+ {
+ exp = new OutOfMemoryException("Out Of Memory");
+ break;
+ }
+
+ case Interop.Telephony.TelephonyError.PermissionDenied:
+ {
+ exp = new UnauthorizedAccessException("Permission Denied");
+ break;
+ }
+
+ case Interop.Telephony.TelephonyError.SIMNotAvailable:
+ {
+ exp = new InvalidOperationException("SIM is Not Available");
+ break;
+ }
+
+ default:
+ {
+ exp = new Exception("");
+ break;
+ }
+
+ }
+
+ return exp;
+ }
+
+ }
+}
diff --git a/src/Tizen.Telephony/Tizen.Telephony/Modem.cs b/src/Tizen.Telephony/Tizen.Telephony/Modem.cs
new file mode 100644
index 0000000..b689eb9
--- /dev/null
+++ b/src/Tizen.Telephony/Tizen.Telephony/Modem.cs
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using static Interop.Telephony;
+namespace Tizen.Telephony
+{
+ /// <summary>
+ /// This Class provides API's to obtain information from the modem.
+ /// </summary>
+ public class Modem
+ {
+ internal IntPtr _handle;
+
+ /// <summary>
+ /// Modem Class Constructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="handle">
+ /// SlotHandle received in the Manager.Init API
+ /// </param>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="ArgumentNullException">
+ /// This exception occurs if handle provided is null
+ /// </exception>
+ public Modem(SlotHandle handle)
+ {
+ if (handle == null)
+ {
+ throw new ArgumentNullException();
+ }
+
+ _handle = handle._handle;
+ }
+
+ /// <summary>
+ /// Enumeration for Modem Power Status.
+ /// </summary>
+ public enum PowerStatus
+ {
+ /// <summary>
+ /// Unknown
+ /// </summary>
+ Unknown = -1,
+ /// <summary>
+ /// Modem power ON
+ /// </summary>
+ On,
+ /// <summary>
+ /// Modem power OFF
+ /// </summary>
+ Off,
+ /// <summary>
+ /// Modem power RESET
+ /// </summary>
+ Reset,
+ /// <summary>
+ /// Modem power LOW
+ /// </summary>
+ Low
+ };
+
+ /// <summary>
+ /// Gets the IMEI (International Mobile Station Equipment Identity) of a mobile phone.
+ /// The IMEI number is used by a GSM network to identify valid devices and therefore can be used for stopping a stolen phone from accessing that network.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/telephony</privilege>
+ /// <value>
+ /// The International Mobile Station Equipment Identity
+ /// empty string if unable to complete the operation
+ /// </value>
+ public string Imei
+ {
+ get
+ {
+ string imei;
+ TelephonyError error = Interop.Modem.GetImei(_handle, out imei);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetImei Failed with error " + error);
+ return "";
+ }
+
+ return imei;
+ }
+ }
+
+ /// <summary>
+ /// Gets the power status of the modem.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/telephony</privilege>
+ /// <value>
+ /// The Modem power status (0=on,1=off,2=reset,3=low)
+ /// </value>
+ public PowerStatus CurrentPowerStatus
+ {
+ get
+ {
+ PowerStatus status;
+ TelephonyError error = Interop.Modem.GetPowerStatus(_handle, out status);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetImei Failed with error " + error);
+ return PowerStatus.Unknown;
+ }
+
+ return status;
+ }
+
+ }
+
+ /// <summary>
+ /// Gets the MEID (Mobile Equipment Identifier) of a mobile phone. (for CDMA)
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/telephony</privilege>
+ /// <value>
+ /// The Mobile Equipment Identifier
+ /// empty string if unable to complete the operation
+ /// </value>
+ public string Meid
+ {
+ get
+ {
+ string meid;
+ TelephonyError error = Interop.Modem.GetMeid(_handle, out meid);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetMeid Failed with error " + error);
+ return "";
+ }
+
+ return meid;
+ }
+
+ }
+ }
+}
diff --git a/src/Tizen.Telephony/Tizen.Telephony/Network.cs b/src/Tizen.Telephony/Tizen.Telephony/Network.cs
new file mode 100644
index 0000000..f8e072a
--- /dev/null
+++ b/src/Tizen.Telephony/Tizen.Telephony/Network.cs
@@ -0,0 +1,831 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using static Interop.Telephony;
+namespace Tizen.Telephony
+{
+ /// <summary>
+ /// The Network class provides API's to obtain information about the current telephony service network.
+ /// </summary>
+ public class Network
+ {
+ internal IntPtr _handle;
+
+ /// <summary>
+ /// Network Class Constructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="handle">
+ /// SlotHandle received in the Manager.Init API
+ /// </param>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="ArgumentNullException">
+ /// This exception occurs if handle provided is null
+ /// </exception>
+ public Network(SlotHandle handle)
+ {
+ if (handle == null)
+ {
+ throw new ArgumentNullException();
+ }
+
+ _handle = handle._handle;
+ }
+
+ /// <summary>
+ /// Enumeration for RSSI (Receive Signal Strength Indicator).
+ /// Rssi6 indicates the highest strength.
+ /// </summary>
+ public enum Rssi
+ {
+ /// <summary>
+ /// Strength 0
+ /// </summary>
+ Rssi0,
+ /// <summary>
+ /// Strength 1
+ /// </summary>
+ Rssi1,
+ /// <summary>
+ /// Strength 2
+ /// </summary>
+ Rssi2,
+ /// <summary>
+ /// Strength 3
+ /// </summary>
+ Rssi3,
+ /// <summary>
+ /// Strength 4
+ /// </summary>
+ Rssi4,
+ /// <summary>
+ /// Strength 5
+ /// </summary>
+ Rssi5,
+ /// <summary>
+ /// Strength 6
+ /// </summary>
+ Rssi6,
+ /// <summary>
+ /// Unavailable
+ /// </summary>
+ Unavailable
+ }
+
+ /// <summary>
+ /// Enumeration for Network Type.
+ /// </summary>
+ public enum Type
+ {
+ /// <summary>
+ /// Unknown
+ /// </summary>
+ Unknown,
+ /// <summary>
+ /// 2G GSM network type
+ /// </summary>
+ Gsm,
+ /// <summary>
+ /// 2.5G GPRS network type
+ /// </summary>
+ Gprs,
+ /// <summary>
+ /// 2.5G EDGE network type
+ /// </summary>
+ Edge,
+ /// <summary>
+ /// 3G UMTS network type
+ /// </summary>
+ Umts,
+ /// <summary>
+ /// HSDPA network type
+ /// </summary>
+ Hsdpa,
+ /// <summary>
+ /// LTE network type
+ /// </summary>
+ Lte,
+ /// <summary>
+ /// IS95A network type
+ /// </summary>
+ Is95a,
+ /// <summary>
+ /// IS95B network type
+ /// </summary>
+ Is95b,
+ /// <summary>
+ /// CDMA 1x network type
+ /// </summary>
+ Cdma1X,
+ /// <summary>
+ /// EVDO revision 0 network type
+ /// </summary>
+ EvdoRev0,
+ /// <summary>
+ /// EVDO revision A network type
+ /// </summary>
+ EvdoRevA,
+ /// <summary>
+ /// EVDO revision B network type
+ /// </summary>
+ EvdoRevB,
+ /// <summary>
+ /// EVDV network type
+ /// </summary>
+ Evdv,
+ /// <summary>
+ /// EHRPD network type
+ /// </summary>
+ Ehrpd
+ }
+
+ /// <summary>
+ /// Enumeration for PS Type.
+ /// </summary>
+ public enum PsType
+ {
+ /// <summary>
+ /// Unknown
+ /// </summary>
+ Unknown,
+ /// <summary>
+ /// HSDPA ps type
+ /// </summary>
+ Hsdpa,
+ /// <summary>
+ /// HSUPA ps type
+ /// </summary>
+ Hsupa,
+ /// <summary>
+ /// HSPA ps type
+ /// </summary>
+ Hspa,
+ /// <summary>
+ /// HSPAP ps type
+ /// </summary>
+ Hspap
+ }
+
+ /// <summary>
+ /// Enumeration for Network Service State.
+ /// </summary>
+ public enum ServiceState
+ {
+ /// <summary>
+ /// In service
+ /// </summary>
+ InService,
+ /// <summary>
+ /// Out of service
+ /// </summary>
+ OutOfService,
+ /// <summary>
+ /// Only emergency call is allowed
+ /// </summary>
+ EmergencyOnly,
+ /// <summary>
+ /// Unavailable
+ /// </summary>
+ Unavailable
+ }
+
+ /// <summary>
+ /// Enumeration for Network Name Priority.
+ /// </summary>
+ public enum NameOption
+ {
+ /// <summary>
+ /// Unknown
+ /// </summary>
+ Unknown,
+ /// <summary>
+ /// Network name displayed by SPN
+ /// </summary>
+ Spn,
+ /// <summary>
+ /// Network name displayed by Network
+ /// </summary>
+ Network,
+ /// <summary>
+ /// Network name displayed by SPN or Network
+ /// </summary>
+ Any
+ }
+
+ /// <summary>
+ /// Enumeration for the possible 'default' Data Subscriptions for Packet Switched(PS).
+ /// </summary>
+ public enum DefaultDataSubscription
+ {
+ /// <summary>
+ /// Unknown status
+ /// </summary>
+ Unknown = -1,
+ /// <summary>
+ /// SIM 1
+ /// </summary>
+ Sim1,
+ /// <summary>
+ /// SIM 2
+ /// </summary>
+ Sim2
+ }
+
+ /// <summary>
+ /// Enumeration defines possible 'default' Subscriptions for Circuit Switched(CS).
+ /// </summary>
+ public enum DefaultSubscription
+ {
+ /// <summary>
+ /// Unknown status
+ /// </summary>
+ Unknown = -1,
+ /// <summary>
+ /// SIM 1 network
+ /// </summary>
+ Sim1,
+ /// <summary>
+ /// SIM 2 network
+ /// </summary>
+ Sim2
+ }
+
+ /// <summary>
+ /// Enumeration for network selection mode.
+ /// </summary>
+ public enum SelectionMode
+ {
+ /// <summary>
+ /// Automatic mode
+ /// </summary>
+ Automatic,
+ /// <summary>
+ /// Manual mode
+ /// </summary>
+ Manual,
+ /// <summary>
+ /// Unavailable
+ /// </summary>
+ Unavailable
+ }
+
+ /// <summary>
+ /// Gets the LAC (Location Area Code) of the current location.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/location.coarse</privilege>
+ /// <remarks>
+ /// This API can be used in GSM / WCDMA network.
+ /// </remarks>
+ /// <value>
+ /// The Location Area Code, -1 if unknown
+ /// </value>
+ public int Lac
+ {
+ get
+ {
+ int lac;
+ TelephonyError error = Interop.Network.GetLac(_handle, out lac);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetLac Failed with error " + error);
+ return -1;
+ }
+
+ Log.Info(Interop.Telephony.LogTag, "Lac Value " + lac);
+ return lac;
+ }
+
+ }
+
+ /// <summary>
+ /// Gets the cell ID of the current location.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/location.coarse</privilege>
+ /// <remarks>
+ /// This API can be used in GSM / WCDMA / LTE network.
+ /// </remarks>
+ /// <value>
+ /// The cell identification number, -1 if unknown
+ /// </value>
+ public int CellId
+ {
+ get
+ {
+ int cellId;
+ TelephonyError error = Interop.Network.GetCellId(_handle, out cellId);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetCellId Failed with error " + error);
+ return -1;
+ }
+
+ Log.Info(Interop.Telephony.LogTag, "CellId Value " + cellId);
+ return cellId;
+ }
+ }
+
+ /// <summary>
+ /// Gets the RSSI (Received Signal Strength Indicator).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/telephony</privilege>
+ /// <value>
+ /// The Received Signal Strength Indicator
+ /// Higher the received number, the stronger the signal strength.
+ /// </value>
+ public Rssi CurrentRssi
+ {
+ get
+ {
+ Rssi currentRssi;
+ TelephonyError error = Interop.Network.GetRssi(_handle, out currentRssi);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetRssi Failed with error " + error);
+ return Rssi.Unavailable;
+ }
+
+ Log.Info(Interop.Telephony.LogTag, "CurrentRssi Value " + currentRssi);
+ return currentRssi;
+ }
+ }
+
+ /// <summary>
+ /// Gets the roaming state of the current registered network.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/telephony</privilege>
+ /// <value>
+ /// true if roaming, otherwise false if not roaming
+ /// </value>
+ public bool RoamingStatus
+ {
+ get
+ {
+ bool roamingStatus;
+ TelephonyError error = Interop.Network.GetRoamingStatus(_handle, out roamingStatus);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetRoamingStatus Failed with error " + error);
+ return false;
+ }
+
+ return roamingStatus;
+ }
+ }
+
+ /// <summary>
+ /// Gets the MCC (Mobile Country Code) of the current registered network.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/telephony</privilege>
+ /// <remarks>
+ /// This API can be used in GSM / WCDMA / LTE network.
+ /// </remarks>
+ /// <value>
+ /// The Mobile Country Code (three digits) Mobile Country Code (MCC) identifies the country where the cell is being used.
+ /// empty string if unknown.
+ /// </value>
+ public string Mcc
+ {
+ get
+ {
+ string mcc;
+ TelephonyError error = Interop.Network.GetMcc(_handle, out mcc);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetMcc Failed with error " + error);
+ return "";
+ }
+
+ return mcc;
+ }
+ }
+
+ /// <summary>
+ /// Gets the MNC (Mobile Network Code) of the current registered network.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/telephony</privilege>
+ /// <remarks>
+ /// This API can be used in GSM / WCDMA / LTE network.
+ /// </remarks>
+ /// <value>
+ /// The Mobile Network Code (three digits) The Mobile Network Code (MNC) identifies the mobile phone operator and network provider.
+ /// empty string if unknown.
+ /// </value>
+ public string Mnc
+ {
+ get
+ {
+ string mnc;
+ TelephonyError error = Interop.Network.GetMnc(_handle, out mnc);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetMnc Failed with error " + error);
+ return "";
+ }
+
+ return mnc;
+ }
+ }
+
+ /// <summary>
+ /// Gets the name of the current registered network.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/telephony</privilege>
+ /// <remarks>
+ /// This API can be used in GSM / WCDMA / LTE network.
+ /// </remarks>
+ /// <value>
+ /// The name of the current registered network
+ /// empty string if unknown.
+ /// </value>
+ public string NetworkName
+ {
+ get
+ {
+ string networkName;
+ TelephonyError error = Interop.Network.GetNetworkName(_handle, out networkName);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetNetworkName Failed with error " + error);
+ return "";
+ }
+
+ return networkName;
+ }
+ }
+
+ /// <summary>
+ /// Gets the network service type of the current registered network.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/telephony</privilege>
+ /// <remarks>
+ /// This API can be used in case network is in service.
+ /// </remarks>
+ /// <value>
+ /// The network service type
+ /// </value>
+ public Type NetworkType
+ {
+ get
+ {
+ Type networkType;
+ TelephonyError error = Interop.Network.GetType(_handle, out networkType);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetType Failed with error " + error);
+ return Type.Unknown;
+ }
+
+ return networkType;
+ }
+ }
+
+ /// <summary>
+ /// Gets the packet service type of the current registered network.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/telephony</privilege>
+ /// <remarks>
+ /// This API can be used in HSDPA network.
+ /// </remarks>
+ /// <value>
+ /// The type of packet service
+ /// </value>
+ public PsType NetworkPsType
+ {
+ get
+ {
+ PsType networkPsType;
+ TelephonyError error = Interop.Network.GetPsType(_handle, out networkPsType);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetPsType Failed with error " + error);
+ return PsType.Unknown;
+ }
+
+ return networkPsType;
+ }
+
+ }
+
+ /// <summary>
+ /// Gets the network name option of the current registered network.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/telephony</privilege>
+ /// <value>
+ /// The network name display option
+ /// </value>
+ public NameOption NetworkNameOption
+ {
+ get
+ {
+ NameOption networkNameOption;
+ TelephonyError error = Interop.Network.GetNetworkNameOption(_handle, out networkNameOption);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetNetworkNameOption Failed with error " + error);
+ return NameOption.Unknown;
+ }
+
+ return networkNameOption;
+ }
+
+ }
+
+ /// <summary>
+ /// Gets the current network state of the telephony service.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/telephony</privilege>
+ /// <value>
+ /// The current network state
+ /// </value>
+ public ServiceState NetworkServiceState
+ {
+ get
+ {
+ ServiceState networkServiceState;
+ TelephonyError error = Interop.Network.GetServiceState(_handle, out networkServiceState);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetServiceState Failed with error " + error);
+ return ServiceState.Unavailable;
+ }
+
+ return networkServiceState;
+ }
+
+ }
+
+ /// <summary>
+ /// Gets the current default subscription for data service (Packet Switched).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/telephony</privilege>
+ /// <value>
+ /// The current default data subscription
+ /// </value>
+ public DefaultDataSubscription NetworkDefaultDataSubscription
+ {
+ get
+ {
+ DefaultDataSubscription networkDefaultDataSubs;
+ TelephonyError error = Interop.Network.GetDefaultDataSubscription(_handle, out networkDefaultDataSubs);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetDefaultDataSubscription Failed with error " + error);
+ return DefaultDataSubscription.Unknown;
+ }
+
+ return networkDefaultDataSubs;
+ }
+
+ }
+
+ /// <summary>
+ /// Gets the current default subscription for voice service (Circuit Switched).
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/telephony</privilege>
+ /// <value>
+ /// The current default voice subscription
+ /// </value>
+ public DefaultSubscription NetworkDefaultSubscription
+ {
+ get
+ {
+ DefaultSubscription networkDefaultSubscription;
+ TelephonyError error = Interop.Network.GetDefaultSubscription(_handle, out networkDefaultSubscription);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetDefaultSubscription Failed with error " + error);
+ return DefaultSubscription.Unknown;
+ }
+
+ return networkDefaultSubscription;
+ }
+
+ }
+
+ /// <summary>
+ /// Gets the network selection mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/telephony</privilege>
+ /// <value>
+ /// The network selection mode.
+ /// </value>
+ public SelectionMode NetworkSelectionMode
+ {
+ get
+ {
+ SelectionMode networkSelectionMode;
+ TelephonyError error = Interop.Network.GetSelectionMode(_handle, out networkSelectionMode);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetSelectionMode Failed with error " + error);
+ return SelectionMode.Unavailable;
+ }
+
+ return networkSelectionMode;
+ }
+
+ }
+
+ /// <summary>
+ /// Gets the TAC (Tracking Area Code) of the current location.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/location.coarse</privilege>
+ /// <remarks>
+ /// This API can be used in LTE network.
+ /// </remarks>
+ /// <value>
+ /// The Tracking Area Code
+ /// -1 if unknown
+ /// </value>
+ public int Tac
+ {
+ get
+ {
+ int tac;
+ TelephonyError error = Interop.Network.GetTac(_handle, out tac);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetTac Failed with error " + error);
+ return -1;
+ }
+
+ return tac;
+ }
+
+ }
+
+ /// <summary>
+ /// Gets the system ID of the current location.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/location.coarse</privilege>
+ /// <remarks>
+ /// This API can be used in CDMA network.
+ /// </remarks>
+ /// <value>
+ /// The system ID
+ /// -1 if unknown
+ /// </value>
+ public int SystemId
+ {
+ get
+ {
+ int systemId;
+ TelephonyError error = Interop.Network.GetSystemId(_handle, out systemId);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetSystemId Failed with error " + error);
+ return -1;
+ }
+
+ return systemId;
+ }
+
+ }
+
+ /// <summary>
+ /// Gets the network ID of the current location.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/location.coarse</privilege>
+ /// <remarks>
+ /// This API can be used in CDMA network.
+ /// </remarks>
+ /// <value>
+ /// The network ID
+ /// -1 if unknown
+ /// </value>
+ public int NetworkId
+ {
+ get
+ {
+ int networkId;
+ TelephonyError error = Interop.Network.GetNetworkId(_handle, out networkId);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetNetworkId Failed with error " + error);
+ return -1;
+ }
+
+ return networkId;
+ }
+
+ }
+
+ /// <summary>
+ /// Gets the base station ID of the current location.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/location.coarse</privilege>>
+ /// <remarks>
+ /// This API can be used in CDMA network.
+ /// </remarks>
+ /// <value>
+ /// The base station ID
+ /// -1 if unknown
+ /// </value>
+
+ public int BaseStationId
+ {
+ get
+ {
+ int baseStationId;
+ TelephonyError error = Interop.Network.GetBaseStationId(_handle, out baseStationId);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetBaseStationId Failed with error " + error);
+ return -1;
+ }
+
+ return baseStationId;
+ }
+
+ }
+
+ /// <summary>
+ /// Gets the base station latitude of the current location.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/location.coarse</privilege>
+ /// <remarks>
+ /// This API can be used in CDMA network.
+ /// </remarks>
+ /// <value>
+ /// The base station latitude
+ /// 0x7FFFFFFF if unknown
+ /// </value>
+ public int BaseStationLatitude
+ {
+ get
+ {
+ int baseStationLatitude;
+ TelephonyError error = Interop.Network.GetBaseStationLatitude(_handle, out baseStationLatitude);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetBaseStationLatitude Failed with error " + error);
+ return 0x7FFFFFFF;
+ }
+
+ return baseStationLatitude;
+ }
+ }
+
+ /// <summary>
+ /// Gets the base station longitude of the current location.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/location.coarse</privilege>
+ /// <remarks>
+ /// This API can be used in CDMA network.
+ /// </remarks>
+ /// <value>
+ /// The base station latitude
+ /// 0x7FFFFFFF if unknown
+ /// </value>
+ public int BaseStationLongitude
+ {
+ get
+ {
+ int baseStationLongitude;
+ TelephonyError error = Interop.Network.GetBaseStationLongitude(_handle, out baseStationLongitude);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetBaseStationLongitude Failed with error " + error);
+ return 0x7FFFFFFF;
+ }
+
+ return baseStationLongitude;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Telephony/Tizen.Telephony/Sim.cs b/src/Tizen.Telephony/Tizen.Telephony/Sim.cs
new file mode 100644
index 0000000..f00383f
--- /dev/null
+++ b/src/Tizen.Telephony/Tizen.Telephony/Sim.cs
@@ -0,0 +1,465 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using static Interop.Telephony;
+
+namespace Tizen.Telephony
+{
+ /// <summary>
+ /// This Class provides API's that allows you to extract information stored on a SIM card
+ /// </summary>
+ public class Sim
+ {
+ internal IntPtr _handle;
+
+ /// <summary>
+ /// Sim Class Constructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="handle">
+ /// SlotHandle received in the Manager.Init API
+ /// </param>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="ArgumentNullException">
+ /// This exception occurs if handle provided is null
+ /// </exception>
+ public Sim(SlotHandle handle)
+ {
+ if (handle == null)
+ {
+ throw new ArgumentNullException();
+ }
+
+ _handle = handle._handle;
+ }
+
+ /// <summary>
+ /// Enumeration for the state of SIM card.
+ /// </summary>
+ public enum State
+ {
+ /// <summary>
+ /// SIM is not available on this device
+ /// </summary>
+ Unavailable,
+ /// <summary>
+ /// SIM is locked
+ /// </summary>
+ Locked,
+ /// <summary>
+ /// SIM is available on this device (SIM is not locked)
+ /// </summary>
+ Available,
+ /// <summary>
+ /// SIM is in transition between states
+ /// </summary>
+ Unknown
+ }
+
+ /// <summary>
+ /// Enumeration for the lock state of SIM card.
+ /// </summary>
+ public enum LockState
+ {
+ /// <summary>
+ /// SIM is not in lock
+ /// </summary>
+ Unknown,
+ /// <summary>
+ /// SIM is PIN(Personal Identification Number) locked
+ /// </summary>
+ PinRequired,
+ /// <summary>
+ /// SIM is PUK(Personal Unblocking Code) locked
+ /// </summary>
+ PukRequired,
+ /// <summary>
+ /// SIM is permanently blocked(All the attempts for PIN/PUK failed)
+ /// </summary>
+ PermLocked,
+ /// <summary>
+ /// SIM is NCK(Network Control Key) locked
+ /// </summary>
+ NckRequired
+ }
+
+ /// <summary>
+ /// Enumeration for the type of SIM card.
+ /// </summary>
+ public enum ApplicationType
+ {
+ /// <summary>
+ /// SIM(GSM) Application
+ /// </summary>
+ Sim = 0x01,
+ /// <summary>
+ /// USIM Application
+ /// </summary>
+ Usim = 0x02,
+ /// <summary>
+ /// CDMA Application
+ /// </summary>
+ Csim = 0x04,
+ /// <summary>
+ /// ISIM Application
+ /// </summary>
+ Isim = 0x08
+ }
+
+ /// <summary>
+ /// Gets the Integrated Circuit Card IDentification (ICC-ID).
+ /// The Integrated Circuit Card Identification number internationally identifies SIM cards.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/telephony</privilege>
+ /// <value>
+ /// The Integrated Circuit Card Identification
+ /// empty string if unable to complete the operation
+ /// </value>
+ /// <precondition>
+ /// The SIM state must be Available
+ /// </precondition>
+ public string IccId
+ {
+ get
+ {
+ string iccId;
+ TelephonyError error = Interop.Sim.GetIccId(_handle, out iccId);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetIccId Failed with error " + error);
+ return "";
+ }
+
+ return iccId;
+ }
+ }
+
+ /// <summary>
+ /// Gets the SIM Operator (MCC [3 digits] + MNC [2~3 digits]).
+ /// The Operator is embedded in the SIM card.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/telephony</privilege>
+ /// <value>
+ /// The SIM Operator
+ /// empty string if unable to complete the operation
+ /// </value>
+ /// <precondition>
+ /// The SIM state must be Available
+ /// </precondition>
+ public string Operator
+ {
+ get
+ {
+ string simOperator;
+ TelephonyError error = Interop.Sim.GetOperator(_handle, out simOperator);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetOperator Failed with error " + error);
+ return "";
+ }
+
+ return simOperator;
+ }
+ }
+
+ /// <summary>
+ /// Gets the Mobile Subscription Identification Number (MSIN [9~10 digits]) of the SIM provider.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/telephony</privilege>
+ /// <value>
+ /// The Mobile Subscription Identification Number
+ /// empty string if unable to complete the operation
+ /// </value>
+ /// <precondition>
+ /// The SIM state must be Available
+ /// </precondition>
+ public string Msin
+ {
+ get
+ {
+ string msin;
+ TelephonyError error = Interop.Sim.GetMsin(_handle, out msin);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetMsin Failed with error " + error);
+ return "";
+ }
+
+ return msin;
+ }
+ }
+
+ /// <summary>
+ /// Gets the Service Provider Name (SPN) of the SIM card.
+ /// Gets Service Provider Name embedded in the SIM card.If this value is not stored in SIM card, empty string will be returned.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/telephony</privilege>
+ /// <value>
+ /// The Service Provider Name
+ /// empty string if unable to complete the operation
+ /// </value>
+ /// <precondition>
+ /// The SIM state must be Available
+ /// </precondition>
+ public string Spn
+ {
+ get
+ {
+ string spn;
+ TelephonyError error = Interop.Sim.GetSpn(_handle, out spn);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetSpn Failed with error " + error);
+ return "";
+ }
+
+ return spn;
+ }
+ }
+
+ /// <summary>
+ /// Checks whether the current SIM card is different from the previous SIM card.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/telephony</privilege>
+ /// <value>
+ /// true if the current SIM card is different from the previous SIM card, otherwise false if the SIM card is not changed
+ /// </value>
+ /// <precondition>
+ /// The SIM state must be Available
+ /// </precondition>
+ public bool IsChanged
+ {
+ get
+ {
+ int ischanged;
+ bool isChanged = false; ;
+ TelephonyError error = Interop.Sim.IsChanged(_handle, out ischanged);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "IsChanged Failed with error " + error);
+ return false;
+ }
+
+ if (ischanged > 0)
+ {
+ isChanged = true;
+ }
+
+ return isChanged;
+ }
+ }
+
+ /// <summary>
+ /// Gets the state of the SIM.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/telephony</privilege>
+ /// <value>
+ /// The current state of the SIM
+ /// </value>
+ public State CurrentState
+ {
+ get
+ {
+ State currentState;
+ TelephonyError error = Interop.Sim.GetState(_handle, out currentState);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetState Failed with error " + error);
+ return State.Unavailable;
+ }
+
+ return currentState;
+ }
+ }
+
+ /// <summary>
+ /// Gets the count of application on UICC.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/telephony</privilege>
+ /// <value>
+ /// The masking value for below values are provided by the enum ApplicationType
+ /// 0 if unable to complete the operation
+ /// </value>
+ /// <precondition>
+ /// The SIM state must be Available
+ /// </precondition>
+ public uint ApplicationList
+ {
+ get
+ {
+ uint appList;
+ TelephonyError error = Interop.Sim.GetApplicationList(_handle, out appList);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetApplicationList Failed with error " + error);
+ return 0;
+ }
+
+ return appList;
+ }
+ }
+
+ /// <summary>
+ /// Gets subscriber number embedded in the SIM card. This value contains MSISDN related to the subscriber.
+ /// If this value is not stored in SIM card, empty string will be returned.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/telephony</privilege>
+ /// <value>
+ /// The subscriber number in the SIM
+ /// empty string if unable to complete the operation
+ /// </value>
+ /// <precondition>
+ /// The SIM state must be Available
+ /// </precondition>
+ public string SubscriberNumber
+ {
+ get
+ {
+ string subscriberNumber;
+ TelephonyError error = Interop.Sim.GetSubscriberNumber(_handle, out subscriberNumber);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetSubscriberNumber Failed with error " + error);
+ return "";
+ }
+
+ return subscriberNumber;
+ }
+ }
+
+ /// <summary>
+ /// Gets the Subscriber ID.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/telephony</privilege>
+ /// <value>
+ /// The subscriber ID
+ /// empty string if unable to complete the operation
+ /// </value>
+ /// <precondition>
+ /// The SIM state must be Available
+ /// </precondition>
+ public string SubscriberId
+ {
+ get
+ {
+ string subscriberId;
+ TelephonyError error = Interop.Sim.GetSubscriberId(_handle, out subscriberId);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetSubscriberId Failed with error " + error);
+ return "";
+ }
+
+ return subscriberId;
+ }
+ }
+
+ /// <summary>
+ /// Gets the lock state of the SIM.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/telephony</privilege>
+ /// <value>
+ /// The current lock state of the SIM
+ /// </value>
+ /// <precondition>
+ /// The SIM state must be Available
+ /// </precondition>
+ public LockState CurrentLockState
+ {
+ get
+ {
+ LockState currentLockState;
+ TelephonyError error = Interop.Sim.GetLockState(_handle, out currentLockState);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetLockState Failed with error " + error);
+ return LockState.Unknown;
+ }
+
+ return currentLockState;
+ }
+ }
+
+ /// <summary>
+ /// Gets the GID1 (Group Identifier Level 1).
+ /// Gets Group Identifier Level 1(GID1) embedded in the SIM card.If this value is not stored in SIM card, empty string will be returned.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/telephony</privilege>
+ /// <value>
+ /// The GID1 (Group Identifier Level 1)
+ /// empty string if unable to complete the operation
+ /// </value>
+ /// <precondition>
+ /// The SIM state must be Available
+ /// </precondition>
+ public string GroupId1
+ {
+ get
+ {
+ string groupId1;
+ TelephonyError error = Interop.Sim.GetGroupId1(_handle, out groupId1);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetGroupId1 Failed with error " + error);
+ return "";
+ }
+
+ return groupId1;
+ }
+ }
+
+ /// <summary>
+ /// Gets the call forwarding indicator state of the SIM.
+ /// If the state is true, incoming call will be forwarded to the selected number.state indicates the CFU(Call Forwarding Unconditional) indicator status - Voice. (3GPP TS 31.102 4.2.64 EF CFIS)
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>http://tizen.org/privilege/telephony</privilege>
+ /// <value>
+ /// The value whether incoming call will be forwarded or not. (true: forwarded, false: not forwarded)
+ /// </value>
+ /// <precondition>
+ /// The SIM state must be Available
+ /// </precondition>
+ public bool CallForwardingIndicatorState
+ {
+ get
+ {
+ bool callForwardingIndicatorState;
+ TelephonyError error = Interop.Sim.GetCallForwardingIndicatorState(_handle, out callForwardingIndicatorState);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetCallForwardingIndicatorState Failed with error " + error);
+ return false;
+ }
+
+ return callForwardingIndicatorState;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Telephony/Tizen.Telephony/SlotHandle.cs b/src/Tizen.Telephony/Tizen.Telephony/SlotHandle.cs
new file mode 100644
index 0000000..967f781
--- /dev/null
+++ b/src/Tizen.Telephony/Tizen.Telephony/SlotHandle.cs
@@ -0,0 +1,309 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Telephony
+{
+ /// <summary>
+ /// This Class provides API's that provides functionality related to slot handle.
+ /// </summary>
+ public class SlotHandle
+ {
+ internal IntPtr _handle;
+ private List<Interop.Telephony.NotificationCallback> _changeNotificationList = new List<Interop.Telephony.NotificationCallback>();
+
+ internal SlotHandle(IntPtr handle)
+ {
+ _handle = handle;
+ }
+
+ /// <summary>
+ /// Event Handler for Receiving the Telephony State Changes
+ /// this event will be triggered for the NotificationId's given in the SetNotificationId API
+ /// </summary>
+ public event EventHandler<ChangeNotificationEventArgs> ChangeNotification;
+
+ internal IntPtr Handle
+ {
+ get
+ {
+ return _handle;
+ }
+ }
+
+ /// <summary>
+ /// The Notification Id's for which the ChangeNotification event will be triggered
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="list">
+ /// The List of Notification Id's for which the ChangeNotification event will be triggered
+ /// </param>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can occur due to:
+ /// 1. Operation Not Supported
+ /// 2. Operation Failed
+ /// </exception>
+ public void SetNotificationId(IEnumerable<ChangeNotificationEventArgs.Notification> list)
+ {
+ try
+ {
+ foreach (ChangeNotificationEventArgs.Notification n in list)
+ {
+ SetCallback(n);
+ }
+ }
+ catch (Exception e)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "SetNotificationId Failed with Error " + e.ToString());
+ throw e;
+ }
+ }
+
+ /// <summary>
+ /// The Notification Id's for which the ChangeNotification event will not be triggered
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="list">
+ /// The List of Notification Id's for which the ChangeNotification event will be not be triggered
+ /// </param>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can occur due to:
+ /// 1. Operation Not Supported
+ /// 2. Operation Failed
+ /// </exception>
+ public void RemoveNotificationId(IEnumerable<ChangeNotificationEventArgs.Notification> list)
+ {
+ foreach (ChangeNotificationEventArgs.Notification n in list)
+ {
+ Interop.Telephony.TelephonyError error = Interop.Telephony.TelephonyUnsetNotiCb(_handle, n);
+ if (error != Interop.Telephony.TelephonyError.None)
+ {
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+ }
+
+ private void SetCallback(ChangeNotificationEventArgs.Notification n)
+ {
+ Interop.Telephony.NotificationCallback NotificationDelegate = (IntPtr handle, ChangeNotificationEventArgs.Notification notiId, IntPtr data, IntPtr userData) =>
+ {
+ SlotHandle simHandle = Manager.FindHandle(handle);
+ object notiData = null;
+ switch (notiId)
+ {
+ case ChangeNotificationEventArgs.Notification.SimStatus:
+ {
+ notiData = (Sim.State)Marshal.ReadInt32(data);
+ break;
+ }
+
+ case ChangeNotificationEventArgs.Notification.SimCallForwardingIndicatorState:
+ {
+ notiData = ((Marshal.ReadInt32(data) == 0) ? false : true);
+ break;
+ }
+
+ case ChangeNotificationEventArgs.Notification.NetworkServiceState:
+ {
+ notiData = (Network.ServiceState)Marshal.ReadInt32(data);
+ break;
+ }
+
+ case ChangeNotificationEventArgs.Notification.NetworkCellid:
+ {
+ notiData = Marshal.ReadInt32(data);
+ break;
+ }
+
+ case ChangeNotificationEventArgs.Notification.NetworkRoamingStatus:
+ {
+ notiData = (Marshal.ReadInt32(data) == 0) ? false : true;
+ break;
+ }
+
+ case ChangeNotificationEventArgs.Notification.NetworkSignalstrengthLevel:
+ {
+ notiData = (Network.Rssi)Marshal.ReadInt32(data);
+ break;
+ }
+
+ case ChangeNotificationEventArgs.Notification.NetworkNetworkName:
+ {
+ notiData = Marshal.PtrToStringAnsi(data);
+ break;
+ }
+
+ case ChangeNotificationEventArgs.Notification.NetworkPsType:
+ {
+ notiData = (Network.PsType)Marshal.ReadInt32(data);
+ break;
+ }
+
+ case ChangeNotificationEventArgs.Notification.NetworkDefaultDataSubscription:
+ {
+ notiData = (Network.DefaultDataSubscription)Marshal.ReadInt32(data);
+ break;
+ }
+
+ case ChangeNotificationEventArgs.Notification.NetworkDefaultSubscription:
+ {
+ notiData = (Network.DefaultSubscription)Marshal.ReadInt32(data);
+ break;
+ }
+
+ case ChangeNotificationEventArgs.Notification.NetworkLac:
+ {
+ notiData = Marshal.ReadInt32(data);
+ break;
+ }
+
+ case ChangeNotificationEventArgs.Notification.NetworkTac:
+ {
+ notiData = Marshal.ReadInt32(data);
+ break;
+ }
+
+ case ChangeNotificationEventArgs.Notification.NetworkSystemId:
+ {
+ notiData = Marshal.ReadInt32(data);
+ break;
+ }
+
+ case ChangeNotificationEventArgs.Notification.NetworkId:
+ {
+ notiData = Marshal.ReadInt32(data);
+ break;
+ }
+
+ case ChangeNotificationEventArgs.Notification.NetworkBsId:
+ {
+ notiData = Marshal.ReadInt32(data);
+ break;
+ }
+
+ case ChangeNotificationEventArgs.Notification.NetworkBsLatitude:
+ {
+ notiData = Marshal.ReadInt32(data);
+ break;
+ }
+
+ case ChangeNotificationEventArgs.Notification.NetworkBsLongitude:
+ {
+ notiData = Marshal.ReadInt32(data);
+ break;
+ }
+
+ case ChangeNotificationEventArgs.Notification.VoiceCallStatusIdle:
+ {
+ notiData = (uint)Marshal.ReadInt32(data);
+ break;
+ }
+
+ case ChangeNotificationEventArgs.Notification.VoiceCallStatusActive:
+ {
+ notiData = (uint)Marshal.ReadInt32(data);
+ break;
+ }
+
+ case ChangeNotificationEventArgs.Notification.VoiceCallStatusHeld:
+ {
+ notiData = (uint)Marshal.ReadInt32(data);
+ break;
+ }
+
+ case ChangeNotificationEventArgs.Notification.VoiceCallStatusDialing:
+ {
+ notiData = (uint)Marshal.ReadInt32(data);
+ break;
+ }
+
+ case ChangeNotificationEventArgs.Notification.VoiceCallStatusAlerting:
+ {
+ notiData = (uint)Marshal.ReadInt32(data);
+ break;
+ }
+
+ case ChangeNotificationEventArgs.Notification.VoiceCallStatusIncoming:
+ {
+ notiData = (uint)Marshal.ReadInt32(data);
+ break;
+ }
+
+ case ChangeNotificationEventArgs.Notification.VideoCallStatusIdle:
+ {
+ notiData = (uint)Marshal.ReadInt32(data);
+ break;
+ }
+
+ case ChangeNotificationEventArgs.Notification.VideoCallStatusActive:
+ {
+ notiData = (uint)Marshal.ReadInt32(data);
+ break;
+ }
+
+ case ChangeNotificationEventArgs.Notification.VideoCallStatusDialing:
+ {
+ notiData = (uint)Marshal.ReadInt32(data);
+ break;
+ }
+
+ case ChangeNotificationEventArgs.Notification.VideoCallStatusAlerting:
+ {
+ notiData = (uint)Marshal.ReadInt32(data);
+ break;
+ }
+
+ case ChangeNotificationEventArgs.Notification.VideoCallStatusIncoming:
+ {
+ notiData = (uint)Marshal.ReadInt32(data);
+ break;
+ }
+
+ case ChangeNotificationEventArgs.Notification.CallPreferredVoiceSubscription:
+ {
+ notiData = (CallPreferredVoiceSubscription)Marshal.ReadInt32(data);
+ break;
+ }
+
+ }
+
+ ChangeNotificationEventArgs args = new ChangeNotificationEventArgs(notiId, notiData);
+ ChangeNotification?.Invoke(simHandle, args);
+ };
+ _changeNotificationList.Add(NotificationDelegate);
+
+ Interop.Telephony.TelephonyError error = Interop.Telephony.TelephonySetNotiCb(_handle, n, NotificationDelegate, IntPtr.Zero);
+ if (error != Interop.Telephony.TelephonyError.None)
+ {
+ Exception e = ExceptionFactory.CreateException(error);
+ // Check if error is Invalid Parameter then hide the error
+ if (e is ArgumentException)
+ {
+ e = new InvalidOperationException("Internal Error Occured");
+ }
+
+ throw e;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Telephony/Tizen.Telephony/StateEventArgs.cs b/src/Tizen.Telephony/Tizen.Telephony/StateEventArgs.cs
new file mode 100644
index 0000000..a7b4e4c
--- /dev/null
+++ b/src/Tizen.Telephony/Tizen.Telephony/StateEventArgs.cs
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+namespace Tizen.Telephony
+{
+ /// <summary>
+ /// This class contain the data related to the State changed event
+ /// </summary>
+ public class StateEventArgs : EventArgs
+ {
+ internal StateEventArgs(State s)
+ {
+ CurrentState = s;
+ }
+
+ /// <summary>
+ /// The Current State
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public State CurrentState
+ {
+ get;
+ internal set;
+ }
+ }
+}
diff --git a/src/Tizen.Telephony/Tizen.Telephony/Telephony.cs b/src/Tizen.Telephony/Tizen.Telephony/Telephony.cs
new file mode 100644
index 0000000..203e2c6
--- /dev/null
+++ b/src/Tizen.Telephony/Tizen.Telephony/Telephony.cs
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using static Interop.Telephony;
+
+namespace Tizen.Telephony
+{
+ /// <summary>
+ /// Enumeration for the telephony state.
+ /// </summary>
+ public enum State
+ {
+ /// <summary>
+ /// Telephony state is not ready
+ /// </summary>
+ NotReady,
+ /// <summary>
+ /// Telephony state is ready
+ /// </summary>
+ Ready,
+ /// <summary>
+ /// Unavailable
+ /// </summary>
+ Unavailable
+ };
+
+ /// <summary>
+ /// Enumeration for the preferred voice call subscription.
+ /// </summary>
+ public enum CallPreferredVoiceSubscription
+ {
+ /// <summary>
+ /// Unknown status
+ /// </summary>
+ Unknown = -1,
+ /// <summary>
+ /// Current network
+ /// </summary>
+ CurrentNetwork = 0,
+ /// <summary>
+ /// ASK Always
+ /// </summary>
+ AskAlways,
+ /// <summary>
+ /// SIM 1
+ /// </summary>
+ Sim1,
+ /// <summary>
+ /// SIM 2
+ /// </summary>
+ Sim2
+ };
+
+ /// <summary>
+ /// This Class provides API's to Initialize and Deinitialize the framework
+ /// it also provides API's to get the SlotHandle's which can then be used to get other Network/Sim/Call/Modem Information.
+ /// </summary>
+ public static class Manager
+ {
+ internal static List<SlotHandle> _telephonyHandle = new List<SlotHandle>();
+ private static HandleList _handleList;
+ private static bool _isInitialized = false;
+ private static event EventHandler<StateEventArgs> _stateChanged;
+ private static StateChangedCallback stateDelegate = delegate(State state, IntPtr userData)
+ {
+ StateEventArgs args = new StateEventArgs(state);
+ _stateChanged?.Invoke(null, args);
+ };
+
+ /// <summary>
+ /// Event Handler to be invoked when the telephony state changes.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static event EventHandler<StateEventArgs> StateChanged
+ {
+ add
+ {
+ if (_stateChanged == null)
+ {
+ Interop.Telephony.TelephonyError error = Interop.Telephony.TelephonySetStateChangedCb(stateDelegate, IntPtr.Zero);
+ if (error != TelephonyError.None)
+ {
+ Log.Error(LogTag, "Add StateChanged Failed with Error: " + error);
+ }
+
+ else
+ {
+ _stateChanged += value;
+ }
+
+ }
+ }
+
+ remove
+ {
+ _stateChanged -= value;
+ if (_stateChanged == null)
+ {
+ Interop.Telephony.TelephonyError error = Interop.Telephony.TelephonyUnsetStateChangedCb(stateDelegate);
+ if (error != TelephonyError.None)
+ {
+ Log.Error(LogTag, "Remove StateChanged Failed with Error: " + error);
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Acquires the telephony state value.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// The state value of telephony.
+ /// </value>
+ public static State CurrentState
+ {
+ get
+ {
+ State state = State.NotReady;
+ TelephonyError error = Interop.Telephony.TelephonyGetState(out state);
+ if (error != TelephonyError.None)
+ {
+ Tizen.Log.Error(Interop.Telephony.LogTag, "GetState Failed with Error " + error);
+ return State.Unavailable;
+ }
+
+ return state;
+ }
+ }
+
+ /// <summary>
+ /// Acquires the Number of available handles to use the telephony API.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// A List of Telephony handles.
+ /// You will get 2 SlotHandles in case of dual SIM device.
+ /// where,SlotHandle at Index '0' represents Primary SIM and Index '1' represents Secondary SIM.
+ /// </returns>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can will be generated in the following cases
+ /// 1. System is out of memory
+ /// 2. If the operation is not supported on device
+ /// 3. If the Operation Failed
+ /// </exception>
+ public static IEnumerable<SlotHandle> Init()
+ {
+ //DeInitialize Previous Handles if present
+ if (_isInitialized)
+ {
+ Deinit();
+ }
+
+ TelephonyError err = Interop.Telephony.TelephonyInit(out _handleList);
+ if (err != TelephonyError.None)
+ {
+ Exception e = ExceptionFactory.CreateException(err);
+ // Check if error is Invalid Parameter then hide the error
+ if (e is ArgumentException)
+ {
+ e = new InvalidOperationException("Internal Error Occured");
+ }
+
+ throw e;
+ }
+
+ int offset = 0;
+ for (int i = 0; i < _handleList.Count; i++)
+ {
+ _telephonyHandle.Add(new SlotHandle(Marshal.ReadIntPtr(_handleList.HandleArrayPointer, offset)));
+ offset += Marshal.SizeOf(_handleList.HandleArrayPointer);
+ }
+
+ _isInitialized = true;
+ //Tizen.Log.Info(Interop.Telephony.LogTag, "Returning the number of sims " + _handleList.Count);
+ return _telephonyHandle;
+ }
+
+ /// <summary>
+ /// Deinitializes the telephony handles.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>http://tizen.org/feature/network.telephony</feature>
+ /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can be generated in the following cases
+ /// 1. If the operation is not supported on device
+ /// 2. If the Operation Failed
+ /// </exception>
+ public static void Deinit()
+ {
+ TelephonyError error = Interop.Telephony.TelephonyDeinit(ref _handleList);
+ if (error != TelephonyError.None)
+ {
+ Exception e = ExceptionFactory.CreateException(error);
+ // Check if error is Invalid Parameter then hide the error
+ if (e is ArgumentException)
+ {
+ e = new InvalidOperationException("Internal Error Occured");
+ }
+
+ throw e;
+ }
+
+ _isInitialized = false;
+ _telephonyHandle.Clear();
+ }
+
+ internal static SlotHandle FindHandle(IntPtr handle)
+ {
+ SlotHandle temp = _telephonyHandle[0];
+ foreach (SlotHandle simHandle in _telephonyHandle)
+ {
+ if (simHandle._handle == handle)
+ {
+ temp = simHandle;
+ }
+ }
+
+ return temp;
+ }
+ }
+}
diff --git a/src/Tizen.Tracer/Interop/Interop.Libraries.cs b/src/Tizen.Tracer/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..cee5a29
--- /dev/null
+++ b/src/Tizen.Tracer/Interop/Interop.Libraries.cs
@@ -0,0 +1,15 @@
+// Copyright 2016 by Samsung Electronics, Inc.,
+//
+// This software is the confidential and proprietary information
+// of Samsung Electronics, Inc. ("Confidential Information"). You
+// shall not disclose such Confidential Information and shall use
+// it only in accordance with the terms of the license agreement
+// you entered into with Samsung.
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string ttrace = "libttrace.so.1";
+ }
+}
diff --git a/src/Tizen.Tracer/Interop/Interop.Tracer.cs b/src/Tizen.Tracer/Interop/Interop.Tracer.cs
new file mode 100755
index 0000000..cd35b1b
--- /dev/null
+++ b/src/Tizen.Tracer/Interop/Interop.Tracer.cs
@@ -0,0 +1,31 @@
+// Copyright 2016 by Samsung Electronics, Inc.,
+//
+// This software is the confidential and proprietary information
+// of Samsung Electronics, Inc. ("Confidential Information"). You
+// shall not disclose such Confidential Information and shall use
+// it only in accordance with the terms of the license agreement
+// you entered into with Samsung.
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Tracer
+ {
+ [DllImport(Libraries.ttrace, EntryPoint = "trace_begin")]
+ internal static extern void Begin (String name);
+
+ [DllImport(Libraries.ttrace, EntryPoint = "trace_end")]
+ internal static extern void End ();
+
+ [DllImport(Libraries.ttrace, EntryPoint = "trace_async_begin")]
+ internal static extern void AsyncBegin (int cookie, String name);
+
+ [DllImport(Libraries.ttrace, EntryPoint = "trace_async_end")]
+ internal static extern void AsyncEnd (int cookie, String name);
+
+ [DllImport(Libraries.ttrace, EntryPoint = "trace_update_counter")]
+ internal static extern void TraceValue (int value, String name);
+ }
+}
diff --git a/src/Tizen.Tracer/Tizen.Tracer.csproj b/src/Tizen.Tracer/Tizen.Tracer.csproj
new file mode 100644
index 0000000..5ed2f1f
--- /dev/null
+++ b/src/Tizen.Tracer/Tizen.Tracer.csproj
@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Tracer/Tizen/Tracer.cs b/src/Tizen.Tracer/Tizen/Tracer.cs
new file mode 100755
index 0000000..e00bfce
--- /dev/null
+++ b/src/Tizen.Tracer/Tizen/Tracer.cs
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen
+{
+ /// <summary>
+ /// Provides functions for writing trace message to the system trace buffer.
+ /// </summary>
+ public static class Tracer
+ {
+ /// <summary>
+ /// Writes a trace event to indicate that a synchronous event has begun.
+ /// </summary>
+ /// <remarks>
+ /// The specific error code can be obtained using the Tizen.Internals.Errors.ErrorFacts.GetLastResult() method.
+ /// </remarks>
+ /// <param name="name">The name of event (optionally containing format specifiers)</param>
+ /// <seealso cref="Tizen.Tracer.End()"/>
+ public static void Begin (String name)
+ {
+ Interop.Tracer.Begin (name);
+ }
+
+ /// <summary>
+ /// Writes a trace event to indicate that the synchronous event has ended.
+ /// </summary>
+ /// <remarks>
+ /// Tizen.Tracer.End() ends the most recently called Tizen.Tracer.Begin().
+ /// The specific error code can be obtained using the Tizen.Internals.Errors.ErrorFacts.GetLastResult() method.
+ /// </remarks>
+ /// <seealso cref="Tizen.Tracer.Begin()"/>
+ public static void End ()
+ {
+ Interop.Tracer.End ();
+ }
+
+ /// <summary>
+ /// Writes a trace event to indicate that an asynchronous event has begun.
+ /// </summary>
+ /// <remarks>
+ /// The specific error code can be obtained using the Tizen.Internals.Errors.ErrorFacts.GetLastResult() method.
+ /// </remarks>
+ /// <param name="cookie">An unique identifier for distinguishing simultaneous events</param>
+ /// <param name="name">The name of event (optionally containing format specifiers)</param>
+ /// <seealso cref="Tizen.Tracer.AsyncEnd()"/>
+ public static void AsyncBegin (int cookie, String name)
+ {
+ Interop.Tracer.AsyncBegin (cookie, name);
+ }
+
+ /// <summary>
+ /// Writes a trace event to indicate that the asynchronous event has ended.
+ /// </summary>
+ /// <remarks>
+ /// Tizen.Tracer.AsyncEnd() ends matched Tizen.Tracer.AsyncBegin() which has same cookie and name.
+ /// The specific error code can be obtained using the Tizen.Internals.Errors.ErrorFacts.GetLastResult() method.
+ /// </remarks>
+ /// <param name="cookie">An unique identifier for distinguishing simultaneous events</param>
+ /// <param name="name">The name of event (optionally containing format specifiers)</param>
+ /// <seealso cref="Tizen.Tracer.AsyncBegin()"/>
+ public static void AsyncEnd (int cookie, String name)
+ {
+ Interop.Tracer.AsyncEnd (cookie, name);
+ }
+
+ /// <summary>
+ /// Writes a trace event to track change of integer value.
+ /// </summary>
+ /// <remarks>
+ /// The specific error code can be obtained using the Tizen.Internals.Errors.ErrorFacts.GetLastResult() method.
+ /// </remarks>
+ /// <param name="value">The integer variable to trace</param>
+ /// <param name="name">The name of event (optionally containing format specifiers)</param>
+ public static void TraceValue (int value, String name)
+ {
+ Interop.Tracer.TraceValue (value, name);
+ }
+ }
+}
+
diff --git a/src/Tizen.Uix.InputMethodManager/Interop/Interop.InputMethodManager.cs b/src/Tizen.Uix.InputMethodManager/Interop/Interop.InputMethodManager.cs
new file mode 100755
index 0000000..747ec7f
--- /dev/null
+++ b/src/Tizen.Uix.InputMethodManager/Interop/Interop.InputMethodManager.cs
@@ -0,0 +1,58 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+using System;
+using System.Runtime.InteropServices;
+
+/// <summary>
+/// Partial Interop Class
+/// </summary>
+internal static partial class Interop
+{
+ /// <summary>
+ /// InputMethodManager Interop Class
+ /// </summary>
+ internal static class InputMethodManager
+ {
+ internal static string LogTag = "Tizen.Uix.InputMethodManager";
+
+ private const int ErrorInputMethodManager = -0x02F20000;
+
+ internal enum ErrorCode
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None, /**< Successful */
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter, /**< Invalid parameter */
+ PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied, /**< Permission denied */
+ OperationFailed = ErrorInputMethodManager | 0x0010, /**< Operation failed */
+ };
+
+ [DllImport(Libraries.InputMethodManager, EntryPoint = "ime_manager_show_ime_list")]
+ internal static extern ErrorCode ImeManagerShowImeList();
+
+ [DllImport(Libraries.InputMethodManager, EntryPoint = "ime_manager_show_ime_selector")]
+ internal static extern ErrorCode ImeManagerShowImeSelector();
+
+ [DllImport(Libraries.InputMethodManager, EntryPoint = "ime_manager_is_ime_enabled")]
+ internal static extern ErrorCode ImeManagerIsImeEnabled(string appId, out bool isEnabled);
+
+ [DllImport(Libraries.InputMethodManager, EntryPoint = "ime_manager_get_active_ime")]
+ internal static extern ErrorCode ImeManagerGetActiveIme(out string app_id);
+
+ [DllImport(Libraries.InputMethodManager, EntryPoint = "ime_manager_get_enabled_ime_count")]
+ internal static extern int ImeManagerGetEnabledImeCount();
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Uix.InputMethodManager/Interop/Interop.Libraries.cs b/src/Tizen.Uix.InputMethodManager/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..603344f
--- /dev/null
+++ b/src/Tizen.Uix.InputMethodManager/Interop/Interop.Libraries.cs
@@ -0,0 +1,30 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/// <summary>
+/// Partial Interop Class
+/// </summary>
+internal static partial class Interop
+{
+ /// <summary>
+ /// Partial Libraries Class
+ /// </summary>
+ internal static partial class Libraries
+ {
+ public const string InputMethodManager = "libcapi-ui-inputmethod-manager.so.0";
+ }
+}
diff --git a/src/Tizen.Uix.InputMethodManager/Tizen.Uix.InputMethodManager.csproj b/src/Tizen.Uix.InputMethodManager/Tizen.Uix.InputMethodManager.csproj
new file mode 100644
index 0000000..5ed2f1f
--- /dev/null
+++ b/src/Tizen.Uix.InputMethodManager/Tizen.Uix.InputMethodManager.csproj
@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Uix.InputMethodManager/Tizen.Uix.InputMethodManager/InputMethodManager.cs b/src/Tizen.Uix.InputMethodManager/Tizen.Uix.InputMethodManager/InputMethodManager.cs
new file mode 100755
index 0000000..f8d797e
--- /dev/null
+++ b/src/Tizen.Uix.InputMethodManager/Tizen.Uix.InputMethodManager/InputMethodManager.cs
@@ -0,0 +1,158 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+using static Interop.InputMethodManager;
+
+namespace Tizen.Uix.InputMethodManager
+{
+ /// <summary>
+ /// This class provides the functions for launching input method editor (IME) list and selector settings. A user can manage the installed IMEs in the system.
+ /// Input method editor (IME) is an input panel that lets users provide input and the platform receives the text data entered.
+ /// Manager is a module for managing the installed IMEs.
+ /// IME developers can use this module to open the installed IME list or selector menu after their IME installation and then guide to select the installed IME.
+ /// </summary>
+ public static class Manager
+ {
+ /// <summary>
+ /// Requests to open the installed IME list menu.
+ /// This api provides the installed IME list menu for the IME developers who might want to open it to enable their IME.
+ /// </summary>
+ /// <privilege>
+ /// http://tizen.org/privilege/imemanager
+ /// </privilege>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can occur if:
+ /// 1) The application does not have the privilege to call this function
+ /// 2) Operation failed
+ /// </exception>
+ public static void ShowIMEList()
+ {
+ ErrorCode error = ImeManagerShowImeList();
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "ShowIMEList Failed with error " + error);
+ throw InputMethodManagerExceptionFactory.CreateException(error);
+ }
+ }
+
+ /// <summary>
+ /// Requests to open the IME selector menu.
+ /// This api provides the IME selector menu for the IME or other application developers who might want to change the default IME.
+ /// </summary>
+ /// <privilege>
+ /// http://tizen.org/privilege/imemanager
+ /// </privilege>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can occur if:
+ /// 1) The application does not have the privilege to call this function
+ /// 2) Operation failed
+ /// </exception>
+ public static void ShowIMESelector()
+ {
+ ErrorCode error = ImeManagerShowImeSelector();
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "ShowIMESelector Failed with error " + error);
+ throw InputMethodManagerExceptionFactory.CreateException(error);
+ }
+ }
+
+ /// <summary>
+ /// Checks if the specific IME is enabled or disabled in the system keyboard setting.
+ /// The IME developers can use this property to check if their IME is enabled or not.
+ /// </summary>
+ /// <privilege>
+ /// http://tizen.org/privilege/imemanager
+ /// </privilege>
+ /// <param name="appId">The application ID of the IME</param>
+ /// <returns>The On (enabled) and Off (disabled) state of the IME</returns>
+ /// <exception cref="ArgumentException">
+ /// This Exception can occur if Invalid parameter is provided
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can occur if:
+ /// 1) The application does not have the privilege to call this function
+ /// 2) Operation failed
+ /// </exception>
+ public static bool IsIMEEnabled(string appId)
+ {
+ bool isIMEEnabled;
+ ErrorCode error = ImeManagerIsImeEnabled(appId, out isIMEEnabled);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "IsIMEEnabled Failed with error " + error);
+ throw InputMethodManagerExceptionFactory.CreateException(error);
+ }
+
+ return isIMEEnabled;
+ }
+
+ /// <summary>
+ /// Checks which IME is the current activated (selected) IME.
+ /// </summary>
+ /// <privilege>
+ /// http://tizen.org/privilege/imemanager
+ /// </privilege>
+ /// <returns>
+ /// Current activated (selected) IME
+ /// </returns>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can occur if:
+ /// 1) The application does not have the privilege to call this function
+ /// 2) Operation failed
+ /// </exception>
+ public static string GetActiveIME()
+ {
+ string activeIME;
+ ErrorCode error = ImeManagerGetActiveIme(out activeIME);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "GetActiveIME Failed with error " + error);
+ throw InputMethodManagerExceptionFactory.CreateException(error);
+ }
+
+ return activeIME;
+ }
+
+ /// <summary>
+ /// Gets the number of IMEs which are enabled (usable).
+ /// </summary>
+ /// <privilege>
+ /// http://tizen.org/privilege/imemanager
+ /// </privilege>
+ /// <returns>
+ /// The number of enabled IMEs
+ /// </returns>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can occur if:
+ /// 1) The application does not have the privilege to call this function
+ /// 2) Operation failed
+ /// </exception>
+ public static int GetEnabledIMECount()
+ {
+ int activeIME = ImeManagerGetEnabledImeCount();
+ ErrorCode error = (ErrorCode)Tizen.Internals.Errors.ErrorFacts.GetLastResult();
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "GetEnabledIMECount Failed with error " + error);
+ throw InputMethodManagerExceptionFactory.CreateException(error);
+ }
+
+ return activeIME;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Uix.InputMethodManager/Tizen.Uix.InputMethodManager/InputMethodManagerExceptionFactory.cs b/src/Tizen.Uix.InputMethodManager/Tizen.Uix.InputMethodManager/InputMethodManagerExceptionFactory.cs
new file mode 100755
index 0000000..283b633
--- /dev/null
+++ b/src/Tizen.Uix.InputMethodManager/Tizen.Uix.InputMethodManager/InputMethodManagerExceptionFactory.cs
@@ -0,0 +1,64 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+using System;
+using static Interop.InputMethodManager;
+
+namespace Tizen.Uix.InputMethodManager
+{
+ internal static class InputMethodManagerExceptionFactory
+ {
+ internal static Exception CreateException(ErrorCode err)
+ {
+ Tizen.Log.Error(LogTag, "Error " + err);
+ Exception exp;
+ switch (err)
+ {
+
+ case ErrorCode.InvalidParameter:
+ {
+ exp = new ArgumentException("Invalid Parameters Provided");
+ break;
+ }
+
+
+ case ErrorCode.PermissionDenied:
+ {
+ exp = new InvalidOperationException("Permission Denied");
+ break;
+ }
+
+
+ case ErrorCode.OperationFailed:
+ {
+ exp = new InvalidOperationException("Operation Failed");
+ break;
+ }
+
+ default:
+ {
+ exp = new Exception("");
+ break;
+ }
+
+ }
+
+ return exp;
+
+ }
+ }
+}
diff --git a/src/Tizen.Uix.Stt/Interop/Interop.Libraries.cs b/src/Tizen.Uix.Stt/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..52501fb
--- /dev/null
+++ b/src/Tizen.Uix.Stt/Interop/Interop.Libraries.cs
@@ -0,0 +1,30 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/// <summary>
+/// Partial Interop Class
+/// </summary>
+internal static partial class Interop
+{
+ /// <summary>
+ /// Partial Libraries Class
+ /// </summary>
+ internal static partial class Libraries
+ {
+ public const string Stt = "libstt.so";
+ }
+}
diff --git a/src/Tizen.Uix.Stt/Interop/Interop.Stt.cs b/src/Tizen.Uix.Stt/Interop/Interop.Stt.cs
new file mode 100755
index 0000000..cbf6f0d
--- /dev/null
+++ b/src/Tizen.Uix.Stt/Interop/Interop.Stt.cs
@@ -0,0 +1,188 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+using System;
+using System.Runtime.InteropServices;
+
+/// <summary>
+/// Partial Interop Class
+/// </summary>
+internal static partial class Interop
+{
+ /// <summary>
+ /// Stt Interop Class
+ /// </summary>
+ internal static class Stt
+ {
+ internal static string LogTag = "Tizen.Uix.Stt";
+
+ private const int ErrorStt = -0x02F00000;
+
+ internal enum SttError
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None, /**< Successful */
+ OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory, /**< Out of Memory */
+ IoError = Tizen.Internals.Errors.ErrorCode.IoError, /**< I/O error */
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter, /**< Invalid parameter */
+ TimedOut = Tizen.Internals.Errors.ErrorCode.TimedOut, /**< No answer from the STT service */
+ RecorderBusy = Tizen.Internals.Errors.ErrorCode.ResourceBusy, /**< Device or resource busy */
+ OutOfNetwork = Tizen.Internals.Errors.ErrorCode.Networkdown, /**< Network is down */
+ PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied, /**< Permission denied */
+ NotSupported = Tizen.Internals.Errors.ErrorCode.NotSupported, /**< STT NOT supported */
+ InvalidState = ErrorStt | 0x01, /**< Invalid state */
+ InvalidLanguage = ErrorStt | 0x02, /**< Invalid language */
+ EngineNotFound = ErrorStt | 0x03, /**< No available engine */
+ OperationFailed = ErrorStt | 0x04, /**< Operation failed */
+ NotSupportedFeature = ErrorStt | 0x05, /**< Not supported feature of current engine */
+ RecordingTimedOut = ErrorStt | 0x06, /**< Recording timed out */
+ NoSpeech = ErrorStt | 0x07, /**< No speech while recording*/
+ InProgressToReady = ErrorStt | 0x08, /**< Progress to ready is not finished*/
+ InProgressToRecording = ErrorStt | 0x09, /**< Progress to recording is not finished*/
+ InProgressToProcessing = ErrorStt | 0x10, /**< Progress to processing is not finished*/
+ ServiceReset = ErrorStt | 0x11 /**< Service reset*/
+ };
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool SupportedEngineCallback(IntPtr handle, IntPtr engineId, IntPtr engineName, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void RecognitionResultCallback(IntPtr handle, Tizen.Uix.Stt.ResultEvent e, IntPtr data, int dataCount, IntPtr msg, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool ResultTimeCallback(IntPtr handle, int index, Tizen.Uix.Stt.TimeEvent e, IntPtr text, IntPtr startTime, IntPtr endTime, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void StateChangedCallback(IntPtr handle, Tizen.Uix.Stt.State previous, Tizen.Uix.Stt.State current, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ErrorCallback(IntPtr handle, SttError reason, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool SupportedLanguageCallback(IntPtr handle, IntPtr language, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void DefaultLanguageChangedCallback(IntPtr handle, IntPtr previousLanguage, IntPtr currentLanguage, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void EngineChangedCallback(IntPtr handle, IntPtr engineId, IntPtr language, bool supportSilence, bool needCredential, IntPtr userData);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_create", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttCreate(out IntPtr handle);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_destroy", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttDestroy(IntPtr handle);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_foreach_supported_engines", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttForeEachSupportedEngines(IntPtr handle, SupportedEngineCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_get_engine", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttGetEngine(IntPtr handle, out string engineId);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_set_engine", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttSetEngine(IntPtr handle, string engineId);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_set_credential", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttSetcredential(IntPtr handle, string credential);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_set_private_data", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttSetPrivateData(IntPtr handle, string key, string data);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_get_private_data", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttGetPrivateData(IntPtr handle, string key, out string data);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_prepare", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttPrepare(IntPtr handle);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_unprepare", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttUnprepare(IntPtr handle);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_foreach_supported_languages", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttForeachSupportedLanguages(IntPtr handle, SupportedLanguageCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_get_default_language", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttGetDefaultLanguage(IntPtr handle, out string language);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_get_state", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttGetState(IntPtr handle, out Tizen.Uix.Stt.State state);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_get_error_message", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttGetErrorMessage(IntPtr handle, out string err_msg);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_is_recognition_type_supported", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttIsRecognitionTypeSupported(IntPtr handle, string type, out bool support);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_set_silence_detection", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttSetSilenceDetection(IntPtr handle, Tizen.Uix.Stt.SilenceDetection type);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_set_start_sound", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttSetStartSound(IntPtr handle, string filename);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_unset_start_sound", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttUnsetStartSound(IntPtr handle);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_set_stop_sound", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttSetStopSound(IntPtr handle, string filename);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_unset_stop_sound", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttUnsetStopSound(IntPtr handle);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_start", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttStart(IntPtr handle, string language, string type);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_stop", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttStop(IntPtr handle);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_cancel", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttCancel(IntPtr handle);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_get_recording_volume", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttGetRecordingVolume(IntPtr handle, out float volume);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_foreach_detailed_result", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttForeachDetailedResult(IntPtr handle, ResultTimeCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_set_recognition_result_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttSetRecognitionResultCB(IntPtr handle, RecognitionResultCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_unset_recognition_result_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttUnsetRecognitionResultCB(IntPtr handle);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_set_state_changed_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttSetStateChangedCB(IntPtr handle, StateChangedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_unset_state_changed_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttUnsetStateChangedCB(IntPtr handle);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_set_error_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttSetErrorCB(IntPtr handle, ErrorCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_unset_error_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttUnsetErrorCB(IntPtr handle);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_set_default_language_changed_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttSetDefaultLanguageChangedCB(IntPtr handle, DefaultLanguageChangedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_unset_default_language_changed_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttUnsetDefaultLanguageChangedCB(IntPtr handle);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_set_engine_changed_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttSetEngineChangedCB(IntPtr handle, EngineChangedCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.Stt, EntryPoint = "stt_unset_engine_changed_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern SttError SttUnsetEngineChangedCB(IntPtr handle);
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Uix.Stt/Tizen.Uix.Stt.csproj b/src/Tizen.Uix.Stt/Tizen.Uix.Stt.csproj
new file mode 100644
index 0000000..5ed2f1f
--- /dev/null
+++ b/src/Tizen.Uix.Stt/Tizen.Uix.Stt.csproj
@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Uix.Stt/Tizen.Uix.Stt/DefaultLanguageChangedEventArgs.cs b/src/Tizen.Uix.Stt/Tizen.Uix.Stt/DefaultLanguageChangedEventArgs.cs
new file mode 100755
index 0000000..7031f5d
--- /dev/null
+++ b/src/Tizen.Uix.Stt/Tizen.Uix.Stt/DefaultLanguageChangedEventArgs.cs
@@ -0,0 +1,53 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+
+namespace Tizen.Uix.Stt
+{
+ /// <summary>
+ /// This class holds information about the DefaultLanguageChanged Event
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class DefaultLanguageChangedEventArgs
+ {
+ internal DefaultLanguageChangedEventArgs(string previous, string current)
+ {
+ PreviousLanguage = previous;
+ CurrentLanguage = current;
+ }
+
+ /// <summary>
+ /// The previous language
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string PreviousLanguage
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// The current language
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string CurrentLanguage
+ {
+ get;
+ internal set;
+ }
+ }
+}
diff --git a/src/Tizen.Uix.Stt/Tizen.Uix.Stt/EngineChangedEventArgs.cs b/src/Tizen.Uix.Stt/Tizen.Uix.Stt/EngineChangedEventArgs.cs
new file mode 100755
index 0000000..3694bbd
--- /dev/null
+++ b/src/Tizen.Uix.Stt/Tizen.Uix.Stt/EngineChangedEventArgs.cs
@@ -0,0 +1,74 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+namespace Tizen.Uix.Stt
+{
+ /// <summary>
+ /// This class holds information related to Engine Changed Event
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class EngineChangedEventArgs
+ {
+ internal EngineChangedEventArgs(string engineId, string language, bool supportSilence, bool needCredential)
+ {
+ this.EngineId = engineId;
+ this.Language = language;
+ this.SupportSilence = supportSilence;
+ this.NeedCredential = needCredential;
+ }
+
+ /// <summary>
+ /// Engine Id
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string EngineId
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// Default Lanaguage
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Language
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// The necessity of credential
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool NeedCredential
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// Whether the silence detection is supported or not
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool SupportSilence
+ {
+ get;
+ internal set;
+ }
+ }
+}
diff --git a/src/Tizen.Uix.Stt/Tizen.Uix.Stt/ErrorOccuredEventArgs.cs b/src/Tizen.Uix.Stt/Tizen.Uix.Stt/ErrorOccuredEventArgs.cs
new file mode 100755
index 0000000..c860cdd
--- /dev/null
+++ b/src/Tizen.Uix.Stt/Tizen.Uix.Stt/ErrorOccuredEventArgs.cs
@@ -0,0 +1,193 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+using System;
+using static Interop.Stt;
+
+namespace Tizen.Uix.Stt
+{
+ /// <summary>
+ /// This class holds information related to the STT ErrorOccured Event
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class ErrorOccuredEventArgs
+ {
+ private IntPtr _handle;
+
+ internal ErrorOccuredEventArgs(IntPtr handle, Interop.Stt.SttError error)
+ {
+ this._handle = handle;
+ switch (error)
+ {
+ case Interop.Stt.SttError.None:
+ {
+ ErrorValue = Error.None;
+ break;
+ }
+
+ case Interop.Stt.SttError.OutOfMemory:
+ {
+ ErrorValue = Error.OutOfMemory;
+ break;
+ }
+
+ case Interop.Stt.SttError.IoError:
+ {
+ ErrorValue = Error.IoError;
+ break;
+ }
+
+ case Interop.Stt.SttError.InvalidParameter:
+ {
+ ErrorValue = Error.InvalidParameter;
+ break;
+ }
+
+ case Interop.Stt.SttError.TimedOut:
+ {
+ ErrorValue = Error.TimedOut;
+ break;
+ }
+
+ case Interop.Stt.SttError.RecorderBusy:
+ {
+ ErrorValue = Error.RecorderBusy;
+ break;
+ }
+
+ case Interop.Stt.SttError.OutOfNetwork:
+ {
+ ErrorValue = Error.OutOfNetwork;
+ break;
+ }
+
+ case Interop.Stt.SttError.PermissionDenied:
+ {
+ ErrorValue = Error.PermissionDenied;
+ break;
+ }
+
+ case Interop.Stt.SttError.NotSupported:
+ {
+ ErrorValue = Error.NotSupported;
+ break;
+ }
+
+ case Interop.Stt.SttError.InvalidState:
+ {
+ ErrorValue = Error.InvalidState;
+ break;
+ }
+
+ case Interop.Stt.SttError.InvalidLanguage:
+ {
+ ErrorValue = Error.InvalidLanguage;
+ break;
+ }
+
+ case Interop.Stt.SttError.EngineNotFound:
+ {
+ ErrorValue = Error.EngineNotFound;
+ break;
+ }
+
+ case Interop.Stt.SttError.OperationFailed:
+ {
+ ErrorValue = Error.OperationFailed;
+ break;
+ }
+
+ case Interop.Stt.SttError.NotSupportedFeature:
+ {
+ ErrorValue = Error.NotSupportedFeature;
+ break;
+ }
+
+ case Interop.Stt.SttError.RecordingTimedOut:
+ {
+ ErrorValue = Error.RecordingTimedOut;
+ break;
+ }
+
+ case Interop.Stt.SttError.NoSpeech:
+ {
+ ErrorValue = Error.NoSpeech;
+ break;
+ }
+
+ case Interop.Stt.SttError.InProgressToReady:
+ {
+ ErrorValue = Error.InProgressToReady;
+ break;
+ }
+
+ case Interop.Stt.SttError.InProgressToRecording:
+ {
+ ErrorValue = Error.InProgressToRecording;
+ break;
+ }
+
+ case Interop.Stt.SttError.InProgressToProcessing:
+ {
+ ErrorValue = Error.InProgressToProcessing;
+ break;
+ }
+
+ case Interop.Stt.SttError.ServiceReset:
+ {
+ ErrorValue = Error.ServiceReset;
+ break;
+ }
+
+ }
+ }
+
+ /// <summary>
+ /// The Error Value
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public Error ErrorValue
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// Gets the current error message.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// string error message
+ /// </returns>
+ public string ErrorMessage
+ {
+ get
+ {
+ string errorMesage = "";
+ SttError error = SttGetErrorMessage(_handle, out errorMesage);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "GetErrorMessage Failed with error " + error);
+ return "";
+ }
+
+ return errorMesage;
+ }
+
+ }
+ }
+}
diff --git a/src/Tizen.Uix.Stt/Tizen.Uix.Stt/ExceptionFactory.cs b/src/Tizen.Uix.Stt/Tizen.Uix.Stt/ExceptionFactory.cs
new file mode 100755
index 0000000..5b59574
--- /dev/null
+++ b/src/Tizen.Uix.Stt/Tizen.Uix.Stt/ExceptionFactory.cs
@@ -0,0 +1,151 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+using System;
+using static Interop.Stt;
+
+namespace Tizen.Uix.Stt
+{
+ internal static class ExceptionFactory
+ {
+ internal static Exception CreateException(SttError err)
+ {
+ Tizen.Log.Error(LogTag, "Error " + err);
+ Exception exp;
+ switch (err)
+ {
+ case SttError.OutOfMemory:
+ {
+ exp = new OutOfMemoryException("Out Of Memory");
+ break;
+ }
+
+ case SttError.IoError:
+ {
+ exp = new InvalidOperationException("I/O Error Occured");
+ break;
+ }
+
+ case SttError.InvalidParameter:
+ {
+ exp = new ArgumentException("Invalid Parameters Provided");
+ break;
+ }
+
+ case SttError.TimedOut:
+ {
+ exp = new TimeoutException("No answer from the STT service");
+ break;
+ }
+
+ case SttError.OutOfNetwork:
+ {
+ exp = new InvalidOperationException("Network is down");
+ break;
+ }
+
+ case SttError.PermissionDenied:
+ {
+ exp = new UnauthorizedAccessException("Permission Denied");
+ break;
+ }
+
+ case SttError.NotSupported:
+ {
+ exp = new NotSupportedException("STT NOT supported");
+ break;
+ }
+
+ case SttError.InvalidState:
+ {
+ exp = new InvalidOperationException("Invalid state");
+ break;
+ }
+
+ case SttError.InvalidLanguage:
+ {
+ exp = new InvalidOperationException("Invalid language");
+ break;
+ }
+
+ case SttError.EngineNotFound:
+ {
+ exp = new InvalidOperationException("No available engine");
+ break;
+ }
+
+ case SttError.OperationFailed:
+ {
+ exp = new InvalidOperationException("Operation Failed");
+ break;
+ }
+
+ case SttError.NotSupportedFeature:
+ {
+ exp = new InvalidOperationException("Not supported feature of current engine");
+ break;
+ }
+
+ case SttError.RecordingTimedOut:
+ {
+ exp = new InvalidOperationException("Recording timed out");
+ break;
+ }
+
+ case SttError.NoSpeech:
+ {
+ exp = new InvalidOperationException("No speech while recording");
+ break;
+ }
+
+ case SttError.InProgressToReady:
+ {
+ exp = new InvalidOperationException("Progress to ready is not finished");
+ break;
+ }
+
+ case SttError.InProgressToRecording:
+ {
+ exp = new InvalidOperationException("Progress to recording is not finished");
+ break;
+ }
+
+ case SttError.InProgressToProcessing:
+ {
+ exp = new InvalidOperationException("Progress to processing is not finished");
+ break;
+ }
+
+ case SttError.ServiceReset:
+ {
+ exp = new InvalidOperationException("Service reset");
+ break;
+ }
+
+ default:
+ {
+ exp = new Exception("");
+ break;
+ }
+
+ }
+
+ return exp;
+
+ }
+ }
+}
diff --git a/src/Tizen.Uix.Stt/Tizen.Uix.Stt/RecognitionResultEventArgs.cs b/src/Tizen.Uix.Stt/Tizen.Uix.Stt/RecognitionResultEventArgs.cs
new file mode 100755
index 0000000..2618585
--- /dev/null
+++ b/src/Tizen.Uix.Stt/Tizen.Uix.Stt/RecognitionResultEventArgs.cs
@@ -0,0 +1,149 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using static Interop.Stt;
+using static Tizen.Uix.Stt.ResultTime;
+
+namespace Tizen.Uix.Stt
+{
+ /// <summary>
+ /// The recognition result from the engine.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class RecognitionResultEventArgs
+ {
+ private ResultEvent _result;
+ private List<string> _data = new List<string>();
+ private ResultMessage _msg;
+ private int _dataCount;
+
+ internal RecognitionResultEventArgs(ResultEvent e, IntPtr data, int count, string msg)
+ {
+ _result = e;
+ switch (msg)
+ {
+ case "stt.result.message.none":
+ {
+ _msg = ResultMessage.None;
+ break;
+ }
+
+ case "stt.result.message.error.too.soon":
+ {
+ _msg = ResultMessage.TooSoon;
+ break;
+ }
+
+ case "stt.result.message.error.too.short":
+ {
+ _msg = ResultMessage.TooShort;
+ break;
+ }
+
+ case "stt.result.message.error.too.long":
+ {
+ _msg = ResultMessage.TooLong;
+ break;
+ }
+
+ case "stt.result.message.error.too.quiet":
+ {
+ _msg = ResultMessage.TooQuiet;
+ break;
+ }
+
+ case "stt.result.message.error.too.loud":
+ {
+ _msg = ResultMessage.TooLoud;
+ break;
+ }
+
+ case "stt.result.message.error.too.fast":
+ {
+ _msg = ResultMessage.TooFast;
+ break;
+ }
+
+ }
+
+ this._dataCount = count;
+
+ _data.Clear();
+ if (count > 0)
+ {
+ IntPtr[] dataArray = new IntPtr[count];
+ Marshal.Copy(data, dataArray, 0, count);
+ foreach (IntPtr handle in dataArray)
+ {
+ string info = Marshal.PtrToStringAnsi(handle);
+ _data.Add(info);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The result event
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ResultEvent Result
+ {
+ get
+ {
+ return _result;
+ }
+ }
+
+ /// <summary>
+ /// Result texts.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public IEnumerable<string> Data
+ {
+ get
+ {
+ return _data;
+ }
+ }
+
+ /// <summary>
+ /// Returns the Result text count.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int DataCount
+ {
+ get
+ {
+ return _dataCount;
+ }
+ }
+
+ /// <summary>
+ /// Engine message
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ResultMessage Message
+ {
+ get
+ {
+ return _msg;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Uix.Stt/Tizen.Uix.Stt/ResultTime.cs b/src/Tizen.Uix.Stt/Tizen.Uix.Stt/ResultTime.cs
new file mode 100755
index 0000000..ecf0b91
--- /dev/null
+++ b/src/Tizen.Uix.Stt/Tizen.Uix.Stt/ResultTime.cs
@@ -0,0 +1,87 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+using static Interop.Stt;
+
+namespace Tizen.Uix.Stt
+{
+ /// <summary>
+ /// This Class represents the result of recognition result from the engine.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class ResultTime
+ {
+ internal ResultTime(int index, TimeEvent e, string text, long startTime, long endTime)
+ {
+ Index = index;
+ TokenEvent = e;
+ Text = text;
+ StartTime = startTime;
+ EndTime = endTime;
+ }
+
+ /// <summary>
+ /// The result index
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Index
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// The token event
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public TimeEvent TokenEvent
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// The result text
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Text
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// The start time of result text
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public long StartTime
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// The end time of result text
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public long EndTime
+ {
+ get;
+ internal set;
+ }
+ }
+}
diff --git a/src/Tizen.Uix.Stt/Tizen.Uix.Stt/StateChangedEventArgs.cs b/src/Tizen.Uix.Stt/Tizen.Uix.Stt/StateChangedEventArgs.cs
new file mode 100755
index 0000000..eb55c4c
--- /dev/null
+++ b/src/Tizen.Uix.Stt/Tizen.Uix.Stt/StateChangedEventArgs.cs
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+namespace Tizen.Uix.Stt
+{
+ /// <summary>
+ /// This class holds information related to the STT StateChanged event
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class StateChangedEventArgs
+ {
+ internal StateChangedEventArgs(State previous, State current)
+ {
+ Previous = previous;
+ Current = current;
+ }
+
+ /// <summary>
+ /// A previous state
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public State Previous
+ {
+ get;
+ internal set;
+ }
+ /// <summary>
+ /// A current state
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public State Current
+ {
+ get;
+ internal set;
+ }
+ }
+}
diff --git a/src/Tizen.Uix.Stt/Tizen.Uix.Stt/SttClient.cs b/src/Tizen.Uix.Stt/Tizen.Uix.Stt/SttClient.cs
new file mode 100644
index 0000000..4e52840
--- /dev/null
+++ b/src/Tizen.Uix.Stt/Tizen.Uix.Stt/SttClient.cs
@@ -0,0 +1,1519 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using static Interop.Stt;
+
+namespace Tizen.Uix.Stt
+{
+ /// <summary>
+ /// The token event
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum ResultEvent
+ {
+ /// <summary>
+ /// Event when the recognition full or last result is ready
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ FinalResult = 0,
+ /// <summary>
+ /// Event when the recognition partial result is ready
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ PartialResult,
+ /// <summary>
+ /// Event when the recognition has failed
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Error
+ };
+
+ /// <summary>
+ /// Enumeration representing the result message
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum ResultMessage
+ {
+ /// <summary>
+ /// No Error
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ None,
+ /// <summary>
+ /// Recognition failed because the speech started too soon.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ TooSoon,
+ /// <summary>
+ /// Recognition failed because the speech is too short.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ TooShort,
+ /// <summary>
+ /// Recognition failed because the speech is too long.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ TooLong,
+ /// <summary>
+ /// Recognition failed because the speech is too quiet to listen.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ TooQuiet,
+ /// <summary>
+ /// Recognition failed because the speech is too loud to listen.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ TooLoud,
+ /// <summary>
+ /// Recognition failed because the speech is too fast to listen.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ TooFast
+ };
+
+ /// <summary>
+ /// Enumeration for the Token type
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum TimeEvent
+ {
+ /// <summary>
+ /// Event when the token is beginning type
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Beginning = 0,
+ /// <summary>
+ /// Event when the token is middle type
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Middle = 1,
+ /// <summary>
+ /// Event when the token is end type
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ End = 2
+ };
+
+ /// <summary>
+ /// Enum for Error values that can occur
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum Error
+ {
+ /// <summary>
+ /// Successful, No error
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ None,
+ /// <summary>
+ /// Out of Memory
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ OutOfMemory,
+ /// <summary>
+ /// I/O error
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ IoError,
+ /// <summary>
+ /// Invalid parameter
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ InvalidParameter,
+ /// <summary>
+ /// No answer from the STT service
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ TimedOut,
+ /// <summary>
+ /// Device or resource busy
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ RecorderBusy,
+ /// <summary>
+ /// Network is down
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ OutOfNetwork,
+ /// <summary>
+ /// Permission denied
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ PermissionDenied,
+ /// <summary>
+ /// STT NOT supported
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ NotSupported,
+ /// <summary>
+ /// Invalid state
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ InvalidState,
+ /// <summary>
+ /// Invalid language
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ InvalidLanguage,
+ /// <summary>
+ /// No available engine
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ EngineNotFound,
+ /// <summary>
+ /// Operation failed
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ OperationFailed,
+ /// <summary>
+ /// Not supported feature of current engine
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ NotSupportedFeature,
+ /// <summary>
+ /// Recording timed out
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ RecordingTimedOut,
+ /// <summary>
+ /// No speech while recording
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ NoSpeech,
+ /// <summary>
+ /// Progress to ready is not finished
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ InProgressToReady,
+ /// <summary>
+ /// Progress to recording is not finished
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ InProgressToRecording,
+ /// <summary>
+ /// Progress to processing is not finished
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ InProgressToProcessing,
+ /// <summary>
+ /// Service reset
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ ServiceReset
+ };
+
+ /// <summary>
+ /// Enumeration for Recognition Types
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum RecognitionType
+ {
+ /// <summary>
+ /// Free form dictation
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Free,
+ /// <summary>
+ /// Continuous free dictation.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Partial,
+ /// <summary>
+ /// Search
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Search,
+ /// <summary>
+ /// Web Search
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ WebSearch,
+ /// <summary>
+ /// Map
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Map
+ };
+
+ /// <summary>
+ /// Enumeration for the State types
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum State
+ {
+ /// <summary>
+ /// Created state
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Created = 0,
+ /// <summary>
+ /// Ready state
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Ready = 1,
+ /// <summary>
+ /// Recording state
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Recording = 2,
+ /// <summary>
+ /// Processing state
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Processing = 3,
+ /// <summary>
+ /// Unavailable
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Unavailable
+ };
+
+ /// <summary>
+ /// Enumeration for the Silence Detection types
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum SilenceDetection
+ {
+ /// <summary>
+ /// Silence detection type - False
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ False = 0,
+ /// <summary>
+ /// Silence detection type - True
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ True = 1,
+ /// <summary>
+ /// Silence detection type - Auto
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Auto = 2
+ };
+
+ /// <summary>
+ /// A main function of Speech-To-Text (below STT) API recognizes sound data recorded by users.
+ /// After choosing a language, applications will start recording and recognizing.
+ /// After recording, the applications will receive the recognized result.
+ /// The STT has a client-server for the service of multi-applications.
+ /// The STT service always works in the background as a server. If the service is not working, client library will invoke it and client will communicate with it.
+ /// The service has engines and the recorder so client does not have the recorder itself. Only the client request commands to the STT service for using STT.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class SttClient : IDisposable
+ {
+ private IntPtr _handle;
+ private Object thisLock = new Object();
+ private event EventHandler<RecognitionResultEventArgs> _recognitionResult;
+ private event EventHandler<StateChangedEventArgs> _stateChanged;
+ private event EventHandler<ErrorOccuredEventArgs> _errorOccured;
+ private event EventHandler<DefaultLanguageChangedEventArgs> _defaultLanguageChanged;
+ private event EventHandler<EngineChangedEventArgs> _engineChanged;
+ private bool disposedValue = false;
+ private Interop.Stt.RecognitionResultCallback _resultDelegate;
+ private Interop.Stt.StateChangedCallback _stateDelegate;
+ private Interop.Stt.ErrorCallback _errorDelegate;
+ private Interop.Stt.DefaultLanguageChangedCallback _languageDelegate;
+ private Interop.Stt.EngineChangedCallback _engineDelegate;
+ private ResultTime _result;
+ private ResultTimeCallback _resultTimeDelegate;
+
+ /// <summary>
+ /// Constructor to create a STT instance.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/speech.recognition
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <exception cref="InvalidOperationException"> This Exception can be due to Operation Failed. </exception>
+ /// <exception cref="OutOfMemoryException"> This Exception can be due to Out of Memory. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to STT Not Supported. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ public SttClient()
+ {
+ IntPtr handle;
+ SttError error = SttCreate(out handle);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "Create Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+
+ _handle = handle;
+ }
+
+ /// <summary>
+ /// Event to be invoked when the recognition is done.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<RecognitionResultEventArgs> RecognitionResult
+ {
+ add
+ {
+ lock (thisLock)
+ {
+ _resultDelegate = (IntPtr handle, ResultEvent e, IntPtr data, int dataCount, IntPtr msg, IntPtr userData) =>
+ {
+ Log.Info(LogTag, "Recognition Result Event Triggered");
+ if (data != null && msg != null)
+ {
+ RecognitionResultEventArgs args = new RecognitionResultEventArgs(e, data, dataCount, Marshal.PtrToStringAnsi(msg));
+ _recognitionResult?.Invoke(this, args);
+ }
+ else
+ {
+ Log.Info(LogTag, "Recognition Result Event null received");
+ }
+ };
+ SttError error = SttSetRecognitionResultCB(_handle, _resultDelegate, IntPtr.Zero);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "Add RecognitionResult Failed with error " + error);
+ }
+ else
+ {
+ _recognitionResult += value;
+ }
+ }
+ }
+
+ remove
+ {
+ lock (thisLock)
+ {
+ SttError error = SttUnsetRecognitionResultCB(_handle);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "Remove RecognitionResult Failed with error " + error);
+ }
+
+ _recognitionResult -= value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Event to be invoked when STT state changes.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<StateChangedEventArgs> StateChanged
+ {
+ add
+ {
+ lock (thisLock)
+ {
+ SttClient obj = this;
+ _stateDelegate = (IntPtr handle, State previous, State current, IntPtr userData) =>
+ {
+ StateChangedEventArgs args = new StateChangedEventArgs(previous, current);
+ _stateChanged?.Invoke(obj, args);
+ };
+ SttError error = SttSetStateChangedCB(_handle, _stateDelegate, IntPtr.Zero);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "Add StateChanged Failed with error " + error);
+ }
+ else
+ {
+ _stateChanged += value;
+ }
+
+ }
+ }
+
+ remove
+ {
+ lock (thisLock)
+ {
+ SttError error = SttUnsetStateChangedCB(_handle);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "Remove StateChanged Failed with error " + error);
+ }
+
+ _stateChanged -= value;
+ }
+ }
+
+ }
+
+ /// <summary>
+ /// Event to be invoked when an error occurs.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<ErrorOccuredEventArgs> ErrorOccured
+ {
+ add
+ {
+ lock (thisLock)
+ {
+ _errorDelegate = (IntPtr handle, SttError reason, IntPtr userData) =>
+ {
+ ErrorOccuredEventArgs args = new ErrorOccuredEventArgs(handle, reason);
+ _errorOccured?.Invoke(this, args);
+ };
+ SttError error = SttSetErrorCB(_handle, _errorDelegate, IntPtr.Zero);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "Add ErrorOccured Failed with error " + error);
+ }
+
+ else
+ {
+ _errorOccured += value;
+ }
+ }
+
+ }
+
+ remove
+ {
+ lock (thisLock)
+ {
+ SttError error = SttUnsetErrorCB(_handle);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "Remove ErrorOccured Failed with error " + error);
+ }
+
+ _errorOccured -= value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Event to be invoked when default laungage change.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<DefaultLanguageChangedEventArgs> DefaultLanguageChanged
+ {
+ add
+ {
+ lock (thisLock)
+ {
+ _languageDelegate = (IntPtr handle, IntPtr previousLanguage, IntPtr currentLanguage, IntPtr userData) =>
+ {
+ string previousLanguageString = Marshal.PtrToStringAnsi(previousLanguage);
+ string currentLanguageString = Marshal.PtrToStringAnsi(currentLanguage);
+ DefaultLanguageChangedEventArgs args = new DefaultLanguageChangedEventArgs(previousLanguageString, currentLanguageString);
+ _defaultLanguageChanged?.Invoke(this, args);
+ };
+ SttError error = SttSetDefaultLanguageChangedCB(_handle, _languageDelegate, IntPtr.Zero);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "Add DefaultLanguageChanged Failed with error " + error);
+ }
+
+ else
+ {
+ _defaultLanguageChanged += value;
+ }
+ }
+
+ }
+
+ remove
+ {
+ lock (thisLock)
+ {
+ SttError error = SttUnsetDefaultLanguageChangedCB(_handle);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "Remove DefaultLanguageChanged Failed with error " + error);
+ }
+
+ _defaultLanguageChanged -= value;
+ }
+ }
+
+ }
+
+ /// <summary>
+ /// Event to be invoked to detect engine change.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<EngineChangedEventArgs> EngineChanged
+ {
+ add
+ {
+ lock (thisLock)
+ {
+ _engineDelegate = (IntPtr handle, IntPtr engineId, IntPtr language, bool supportSilence, bool needCredential, IntPtr userData) =>
+ {
+ string engineIdString = Marshal.PtrToStringAnsi(engineId);
+ string languageString = Marshal.PtrToStringAnsi(language);
+ EngineChangedEventArgs args = new EngineChangedEventArgs(engineIdString, languageString, supportSilence, needCredential);
+ _engineChanged?.Invoke(this, args);
+ };
+ SttError error = SttSetEngineChangedCB(_handle, _engineDelegate, IntPtr.Zero);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "Add EngineChanged Failed with error " + error);
+ }
+ else
+ {
+ _engineChanged += value;
+ }
+ }
+ }
+
+ remove
+ {
+ lock (thisLock)
+ {
+ SttError error = SttUnsetEngineChangedCB(_handle);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "Remove EngineChanged Failed with error " + error);
+ }
+
+ _engineChanged -= value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the default language set by the user.
+ /// The language is specified as an ISO 3166 alpha-2 two letter country-code followed by ISO 639-1 for the two-letter language code.
+ /// For example, "ko_KR" for Korean, "en_US" for American English.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// Default language in STT.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <returns>
+ /// Default Lanaguage string value.
+ /// </returns>
+ public string DefaultLanguage
+ {
+ get
+ {
+ string language;
+ lock (thisLock)
+ {
+ SttError error = SttGetDefaultLanguage(_handle, out language);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "DefaultLanaguage Failed with error " + error);
+ return "";
+ }
+ }
+
+ return language;
+ }
+ }
+
+ /// <summary>
+ /// Gets the microphone volume during recording.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// Recording volume in STT.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <pre>
+ /// The State must be Recording.
+ /// </pre>
+ public float RecordingVolume
+ {
+ get
+ {
+ float volume;
+ lock (thisLock)
+ {
+ SttError error = SttGetRecordingVolume(_handle, out volume);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "GetRecordingVolume Failed with error " + error);
+ return 0.0f;
+ }
+
+ }
+
+ return volume;
+ }
+
+ }
+
+ /// <summary>
+ /// Gets the current STT state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// Current state of STT.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <returns>
+ /// Current STT State value.
+ /// </returns>
+ public State CurrentState
+ {
+ get
+ {
+ State state;
+ lock (thisLock)
+ {
+ SttError error = SttGetState(_handle, out state);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "GetState Failed with error " + error);
+ return State.Unavailable;
+ }
+ }
+
+ return state;
+ }
+
+ }
+
+ /// <summary>
+ /// This property can be used to get and set the current engine id.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// Current STT engine id.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can occur while setting due to the following reaons
+ /// 1. Operation Failed
+ /// 2. Invalid State
+ /// </exception>
+ /// <exception cref="OutOfMemoryException"> This Exception can be due to Out of Memory. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to STT Not Supported. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <exception cref="ArgumentException"> This can happen if Improper EngineId is provided while setting the value. </exception>
+ /// <pre>
+ /// The State must be Created.
+ /// </pre>
+ public string Engine
+ {
+ get
+ {
+ string engineId;
+ lock (thisLock)
+ {
+ SttError error = SttGetEngine(_handle, out engineId);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "Get EngineId Failed with error " + error);
+ return "";
+ }
+ }
+
+ return engineId;
+ }
+ set
+ {
+ lock (thisLock)
+ {
+ SttError error = SttSetEngine(_handle, value);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "Set EngineId Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+
+ }
+ }
+
+ /// <summary>
+ /// Retrieves the time stamp of the current recognition result
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// list of ResultTime
+ /// </returns>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/speech.recognition
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <remarks>
+ /// This function should only be called in RecognitionResult Event
+ /// </remarks>
+ /// <exception cref="InvalidOperationException"> This Exception can be due to Opearation Failed. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to STT Not Supported. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ public IEnumerable<ResultTime> GetDetailedResult()
+ {
+ List<ResultTime> list = new List<ResultTime>();
+ _resultTimeDelegate = (IntPtr handle, int index, TimeEvent e, IntPtr text, IntPtr startTime, IntPtr endTime, IntPtr userData) =>
+ {
+ _result = new ResultTime(index, e, Marshal.PtrToStringAnsi(text), (long)startTime, (long)endTime);
+ list.Add(_result);
+ return true;
+ };
+ SttError error = SttForeachDetailedResult(_handle, _resultTimeDelegate, IntPtr.Zero);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "GetDetailedResult Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ return list;
+ }
+
+
+ /// <summary>
+ /// Gets the private data from stt engine.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="key">
+ /// The key string
+ /// </param>
+ /// <returns>
+ /// The Data Corresponding to the Key provided
+ /// </returns>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/speech.recognition
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <exception cref="InvalidOperationException"> This Exception can be due to Invalid State. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to STT Not Supported. </exception>
+ /// <exception cref="TimeoutException"> This Exception can be due to No Answer from STT Service. </exception>
+ /// <pre>
+ /// The State must be Ready.
+ /// </pre>
+ public string GetPrivateData(string key)
+ {
+ string data;
+ lock (thisLock)
+ {
+ SttError error = SttGetPrivateData(_handle, key, out data);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "GetPrivateData Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+
+ return data;
+ }
+
+ /// <summary>
+ /// Sets the private data to stt engine.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="key">
+ /// The key string
+ /// </param>
+ /// <param name="data">
+ /// The data string
+ /// </param>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/speech.recognition
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <exception cref="InvalidOperationException"> This Exception can be due to Invalid State. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to STT Not Supported. </exception>
+ /// <exception cref="TimeoutException"> This Exception can be due to No Answer from STT Service. </exception>
+ /// <exception cref="ArgumentException"> This can happen if Improper value is provided while setting the value. </exception>
+ /// <pre>
+ /// The State must be Ready.
+ /// </pre>
+ public void SetPrivateData(string key, string data)
+ {
+ lock (thisLock)
+ {
+ SttError error = SttSetPrivateData(_handle, key, data);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "SetPrivateData Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the list of Supported Engine
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// IEnumerable<SupportedEngine> list of supported engines
+ /// </returns>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/speech.recognition
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <exception cref="InvalidOperationException"> This Exception can be due to Operation Failed. </exception>
+ /// <exception cref="OutOfMemoryException"> This Exception can be due to Out of Memory. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to STT Not Supported. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ public IEnumerable<SupportedEngine> GetSupportedEngines()
+ {
+ List<SupportedEngine> engineList = new List<SupportedEngine>();
+ lock (thisLock)
+ {
+ SupportedEngineCallback supportedEngineDelegate = (IntPtr handle, IntPtr engineId, IntPtr engineName, IntPtr userData) =>
+ {
+ string id = Marshal.PtrToStringAnsi(engineId);
+ string name = Marshal.PtrToStringAnsi(engineName);
+ SupportedEngine engine = new SupportedEngine(id, name);
+ engineList.Add(engine);
+ return true;
+ };
+ SttError error = SttForeEachSupportedEngines(_handle, supportedEngineDelegate, IntPtr.Zero);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "Create Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+
+ return engineList;
+ }
+
+ /// <summary>
+ /// Sets the app credential
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="credential">
+ /// The credential string
+ /// </param>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/speech.recognition
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can be due to the following reaons
+ /// 1. Operation Failed
+ /// 2. Invalid State
+ /// </exception>
+ /// <exception cref="OutOfMemoryException"> This Exception can be due to Out of Memory. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to STT Not Supported. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <exception cref="ArgumentException"> This can happen if Improper value is provided while setting the value. </exception>
+ /// <pre>
+ /// The State must be Created.
+ /// </pre>
+ public void SetCredential(string credential)
+ {
+ lock (thisLock)
+ {
+ SttError error = SttSetcredential(_handle, credential);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "SetCredential Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Connects to the STT service asynchronously.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/speech.recognition
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <exception cref="InvalidOperationException"> This Exception can be due to Invalid State. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to STT Not Supported. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <pre>
+ /// The State must be Created.
+ /// </pre>
+ /// <post>
+ /// If this function is successful, the STT state will be Ready
+ /// If this function is unsuccessful, ErrorOccured event will be invoked
+ /// </post>
+ public void Prepare()
+ {
+ lock (thisLock)
+ {
+ SttError error = SttPrepare(_handle);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "SetEngine Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Disconnects from the STT service.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/speech.recognition
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <exception cref="InvalidOperationException"> This Exception can be due to Invalid State. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to STT Not Supported. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <pre>
+ /// The State must be Ready.
+ /// </pre>
+ /// <post>
+ /// If this function is successful, the STT state will be Created
+ /// </post>
+ public void Unprepare()
+ {
+ lock (thisLock)
+ {
+ SttError error = SttUnprepare(_handle);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "Unprepare Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Retrieves all supported languages of current engine.
+ /// The language is specified as an ISO 3166 alpha-2 two letter country-code followed by ISO 639-1 for the two-letter language code.
+ /// For example, "ko_KR" for Korean, "en_US" for American English.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <returns>
+ /// list of strings of supported languages.
+ /// </returns>
+ /// <feature>
+ /// http://tizen.org/feature/speech.recognition
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can be due to the following reasons
+ /// 1. Engine Not Found.
+ /// 2. Operation Failed.
+ /// </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to STT Not Supported. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ public IEnumerable<string> GetSupportedLangauages()
+ {
+ List<string> languageList = new List<string>();
+ lock (thisLock)
+ {
+ SupportedLanguageCallback supportedLanguageDelegate = (IntPtr handle, IntPtr language, IntPtr userData) =>
+ {
+ string lang = Marshal.PtrToStringAnsi(language);
+ languageList.Add(lang);
+ return true;
+ };
+
+ SttError error = SttForeachSupportedLanguages(_handle, supportedLanguageDelegate, IntPtr.Zero);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "GetSupportedLangauages Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+
+ return languageList;
+ }
+
+ /// <summary>
+ /// Checks whether the recognition type is supported.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <param name="type">
+ /// RecognitionType value.
+ /// </param>
+ /// <returns>
+ /// bool value indicating whether the recognition type is supported.
+ /// </returns>
+ /// <feature>
+ /// http://tizen.org/feature/speech.recognition
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can be due to the following reasons
+ /// 1. Invalid State
+ /// 2. Engine Not Found.
+ /// 3. Operation Failed.
+ /// </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to STT Not Supported. </exception>
+ /// <pre>
+ /// The state should be Ready.
+ /// </pre>
+ public bool IsRecognitionTypeSupported(RecognitionType type)
+ {
+ bool supported;
+ lock (thisLock)
+ {
+ string recType = "stt.recognition.type.FREE";
+ switch (type)
+ {
+ case RecognitionType.Free:
+ {
+ recType = "stt.recognition.type.FREE";
+ break;
+ }
+
+ case RecognitionType.Partial:
+ {
+ recType = "stt.recognition.type.FREE.PARTIAL";
+ break;
+ }
+
+ case RecognitionType.Search:
+ {
+ recType = "stt.recognition.type.SEARCH";
+ break;
+ }
+
+ case RecognitionType.WebSearch:
+ {
+ recType = "stt.recognition.type.WEB_SEARCH";
+ break;
+ }
+
+ case RecognitionType.Map:
+ {
+ recType = "stt.recognition.type.MAP";
+ break;
+ }
+
+ }
+
+ SttError error = SttIsRecognitionTypeSupported(_handle, recType, out supported);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "IsRecognitionTypeSupported Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+
+ }
+
+ return supported;
+ }
+
+ /// <summary>
+ /// Sets the silence detection.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <param name="type">
+ /// SilenceDetection value.
+ /// </param>
+ /// <feature>
+ /// http://tizen.org/feature/speech.recognition
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can be due to the following reasons
+ /// 1. Invalid State
+ /// 2. Not supported feature of current engine.
+ /// 3. Operation Failed.
+ /// </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to STT Not Supported. </exception>
+ /// <pre>
+ /// The state should be Ready.
+ /// </pre>
+ public void SetSilenceDetection(SilenceDetection type)
+ {
+ lock (thisLock)
+ {
+ SttError error = SttSetSilenceDetection(_handle, type);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "SetSilenceDetection Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Sets the sound to start recording.
+ /// Sound file type should be wav type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <param name="filePath">
+ /// File Path for the sound.
+ /// </param>
+ /// <feature>
+ /// http://tizen.org/feature/speech.recognition
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can be due to the following reasons
+ /// 1. Invalid State.
+ /// 2. Operation Failed.
+ /// </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to STT Not Supported. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <exception cref="ArgumentException"> If an Invalid Parameter is provided. </exception>
+ /// <pre>
+ /// The state should be Ready.
+ /// </pre>
+ public void SetStartSound(string filePath)
+ {
+ lock (thisLock)
+ {
+ SttError error = SttSetStartSound(_handle, filePath);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "SetStartSound Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Unsets the sound to start recording.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/speech.recognition
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can be due to the following reasons
+ /// 1. Invalid State.
+ /// 2. Operation Failed.
+ /// </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to STT Not Supported. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <pre>
+ /// The state should be Ready.
+ /// </pre>
+ public void UnsetStartSound()
+ {
+ lock (thisLock)
+ {
+ SttError error = SttUnsetStartSound(_handle);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "UnsetStartSound Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Sets the sound to stop recording.
+ /// Sound file type should be wav type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <param name="filePath">
+ /// File Path for the sound.
+ /// </param>
+ /// <feature>
+ /// http://tizen.org/feature/speech.recognition
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can be due to the following reasons
+ /// 1. Invalid State.
+ /// 2. Operation Failed.
+ /// </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to STT Not Supported. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <exception cref="ArgumentException"> If an Invalid Parameter is provided. </exception>
+ /// <pre>
+ /// The state should be Ready.
+ /// </pre>
+ public void SetStopSound(string filePath)
+ {
+ lock (thisLock)
+ {
+ SttError error = SttSetStopSound(_handle, filePath);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "SetStopSound Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Unsets the sound to stop recording.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/speech.recognition
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can be due to the following reasons
+ /// 1. Invalid State.
+ /// 2. Operation Failed.
+ /// </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to STT Not Supported. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <pre>
+ /// The state should be Ready.
+ /// </pre>
+ public void UnsetStopSound()
+ {
+ lock (thisLock)
+ {
+ SttError error = SttUnsetStopSound(_handle);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "UnsetStopSound Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Starts recording and recognition asynchronously.
+ /// This function starts recording in the STT service and sending recording data to engine.
+ /// This work continues until Stop, Cancel or silence detected by engine
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <param name="language">
+ /// The language selected
+ /// </param>
+ /// <param name="type">
+ /// The type for recognition
+ /// </param>
+ /// <feature>
+ /// http://tizen.org/feature/speech.recognition
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can be due to the following reasons
+ /// 1. Invalid State.
+ /// 2. Operation Failed.
+ /// 3. Recorder Busy.
+ /// 4. Progress to recording is not finished
+ /// </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to STT Not Supported. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <exception cref="ArgumentException"> If an Invalid Language is provided. </exception>
+ /// <pre>
+ /// The state should be Ready.
+ /// </pre>
+ /// <post>
+ /// It will invoke StateChanged Event if registerd.
+ /// If this function succeeds, the STT state will be Recording.
+ /// If you call this function again before state changes, you will receive ErrorINProgressToRecording.
+ /// </post>
+ public void Start(string language, RecognitionType type)
+ {
+ lock (thisLock)
+ {
+ string recType = "stt.recognition.type.FREE";
+ switch (type)
+ {
+ case RecognitionType.Free:
+ {
+ recType = "stt.recognition.type.FREE";
+ break;
+ }
+
+ case RecognitionType.Partial:
+ {
+ recType = "stt.recognition.type.FREE.PARTIAL";
+ break;
+ }
+
+ case RecognitionType.Search:
+ {
+ recType = "stt.recognition.type.SEARCH";
+ break;
+ }
+
+ case RecognitionType.WebSearch:
+ {
+ recType = "stt.recognition.type.WEB_SEARCH";
+ break;
+ }
+
+ case RecognitionType.Map:
+ {
+ recType = "stt.recognition.type.MAP";
+ break;
+ }
+
+ }
+
+ SttError error = SttStart(_handle, language, recType);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "Start Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Finishes the recording and starts recognition processing in engine asynchronously.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/speech.recognition
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can be due to the following reasons
+ /// 1. Invalid State.
+ /// 2. Operation Failed.
+ /// 3. Progress to ready is not finished.
+ /// 4. Progress to recording is not finished.
+ /// 5. Progress to processing is not finished.
+ /// </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to STT Not Supported. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <pre>
+ /// The state should be Recording.
+ /// </pre>
+ /// <post>
+ /// It will invoke StateChanged Event if registerd.
+ /// If this function succeeds, the STT state will be Processing.
+ /// If you call this function again before state changes, you will receive ErrorINProgressToProcessing.
+ /// After processing of engine, RecognitionResult event is invoked
+ /// </post>
+ public void Stop()
+ {
+ lock (thisLock)
+ {
+ SttError error = SttStop(_handle);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "Stop Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Cancels processing recognition and recording asynchronously.
+ /// This function cancels recording and engine cancels recognition processing.
+ /// After successful cancel, StateChanged event is invoked otherwise if error is occurred, ErrorOccured event is invoked.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <feature>
+ /// http://tizen.org/feature/speech.recognition
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can be due to the following reasons
+ /// 1. Invalid State.
+ /// 2. Operation Failed.
+ /// 3. Progress to ready is not finished.
+ /// 4. Progress to recording is not finished.
+ /// 5. Progress to processing is not finished.
+ /// </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to STT Not Supported. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <pre>
+ /// The state should be Recording or Processing.
+ /// </pre>
+ /// <post>
+ /// It will invoke StateChanged Event if registerd.
+ /// If this function succeeds, the STT state will be Ready.
+ /// If you call this function again before state changes, you will receive ErrorINProgressToReady.
+ /// </post>
+ public void Cancel()
+ {
+ lock (thisLock)
+ {
+ SttError error = SttCancel(_handle);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "Cancel Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Method to release resources
+ /// </summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ SttError error = SttDestroy(_handle);
+ if (error != SttError.None)
+ {
+ Log.Error(LogTag, "Destroy Failed with error " + error);
+ }
+ }
+
+ disposedValue = true;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Uix.Stt/Tizen.Uix.Stt/SupportedEngine.cs b/src/Tizen.Uix.Stt/Tizen.Uix.Stt/SupportedEngine.cs
new file mode 100755
index 0000000..d2129e8
--- /dev/null
+++ b/src/Tizen.Uix.Stt/Tizen.Uix.Stt/SupportedEngine.cs
@@ -0,0 +1,64 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+namespace Tizen.Uix.Stt
+{
+ /// <summary>
+ /// This Class provideds the Information related to STT Engine.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class SupportedEngine
+ {
+ private string _engineId;
+ private string _engineName;
+
+ internal SupportedEngine(string id, string name)
+ {
+ this._engineId = id;
+ this._engineName = name;
+ }
+ /// <summary>
+ /// The Engine Id
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// The string Engine Id
+ /// </returns>
+ public string EngineId
+ {
+ get
+ {
+ return _engineId;
+ }
+ }
+
+ /// <summary>
+ /// The Engine Name
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// The string Engine Name
+ /// </returns>
+ public string EngineName
+ {
+ get
+ {
+ return _engineName;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Uix.Tts/Interop/Interop.Libraries.cs b/src/Tizen.Uix.Tts/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..b99ba12
--- /dev/null
+++ b/src/Tizen.Uix.Tts/Interop/Interop.Libraries.cs
@@ -0,0 +1,29 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/// <summary>
+/// Partial Interop Class
+/// </summary>
+internal static partial class Interop
+{
+ /// <summary>
+ /// Partial Libraries Class
+ /// </summary>
+ internal static partial class Libraries
+ {
+ public const string Tts = "libtts.so";
+ }
+}
diff --git a/src/Tizen.Uix.Tts/Interop/Interop.Tts.cs b/src/Tizen.Uix.Tts/Interop/Interop.Tts.cs
new file mode 100755
index 0000000..be7999d
--- /dev/null
+++ b/src/Tizen.Uix.Tts/Interop/Interop.Tts.cs
@@ -0,0 +1,172 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Uix.Tts;
+
+/// <summary>
+/// Partial Interop Class
+/// </summary>
+internal static partial class Interop
+{
+ /// <summary>
+ /// Tts Interop Class
+ /// </summary>
+ internal static class Tts
+ {
+ internal static string LogTag = "Tizen.Uix.Tts";
+
+ private const int ErrorTts = -0x02F10000;
+
+ internal enum TtsError
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None, /**< Successful */
+ OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory, /**< Out of Memory */
+ IoError = Tizen.Internals.Errors.ErrorCode.IoError, /**< I/O error */
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter, /**< Invalid parameter */
+ OutOfNetwork = Tizen.Internals.Errors.ErrorCode.Networkdown, /**< Network is down */
+ TimedOut = Tizen.Internals.Errors.ErrorCode.TimedOut, /**< No answer from the STT service */
+ PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied, /**< Permission denied */
+ NotSupported = Tizen.Internals.Errors.ErrorCode.NotSupported, /**< STT NOT supported */
+ InvalidState = ErrorTts | 0x01, /**< Invalid state */
+ InvalidVoice = ErrorTts | 0x02, /**< Invalid language */
+ EngineNotFound = ErrorTts | 0x03, /**< No available engine */
+ OperationFailed = ErrorTts | 0x04, /**< Operation failed */
+ AudioPolicyBlocked = ErrorTts | 0x05, /**< Audio policy blocked */
+ NotSupportedFeature = ErrorTts | 0x06, /**< Not supported feature of current engine*/
+ ServiceReset = ErrorTts | 0x07 /**< Service reset*/
+ };
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void TtsStateChangedCB(IntPtr handle, State previous, State current, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void TtsUtteranceStartedCB(IntPtr handle, int uttId, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void TtsUtteranceCompletedCB(IntPtr handle, int uttId, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void TtsErrorCB(IntPtr handle, int uttId, TtsError reason, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool TtsSupportedVoiceCB(IntPtr handle, IntPtr language, int voiceType, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void TtsDefaultVoiceChangedCB(IntPtr handle, IntPtr previous_language, int previous_voice_type, IntPtr current_language, int current_voice_type, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void TtsEngineChangedCB(IntPtr handle, IntPtr engine_id, IntPtr language, int voice_type, bool need_credential, IntPtr userData);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_create", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsCreate(out IntPtr handle);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_destroy", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsDestroy(IntPtr handle);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_set_mode", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsSetMode(IntPtr handle, Mode m);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_get_mode", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsGetMode(IntPtr handle, out Mode m);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_set_credential", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsSetCredential(IntPtr handle, string credential);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_prepare", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsPrepare(IntPtr handle);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_unprepare", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsUnprepare(IntPtr handle);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_foreach_supported_voices", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsForeachSupportedVoices(IntPtr handle, TtsSupportedVoiceCB callback, IntPtr userData);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_get_default_voice", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsGetDefaultVoice(IntPtr handle, out string language, out int voice_type);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_set_private_data", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsSetPrivateData(IntPtr handle, string key, string data);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_get_private_data", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsGetPrivateData(IntPtr handle, string key, out string data);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_get_max_text_size", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsGetMaxTextSize(IntPtr handle, out uint size);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_get_state", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsGetState(IntPtr handle, out State state);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_get_speed_range", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsGetSpeedRange(IntPtr handle, out int min, out int normal, out int max);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_get_error_message", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsGetErrorMessage(IntPtr handle, out string err_msg);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_is_recognition_type_supported", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsIsRecognitionTypeSupported(IntPtr handle, string type, out bool support);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_add_text", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsAddText(IntPtr handle, string text, string language, int voice_type, int speed, out int uttId);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_play", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsPlay(IntPtr handle);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_stop", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsStop(IntPtr handle);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_pause", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsPause(IntPtr handle);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_set_state_changed_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsSetStateChangedCB(IntPtr handle, TtsStateChangedCB callback, IntPtr userData);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_unset_state_changed_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsUnsetStateChangedCB(IntPtr handle);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_set_utterance_started_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsSetUtteranceStartedCB(IntPtr handle, TtsUtteranceStartedCB callback, IntPtr userData);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_unset_utterance_started_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsUnsetUtteranceStartedCB(IntPtr handle);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_set_utterance_completed_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsSetUtteranceCompletedCB(IntPtr handle, TtsUtteranceCompletedCB callback, IntPtr userData);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_unset_utterance_completed_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsUnsetUtteranceCompletedCB(IntPtr handle);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_set_error_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsSetErrorCB(IntPtr handle, TtsErrorCB callback, IntPtr userData);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_unset_error_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsUnsetErrorCB(IntPtr handle);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_set_default_voice_changed_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsSetDefaultVoiceChangedCB(IntPtr handle, TtsDefaultVoiceChangedCB callback, IntPtr userData);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_unset_default_voice_changed_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsUnsetDefaultVoiceChangedCB(IntPtr handle);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_set_engine_changed_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsSetEngineChangedCB(IntPtr handle, TtsEngineChangedCB callback, IntPtr userData);
+
+ [DllImport(Libraries.Tts, EntryPoint = "tts_unset_engine_changed_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern TtsError TtsUnsetEngineChangedCB(IntPtr handle);
+ }
+}
diff --git a/src/Tizen.Uix.Tts/Tizen.Uix.Tts.csproj b/src/Tizen.Uix.Tts/Tizen.Uix.Tts.csproj
new file mode 100644
index 0000000..5ed2f1f
--- /dev/null
+++ b/src/Tizen.Uix.Tts/Tizen.Uix.Tts.csproj
@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Uix.Tts/Tizen.Uix.Tts/DefaultVoiceChangedEventArgs.cs b/src/Tizen.Uix.Tts/Tizen.Uix.Tts/DefaultVoiceChangedEventArgs.cs
new file mode 100755
index 0000000..6ece3cc
--- /dev/null
+++ b/src/Tizen.Uix.Tts/Tizen.Uix.Tts/DefaultVoiceChangedEventArgs.cs
@@ -0,0 +1,52 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+namespace Tizen.Uix.Tts
+{
+ /// <summary>
+ /// This Class holds information related to DefaultVoiceChanged Event
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class DefaultVoiceChangedEventArgs
+ {
+ internal DefaultVoiceChangedEventArgs(string previousLanguage, int previousVoiceType, string currentLanguage, int currentVoiceType)
+ {
+ this.Previous = new SupportedVoice(previousLanguage, previousVoiceType);
+ this.Current = new SupportedVoice(currentLanguage, currentVoiceType);
+ }
+
+ /// <summary>
+ /// The Previous SupportedVoice
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public SupportedVoice Previous
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// The current SupportedVoice
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public SupportedVoice Current
+ {
+ get;
+ internal set;
+ }
+ }
+}
diff --git a/src/Tizen.Uix.Tts/Tizen.Uix.Tts/EngineChangedEventArgs.cs b/src/Tizen.Uix.Tts/Tizen.Uix.Tts/EngineChangedEventArgs.cs
new file mode 100755
index 0000000..6419660
--- /dev/null
+++ b/src/Tizen.Uix.Tts/Tizen.Uix.Tts/EngineChangedEventArgs.cs
@@ -0,0 +1,65 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+using static Tizen.Uix.Tts.SupportedVoice;
+
+namespace Tizen.Uix.Tts
+{
+ /// <summary>
+ /// This class holds information related to Engine Changed Event
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class EngineChangedEventArgs
+ {
+ internal EngineChangedEventArgs(string engineId, string language, int voiceType, bool needCredential)
+ {
+ this.EngineId = engineId;
+ this.VoiceType = new SupportedVoice(language, voiceType);
+ this.NeedCredential = needCredential;
+ }
+
+ /// <summary>
+ /// Engine Id
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string EngineId
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// The necessity of credential
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public bool NeedCredential
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// The supported voice
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public SupportedVoice VoiceType
+ {
+ get;
+ internal set;
+ }
+ }
+}
diff --git a/src/Tizen.Uix.Tts/Tizen.Uix.Tts/ErrorOccuredEventArgs.cs b/src/Tizen.Uix.Tts/Tizen.Uix.Tts/ErrorOccuredEventArgs.cs
new file mode 100755
index 0000000..dd173dc
--- /dev/null
+++ b/src/Tizen.Uix.Tts/Tizen.Uix.Tts/ErrorOccuredEventArgs.cs
@@ -0,0 +1,161 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+using System;
+using static Interop.Tts;
+
+namespace Tizen.Uix.Tts
+{
+ /// <summary>
+ /// This class holds information related to the TTS ErrorOccured Event
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class ErrorOccuredEventArgs
+ {
+ private IntPtr _handle;
+
+ internal ErrorOccuredEventArgs(IntPtr handle, int utteranceId, Interop.Tts.TtsError error)
+ {
+ this._handle = handle;
+ this.UtteranceId = utteranceId;
+ switch (error)
+ {
+ case Interop.Tts.TtsError.None:
+ {
+ ErrorValue = Error.None;
+ break;
+ }
+
+ case Interop.Tts.TtsError.OutOfMemory:
+ {
+ ErrorValue = Error.OutOfMemory;
+ break;
+ }
+
+ case Interop.Tts.TtsError.IoError:
+ {
+ ErrorValue = Error.IoError;
+ break;
+ }
+
+ case Interop.Tts.TtsError.InvalidParameter:
+ {
+ ErrorValue = Error.InvalidParameter;
+ break;
+ }
+
+ case Interop.Tts.TtsError.TimedOut:
+ {
+ ErrorValue = Error.TimedOut;
+ break;
+ }
+
+ case Interop.Tts.TtsError.OutOfNetwork:
+ {
+ ErrorValue = Error.OutOfNetwork;
+ break;
+ }
+
+ case Interop.Tts.TtsError.PermissionDenied:
+ {
+ ErrorValue = Error.PermissionDenied;
+ break;
+ }
+
+ case Interop.Tts.TtsError.NotSupported:
+ {
+ ErrorValue = Error.NotSupported;
+ break;
+ }
+
+ case Interop.Tts.TtsError.InvalidState:
+ {
+ ErrorValue = Error.InvalidState;
+ break;
+ }
+
+ case Interop.Tts.TtsError.InvalidVoice:
+ {
+ ErrorValue = Error.InvalidVoice;
+ break;
+ }
+
+ case Interop.Tts.TtsError.EngineNotFound:
+ {
+ ErrorValue = Error.EngineNotFound;
+ break;
+ }
+
+ case Interop.Tts.TtsError.OperationFailed:
+ {
+ ErrorValue = Error.OperationFailed;
+ break;
+ }
+
+ case Interop.Tts.TtsError.AudioPolicyBlocked:
+ {
+ ErrorValue = Error.AudioPolicyBlocked;
+ break;
+ }
+ }
+ }
+
+ /// <summary>
+ /// The Utterance Id
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int UtteranceId
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// The Error Value
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public Error ErrorValue
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// Gets the current error message.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// string error message
+ /// </returns>
+ public string ErrorMessage
+ {
+ get
+ {
+ string errorMesage = "";
+ TtsError error = TtsGetErrorMessage(_handle, out errorMesage);
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "GetErrorMessage Failed with error " + error);
+ return "";
+ }
+
+ return errorMesage;
+ }
+
+ }
+ }
+}
diff --git a/src/Tizen.Uix.Tts/Tizen.Uix.Tts/ExceptionFactory.cs b/src/Tizen.Uix.Tts/Tizen.Uix.Tts/ExceptionFactory.cs
new file mode 100755
index 0000000..a29d9dd
--- /dev/null
+++ b/src/Tizen.Uix.Tts/Tizen.Uix.Tts/ExceptionFactory.cs
@@ -0,0 +1,127 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+using System;
+using static Interop.Tts;
+
+namespace Tizen.Uix.Tts
+{
+ internal static class ExceptionFactory
+ {
+ internal static Exception CreateException(TtsError err)
+ {
+ Tizen.Log.Error(LogTag, "Error " + err);
+ Exception exp;
+ switch (err)
+ {
+ case TtsError.OutOfMemory:
+ {
+ exp = new OutOfMemoryException("Out Of Memory");
+ break;
+ }
+
+ case TtsError.IoError:
+ {
+ exp = new InvalidOperationException("I/O Error Occured");
+ break;
+ }
+
+ case TtsError.InvalidParameter:
+ {
+ exp = new ArgumentException("Invalid Parameters Provided");
+ break;
+ }
+
+ case TtsError.TimedOut:
+ {
+ exp = new TimeoutException("No answer from the TTS service");
+ break;
+ }
+
+ case TtsError.OutOfNetwork:
+ {
+ exp = new InvalidOperationException("Network is down");
+ break;
+ }
+
+ case TtsError.PermissionDenied:
+ {
+ exp = new UnauthorizedAccessException("Permission Denied");
+ break;
+ }
+
+ case TtsError.NotSupported:
+ {
+ exp = new NotSupportedException("TTS NOT supported");
+ break;
+ }
+
+ case TtsError.InvalidState:
+ {
+ exp = new InvalidOperationException("Invalid state");
+ break;
+ }
+
+ case TtsError.InvalidVoice:
+ {
+ exp = new InvalidOperationException("Invalid Voice");
+ break;
+ }
+
+ case TtsError.EngineNotFound:
+ {
+ exp = new InvalidOperationException("No available engine");
+ break;
+ }
+
+ case TtsError.OperationFailed:
+ {
+ exp = new InvalidOperationException("Operation Failed");
+ break;
+ }
+
+ case TtsError.AudioPolicyBlocked:
+ {
+ exp = new InvalidOperationException("AudioPolicyBlocked");
+ break;
+ }
+
+ case TtsError.NotSupportedFeature:
+ {
+ exp = new InvalidOperationException("Feature NotSupported");
+ break;
+ }
+
+ case TtsError.ServiceReset:
+ {
+ exp = new InvalidOperationException("Service Reset");
+ break;
+ }
+
+ default:
+ {
+ exp = new Exception("");
+ break;
+ }
+
+ }
+
+ return exp;
+
+ }
+ }
+}
diff --git a/src/Tizen.Uix.Tts/Tizen.Uix.Tts/SpeedRange.cs b/src/Tizen.Uix.Tts/Tizen.Uix.Tts/SpeedRange.cs
new file mode 100755
index 0000000..dbe1f68
--- /dev/null
+++ b/src/Tizen.Uix.Tts/Tizen.Uix.Tts/SpeedRange.cs
@@ -0,0 +1,63 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+namespace Tizen.Uix.Tts
+{
+ /// <summary>
+ /// This class holds the Speed Range Values
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class SpeedRange
+ {
+ internal SpeedRange(int min, int normal, int max)
+ {
+ this.Min = min;
+ this.Normal = normal;
+ this.Max = max;
+ }
+
+ /// <summary>
+ /// The Max Speed Range Value
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Max
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// The Min Speed Range Value
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Min
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// The Normal Speed Range Value
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int Normal
+ {
+ get;
+ internal set;
+ }
+ }
+}
diff --git a/src/Tizen.Uix.Tts/Tizen.Uix.Tts/StateChangedEventArgs.cs b/src/Tizen.Uix.Tts/Tizen.Uix.Tts/StateChangedEventArgs.cs
new file mode 100755
index 0000000..ba1db04
--- /dev/null
+++ b/src/Tizen.Uix.Tts/Tizen.Uix.Tts/StateChangedEventArgs.cs
@@ -0,0 +1,52 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+namespace Tizen.Uix.Tts
+{
+ /// <summary>
+ /// This class holds information related to the TTS state change event
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class StateChangedEventArgs
+ {
+ internal StateChangedEventArgs(State previous, State current)
+ {
+ Previous = previous;
+ Current = current;
+ }
+
+ /// <summary>
+ /// A previous state
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public State Previous
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// A current state
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public State Current
+ {
+ get;
+ internal set;
+ }
+ }
+}
diff --git a/src/Tizen.Uix.Tts/Tizen.Uix.Tts/SupportedVoice.cs b/src/Tizen.Uix.Tts/Tizen.Uix.Tts/SupportedVoice.cs
new file mode 100755
index 0000000..eb6f75b
--- /dev/null
+++ b/src/Tizen.Uix.Tts/Tizen.Uix.Tts/SupportedVoice.cs
@@ -0,0 +1,72 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+namespace Tizen.Uix.Tts
+{
+ /// <summary>
+ /// This Class holds information about the Supported Voices.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class SupportedVoice
+ {
+ internal SupportedVoice(string lang, int voiceType)
+ {
+ this.Language = lang;
+ if (voiceType == 0)
+ {
+ this.VoiceType = Voice.Auto;
+ }
+
+ else if (voiceType == 1)
+ {
+ this.VoiceType = Voice.Male;
+ }
+
+ else if (voiceType == 2)
+ {
+ this.VoiceType = Voice.Female;
+ }
+
+ else if (voiceType == 3)
+ {
+ this.VoiceType = Voice.Child;
+ }
+ }
+
+ internal SupportedVoice()
+ {
+ this.Language = "";
+ this.VoiceType = Voice.Auto;
+ }
+
+ /// <summary>
+ /// Language specified as an ISO 3166 alpha-2 two letter country-code followed by ISO 639-1 for the two-letter language code (for example, "ko_KR" for Korean, "en_US" for American English)
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string Language
+ {
+ get;
+ internal set;
+ }
+
+ public Voice VoiceType
+ {
+ get;
+ internal set;
+ }
+ }
+}
diff --git a/src/Tizen.Uix.Tts/Tizen.Uix.Tts/TtsClient.cs b/src/Tizen.Uix.Tts/Tizen.Uix.Tts/TtsClient.cs
new file mode 100755
index 0000000..a8dedcc
--- /dev/null
+++ b/src/Tizen.Uix.Tts/Tizen.Uix.Tts/TtsClient.cs
@@ -0,0 +1,1069 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using static Interop.Tts;
+
+namespace Tizen.Uix.Tts
+{
+ /// <summary>
+ /// Enumeration for States
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum State
+ {
+ /// <summary>
+ /// Created atate
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Created = 0,
+
+ /// <summary>
+ /// Ready state
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Ready = 1,
+
+ /// <summary>
+ /// Playing state
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Playing = 2,
+
+ /// <summary>
+ /// Paused state
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Paused = 3,
+
+ /// <summary>
+ /// state Unavailable
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Unavailable
+ };
+
+ /// <summary>
+ /// Enumeration for TTS mode.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum Mode
+ {
+ /// <summary>
+ /// Default mode for normal application
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Default = 0,
+
+ /// <summary>
+ /// Notification mode
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Notification = 1,
+
+ /// <summary>
+ /// Accessibiliity mode
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ ScreenReader = 2
+ };
+
+ /// <summary>
+ /// Enum for Error values that can occur
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum Error
+ {
+ /// <summary>
+ /// Successful, No error
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ None,
+ /// <summary>
+ /// Out of Memory
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ OutOfMemory,
+ /// <summary>
+ /// I/O error
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ IoError,
+ /// <summary>
+ /// Invalid parameter
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ InvalidParameter,
+ /// <summary>
+ /// No answer from the STT service
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ TimedOut,
+ /// <summary>
+ /// Network is down
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ OutOfNetwork,
+ /// <summary>
+ /// Permission denied
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ PermissionDenied,
+ /// <summary>
+ /// STT NOT supported
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ NotSupported,
+ /// <summary>
+ /// Invalid state
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ InvalidState,
+ /// <summary>
+ /// Invalid Voice
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ InvalidVoice,
+ /// <summary>
+ /// No available engine
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ EngineNotFound,
+ /// <summary>
+ /// Operation failed
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ OperationFailed,
+ /// <summary>
+ /// Audio policy blocked
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ AudioPolicyBlocked
+ };
+
+ /// <summary>
+ /// Enumeration for Voice Types
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum Voice
+ {
+ /// <summary>
+ /// Automatic Voice Type
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Auto,
+
+ /// <summary>
+ /// Male Voice
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Male,
+
+ /// <summary>
+ /// Female Voice
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Female,
+
+ /// <summary>
+ /// Child Voice Type
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ Child
+ };
+
+ /// <summary>
+ /// You can use Text-To-Speech (TTS) API's to read sound data transformed by the engine from input texts.
+ /// Applications can add input-text to queue for reading continuously and control the player that can play, pause, and stop sound data synthesized from text.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class TtsClient : IDisposable
+ {
+ private IntPtr _handle;
+ private event EventHandler<StateChangedEventArgs> _stateChanged;
+ private event EventHandler<UtteranceEventArgs> _utteranceStarted;
+ private event EventHandler<UtteranceEventArgs> _utteranceCompleted;
+ private event EventHandler<ErrorOccuredEventArgs> _errorOccured;
+ private event EventHandler<DefaultVoiceChangedEventArgs> _defaultVoiceChanged;
+ private event EventHandler<EngineChangedEventArgs> _engineChanged;
+ private bool disposedValue = false;
+ private Object thisLock = new Object();
+ private TtsStateChangedCB _stateDelegate;
+ private TtsUtteranceStartedCB _utteranceStartedResultDelegate;
+ private TtsUtteranceCompletedCB _utteranceCompletedResultDelegate;
+ private TtsErrorCB _errorDelegate;
+ private TtsDefaultVoiceChangedCB _voiceChangedDelegate;
+ private TtsEngineChangedCB _engineDelegate;
+ private TtsSupportedVoiceCB _supportedvoiceDelegate;
+
+ /// <summary>
+ /// Constructor to create a TTS instance.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>
+ /// http://tizen.org/feature/speech.synthesis
+ /// </feature>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can be due to the following reaons
+ /// 1. Operation Failed
+ /// 2. Engine Not Found
+ /// </exception>
+ /// <exception cref="OutOfMemoryException"> This Exception can be due to Out Of Memory. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to TTS Not Supported. </exception>
+ public TtsClient()
+ {
+ IntPtr handle;
+ TtsError error = TtsCreate(out handle);
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "Create Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+
+ _handle = handle;
+ }
+
+ /// <summary>
+ /// Event to be invoked when TTS state changes.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<StateChangedEventArgs> StateChanged
+ {
+ add
+ {
+ lock (thisLock)
+ {
+ _stateDelegate = (IntPtr handle, State previous, State current, IntPtr userData) =>
+ {
+ StateChangedEventArgs args = new StateChangedEventArgs(previous, current);
+ _stateChanged?.Invoke(this, args);
+ };
+ TtsError error = TtsSetStateChangedCB(_handle, _stateDelegate, IntPtr.Zero);
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "Add StateChanged Failed with error " + error);
+ }
+ else
+ {
+ _stateChanged += value;
+ }
+ }
+
+ }
+
+ remove
+ {
+ lock (thisLock)
+ {
+ TtsError error = TtsUnsetStateChangedCB(_handle);
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "Remove StateChanged Failed with error " + error);
+ }
+
+ _stateChanged -= value;
+ }
+ }
+
+ }
+
+ /// <summary>
+ /// Event to be invoked when the utterance starts.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<UtteranceEventArgs> UtteranceStarted
+ {
+ add
+ {
+ lock (thisLock)
+ {
+ _utteranceStartedResultDelegate = (IntPtr handle, int uttId, IntPtr userData) =>
+ {
+ UtteranceEventArgs args = new UtteranceEventArgs(uttId);
+ _utteranceStarted?.Invoke(this, args);
+ };
+ TtsError error = TtsSetUtteranceStartedCB(_handle, _utteranceStartedResultDelegate, IntPtr.Zero);
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "Add UtteranceStarted Failed with error " + error);
+ }
+ else
+ {
+ _utteranceStarted += value;
+ }
+ }
+ }
+
+ remove
+ {
+ lock (thisLock)
+ {
+ TtsError error = TtsUnsetUtteranceStartedCB(_handle);
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "Remove UtteranceStarted Failed with error " + error);
+ }
+
+ _utteranceStarted -= value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Event to be invoked when the utterance completes.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<UtteranceEventArgs> UtteranceCompleted
+ {
+ add
+ {
+ lock (thisLock)
+ {
+ _utteranceCompletedResultDelegate = (IntPtr handle, int uttId, IntPtr userData) =>
+ {
+ UtteranceEventArgs args = new UtteranceEventArgs(uttId);
+ _utteranceCompleted?.Invoke(this, args);
+ };
+ TtsError error = TtsSetUtteranceCompletedCB(_handle, _utteranceCompletedResultDelegate, IntPtr.Zero);
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "Add UtteranceCompleted Failed with error " + error);
+ }
+ else
+ {
+ _utteranceCompleted += value;
+ }
+ }
+ }
+
+ remove
+ {
+ lock (thisLock)
+ {
+ TtsError error = TtsUnsetUtteranceCompletedCB(_handle);
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "Remove UtteranceCompleted Failed with error " + error);
+ }
+
+ _utteranceCompleted -= value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Event to be invoked when an error occurs.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<ErrorOccuredEventArgs> ErrorOccured
+ {
+ add
+ {
+ lock (thisLock)
+ {
+ _errorDelegate = (IntPtr handle, int uttId, TtsError reason, IntPtr userData) =>
+ {
+ ErrorOccuredEventArgs args = new ErrorOccuredEventArgs(handle, uttId, reason);
+ _errorOccured?.Invoke(this, args);
+ };
+ TtsError error = TtsSetErrorCB(_handle, _errorDelegate, IntPtr.Zero);
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "Add ErrorOccured Failed with error " + error);
+ }
+
+ else
+ {
+ _errorOccured += value;
+ }
+ }
+ }
+
+ remove
+ {
+ lock (thisLock)
+ {
+ TtsError error = TtsUnsetErrorCB(_handle);
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "Remove ErrorOccured Failed with error " + error);
+ }
+
+ _errorOccured -= value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Event to be invoked when an error occurs.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<DefaultVoiceChangedEventArgs> DefaultVoiceChanged
+ {
+ add
+ {
+ lock (thisLock)
+ {
+ _voiceChangedDelegate = (IntPtr handle, IntPtr previousLanguage, int previousVoiceType, IntPtr currentLanguage, int currentVoiceType, IntPtr userData) =>
+ {
+ string previousLanguageString = Marshal.PtrToStringAnsi(previousLanguage);
+ string currentLanguageString = Marshal.PtrToStringAnsi(currentLanguage);
+ DefaultVoiceChangedEventArgs args = new DefaultVoiceChangedEventArgs(previousLanguageString, previousVoiceType, currentLanguageString, currentVoiceType);
+ _defaultVoiceChanged?.Invoke(this, args);
+ };
+ TtsError error = TtsSetDefaultVoiceChangedCB(_handle, _voiceChangedDelegate, IntPtr.Zero);
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "Add DefaultVoiceChanged Failed with error " + error);
+ }
+
+ else
+ {
+ _defaultVoiceChanged += value;
+ }
+ }
+
+ }
+
+ remove
+ {
+ lock (thisLock)
+ {
+ TtsError error = TtsUnsetDefaultVoiceChangedCB(_handle);
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "Remove DefaultVoiceChanged Failed with error " + error);
+ }
+
+ _defaultVoiceChanged -= value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Event to be invoked to detect engine change.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<EngineChangedEventArgs> EngineChanged
+ {
+ add
+ {
+ lock (thisLock)
+ {
+ _engineDelegate = (IntPtr handle, IntPtr engineId, IntPtr language, int voiceType, bool needCredential, IntPtr userData) =>
+ {
+ string engineIdString = Marshal.PtrToStringAnsi(engineId);
+ string languageString = Marshal.PtrToStringAnsi(language);
+ EngineChangedEventArgs args = new EngineChangedEventArgs(engineIdString, languageString, voiceType, needCredential);
+ _engineChanged?.Invoke(this, args);
+ };
+ TtsError error = TtsSetEngineChangedCB(_handle, _engineDelegate, IntPtr.Zero);
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "Add EngineChanged Failed with error " + error);
+ }
+ else
+ {
+ _engineChanged += value;
+ }
+ }
+ }
+
+ remove
+ {
+ lock (thisLock)
+ {
+ TtsError error = TtsUnsetEngineChangedCB(_handle);
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "Remove EngineChanged Failed with error " + error);
+ }
+
+ _engineChanged -= value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the default voice set by the user.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// Default voice in TTS
+ /// </value>
+ /// <returns>
+ /// Default Voice SupportedVoice value.
+ /// </returns>
+ public SupportedVoice DefaultVoice
+ {
+ get
+ {
+ lock (thisLock)
+ {
+ string language;
+ int voiceType;
+ TtsError error = TtsGetDefaultVoice(_handle, out language, out voiceType);
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "DefaultVoice Failed with error " + error);
+ return new SupportedVoice();
+ }
+
+ return new SupportedVoice(language, voiceType);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the maximum byte size for text.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// Maximum byte size for text
+ /// </value>
+ /// <returns>
+ /// Default Voice SupportedVoice value, 0 if unable to get the value
+ /// </returns>
+ /// <pre>
+ /// The State should be Ready
+ /// </pre>
+ public uint MaxTextSize
+ {
+ get
+ {
+ uint maxTextSize;
+ lock (thisLock)
+ {
+ TtsError error = TtsGetMaxTextSize(_handle, out maxTextSize);
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "MaxTextSize Failed with error " + error);
+ return 0;
+ }
+
+ }
+
+ return maxTextSize;
+ }
+
+ }
+
+ /// <summary>
+ /// Gets the current TTS state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// Current state of TTS
+ /// </value>
+ /// <returns>
+ /// Current TTS State value.
+ /// </returns>
+ public State CurrentState
+ {
+ get
+ {
+ State state;
+ lock (thisLock)
+ {
+ TtsError error = TtsGetState(_handle, out state);
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "CurrentState Failed with error " + error);
+ return State.Unavailable;
+ }
+
+ }
+
+ return state;
+ }
+
+ }
+
+ /// <summary>
+ /// The TTS Mode can be set using this property
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// Current mode of TTS (default, screen-reader, notification)
+ /// </value>
+ /// <returns>
+ /// The Mode value
+ /// </returns>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can be due to the following reaons while setting the value
+ /// 1. Operation Failed
+ /// 2. Engine Not Found
+ /// </exception>
+ /// <exception cref="OutOfMemoryException"> This Exception can be due to Out Of Memory. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to TTS Not Supported. </exception>
+ /// <pre>
+ /// State should be Created
+ /// </pre>
+ public Mode CurrentMode
+ {
+ get
+ {
+ Mode mode = Mode.Default;
+ lock (thisLock)
+ {
+ TtsError error = TtsGetMode(_handle, out mode);
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "Get Mode Failed with error " + error);
+ return Mode.Default;
+ }
+ }
+
+ return mode;
+ }
+ set
+ {
+ TtsError error;
+ lock (thisLock)
+ {
+ error = TtsSetMode(_handle, value);
+ }
+
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "Set Mode Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Sets the app credential
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="credential">
+ /// The credential string
+ /// </param>
+ /// <feature>
+ /// http://tizen.org/feature/speech.synthesis
+ /// </feature>
+ /// <exception cref="InvalidOperationException"> This Exception can be due to Invalid State. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to TTS Not Supported. </exception>
+ /// <exception cref="ArgumentException"> This can happen if Improper value is provided while setting the value. </exception>
+ /// <pre>
+ /// The State must be Created or Ready.
+ /// </pre>
+ public void SetCredential(string credential)
+ {
+ lock (thisLock)
+ {
+ TtsError error = TtsSetCredential(_handle, credential);
+ if (error != TtsError.None)
+ {
+ Tizen.Log.Error(LogTag, "SetCredential Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Connects to the TTS service asynchronously.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>
+ /// http://tizen.org/feature/speech.synthesis
+ /// </feature>
+ /// <exception cref="InvalidOperationException"> This Exception can be due to Invalid State. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to TTS Not Supported. </exception>
+ /// <pre>
+ /// The State must be Created.
+ /// </pre>
+ /// <post>
+ /// If this function is successful, the TTS state will be Ready
+ /// If this function is unsuccessful, ErrorOccured event will be invoked
+ /// </post>
+ public void Prepare()
+ {
+ lock (thisLock)
+ {
+ TtsError error = TtsPrepare(_handle);
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "Prepare Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Disconnects from the STT service.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>
+ /// http://tizen.org/feature/speech.synthesis
+ /// </feature>
+ /// <exception cref="InvalidOperationException"> This Exception can be due to Invalid State. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to TTS Not Supported. </exception>
+ /// <pre>
+ /// The State must be Ready.
+ /// </pre>
+ /// <post>
+ /// If this function is successful, the TTS state will be Created
+ /// </post>
+ public void Unprepare()
+ {
+ lock (thisLock)
+ {
+ TtsError error = TtsUnprepare(_handle);
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "Unprepare Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Retrieves all supported voices of the current engine.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// list of SupportedVoice.
+ /// </returns>
+ /// <feature>
+ /// http://tizen.org/feature/speech.synthesis
+ /// </feature>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can be due to the following reasons
+ /// 1. Engine Not Found.
+ /// 2. Operation Failed.
+ /// </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to TTS Not Supported. </exception>
+ public IEnumerable<SupportedVoice> GetSupportedVoices()
+ {
+ List<SupportedVoice> voicesList = new List<SupportedVoice>();
+ lock (thisLock)
+ {
+ _supportedvoiceDelegate = (IntPtr handle, IntPtr language, int voiceType, IntPtr userData) =>
+ {
+ string lang = Marshal.PtrToStringAnsi(language);
+ SupportedVoice voice = new SupportedVoice(lang, voiceType);
+ voicesList.Add(voice);
+ return true;
+ };
+ TtsError error = TtsForeachSupportedVoices(_handle, _supportedvoiceDelegate, IntPtr.Zero);
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "GetSupportedVoices Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+
+ }
+
+ return voicesList;
+ }
+
+ /// <summary>
+ /// Gets the private data from tts engine.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="key">
+ /// The key string
+ /// </param>
+ /// <returns>
+ /// The Data Corresponding to the Key provided
+ /// </returns>
+ /// <feature>
+ /// http://tizen.org/feature/speech.synthesis
+ /// </feature>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can be due to the following reaons
+ /// 1. Invalid State
+ /// 2. Engine Not found
+ /// 3. Operation Failure
+ /// </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to TTS Not Supported. </exception>
+ /// <pre>
+ /// The State must be Ready.
+ /// </pre>
+ public string GetPrivateData(string key)
+ {
+ string data;
+ lock (thisLock)
+ {
+ TtsError error = TtsGetPrivateData(_handle, key, out data);
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "GetPrivateData Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+
+ }
+
+ return data;
+ }
+
+ /// <summary>
+ /// Sets the private data to tts engine.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <param name="key">
+ /// The key string
+ /// </param>
+ /// <param name="data">
+ /// The data string
+ /// </param>
+ /// <feature>
+ /// http://tizen.org/feature/speech.synthesis
+ /// </feature>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can be due to the following reaons
+ /// 1. Invalid State
+ /// 2. Engine Not found
+ /// 3. Operation Failure
+ /// </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to TTS Not Supported. </exception>
+ /// <exception cref="ArgumentException"> This can happen if Improper value is provided while setting the value. </exception>
+ /// <pre>
+ /// The State must be Ready.
+ /// </pre>
+ public void SetPrivateData(string key, string data)
+ {
+ lock (thisLock)
+ {
+ TtsError error = TtsSetPrivateData(_handle, key, data);
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "SetPrivateData Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the speed range.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// The SpeedRange value
+ /// </returns>
+ /// <feature>
+ /// http://tizen.org/feature/speech.synthesis
+ /// </feature>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can be due to the following reaons
+ /// 1. Invalid State
+ /// 2. Operation Failure
+ /// </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to TTS Not Supported. </exception>
+ /// <pre>
+ /// The State must be Created.
+ /// </pre>
+ public SpeedRange GetSpeedRange()
+ {
+ int min = 0, max = 0, normal = 0;
+ lock (thisLock)
+ {
+ TtsError error = TtsGetSpeedRange(_handle, out min, out normal, out max);
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "GetSpeedRange Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+
+ }
+
+ return new SpeedRange(min, normal, max);
+ }
+
+ /// <summary>
+ /// Adds a text to the queue.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// Locale MUST be set for utf8 text validation check.
+ /// </remarks>
+ /// <param name="text">
+ /// An input text based utf8
+ /// </param>
+ /// <param name="language">
+ /// The language selected from the SupportedVoice.Language Property obtained from GetSupportedVoices() (e.g. 'NULL'(Automatic), 'en_US')
+ /// </param>
+ /// <param name="voiceType">
+ /// The voice type selected from the SupportedVoice.VoiceType Property obtained from GetSupportedVoices()
+ /// </param>
+ /// <param name="speed">
+ /// A speaking speed (e.g.0 for Auto or the value from SpeedRange Property)
+ /// </param>
+ /// <returns>
+ /// The utterance ID.
+ /// </returns>
+ /// <feature>
+ /// http://tizen.org/feature/speech.synthesis
+ /// </feature>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can be due to the following reaons
+ /// 1. Invalid State
+ /// 2. Operation Failure
+ /// 3. Invalid Voice
+ /// </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to TTS Not Supported. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <exception cref="ArgumentException"> This can happen if Improper value is provided. </exception>
+ /// <pre>
+ /// The State must be Ready or Playing or Paused.
+ /// </pre>
+ public int AddText(string text, string language, int voiceType, int speed)
+ {
+ int id;
+ lock (thisLock)
+ {
+ TtsError error = TtsAddText(_handle, text, language, voiceType, speed, out id);
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "AddText Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+
+ }
+
+ return id;
+ }
+
+ /// <summary>
+ /// Starts synthesizing voice from the text and plays the synthesized audio data.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>
+ /// http://tizen.org/feature/speech.synthesis
+ /// </feature>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can be due to the following reaons
+ /// 1. Invalid State
+ /// 2. Operation Failure
+ /// 3. Out of Network
+ /// </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to TTS Not Supported. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <pre>
+ /// The State must be Ready or Paused.
+ /// </pre>
+ /// <post>
+ /// If this function succeeds, the TTS state will be Playing.
+ /// </post>
+ public void Play()
+ {
+ lock (thisLock)
+ {
+ TtsError error = TtsPlay(_handle);
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "Play Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Stops playing the utterance and clears the queue.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>
+ /// http://tizen.org/feature/speech.synthesis
+ /// </feature>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can be due to the following reaons
+ /// 1. Invalid State
+ /// 2. Operation Failure
+ /// </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to TTS Not Supported. </exception>
+ /// <pre>
+ /// The State must be Ready or Playing or Paused.
+ /// </pre>
+ /// <post>
+ /// If this function succeeds, the TTS state will be Ready.
+ /// This function will remove all text added via AddText() and synthesized sound data.
+ /// </post>
+ public void Stop()
+ {
+ lock (thisLock)
+ {
+ TtsError error = TtsStop(_handle);
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "Stop Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Pauses the currently playing utterance.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <feature>
+ /// http://tizen.org/feature/speech.synthesis
+ /// </feature>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can be due to the following reaons
+ /// 1. Invalid State
+ /// 2. Operation Failure
+ /// </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to TTS Not Supported. </exception>
+ /// <pre>
+ /// The State must be Playing.
+ /// </pre>
+ /// <post>
+ /// If this function succeeds, the TTS state will be Paused.
+ /// </post>
+ public void Pause()
+ {
+ lock (thisLock)
+ {
+ TtsError error = TtsPause(_handle);
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "Pause Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Method to release resources
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ TtsError error = TtsDestroy(_handle);
+ if (error != TtsError.None)
+ {
+ Log.Error(LogTag, "Destroy Failed with error " + error);
+ }
+ }
+
+ disposedValue = true;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Uix.Tts/Tizen.Uix.Tts/UtteranceEventArgs.cs b/src/Tizen.Uix.Tts/Tizen.Uix.Tts/UtteranceEventArgs.cs
new file mode 100755
index 0000000..ba06b1d
--- /dev/null
+++ b/src/Tizen.Uix.Tts/Tizen.Uix.Tts/UtteranceEventArgs.cs
@@ -0,0 +1,41 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+namespace Tizen.Uix.Tts
+{
+ /// <summary>
+ /// This Class hold information related to UtteranceStared and UtteranceCompleted Events
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class UtteranceEventArgs
+ {
+ internal UtteranceEventArgs(int uttId)
+ {
+ this.UtteranceId = uttId;
+ }
+
+ /// <summary>
+ /// The utterance ID
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public int UtteranceId
+ {
+ get;
+ internal set;
+ }
+ }
+}
diff --git a/src/Tizen.Uix.VoiceControl/Interop/Interop.Libraries.cs b/src/Tizen.Uix.VoiceControl/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..22f391b
--- /dev/null
+++ b/src/Tizen.Uix.VoiceControl/Interop/Interop.Libraries.cs
@@ -0,0 +1,29 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/// <summary>
+/// Partial Interop Class
+/// </summary>
+internal static partial class Interop
+{
+ /// <summary>
+ /// Partial Libraries Class
+ /// </summary>
+ internal static partial class Libraries
+ {
+ internal const string VoiceControl = "libvc.so";
+ }
+}
diff --git a/src/Tizen.Uix.VoiceControl/Interop/Interop.VoiceControl.cs b/src/Tizen.Uix.VoiceControl/Interop/Interop.VoiceControl.cs
new file mode 100755
index 0000000..edc20f6
--- /dev/null
+++ b/src/Tizen.Uix.VoiceControl/Interop/Interop.VoiceControl.cs
@@ -0,0 +1,156 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Uix.VoiceControl;
+using static Interop.VoiceControlCommand;
+
+/// <summary>
+/// Partial Interop Class
+/// </summary>
+internal static partial class Interop
+{
+ /// <summary>
+ /// VoiceControl Interop Class
+ /// </summary>
+ internal static class VoiceControl
+ {
+ internal static string LogTag = "Tizen.Uix.VoiceControl";
+
+ private const int ErrorVoiceControl = -0x02F50000;
+
+ internal enum ErrorCode
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None, /**< Successful */
+ OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory, /**< Out of Memory */
+ IoError = Tizen.Internals.Errors.ErrorCode.IoError, /**< I/O error */
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter, /**< Invalid parameter */
+ TimedOut = Tizen.Internals.Errors.ErrorCode.TimedOut, /**< No answer from service */
+ RecorderBusy = Tizen.Internals.Errors.ErrorCode.ResourceBusy, /**< Busy recorder */
+ PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied, /**< Permission denied */
+ NotSupported = Tizen.Internals.Errors.ErrorCode.NotSupported, /**< VC NOT supported */
+ InvalidState = ErrorVoiceControl | 0x011, /**< Invalid state */
+ InvalidLanguage = ErrorVoiceControl | 0x012, /**< Invalid language */
+ EngineNotFound = ErrorVoiceControl | 0x013, /**< No available engine */
+ OperationFailed = ErrorVoiceControl | 0x014, /**< Operation failed */
+ OperationRejected = ErrorVoiceControl | 0x015, /**< Operation rejected */
+ IterationEnd = ErrorVoiceControl | 0x016, /**< List reached end */
+ Empty = ErrorVoiceControl | 0x017, /**< List empty */
+ ServiceReset = ErrorVoiceControl | 0x018, /**< Service daemon reset (Since 3.0) */
+ InProgressToReady = ErrorVoiceControl | 0x019, /**< In progress to ready (Since 3.0) */
+ InProgressToRecording = ErrorVoiceControl | 0x020, /**< In progress to recording (Since 3.0) */
+ InProgressToProcessing = ErrorVoiceControl | 0x021 /**< In progress to processing (Since 3.0) */
+ };
+
+ internal enum VoiceCommandType
+ {
+ Foreground = 1, /* Foreground command type. */
+ BackGround = 2 /* background command type. */
+ };
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_initialize")]
+ internal static extern ErrorCode VcInitialize();
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_deinitialize")]
+ internal static extern ErrorCode VcDeinitialize();
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_prepare")]
+ internal static extern ErrorCode VcPrepare();
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_unprepare")]
+ internal static extern ErrorCode VcUnprepare();
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_foreach_supported_languages")]
+ internal static extern ErrorCode VcForeachSupportedLanguages(VcSupportedLanguageCb callback, IntPtr userData);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_get_current_language")]
+ internal static extern ErrorCode VcGetCurrentLanguage(out string language);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_get_state")]
+ internal static extern ErrorCode VcGetState(out State state);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_get_service_state")]
+ internal static extern ErrorCode VcGetServiceState(out ServiceState state);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_get_system_command_list")]
+ internal static extern ErrorCode VcGetSystemCommandList(out IntPtr vc_sys_cmd_list);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_set_invocation_name")]
+ internal static extern ErrorCode VcSetInvocationName(string name);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_request_dialog")]
+ internal static extern ErrorCode VcRequestDialog(string dispText, string uttText, bool autoStart);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_set_command_list")]
+ internal static extern ErrorCode VcSetCommandList(SafeCommandListHandle cmdList, VoiceCommandType type);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_unset_command_list")]
+ internal static extern ErrorCode VcUnsetCommandList(VoiceCommandType type);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_get_result")]
+ internal static extern ErrorCode VcGetResult(VcResultCb callback, IntPtr userData);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_set_result_cb")]
+ internal static extern ErrorCode VcSetResultCb(VcResultCb callback, IntPtr userData);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_unset_result_cb")]
+ internal static extern ErrorCode VcUnsetResultCb();
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_set_service_state_changed_cb")]
+ internal static extern ErrorCode VcSetServiceStateChangedCb(VcServiceStateChangedCb callback, IntPtr userData);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_unset_service_state_changed_cb")]
+ internal static extern ErrorCode VcUnsetServiceStateChangedCb();
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_set_state_changed_cb")]
+ internal static extern ErrorCode VcSetStateChangedCb(VcStateChangedCb callback, IntPtr userData);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_unset_state_changed_cb")]
+ internal static extern ErrorCode VcUnsetStateChangedCb();
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_set_current_language_changed_cb")]
+ internal static extern ErrorCode VcSetCurrentLanguageChangedCb(VcCurrentLanguageChangedCb callback, IntPtr userData);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_unset_current_language_changed_cb")]
+ internal static extern ErrorCode VcUnsetCurrentLanguageChangedCb();
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_set_error_cb")]
+ internal static extern ErrorCode VcSetErrorCb(VcErrorCb callback, IntPtr userData);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_unset_error_cb")]
+ internal static extern ErrorCode VcUnsetErrorCb();
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void VcResultCb(ResultEvent evt, IntPtr cmdList, IntPtr result, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void VcCurrentLanguageChangedCb(IntPtr previous, IntPtr current, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool VcSupportedLanguageCb(IntPtr language, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void VcStateChangedCb(State previous, State current, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void VcServiceStateChangedCb(ServiceState previous, ServiceState current, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void VcErrorCb(ErrorCode reason, IntPtr userData);
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Uix.VoiceControl/Interop/Interop.VoiceControlCommand.cs b/src/Tizen.Uix.VoiceControl/Interop/Interop.VoiceControlCommand.cs
new file mode 100755
index 0000000..c29057a
--- /dev/null
+++ b/src/Tizen.Uix.VoiceControl/Interop/Interop.VoiceControlCommand.cs
@@ -0,0 +1,169 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen;
+using Tizen.Uix.VoiceControl;
+
+/// <summary>
+/// Partial Interop Class
+/// </summary>
+internal static partial class Interop
+{
+ /// <summary>
+ /// VoiceControlCommand Interop Class
+ /// </summary>
+ internal static class VoiceControlCommand
+ {
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_cmd_list_create")]
+ internal static extern Interop.VoiceControl.ErrorCode VcCmdListCreate(out SafeCommandListHandle cmdList);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_cmd_list_destroy")]
+ internal static extern Interop.VoiceControl.ErrorCode VcCmdListDestroy(IntPtr cmdList, bool freeCommand);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_cmd_list_get_count")]
+ internal static extern Interop.VoiceControl.ErrorCode VcCmdListGetCount(SafeCommandListHandle cmdList, out int count);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_cmd_list_add")]
+ internal static extern Interop.VoiceControl.ErrorCode VcCmdListAdd(SafeCommandListHandle cmdList, SafeCommandHandle vcCommand);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_cmd_list_remove")]
+ internal static extern Interop.VoiceControl.ErrorCode VcCmdListRemove(SafeCommandListHandle cmdList, SafeCommandHandle vcCommand);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_cmd_list_foreach_commands")]
+ internal static extern Interop.VoiceControl.ErrorCode VcCmdListForeachCommands(SafeCommandListHandle cmdList, VcCmdListCb callback, IntPtr userData);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_cmd_list_first")]
+ internal static extern Interop.VoiceControl.ErrorCode VcCmdListFirst(SafeCommandListHandle cmdList);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_cmd_list_last")]
+ internal static extern Interop.VoiceControl.ErrorCode VcCmdListLast(SafeCommandListHandle cmdList);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_cmd_list_next")]
+ internal static extern Interop.VoiceControl.ErrorCode VcCmdListNext(SafeCommandListHandle cmdList);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_cmd_list_prev")]
+ internal static extern Interop.VoiceControl.ErrorCode VcCmdListPrev(SafeCommandListHandle cmdList);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_cmd_list_get_current")]
+ internal static extern Interop.VoiceControl.ErrorCode VcCmdListGetCurrent(SafeCommandListHandle cmdList, out SafeCommandHandle vcCommand);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_cmd_create")]
+ internal static extern Interop.VoiceControl.ErrorCode VcCmdCreate(out SafeCommandHandle vcCommand);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_cmd_destroy")]
+ internal static extern Interop.VoiceControl.ErrorCode VcCmdDestroy(IntPtr vcCommand);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_cmd_set_command")]
+ internal static extern Interop.VoiceControl.ErrorCode VcCmdSetCommand(SafeCommandHandle vcCommand, string command);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_cmd_get_command")]
+ internal static extern Interop.VoiceControl.ErrorCode VcCmdGetCommand(SafeCommandHandle vcCommand, out string command);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_cmd_get_unfixed_command")]
+ internal static extern Interop.VoiceControl.ErrorCode VcCmdGetUnfixedCommand(SafeCommandHandle vcCommand, out string command);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_cmd_set_type")]
+ internal static extern Interop.VoiceControl.ErrorCode VcCmdSetType(SafeCommandHandle vcCommand, CommandType type);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_cmd_get_type")]
+ internal static extern Interop.VoiceControl.ErrorCode VcCmdGetType(SafeCommandHandle vcCommand, out int type);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_cmd_set_format")]
+ internal static extern Interop.VoiceControl.ErrorCode VcCmdSetFormat(SafeCommandHandle vcCommand, CommandFormat format);
+
+ [DllImport(Libraries.VoiceControl, EntryPoint = "vc_cmd_get_format")]
+ internal static extern Interop.VoiceControl.ErrorCode VcCmdGetFormat(SafeCommandHandle vcCommand, out CommandFormat format);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool VcCmdListCb(IntPtr vcCommand, IntPtr userData);
+
+ internal sealed class SafeCommandListHandle : SafeHandle
+ {
+ internal bool _ownership;
+
+ public SafeCommandListHandle(IntPtr handle)
+ : base(handle, true)
+ {
+ _ownership = true;
+ }
+
+ public SafeCommandListHandle()
+ : base(IntPtr.Zero, true)
+ {
+ _ownership = true;
+ }
+
+ public override bool IsInvalid
+ {
+ get { return this.handle == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ if (_ownership && !IsInvalid)
+ {
+ Interop.VoiceControl.ErrorCode error = VcCmdListDestroy(this.handle, false);
+ if (error != Interop.VoiceControl.ErrorCode.None)
+ {
+ Log.Error(VoiceControl.LogTag, "Destroy Failed with error " + error);
+ }
+ }
+ this.SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+
+ internal sealed class SafeCommandHandle : SafeHandle
+ {
+ internal bool _ownership;
+
+ public SafeCommandHandle(IntPtr handle)
+ : base(handle, true)
+ {
+ _ownership = true;
+ }
+
+ public SafeCommandHandle()
+ : base(IntPtr.Zero, true)
+ {
+ _ownership = true;
+ }
+
+ public override bool IsInvalid
+ {
+ get { return this.handle == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ Interop.VoiceControl.ErrorCode error = VoiceControl.ErrorCode.None;
+ if (_ownership && !IsInvalid)
+ {
+ error = VcCmdDestroy(this.handle);
+ if (error != Interop.VoiceControl.ErrorCode.None)
+ {
+ Log.Error(VoiceControl.LogTag, "Destroy Failed with error " + error);
+ }
+ }
+ this.SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl.csproj b/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl.csproj
new file mode 100644
index 0000000..5ed2f1f
--- /dev/null
+++ b/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl.csproj
@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/CurrentLanguageChangedEventArgs.cs b/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/CurrentLanguageChangedEventArgs.cs
new file mode 100755
index 0000000..8ab933d
--- /dev/null
+++ b/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/CurrentLanguageChangedEventArgs.cs
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+namespace Tizen.Uix.VoiceControl
+{
+ /// <summary>
+ /// This class holds information about the CurrentLanguageChanged Event
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class CurrentLanguageChangedEventArgs
+ {
+ internal CurrentLanguageChangedEventArgs(string previous, string current)
+ {
+ PreviousLanguage = previous;
+ CurrentLanguage = current;
+ }
+
+ /// <summary>
+ /// The previous language
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string PreviousLanguage
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// The current language
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string CurrentLanguage
+ {
+ get;
+ internal set;
+ }
+ }
+}
diff --git a/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/ErrorOccuredEventArgs.cs b/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/ErrorOccuredEventArgs.cs
new file mode 100755
index 0000000..ce5de7b
--- /dev/null
+++ b/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/ErrorOccuredEventArgs.cs
@@ -0,0 +1,158 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using static Interop.VoiceControl;
+
+namespace Tizen.Uix.VoiceControl
+{
+ /// <summary>
+ /// This class holds information related to the VoiceControl ErrorOccured Event
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class ErrorOccuredEventArgs
+ {
+ internal ErrorOccuredEventArgs(ErrorCode error)
+ {
+ switch (error)
+ {
+ case ErrorCode.None:
+ {
+ ErrorValue = Error.None;
+ break;
+ }
+
+ case ErrorCode.OutOfMemory:
+ {
+ ErrorValue = Error.OutOfMemory;
+ break;
+ }
+
+ case ErrorCode.IoError:
+ {
+ ErrorValue = Error.IoError;
+ break;
+ }
+
+ case ErrorCode.InvalidParameter:
+ {
+ ErrorValue = Error.InvalidParameter;
+ break;
+ }
+
+ case ErrorCode.TimedOut:
+ {
+ ErrorValue = Error.TimedOut;
+ break;
+ }
+
+ case ErrorCode.RecorderBusy:
+ {
+ ErrorValue = Error.RecorderBusy;
+ break;
+ }
+
+ case ErrorCode.PermissionDenied:
+ {
+ ErrorValue = Error.PermissionDenied;
+ break;
+ }
+
+ case ErrorCode.NotSupported:
+ {
+ ErrorValue = Error.NotSupported;
+ break;
+ }
+
+ case ErrorCode.InvalidState:
+ {
+ ErrorValue = Error.InvalidState;
+ break;
+ }
+
+ case ErrorCode.InvalidLanguage:
+ {
+ ErrorValue = Error.InvalidLanguage;
+ break;
+ }
+
+ case ErrorCode.EngineNotFound:
+ {
+ ErrorValue = Error.EngineNotFound;
+ break;
+ }
+
+ case ErrorCode.OperationFailed:
+ {
+ ErrorValue = Error.OperationFailed;
+ break;
+ }
+
+ case ErrorCode.OperationRejected:
+ {
+ ErrorValue = Error.OperationRejected;
+ break;
+ }
+
+ case ErrorCode.IterationEnd:
+ {
+ ErrorValue = Error.IterationEnd;
+ break;
+ }
+
+ case ErrorCode.Empty:
+ {
+ ErrorValue = Error.Empty;
+ break;
+ }
+
+ case ErrorCode.InProgressToReady:
+ {
+ ErrorValue = Error.InProgressToReady;
+ break;
+ }
+
+ case ErrorCode.InProgressToRecording:
+ {
+ ErrorValue = Error.InProgressToRecording;
+ break;
+ }
+
+ case ErrorCode.InProgressToProcessing:
+ {
+ ErrorValue = Error.InProgressToProcessing;
+ break;
+ }
+
+ case ErrorCode.ServiceReset:
+ {
+ ErrorValue = Error.ServiceReset;
+ break;
+ }
+ }
+ }
+
+ /// <summary>
+ /// The Error Value
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public Error ErrorValue
+ {
+ get;
+ internal set;
+ }
+ }
+}
diff --git a/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/ExceptionFactory.cs b/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/ExceptionFactory.cs
new file mode 100755
index 0000000..8c6e35f
--- /dev/null
+++ b/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/ExceptionFactory.cs
@@ -0,0 +1,148 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using static Interop.VoiceControl;
+
+namespace Tizen.Uix.VoiceControl
+{
+ internal static class ExceptionFactory
+ {
+ internal static Exception CreateException(ErrorCode err)
+ {
+ Tizen.Log.Error(LogTag, "Error " + err);
+ Exception exp;
+ switch (err)
+ {
+ case ErrorCode.OutOfMemory:
+ {
+ exp = new OutOfMemoryException("Out Of Memory");
+ break;
+ }
+
+ case ErrorCode.IoError:
+ {
+ exp = new InvalidOperationException("I/O Error Occured");
+ break;
+ }
+
+ case ErrorCode.InvalidParameter:
+ {
+ exp = new ArgumentException("Invalid Parameters Provided");
+ break;
+ }
+
+ case ErrorCode.TimedOut:
+ {
+ exp = new TimeoutException("No answer from service");
+ break;
+ }
+
+ case ErrorCode.RecorderBusy:
+ {
+ exp = new InvalidOperationException("Recorder is Busy ");
+ break;
+ }
+
+ case ErrorCode.PermissionDenied:
+ {
+ exp = new UnauthorizedAccessException("Permission Denied");
+ break;
+ }
+
+ case ErrorCode.NotSupported:
+ {
+ exp = new NotSupportedException("VC NOT supported");
+ break;
+ }
+
+ case ErrorCode.InvalidState:
+ {
+ exp = new InvalidOperationException("Invalid state");
+ break;
+ }
+
+ case ErrorCode.InvalidLanguage:
+ {
+ exp = new InvalidOperationException("Invalid language");
+ break;
+ }
+
+ case ErrorCode.EngineNotFound:
+ {
+ exp = new InvalidOperationException("No available engine");
+ break;
+ }
+
+ case ErrorCode.OperationFailed:
+ {
+ exp = new InvalidOperationException("Operation Failed");
+ break;
+ }
+
+ case ErrorCode.OperationRejected:
+ {
+ exp = new InvalidOperationException("Operation Rejected");
+ break;
+ }
+
+ case ErrorCode.IterationEnd:
+ {
+ exp = new InvalidOperationException("List Reached End");
+ break;
+ }
+
+ case ErrorCode.Empty:
+ {
+ exp = new InvalidOperationException("List Empty");
+ break;
+ }
+
+ case ErrorCode.InProgressToReady:
+ {
+ exp = new InvalidOperationException("Progress to ready is not finished");
+ break;
+ }
+
+ case ErrorCode.InProgressToRecording:
+ {
+ exp = new InvalidOperationException("Progress to recording is not finished");
+ break;
+ }
+
+ case ErrorCode.InProgressToProcessing:
+ {
+ exp = new InvalidOperationException("Progress to processing is not finished");
+ break;
+ }
+
+ case ErrorCode.ServiceReset:
+ {
+ exp = new InvalidOperationException("Service reset");
+ break;
+ }
+
+ default:
+ {
+ exp = new Exception("");
+ break;
+ }
+ }
+
+ return exp;
+ }
+ }
+}
diff --git a/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/RecognitionResult.cs b/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/RecognitionResult.cs
new file mode 100755
index 0000000..d3e3103
--- /dev/null
+++ b/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/RecognitionResult.cs
@@ -0,0 +1,83 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using static Interop.VoiceControl;
+using static Interop.VoiceControlCommand;
+
+namespace Tizen.Uix.VoiceControl
+{
+ /// <summary>
+ /// The recognition result from the engine.
+ /// If the duplicated commands are recognized, the event(e.g. Result.Rejected) of command may be rejected
+ /// for selecting command as priority.If you set similar or same commands or the recognized results are multi-results, CommandList has the multi commands.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class RecognitionResult
+ {
+ private ResultEvent _resultEvent;
+ private VoiceCommandList _list;
+ private string _result;
+
+ internal RecognitionResult(ResultEvent evt, IntPtr cmdList, IntPtr result)
+ {
+ _resultEvent = evt;
+ SafeCommandListHandle handle = new SafeCommandListHandle(cmdList);
+ handle._ownership = false;
+ _list = new VoiceCommandList(handle);
+ _result = Marshal.PtrToStringAnsi(result);
+ }
+
+ /// <summary>
+ /// The result event
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ResultEvent Result
+ {
+ get
+ {
+ return _resultEvent;
+ }
+ }
+
+ /// <summary>
+ /// The spoken text
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string ResultMessage
+ {
+ get
+ {
+ return _result;
+ }
+ }
+
+
+ /// <summary>
+ /// The recognized command list
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public VoiceCommandList CommandList
+ {
+ get
+ {
+ return _list;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/RecognitionResultEventArgs.cs b/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/RecognitionResultEventArgs.cs
new file mode 100755
index 0000000..c3fc3dc
--- /dev/null
+++ b/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/RecognitionResultEventArgs.cs
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+
+namespace Tizen.Uix.VoiceControl
+{
+ /// <summary>
+ /// The recognition result from the engine.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class RecognitionResultEventArgs : EventArgs
+ {
+ private RecognitionResult _result;
+ internal RecognitionResultEventArgs(RecognitionResult result)
+ {
+ _result = result;
+ }
+
+ /// <summary>
+ /// Gets the Recognition result
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public RecognitionResult Result
+ {
+ get
+ {
+ return _result;
+ }
+ }
+
+ }
+}
diff --git a/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/ServiceStateChangedEventArgs.cs b/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/ServiceStateChangedEventArgs.cs
new file mode 100755
index 0000000..077c623
--- /dev/null
+++ b/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/ServiceStateChangedEventArgs.cs
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+namespace Tizen.Uix.VoiceControl
+{
+ /// <summary>
+ /// This class holds information related to the VoiceControl service ServiceStateChanged event
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class ServiceStateChangedEventArgs
+ {
+ internal ServiceStateChangedEventArgs(ServiceState previous, ServiceState current)
+ {
+ Previous = previous;
+ Current = current;
+ }
+
+ /// <summary>
+ /// A previous state
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ServiceState Previous
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// A current state
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public ServiceState Current
+ {
+ get;
+ internal set;
+ }
+ }
+}
diff --git a/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/StateChangedEventArgs.cs b/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/StateChangedEventArgs.cs
new file mode 100755
index 0000000..d69e2fe
--- /dev/null
+++ b/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/StateChangedEventArgs.cs
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+namespace Tizen.Uix.VoiceControl
+{
+ /// <summary>
+ /// This class holds information related to the VoiceControl client StateChanged event
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class StateChangedEventArgs
+ {
+ internal StateChangedEventArgs(State previous, State current)
+ {
+ Previous = previous;
+ Current = current;
+ }
+
+ /// <summary>
+ /// A previous state
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public State Previous
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// A current state
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public State Current
+ {
+ get;
+ internal set;
+ }
+ }
+}
diff --git a/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/VoiceCommand.cs b/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/VoiceCommand.cs
new file mode 100755
index 0000000..b6be557
--- /dev/null
+++ b/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/VoiceCommand.cs
@@ -0,0 +1,209 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using static Interop.VoiceControl;
+using static Interop.VoiceControlCommand;
+
+namespace Tizen.Uix.VoiceControl
+{
+ /// <summary>
+ /// Enumeration for Command Format
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CommandFormat
+ {
+ /// <summary>
+ /// fixed command format.
+ /// </summary>
+ Fixed = 0,
+ /// <summary>
+ /// fixed and variable fixed command format.
+ /// </summary>
+ FixedAndVFixed = 1,
+ /// <summary>
+ /// variable fixed and fixed command format.
+ /// </summary>
+ VFixedAndFixed = 2,
+ /// <summary>
+ /// fixed and non-fixed command format.
+ /// </summary>
+ FixedAndNonFixed = 3,
+ /// <summary>
+ /// non-fixed and fixed command format.
+ /// </summary>
+ NonFixedAndFixed = 4,
+ /// <summary>
+ /// Undefined
+ /// </summary>
+ Undefined = 5
+ };
+
+ /// <summary>
+ /// This class represents a Voice Command
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class VoiceCommand
+ {
+ internal SafeCommandHandle _handle;
+
+ /// <summary>
+ /// Public Constructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="InvalidOperationException"> This Exception can be due to Invalid State. </exception>
+ /// <exception cref="OutOfMemoryException"> This Exception can be due to Out Of Memory. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
+ public VoiceCommand()
+ {
+ SafeCommandHandle handle;
+ ErrorCode error = VcCmdCreate(out handle);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Create Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ _handle = handle;
+ }
+
+ internal VoiceCommand(SafeCommandHandle handle)
+ {
+ _handle = handle;
+ }
+
+ /// <summary>
+ /// Gets the unfixed command.
+ /// This property should be used for commands which have non-fixed format.
+ /// empty string will be returned in case of some internal error
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public string UnfixedCommand
+ {
+ get
+ {
+ string unfixedCommand;
+ ErrorCode error = VcCmdGetUnfixedCommand(_handle, out unfixedCommand);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "UnfixedCommand Failed with error " + error);
+ return "";
+ }
+
+ return unfixedCommand;
+ }
+ }
+
+ /// <summary>
+ /// Gets/Sets command type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>If you do not set the command type, the default value is Undefined. You should set type if command is valid</remarks>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
+ public CommandType Type
+ {
+ get
+ {
+ CommandType cmdType = CommandType.Undefined;
+ int type;
+ ErrorCode error = VcCmdGetType(_handle, out type);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "GetType Failed with error " + error);
+ return CommandType.Undefined;
+ }
+
+ if (type != -1)
+ {
+ cmdType = (CommandType)type;
+ }
+
+ return cmdType;
+ }
+ set
+ {
+ ErrorCode error = VcCmdSetType(_handle, value);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "SetType Failed with error " + error);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets/Sets the command format.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>The default format is Fixed</remarks>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
+ public CommandFormat Format
+ {
+ get
+ {
+ CommandFormat format;
+ ErrorCode error = VcCmdGetFormat(_handle, out format);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "GetFormat Failed with error " + error);
+ return CommandFormat.Undefined;
+ }
+
+ return format;
+ }
+ set
+ {
+ ErrorCode error = VcCmdSetFormat(_handle, value);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "SetFormat Failed with error " + error);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets/Sets command
+ /// in case of get empty string will be returned in case of some internal error
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
+ public string Command
+ {
+ get
+ {
+ string command;
+ ErrorCode error = VcCmdGetCommand(_handle, out command);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "GetCommand Failed with error " + error);
+ return "";
+ }
+
+ return command;
+ }
+ set
+ {
+ ErrorCode error = VcCmdSetCommand(_handle, value);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "SetCommand Failed with error " + error);
+ }
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/VoiceCommandList.cs b/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/VoiceCommandList.cs
new file mode 100755
index 0000000..f3b962f
--- /dev/null
+++ b/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/VoiceCommandList.cs
@@ -0,0 +1,337 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Collections.Generic;
+using static Interop.VoiceControl;
+using static Interop.VoiceControlCommand;
+
+namespace Tizen.Uix.VoiceControl
+{
+ /// <summary>
+ /// this class represents list of Voice Commands
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public class VoiceCommandList
+ {
+ internal SafeCommandListHandle _handle;
+ private List<VoiceCommand> _list;
+ private VcCmdListCb _callback;
+
+ /// <summary>
+ /// Public Constructor
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <privlevel>
+ /// public
+ /// </privlevel>
+ /// <feature>
+ /// http://tizen.org/feature/speech.control
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <exception cref="OutOfMemoryException"> This Exception can be due to Out of memory. </exception>
+ /// <exception cref="ArgumentException"> This Exception can be due to Invalid Parameter. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
+ public VoiceCommandList()
+ {
+ SafeCommandListHandle handle;
+ ErrorCode error = VcCmdListCreate(out handle);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Create Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ _handle = handle;
+ }
+
+ internal VoiceCommandList(SafeCommandListHandle handle)
+ {
+ _handle = handle;
+ }
+
+ /// <summary>
+ /// Gets command count of list.
+ /// -1 is returned in case of internal failure.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// Command counts of the list.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <privlevel>
+ /// public
+ /// </privlevel>
+ public int Count
+ {
+ get
+ {
+ int count;
+ ErrorCode error = VcCmdListGetCount(_handle, out count);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Count Failed with error " + error);
+ return -1;
+ }
+
+ return count;
+ }
+ }
+
+ /// <summary>
+ /// Get current command from command list by index.
+ /// null will be returned in case of Empty List
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// Current command from the command list.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <privlevel>
+ /// public
+ /// </privlevel>
+ public VoiceCommand Current
+ {
+ get
+ {
+ SafeCommandHandle current;
+ ErrorCode error = VcCmdListGetCurrent(_handle, out current);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Current Failed with error " + error);
+ return null;
+ }
+ current._ownership = false;
+ return new VoiceCommand(current);
+ }
+ }
+
+ /// <summary>
+ /// Adds command to command list.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <privlevel>
+ /// public
+ /// </privlevel>
+ /// <feature>
+ /// http://tizen.org/feature/speech.control
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <param name="command">The command</param>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
+ /// <exception cref="NullReferenceException"> This will occur if the provide parameter is null. </exception>
+ public void Add(VoiceCommand command)
+ {
+ ErrorCode error = VcCmdListAdd(_handle, command._handle);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Add Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+
+ /// <summary>
+ /// Removes command from command list.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <privlevel>
+ /// public
+ /// </privlevel>
+ /// <feature>
+ /// http://tizen.org/feature/speech.control
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <param name="command">The command</param>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
+ /// <exception cref="NullReferenceException"> This will occur if the provide parameter is null. </exception>
+ public void Remove(VoiceCommand command)
+ {
+ ErrorCode error = VcCmdListRemove(_handle, command._handle);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Remove Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+
+ /// <summary>
+ /// Retrieves all commands of command list.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <privlevel>
+ /// public
+ /// </privlevel>
+ /// <feature>
+ /// http://tizen.org/feature/speech.control
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
+ public IEnumerable<VoiceCommand> GetAllCommands()
+ {
+ _list = new List<VoiceCommand>();
+ _callback = (IntPtr vcCommand, IntPtr userData) =>
+ {
+ SafeCommandHandle handle = new SafeCommandHandle(vcCommand);
+ handle._ownership = false;
+ _list.Add(new VoiceCommand(handle));
+ return true;
+ };
+ ErrorCode error = VcCmdListForeachCommands(_handle, _callback, IntPtr.Zero);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "GetAllCommands Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+
+ return _list;
+ }
+
+ /// <summary>
+ /// Moves index to first command.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <privlevel>
+ /// public
+ /// </privlevel>
+ /// <feature>
+ /// http://tizen.org/feature/speech.control
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <exception cref="InvalidOperationException"> This Exception can be due to List Empty. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
+ public void First()
+ {
+ ErrorCode error = VcCmdListFirst(_handle);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "First Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+
+ /// <summary>
+ /// Moves index to last command.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <privlevel>
+ /// public
+ /// </privlevel>
+ /// <feature>
+ /// http://tizen.org/feature/speech.control
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <exception cref="InvalidOperationException"> This Exception can be due to List Empty. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
+ public void Last()
+ {
+ ErrorCode error = VcCmdListLast(_handle);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Last Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+
+ /// <summary>
+ /// Moves index to next command.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <privlevel>
+ /// public
+ /// </privlevel>
+ /// <feature>
+ /// http://tizen.org/feature/speech.control
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can be due to the following reaons
+ /// 1. List Empty
+ /// 2. List reached end
+ /// </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
+ public void Next()
+ {
+ ErrorCode error = VcCmdListNext(_handle);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Next Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+
+ /// <summary>
+ /// Moves index to previous command.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <privlevel>
+ /// public
+ /// </privlevel>
+ /// <feature>
+ /// http://tizen.org/feature/speech.control
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <exception cref="InvalidOperationException">
+ /// This Exception can be due to the following reaons
+ /// 1. List Empty
+ /// 2. List reached end
+ /// </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
+ public void Previous()
+ {
+ ErrorCode error = VcCmdListPrev(_handle);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Previous Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/VoiceControlClient.cs b/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/VoiceControlClient.cs
new file mode 100755
index 0000000..4b8638d
--- /dev/null
+++ b/src/Tizen.Uix.VoiceControl/Tizen.Uix.VoiceControl/VoiceControlClient.cs
@@ -0,0 +1,958 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using static Interop.VoiceControl;
+using static Interop.VoiceControlCommand;
+
+namespace Tizen.Uix.VoiceControl
+{
+ /// <summary>
+ /// Enum for Error values that can occur
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum Error
+ {
+ /// <summary>
+ /// Successful, No error
+ /// </summary>
+ None,
+ /// <summary>
+ /// Out of Memory
+ /// </summary>
+ OutOfMemory,
+ /// <summary>
+ /// I/O error
+ /// </summary>
+ IoError,
+ /// <summary>
+ /// Invalid parameter
+ /// </summary>
+ InvalidParameter,
+ /// <summary>
+ /// No answer from the STT service
+ /// </summary>
+ TimedOut,
+ /// <summary>
+ /// Device or resource busy
+ /// </summary>
+ RecorderBusy,
+ /// <summary>
+ /// Permission denied
+ /// </summary>
+ PermissionDenied,
+ /// <summary>
+ /// VC NOT supported
+ /// </summary>
+ NotSupported,
+ /// <summary>
+ /// Invalid state
+ /// </summary>
+ InvalidState,
+ /// <summary>
+ /// Invalid language
+ /// </summary>
+ InvalidLanguage,
+ /// <summary>
+ /// No available engine
+ /// </summary>
+ EngineNotFound,
+ /// <summary>
+ /// Operation failed
+ /// </summary>
+ OperationFailed,
+ /// <summary>
+ /// Operation Rejected
+ /// </summary>
+ OperationRejected,
+ /// <summary>
+ /// List reached end
+ /// </summary>
+ IterationEnd,
+ /// <summary>
+ /// List Empty
+ /// </summary>
+ Empty,
+ /// <summary>
+ /// Service reset
+ /// </summary>
+ ServiceReset,
+ /// <summary>
+ /// Progress to ready is not finished
+ /// </summary>
+ InProgressToReady,
+ /// <summary>
+ /// Progress to recording is not finished
+ /// </summary>
+ InProgressToRecording,
+ /// <summary>
+ /// Progress to processing is not finished
+ /// </summary>
+ InProgressToProcessing
+ };
+
+ /// <summary>
+ /// Enumeration for the client state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum State
+ {
+ /// <summary>
+ /// 'None' state
+ /// </summary>
+ None = 0,
+ /// <summary>
+ /// 'Initialized' state
+ /// </summary>
+ Initialized = 1,
+ /// <summary>
+ /// 'Ready' state
+ /// </summary>
+ Ready = 2,
+ /// <summary>
+ /// state cannot be determined
+ /// </summary>
+ Unavailable
+ };
+
+ /// <summary>
+ /// Enumerations of service state.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum ServiceState
+ {
+ /// <summary>
+ /// 'None' state
+ /// </summary>
+ None = 0,
+ /// <summary>
+ /// 'Ready' state
+ /// </summary>
+ Ready = 1,
+ /// <summary>
+ /// 'Recording' state
+ /// </summary>
+ Recording = 2,
+ /// <summary>
+ /// 'Processing' state
+ /// </summary>
+ Processing = 3,
+ /// <summary>
+ /// state cannot be determined
+ /// </summary>
+ Unavailable
+ };
+
+ /// <summary>
+ /// Enumerations of result event.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum ResultEvent
+ {
+ /// <summary>
+ /// Normal result
+ /// </summary>
+ Success = 0,
+ /// <summary>
+ /// Rejected result
+ /// </summary>
+ Rejected = 1
+ };
+
+ /// <summary>
+ /// Enumerations of command type.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public enum CommandType
+ {
+ /// <summary>
+ /// Foreground command by client
+ /// </summary>
+ Foreground = 1,
+ /// <summary>
+ /// Background command by client
+ /// </summary>
+ Background = 2,
+ /// <summary>
+ /// Undefined command
+ /// </summary>
+ Undefined = -1
+ };
+
+ /// <summary>
+ /// A main function of Voice Control API register command and gets notification for recognition result.
+ /// Applications can add their own commands and be provided result when their command is recognized by user voice input.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ public static class VoiceControlClient
+ {
+ /// <summary>
+ /// Called when client gets the recognition result.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <remarks>
+ /// If the duplicated commands are recognized, the event(e.g. Result.Rejected) of command may be rejected
+ /// for selecting command as priority.If you set similar or same commands or the recognized results are multi-results, cmdList has the multi commands.
+ /// </remarks>
+ /// <param name="evt">The ResultEvent</param>
+ /// <param name="cmdList">Command List</param>
+ /// <param name="result">Result</param>
+
+ private static event EventHandler<RecognitionResultEventArgs> _recognitionResult;
+ private static event EventHandler<StateChangedEventArgs> _stateChanged;
+ private static event EventHandler<ServiceStateChangedEventArgs> _serviceStateChanged;
+ private static event EventHandler<ErrorOccuredEventArgs> _errorOccured;
+ private static event EventHandler<CurrentLanguageChangedEventArgs> _currentLanguageChanged;
+ private static VcResultCb s_resultDelegate;
+ private static VcStateChangedCb s_stateDelegate;
+ private static VcServiceStateChangedCb s_serviceStateDelegate;
+ private static VcErrorCb s_errorDelegate;
+ private static VcCurrentLanguageChangedCb s_languageDelegate;
+ private static List<string> s_supportedLanguages;
+ private static VcSupportedLanguageCb s_supportedLanguagesCb;
+ private static VcResultCb s_resultCb;
+ private static RecognitionResult s_recognitionResult;
+
+ /// <summary>
+ /// Gets current language.
+ /// A language is specified as an ISO 3166 alpha-2 two letter country-code
+ /// followed by ISO 639-1 for the two-letter language code.
+ /// For example, "ko_KR" for Korean, "en_US" for American English.
+ /// Empty string is returned incase of some internal error
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// Current language in voice control.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <pre>
+ /// The State must be Initialized or Ready.
+ /// </pre>
+ public static string CurrentLanguage
+ {
+ get
+ {
+ string currentLanguage;
+
+ ErrorCode error = VcGetCurrentLanguage(out currentLanguage);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "CurrentLanguage Failed with error " + error);
+ return "";
+ }
+
+ return currentLanguage;
+ }
+ }
+
+ /// <summary>
+ /// Gets current state of voice control client.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// Current state of voice control client.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <pre>
+ /// The State must be Initialized or Ready.
+ /// </pre>
+ public static State State
+ {
+ get
+ {
+ State state;
+
+ ErrorCode error = VcGetState(out state);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "State Failed with error " + error);
+ return State.Unavailable;
+ }
+
+ return state;
+ }
+ }
+
+ /// <summary>
+ /// Gets current state of voice control service.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <value>
+ /// Current state of voice control service.
+ /// </value>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <pre>
+ /// The State must be Ready.
+ /// </pre>
+ public static ServiceState ServiceState
+ {
+ get
+ {
+ ServiceState state;
+
+ ErrorCode error = VcGetServiceState(out state);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "ServiceState Failed with error " + error);
+ return ServiceState.Unavailable;
+ }
+
+ return state;
+ }
+ }
+
+ /// <summary>
+ /// Sets the invocation name.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <privlevel>
+ /// public
+ /// </privlevel>
+ /// <feature>
+ /// http://tizen.org/feature/speech.control
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <remarks>
+ /// Invocation name is used to activate background commands. The invocation name can be the same as the application name or any other phrase.
+ /// For example, an application "Tizen Sample" has a background command, "Play music", and the invocation name of the application is set to "Tizen Sample".
+ /// In order to activate the background command, users can say "Tizen Sample, Play music". The invocation name is dependent on the current language.
+ /// For example, if the current language is "en_US"(English), the invocation name is also "en_US".
+ /// If the current language is "ja_JP"(Japanese) and the invocation name is "en_US", the invocation name will not be recognized.
+ /// This function should be called before SetCommandList().
+ /// </remarks>
+ /// <param name="name">Invocation name that an application wants to be invoked by</param>
+ /// <exception cref="InvalidOperationException"> This Exception can be due to Invalid State. </exception>
+ /// <exception cref="ArgumentException"> This Exception can be due to Invalid Parameter. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <pre>
+ /// The State must be Ready.
+ /// </pre>
+ public static void SetInvocationName(string name)
+ {
+ ErrorCode error = VcSetInvocationName(name);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "SetInvocationName Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+
+ /// <summary>
+ /// Initializes voice control.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <privlevel>
+ /// public
+ /// </privlevel>
+ /// <feature>
+ /// http://tizen.org/feature/speech.control
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <exception cref="InvalidOperationException"> This Exception can be due to Operation Failed. </exception>
+ /// <exception cref="OutOfMemoryException"> This Exception can be due to Out Of Memory. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <post>
+ /// The State will be Initialized.
+ /// </post>
+ public static void Initialize()
+ {
+ ErrorCode error = VcInitialize();
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Initialize Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+
+ /// <summary>
+ /// Deinitializes voice control.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <privlevel>
+ /// public
+ /// </privlevel>
+ /// <feature>
+ /// http://tizen.org/feature/speech.control
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <exception cref="InvalidOperationException"> This Exception can be due to Invalid State. </exception>
+ /// <exception cref="InvalidOperationException"> This Exception can be due to Operation Failed. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ public static void Deinitialize()
+ {
+ ErrorCode error = VcDeinitialize();
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Deinitialize Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+
+ /// <summary>
+ /// Connects the voice control service.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <privlevel>
+ /// public
+ /// </privlevel>
+ /// <feature>
+ /// http://tizen.org/feature/speech.control
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <exception cref="InvalidOperationException"> This Exception can be due to Invalid State. </exception>
+ /// <exception cref="InvalidOperationException"> This Exception can be due to Operation Failed. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <pre>
+ /// The State should be Initialized
+ /// </pre>
+ /// <post>
+ /// The State will be Ready
+ /// </post>
+ public static void Prepare()
+ {
+ ErrorCode error = VcPrepare();
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Prepare Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+
+ /// <summary>
+ /// Disconnects the voice control service.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <privlevel>
+ /// public
+ /// </privlevel>
+ /// <feature>
+ /// http://tizen.org/feature/speech.control
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <exception cref="InvalidOperationException"> This Exception can be due to Invalid State. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <pre>
+ /// The State should be Ready
+ /// </pre>
+ /// <post>
+ /// The State should be Initialized
+ /// </post>
+ public static void Unprepare()
+ {
+ ErrorCode error = VcUnprepare();
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Unprepare Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+
+ /// <summary>
+ /// Retrieves all supported languages.
+ /// A language is specified as an ISO 3166 alpha-2 two letter country-code
+ /// followed by ISO 639-1 for the two-letter language code.
+ /// For example, "ko_KR" for Korean, "en_US" for American English.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <privlevel>
+ /// public
+ /// </privlevel>
+ /// <feature>
+ /// http://tizen.org/feature/speech.control
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <exception cref="InvalidOperationException"> This Exception can be due to Invalid State. </exception>
+ /// <exception cref="InvalidOperationException"> This Exception can be due to Operation Failed. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <pre>
+ /// The State should be Ready or Initialized
+ /// </pre>
+ public static IEnumerable<string> GetSupportedLanguages()
+ {
+ s_supportedLanguages = new List<string>();
+ s_supportedLanguagesCb = (IntPtr language, IntPtr userData) =>
+ {
+ string languageStr = Marshal.PtrToStringAnsi(language);
+ s_supportedLanguages.Add(languageStr);
+ return true;
+ };
+ ErrorCode error = VcForeachSupportedLanguages(s_supportedLanguagesCb, IntPtr.Zero);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "GetSupportedLanguages Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+
+ return s_supportedLanguages;
+ }
+
+ /// <summary>
+ /// Gets the system command list.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <returns>
+ /// The Command List else null in case of no System Commands
+ /// </returns>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <privlevel>
+ /// public
+ /// </privlevel>
+ /// <feature>
+ /// http://tizen.org/feature/speech.control
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <remarks>
+ /// In the system command list, there are system commands predefined by product manufacturers.
+ /// Those commands have the highest priority. Therefore, the user can not set any commands same with the system commands.
+ /// </remarks>
+ /// <exception cref="InvalidOperationException"> This Exception can be due to Invalid State. </exception>
+ /// <exception cref="InvalidOperationException"> This Exception can be due to Operation Failed. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <pre>
+ /// The State should be Ready
+ /// </pre>
+ public static VoiceCommandList GetSystemCommandList()
+ {
+ IntPtr handle = IntPtr.Zero;
+ ErrorCode error = VcGetSystemCommandList(out handle);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "GetSystemCommandList Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+
+ if (handle == IntPtr.Zero)
+ {
+ Log.Error(LogTag, "GetSystemCommandList handle is null");
+ return null;
+ }
+
+ SafeCommandListHandle list = new SafeCommandListHandle(handle);
+ return new VoiceCommandList(list);
+ }
+
+ /// <summary>
+ /// Requests to start the dialogue.
+ /// Using this function, the developer can request starting the dialogue to the framework.
+ /// When the developer requests the dialogue, two types of texts, dispText and uttText, can be sent by this function.dispText is a text for displaying, and uttText is that for uttering.
+ /// For example, if dispText is "October 10th" and uttText is "Today is October 10th.", "October 10th" will be displayed on the screen and "Today is October 10th." will be spoken.
+ /// Also, the developer can set whether the dialogue starts automatically or not, using autoStart.
+ /// If the developer sets autoStart as true, the framework will start to record next speech and continue the dialogue.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <privlevel>
+ /// public
+ /// </privlevel>
+ /// <feature>
+ /// http://tizen.org/feature/speech.control
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <remarks>
+ /// If autoStart is true, the recognition will start again. In this case, it can be restarted up to 4 times.
+ /// </remarks>
+ /// <param name="dispText"> Text to be displayed on the screen/// </param>
+ /// <param name="uttText">Text to be spoken</param>
+ /// <param name="autoStart">A variable for setting whether the dialog session will be restarted automatically or not</param>
+ /// <exception cref="InvalidOperationException"> This Exception can be due to Invalid State. </exception>
+ /// <exception cref="ArgumentException"> This Exception can be due to Invalid Parameter. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <pre>
+ /// The State should be Ready
+ /// </pre>
+ public static void RequestDialog(string dispText, string uttText, bool autoStart)
+ {
+ ErrorCode error = VcRequestDialog(dispText, uttText, autoStart);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "RequestDialog Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+
+ /// <summary>
+ /// Sets command list.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <privlevel>
+ /// public
+ /// </privlevel>
+ /// <feature>
+ /// http://tizen.org/feature/speech.control
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <remarks>
+ /// The command type is valid for CommandType 'Foreground' or 'Background'.
+ /// The matched commands of command list should be set and they should include type and command text at least.
+ /// </remarks>
+ /// <param name="list">Command list</param>
+ /// <param name="type">Command type</param>
+ /// <exception cref="InvalidOperationException"> This Exception can be due to Invalid State. </exception>
+ /// <exception cref="ArgumentException"> This Exception can be due to Invalid Parameter. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <pre>
+ /// The State should be Ready
+ /// </pre>
+ public static void SetCommandList(VoiceCommandList list, CommandType type)
+ {
+ if ((type == CommandType.Foreground) || (type == CommandType.Background))
+ {
+ ErrorCode error = VcSetCommandList(list._handle, (VoiceCommandType)type);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "SetCommandList Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+
+ else
+ {
+ throw ExceptionFactory.CreateException(ErrorCode.InvalidParameter);
+ }
+ }
+
+ /// <summary>
+ /// Unsets command list.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <privlevel>
+ /// public
+ /// </privlevel>
+ /// <feature>
+ /// http://tizen.org/feature/speech.control
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <param name="type">Command type</param>
+ /// <exception cref="InvalidOperationException"> This Exception can be due to Invalid State. </exception>
+ /// <exception cref="ArgumentException"> This Exception can be due to Invalid Parameter. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
+ /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
+ /// <pre>
+ /// The State should be Ready
+ /// </pre>
+ public static void UnsetCommandList(CommandType type)
+ {
+ if ((type == CommandType.Foreground) || (type == CommandType.Background))
+ {
+ VoiceCommandType commandType = VoiceCommandType.Foreground;
+ if (type == CommandType.Background)
+ commandType = VoiceCommandType.BackGround;
+ ErrorCode error = VcUnsetCommandList(commandType);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "UnsetCommandList Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+ }
+
+ else
+ {
+ throw ExceptionFactory.CreateException(ErrorCode.InvalidParameter);
+ }
+ }
+
+ /// <summary>
+ /// Gets the recognition result.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <privilege>
+ /// http://tizen.org/privilege/recorder
+ /// </privilege>
+ /// <privlevel>
+ /// public
+ /// </privlevel>
+ /// <feature>
+ /// http://tizen.org/feature/speech.control
+ /// http://tizen.org/feature/microphone
+ /// </feature>
+ /// <exception cref="InvalidOperationException"> This Exception can be due to Invalid State. </exception>
+ /// <exception cref="ArgumentException"> This Exception can be due to Invalid Parameter. </exception>
+ /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
+ /// <returns>The Recognition Result if possible else a null object</returns>
+ /// <pre>
+ /// The State should be Ready
+ /// </pre>
+ public static RecognitionResult GetResult()
+ {
+ s_recognitionResult = null;
+ s_resultCb = (ResultEvent evt, IntPtr cmdList, IntPtr result, IntPtr userData) =>
+ {
+ s_recognitionResult = new RecognitionResult(evt, cmdList, result);
+ };
+ ErrorCode error = VcGetResult(s_resultCb, IntPtr.Zero);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "GetResult Failed with error " + error);
+ throw ExceptionFactory.CreateException(error);
+ }
+
+ return s_recognitionResult;
+ }
+
+ /// <summary>
+ /// Event to be invoked when the recognition is done.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <pre>
+ /// The State should be Initialized
+ /// </pre>
+ public static event EventHandler<RecognitionResultEventArgs> RecognitionResult
+ {
+ add
+ {
+ s_resultDelegate = (ResultEvent evt, IntPtr cmdList, IntPtr result, IntPtr userData) =>
+ {
+ Log.Info(LogTag, "Recognition Result Event Triggered");
+ if ((cmdList != null) && (result != null))
+ {
+ RecognitionResultEventArgs args = new RecognitionResultEventArgs(new RecognitionResult( evt, cmdList, result));
+ _recognitionResult?.Invoke(null, args);
+ }
+ else
+ {
+ Log.Info(LogTag, "Recognition Result Event null received");
+ }
+ };
+ ErrorCode error = VcSetResultCb(s_resultDelegate, IntPtr.Zero);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Add RecognitionResult Failed with error " + error);
+ }
+ else
+ {
+ _recognitionResult += value;
+ }
+ }
+
+ remove
+ {
+ ErrorCode error = VcUnsetResultCb();
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Remove RecognitionResult Failed with error " + error);
+ }
+
+ _recognitionResult -= value;
+ }
+ }
+
+ /// <summary>
+ /// Event to be invoked when VoiceControl service state changes.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <pre>
+ /// The State should be Initialized
+ /// </pre>
+ public static event EventHandler<ServiceStateChangedEventArgs> ServiceStateChanged
+ {
+ add
+ {
+ s_serviceStateDelegate = (ServiceState previous, ServiceState current, IntPtr userData) =>
+ {
+ ServiceStateChangedEventArgs args = new ServiceStateChangedEventArgs(previous, current);
+ _serviceStateChanged?.Invoke(null, args);
+ };
+ ErrorCode error = VcSetServiceStateChangedCb(s_serviceStateDelegate, IntPtr.Zero);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Add ServiceStateChanged Failed with error " + error);
+ }
+ else
+ {
+ _serviceStateChanged += value;
+ }
+ }
+
+ remove
+ {
+ ErrorCode error = VcUnsetServiceStateChangedCb();
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Remove ServiceStateChanged Failed with error " + error);
+ }
+
+ _serviceStateChanged -= value;
+ }
+ }
+
+ /// <summary>
+ /// Event to be invoked when VoiceControl client state changes.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <pre>
+ /// The State should be Initialized
+ /// </pre>
+ public static event EventHandler<StateChangedEventArgs> StateChanged
+ {
+ add
+ {
+ s_stateDelegate = (State previous, State current, IntPtr userData) =>
+ {
+ StateChangedEventArgs args = new StateChangedEventArgs(previous, current);
+ _stateChanged?.Invoke(null, args);
+ };
+ ErrorCode error = VcSetStateChangedCb(s_stateDelegate, IntPtr.Zero);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Add StateChanged Failed with error " + error);
+ }
+ else
+ {
+ _stateChanged += value;
+ }
+ }
+
+ remove
+ {
+ ErrorCode error = VcUnsetStateChangedCb();
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Remove StateChanged Failed with error " + error);
+ }
+
+ _stateChanged -= value;
+ }
+ }
+
+ /// <summary>
+ /// Event to be invoked when an error occurs.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <pre>
+ /// The State should be Initialized
+ /// </pre>
+ public static event EventHandler<ErrorOccuredEventArgs> ErrorOccured
+ {
+ add
+ {
+ s_errorDelegate = (ErrorCode reason, IntPtr userData) =>
+ {
+ ErrorOccuredEventArgs args = new ErrorOccuredEventArgs(reason);
+ _errorOccured?.Invoke(null, args);
+ };
+ ErrorCode error = VcSetErrorCb(s_errorDelegate, IntPtr.Zero);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Add ErrorOccured Failed with error " + error);
+ }
+
+ else
+ {
+ _errorOccured += value;
+ }
+ }
+
+
+ remove
+ {
+ ErrorCode error = VcUnsetErrorCb();
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Remove ErrorOccured Failed with error " + error);
+ }
+
+ _errorOccured -= value;
+ }
+ }
+
+ /// <summary>
+ /// Event to be invoked when default laungage change.
+ /// </summary>
+ /// <since_tizen> 3 </since_tizen>
+ /// <pre>
+ /// The State should be Initialized
+ /// </pre>
+ public static event EventHandler<CurrentLanguageChangedEventArgs> CurrentLanguageChanged
+ {
+ add
+ {
+ s_languageDelegate = (IntPtr previousLanguage, IntPtr currentLanguage, IntPtr userData) =>
+ {
+ string previousLanguageString = Marshal.PtrToStringAnsi(previousLanguage);
+ string currentLanguageString = Marshal.PtrToStringAnsi(currentLanguage);
+ CurrentLanguageChangedEventArgs args = new CurrentLanguageChangedEventArgs(previousLanguageString, currentLanguageString);
+ _currentLanguageChanged?.Invoke(null, args);
+ };
+ ErrorCode error = VcSetCurrentLanguageChangedCb(s_languageDelegate, IntPtr.Zero);
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Add CurrentLanguageChanged Failed with error " + error);
+ }
+
+ else
+ {
+ _currentLanguageChanged += value;
+ }
+ }
+
+ remove
+ {
+ ErrorCode error = VcUnsetCurrentLanguageChangedCb();
+ if (error != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Remove CurrentLanguageChanged Failed with error " + error);
+ }
+
+ _currentLanguageChanged -= value;
+ }
+ }
+ }
+}
diff --git a/src/Tizen.WebView/Interop/Interop.ChromiumEwk.Context.cs b/src/Tizen.WebView/Interop/Interop.ChromiumEwk.Context.cs
new file mode 100644
index 0000000..7930e1c
--- /dev/null
+++ b/src/Tizen.WebView/Interop/Interop.ChromiumEwk.Context.cs
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class ChromiumEwk
+ {
+ public enum CacheModel
+ {
+ DocumentViewer,
+ DocumentBrowser,
+ PrimaryWebBrowser
+ }
+
+ [DllImport(Libraries.ChromiumEwk)]
+ internal static extern IntPtr ewk_context_cookie_manager_get(IntPtr context);
+
+ [DllImport(Libraries.ChromiumEwk)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool ewk_context_cache_model_set(IntPtr context, CacheModel model);
+
+ [DllImport(Libraries.ChromiumEwk)]
+ internal static extern CacheModel ewk_context_cache_model_get(IntPtr context);
+ }
+}
diff --git a/src/Tizen.WebView/Interop/Interop.ChromiumEwk.CookieManager.cs b/src/Tizen.WebView/Interop/Interop.ChromiumEwk.CookieManager.cs
new file mode 100644
index 0000000..23fb70e
--- /dev/null
+++ b/src/Tizen.WebView/Interop/Interop.ChromiumEwk.CookieManager.cs
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class ChromiumEwk
+ {
+ public enum CookieAcceptPolicy
+ {
+ Always,
+ Never,
+ NoThirdParty
+ }
+
+ public enum CookiePersistentStorage
+ {
+ Text,
+ SqlLite
+ }
+
+ [DllImport(Libraries.ChromiumEwk)]
+ internal static extern void ewk_cookie_manager_accept_policy_set(IntPtr manager, CookieAcceptPolicy policy);
+
+ [DllImport(Libraries.ChromiumEwk)]
+ internal static extern void ewk_cookie_manager_cookies_clear(IntPtr manager);
+
+ [DllImport(Libraries.ChromiumEwk)]
+ internal static extern void ewk_cookie_manager_persistent_storage_set(IntPtr manager, string path, CookiePersistentStorage storage);
+ }
+}
diff --git a/src/Tizen.WebView/Interop/Interop.ChromiumEwk.Error.cs b/src/Tizen.WebView/Interop/Interop.ChromiumEwk.Error.cs
new file mode 100644
index 0000000..7d22a3d
--- /dev/null
+++ b/src/Tizen.WebView/Interop/Interop.ChromiumEwk.Error.cs
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class ChromiumEwk
+ {
+ [DllImport(Libraries.ChromiumEwk, EntryPoint = "ewk_error_url_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, CharSet = CharSet.Ansi)]
+ internal static extern IntPtr _ewk_error_url_get(IntPtr error);
+
+ internal static string ewk_error_url_get(IntPtr error)
+ {
+ IntPtr ptr = _ewk_error_url_get(error);
+ return Marshal.PtrToStringAnsi(ptr);
+ }
+
+ [DllImport(Libraries.ChromiumEwk)]
+ internal static extern int ewk_error_code_get(IntPtr error);
+
+ [DllImport(Libraries.ChromiumEwk, EntryPoint = "ewk_error_description_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, CharSet = CharSet.Ansi)]
+ internal static extern IntPtr _ewk_error_description_get(IntPtr error);
+
+ internal static string ewk_error_description_get(IntPtr error)
+ {
+ IntPtr ptr = _ewk_error_description_get(error);
+ return Marshal.PtrToStringAnsi(ptr);
+ }
+
+ [DllImport(Libraries.ChromiumEwk)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool ewk_error_cancellation_get(IntPtr error);
+ }
+}
diff --git a/src/Tizen.WebView/Interop/Interop.ChromiumEwk.Settings.cs b/src/Tizen.WebView/Interop/Interop.ChromiumEwk.Settings.cs
new file mode 100644
index 0000000..ab7a5ef
--- /dev/null
+++ b/src/Tizen.WebView/Interop/Interop.ChromiumEwk.Settings.cs
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class ChromiumEwk
+ {
+ [DllImport(Libraries.ChromiumEwk)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool ewk_settings_javascript_enabled_set(IntPtr settings, bool enable);
+
+ [DllImport(Libraries.ChromiumEwk)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool ewk_settings_javascript_enabled_get(IntPtr settings);
+
+ [DllImport(Libraries.ChromiumEwk)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool ewk_settings_loads_images_automatically_set(IntPtr settings, bool enable);
+
+ [DllImport(Libraries.ChromiumEwk)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool ewk_settings_loads_images_automatically_get(IntPtr settings);
+
+ [DllImport(Libraries.ChromiumEwk)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool ewk_settings_default_text_encoding_name_set(IntPtr settings, string encoding);
+
+ [DllImport(Libraries.ChromiumEwk, EntryPoint = "ewk_settings_default_text_encoding_name_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, CharSet = CharSet.Ansi)]
+ internal static extern IntPtr _ewk_settings_default_text_encoding_name_get(IntPtr settings);
+
+ internal static string ewk_settings_default_text_encoding_name_get(IntPtr settings)
+ {
+ IntPtr ptr = _ewk_settings_default_text_encoding_name_get(settings);
+ return Marshal.PtrToStringAnsi(ptr);
+ }
+
+ [DllImport(Libraries.ChromiumEwk)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool ewk_settings_default_font_size_set(IntPtr settings, int size);
+
+ [DllImport(Libraries.ChromiumEwk)]
+ internal static extern int ewk_settings_default_font_size_get(IntPtr settings);
+ }
+}
diff --git a/src/Tizen.WebView/Interop/Interop.ChromiumEwk.View.cs b/src/Tizen.WebView/Interop/Interop.ChromiumEwk.View.cs
new file mode 100644
index 0000000..0f8a17c
--- /dev/null
+++ b/src/Tizen.WebView/Interop/Interop.ChromiumEwk.View.cs
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class ChromiumEwk
+ {
+ [DllImport(Libraries.ChromiumEwk)]
+ internal static extern IntPtr ewk_view_add(IntPtr evas);
+
+ [DllImport(Libraries.ChromiumEwk)]
+ internal static extern IntPtr ewk_view_context_get(IntPtr obj);
+
+ [DllImport(Libraries.ChromiumEwk)]
+ internal static extern IntPtr ewk_view_settings_get(IntPtr obj);
+
+ [DllImport(Libraries.ChromiumEwk)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool ewk_view_url_set(IntPtr obj, string url);
+
+ [DllImport(Libraries.ChromiumEwk, EntryPoint = "ewk_view_url_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, CharSet = CharSet.Ansi)]
+ internal static extern IntPtr _ewk_view_url_get(IntPtr obj);
+
+ internal static string ewk_view_url_get(IntPtr obj)
+ {
+ IntPtr ptr = _ewk_view_url_get(obj);
+ return Marshal.PtrToStringAnsi(ptr);
+ }
+
+ [DllImport(Libraries.ChromiumEwk)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool ewk_view_html_string_load(IntPtr obj, string html, string baseUrl, string unreachableUrl);
+
+ [DllImport(Libraries.ChromiumEwk)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool ewk_view_reload(IntPtr obj);
+
+ [DllImport(Libraries.ChromiumEwk)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool ewk_view_stop(IntPtr obj);
+
+ [DllImport(Libraries.ChromiumEwk)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool ewk_view_back(IntPtr obj);
+
+ [DllImport(Libraries.ChromiumEwk)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool ewk_view_forward(IntPtr obj);
+
+ [DllImport(Libraries.ChromiumEwk)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool ewk_view_back_possible(IntPtr obj);
+
+ [DllImport(Libraries.ChromiumEwk)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool ewk_view_forward_possible(IntPtr obj);
+
+ internal delegate void ScriptExcuteCallback(IntPtr obj, IntPtr resultValue, IntPtr userData);
+
+ [DllImport(Libraries.ChromiumEwk)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool ewk_view_script_execute(IntPtr obj, string script, ScriptExcuteCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.ChromiumEwk, EntryPoint = "ewk_view_title_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, CharSet = CharSet.Ansi)]
+ internal static extern IntPtr _ewk_view_title_get(IntPtr obj);
+
+ internal static string ewk_view_title_get(IntPtr obj)
+ {
+ IntPtr ptr = _ewk_view_url_get(obj);
+ return Marshal.PtrToStringAnsi(ptr);
+ }
+
+ [DllImport(Libraries.ChromiumEwk, EntryPoint = "ewk_view_user_agent_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, CharSet = CharSet.Ansi)]
+ internal static extern IntPtr _ewk_view_user_agent_get(IntPtr obj);
+
+ internal static string ewk_view_user_agent_get(IntPtr obj)
+ {
+ IntPtr ptr = _ewk_view_user_agent_get(obj);
+ return Marshal.PtrToStringAnsi(ptr);
+ }
+
+ [DllImport(Libraries.ChromiumEwk)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool ewk_view_user_agent_set(IntPtr obj, string userAgent);
+
+ [DllImport(Libraries.ChromiumEwk)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool ewk_view_focus_set(IntPtr obj, bool focused);
+
+ [DllImport(Libraries.ChromiumEwk)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool ewk_view_focus_get(IntPtr obj);
+
+ [StructLayout(LayoutKind.Sequential, CharSet =CharSet.Ansi)]
+ internal struct ScriptMessage
+ {
+ public IntPtr name;
+ public IntPtr body;
+ }
+
+ internal delegate void ScriptMessageCallback(IntPtr obj, ScriptMessage message);
+
+ [DllImport(Libraries.ChromiumEwk)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool ewk_view_javascript_message_handler_add(IntPtr obj, ScriptMessageCallback callback, string name);
+
+ [DllImport(Libraries.ChromiumEwk)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool ewk_view_evaluate_javascript(IntPtr obj, string name, string result);
+ }
+}
diff --git a/src/Tizen.WebView/Interop/Interop.ChromiumEwk.cs b/src/Tizen.WebView/Interop/Interop.ChromiumEwk.cs
new file mode 100644
index 0000000..cd9ca31
--- /dev/null
+++ b/src/Tizen.WebView/Interop/Interop.ChromiumEwk.cs
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class ChromiumEwk
+ {
+ [DllImport(Libraries.ChromiumEwk)]
+ internal static extern int ewk_init();
+
+ [DllImport(Libraries.ChromiumEwk)]
+ internal static extern int ewk_shutdown();
+ }
+}
diff --git a/src/Tizen.WebView/Interop/Interop.Elementary.cs b/src/Tizen.WebView/Interop/Interop.Elementary.cs
new file mode 100644
index 0000000..e981fe2
--- /dev/null
+++ b/src/Tizen.WebView/Interop/Interop.Elementary.cs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Elementary
+ {
+ [DllImport(Libraries.Elementary)]
+ internal static extern IntPtr elm_layout_add(IntPtr obj);
+
+ [DllImport(Libraries.Elementary)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool elm_layout_theme_set(IntPtr obj, string klass, string group, string style);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_part_content_set(IntPtr obj, string part, IntPtr content);
+
+ [DllImport(Libraries.Elementary)]
+ internal static extern void elm_object_focus_allow_set(IntPtr obj, bool enable);
+ }
+} \ No newline at end of file
diff --git a/src/Tizen.WebView/Interop/Interop.Evas.cs b/src/Tizen.WebView/Interop/Interop.Evas.cs
new file mode 100644
index 0000000..52eef2c
--- /dev/null
+++ b/src/Tizen.WebView/Interop/Interop.Evas.cs
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Evas
+ {
+ [DllImport(Libraries.Evas)]
+ internal static extern IntPtr evas_object_evas_get(IntPtr obj);
+ }
+}
diff --git a/src/Tizen.WebView/Interop/Interop.Libraries.cs b/src/Tizen.WebView/Interop/Interop.Libraries.cs
new file mode 100644
index 0000000..7dab1c4
--- /dev/null
+++ b/src/Tizen.WebView/Interop/Interop.Libraries.cs
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+internal static partial class Interop
+{
+ private static class Libraries
+ {
+ internal const string ChromiumEwk = "libchromium-ewk.so";
+ internal const string Elementary = "libelementary.so.1";
+ internal const string Evas = "libevas.so.1";
+ }
+}
diff --git a/src/Tizen.WebView/Tizen.WebView.csproj b/src/Tizen.WebView/Tizen.WebView.csproj
new file mode 100644
index 0000000..5efcc98
--- /dev/null
+++ b/src/Tizen.WebView/Tizen.WebView.csproj
@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\ElmSharp\ElmSharp.csproj" />
+ </ItemGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>
diff --git a/src/Tizen.WebView/Tizen.WebView/Chromium.cs b/src/Tizen.WebView/Tizen.WebView/Chromium.cs
new file mode 100644
index 0000000..8511dcd
--- /dev/null
+++ b/src/Tizen.WebView/Tizen.WebView/Chromium.cs
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.WebView
+{
+ public static class Chromium
+ {
+ /// <summary>
+ /// Initializes Chromium's instance
+ /// </summary>
+ /// <returns>A reference count of Chromium's instance</returns>
+ public static int Initialize()
+ {
+ return Interop.ChromiumEwk.ewk_init();
+ }
+
+ /// <summary>
+ /// Decreases a reference count of WebKit's instance, possibly destroying it
+ /// </summary>
+ /// <returns>A reference count of Chromium's instance</returns>
+ public static int Shutdown()
+ {
+ return Interop.ChromiumEwk.ewk_shutdown();
+ }
+ }
+}
diff --git a/src/Tizen.WebView/Tizen.WebView/Context.cs b/src/Tizen.WebView/Tizen.WebView/Context.cs
new file mode 100644
index 0000000..6e58cad
--- /dev/null
+++ b/src/Tizen.WebView/Tizen.WebView/Context.cs
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.WebView
+{
+ /// <summary>
+ /// Enumeration that contains option for cache model.
+ /// </summary>
+ public enum CacheModel
+ {
+ DocumentViewer, /* Use the smallest cache capacity */
+ DocumentBrowser, /* Use bigger cache capacity than DocumentBrowser */
+ PrimaryWebBrowser /* Use the biggest cache capacity. */
+ }
+
+ public class Context
+ {
+ private IntPtr _handle;
+ private CookieManager _cookieManager;
+
+ internal Context(IntPtr handle)
+ {
+ _handle = handle;
+ }
+
+ /// <summary>
+ /// The cache model.
+ /// </summary>
+ /// <remarks>
+ /// The default cache model is DocumentViewer.
+ /// </remarks>
+ public CacheModel CacheModel
+ {
+ get
+ {
+ return (CacheModel)Interop.ChromiumEwk.ewk_context_cache_model_get(_handle);
+ }
+
+ set
+ {
+ Interop.ChromiumEwk.ewk_context_cache_model_set(_handle, (Interop.ChromiumEwk.CacheModel)value);
+ }
+ }
+
+ /// <summary>
+ /// Gets the CookieManager object for this context.
+ /// </summary>
+ /// <returns>The CookieManager object</returns>
+ public CookieManager GetCookieManager()
+ {
+ if (_cookieManager == null)
+ {
+ IntPtr cookieManagerHandle = Interop.ChromiumEwk.ewk_context_cookie_manager_get(_handle);
+ if (cookieManagerHandle == IntPtr.Zero)
+ {
+ return null;
+ }
+ _cookieManager = new CookieManager(cookieManagerHandle);
+ }
+ return _cookieManager;
+ }
+ }
+}
diff --git a/src/Tizen.WebView/Tizen.WebView/CookieManager.cs b/src/Tizen.WebView/Tizen.WebView/CookieManager.cs
new file mode 100644
index 0000000..487e88b
--- /dev/null
+++ b/src/Tizen.WebView/Tizen.WebView/CookieManager.cs
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+
+namespace Tizen.WebView
+{
+ /// <summary>
+ /// Enumeration that contains accept policies for the cookies.
+ /// </summary>
+ public enum CookieAcceptPolicy
+ {
+ Always, /* Accepts every cookie sent from any page */
+ Never, /* Rejects all cookies */
+ NoThirdParty /* Accepts only cookies set by the main document loaded */
+ }
+
+ /// <summary>
+ /// Enumeration that creates a type name for the storage of persistent cookies.
+ /// </summary>
+ public enum CookiePersistentStorage
+ {
+ Text, /* Cookies are stored in a text file in the Mozilla "cookies.txt" format */
+ SqlLite /* Cookies are stored in a SQLite file in the current Mozilla format. */
+ }
+
+ public class CookieManager
+ {
+ private IntPtr _handle;
+
+ internal CookieManager(IntPtr handle)
+ {
+ _handle = handle;
+ }
+
+ /// <summary>
+ /// Sets the cookie acceptance policy.
+ /// </summary>
+ /// <remarks>
+ /// By default, only cookies set by the main document loaded are accepted.
+ /// </remarks>
+ /// <param name="policy">The cookie acceptance policy</param>
+ public void SetCookieAcceptPolicy(CookieAcceptPolicy policy)
+ {
+ Interop.ChromiumEwk.ewk_cookie_manager_accept_policy_set(_handle, (Interop.ChromiumEwk.CookieAcceptPolicy)policy);
+ }
+
+ /// <summary>
+ /// Deletes all the cookies.
+ /// </summary>
+ public void ClearCookies()
+ {
+ Interop.ChromiumEwk.ewk_cookie_manager_cookies_clear(_handle);
+ }
+
+ /// <summary>
+ /// Sets the storage where non-session cookies are stored persistently to read/write the cookies.
+ /// </summary>
+ ///<privilege>
+ /// http://tizen.org/privilege/mediastorage
+ /// http://tizen.org/privilege/externalstorage
+ /// </privilege>
+ /// <param name="path">The path where to read/write Cookies</param>
+ /// <param name="storage">The type of storage</param>
+ public void SetPersistentStorage(string path, CookiePersistentStorage storage)
+ {
+ Interop.ChromiumEwk.ewk_cookie_manager_persistent_storage_set(_handle, path, (Interop.ChromiumEwk.CookiePersistentStorage)storage);
+ }
+ }
+}
diff --git a/src/Tizen.WebView/Tizen.WebView/JavaScriptMessage.cs b/src/Tizen.WebView/Tizen.WebView/JavaScriptMessage.cs
new file mode 100644
index 0000000..07454ed
--- /dev/null
+++ b/src/Tizen.WebView/Tizen.WebView/JavaScriptMessage.cs
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace Tizen.WebView
+{
+ public delegate void JavaScriptMessageHandler(JavaScriptMessage message);
+
+ /// <summary>
+ /// A Script message contains information that sent from JavaScript runtime.
+ /// </summary>
+ public class JavaScriptMessage
+ {
+ private string _name;
+ private IntPtr _body;
+
+ internal JavaScriptMessage(Interop.ChromiumEwk.ScriptMessage message)
+ {
+ _name = Marshal.PtrToStringAnsi(message.name);
+ _body = message.body;
+ }
+
+ /// <summary>
+ /// Obect name in JavaScript.
+ /// </summary>
+ public string Name
+ {
+ get
+ {
+ return _name;
+ }
+ }
+
+ /// <summary>
+ /// Gets the value of body as integer type.
+ /// </summary>
+ /// <returns>The value of body as integer type</returns>
+ public int GetBodyAsInteger()
+ {
+ if (_body == IntPtr.Zero)
+ {
+ return 0;
+ }
+ return Marshal.ReadInt32(_body, 0);
+ }
+
+ /// <summary>
+ /// Gets the value of body as double type.
+ /// </summary>
+ /// <returns>The value of body as double type</returns>
+ public double GetBodyAsDouble()
+ {
+ if (_body == IntPtr.Zero)
+ {
+ return 0d;
+ }
+ double[] ret = new double[1] ;
+ Marshal.Copy(_body, ret, 0, 1);
+ return ret[0];
+ }
+
+ /// <summary>
+ /// Gets the value of body as boolean type.
+ /// </summary>
+ /// <returns>The value of body as boolean type</returns>
+ public bool GetBodyAsBoolean()
+ {
+ if (_body == IntPtr.Zero)
+ {
+ return false;
+ }
+ return Marshal.ReadByte(_body) != (byte)0;
+ }
+
+ /// <summary>
+ /// Gets the value of body as string type.
+ /// </summary>
+ /// <returns>The value of body as string type</returns>
+ public string GetBodyAsString()
+ {
+ if (_body == IntPtr.Zero)
+ {
+ return string.Empty;
+ }
+ return Marshal.PtrToStringAnsi(_body);
+ }
+ }
+}
diff --git a/src/Tizen.WebView/Tizen.WebView/Settings.cs b/src/Tizen.WebView/Tizen.WebView/Settings.cs
new file mode 100644
index 0000000..8e1f349
--- /dev/null
+++ b/src/Tizen.WebView/Tizen.WebView/Settings.cs
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.WebView
+{
+ public class Settings
+ {
+ private IntPtr _handle;
+
+ internal Settings(IntPtr handle)
+ {
+ _handle = handle;
+ }
+
+ /// <summary>
+ /// Whether JavaScript can be executable.
+ /// </summary>
+ public bool JavaScriptEnabled
+ {
+ get
+ {
+ return Interop.ChromiumEwk.ewk_settings_javascript_enabled_get(_handle);
+ }
+
+ set
+ {
+ Interop.ChromiumEwk.ewk_settings_javascript_enabled_set(_handle, value);
+ }
+ }
+
+ /// <summary>
+ /// Whether images can be loaded automatically.
+ /// </summary>
+ public bool LoadImageAutomatically
+ {
+ get
+ {
+ return Interop.ChromiumEwk.ewk_settings_loads_images_automatically_get(_handle);
+ }
+
+ set
+ {
+ Interop.ChromiumEwk.ewk_settings_loads_images_automatically_set(_handle, value);
+ }
+ }
+
+ /// <summary>
+ /// The default text encoding name.
+ /// </summary>
+ public string DefaultTextEncodingName
+ {
+ get
+ {
+ return Interop.ChromiumEwk.ewk_settings_default_text_encoding_name_get(_handle);
+ }
+
+ set
+ {
+ Interop.ChromiumEwk.ewk_settings_default_text_encoding_name_set(_handle, value);
+ }
+ }
+
+ /// <summary>
+ /// The default font size of a pixel.
+ /// </summary>
+ public int DefaultFontSize
+ {
+ get
+ {
+ return Interop.ChromiumEwk.ewk_settings_default_font_size_get(_handle);
+ }
+
+ set
+ {
+ Interop.ChromiumEwk.ewk_settings_default_font_size_set(_handle, value);
+ }
+ }
+ }
+}
diff --git a/src/Tizen.WebView/Tizen.WebView/SmartCallbackArgs.cs b/src/Tizen.WebView/Tizen.WebView/SmartCallbackArgs.cs
new file mode 100644
index 0000000..9e0f01d
--- /dev/null
+++ b/src/Tizen.WebView/Tizen.WebView/SmartCallbackArgs.cs
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.WebView
+{
+ /// <summary>
+ /// Argument from the SmartCallback.
+ /// </summary>
+ public class SmartCallbackArgs : EventArgs
+ {
+ private IntPtr _arg;
+
+ internal SmartCallbackArgs(IntPtr arg)
+ {
+ _arg = arg;
+ }
+
+ /// <summary>
+ /// Gets argument as integer type.
+ /// </summary>
+ /// <returns>Argument as integer type</returns>
+ public int GetAsInteger()
+ {
+ if (_arg == IntPtr.Zero)
+ {
+ return 0;
+ }
+ return Marshal.ReadInt32(_arg, 0);
+ }
+
+ /// <summary>
+ /// Gets argument as double type.
+ /// </summary>
+ /// <returns>Argument as double type</returns>
+ public double GetAsDouble()
+ {
+ if (_arg == IntPtr.Zero)
+ {
+ return 0d;
+ }
+ double[] ret = new double[1];
+ Marshal.Copy(_arg, ret, 0, 1);
+ return ret[0];
+ }
+
+ /// <summary>
+ /// Gets argument as boolean type.
+ /// </summary>
+ /// <returns>Argument as boolean type</returns>
+ public bool GetAsBoolean()
+ {
+ if (_arg == IntPtr.Zero)
+ {
+ return false;
+ }
+ return Marshal.ReadByte(_arg) != (byte)0;
+ }
+
+ /// <summary>
+ /// Gets argument as string type.
+ /// </summary>
+ /// <returns>Argument as string type</returns>
+ public string GetAsString()
+ {
+ if (_arg == IntPtr.Zero)
+ {
+ return string.Empty;
+ }
+ return Marshal.PtrToStringAnsi(_arg);
+ }
+
+ internal static SmartCallbackArgs CreateFromSmartEvent(IntPtr data, IntPtr obj, IntPtr info)
+ {
+ return new SmartCallbackArgs(info);
+ }
+ }
+}
diff --git a/src/Tizen.WebView/Tizen.WebView/SmartCallbackLoadErrorArgs.cs b/src/Tizen.WebView/Tizen.WebView/SmartCallbackLoadErrorArgs.cs
new file mode 100644
index 0000000..8aa6704
--- /dev/null
+++ b/src/Tizen.WebView/Tizen.WebView/SmartCallbackLoadErrorArgs.cs
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.WebView
+{
+ /// <summary>
+ /// Enumeration that provides an option to error codes.
+ /// </summary>
+ public enum LoadErrorCode
+ {
+ /// <summary>
+ /// Unknown
+ /// </summary>
+ Unknown = 0,
+ /// <summary>
+ /// User canceled
+ /// </summary>
+ Canceled,
+ /// <summary>
+ /// Can't show page for this MIME Type
+ /// </summary>
+ CantSupportMimetype,
+ /// <summary>
+ /// File IO error
+ /// </summary>
+ FailedFileIo,
+ /// <summary>
+ /// Cannot connect to network
+ /// </summary>
+ CantConnect,
+ /// <summary>
+ /// Fail to look up host from DNS
+ /// </summary>
+ CantLookupHost,
+ /// <summary>
+ /// Fail to SSL/TLS handshake
+ /// </summary>
+ FailedTlsHandshake,
+ /// <summary>
+ /// Received certificate is invalid
+ /// </summary>
+ InvalidCertificate,
+ /// <summary>
+ /// Connection timeout
+ /// </summary>
+ RequestTimeout,
+ /// <summary>
+ /// Too many redirects
+ /// </summary>
+ TooManyRedirects,
+ /// <summary>
+ /// Too many requests during this load
+ /// </summary>
+ TooManyRequests,
+ /// <summary>
+ /// Malformed url
+ /// </summary>
+ BadUrl,
+ /// <summary>
+ /// Unsupported scheme
+ /// </summary>
+ UnsupportedScheme,
+ /// <summary>
+ /// User authentication failed on server
+ /// </summary>
+ Authentication,
+ /// <summary>
+ /// Web server has internal server error
+ /// </summary>
+ InternalServer,
+ }
+
+ /// <summary>
+ /// Argument from the LoadError SmartCallback.
+ /// </summary>
+ public class SmartCallbackLoadErrorArgs : EventArgs
+ {
+ IntPtr _handle;
+
+ internal SmartCallbackLoadErrorArgs(IntPtr handle)
+ {
+ _handle = handle;
+ }
+
+ /// <summary>
+ /// Failing URL for the error.
+ /// </summary>
+ public string Url
+ {
+ get
+ {
+ return Interop.ChromiumEwk.ewk_error_url_get(_handle);
+ }
+ }
+
+ /// <summary>
+ /// The error code.
+ /// </summary>
+ public LoadErrorCode Code
+ {
+ get
+ {
+ return (LoadErrorCode)Interop.ChromiumEwk.ewk_error_code_get(_handle);
+ }
+ }
+
+ /// <summary>
+ /// The description for the error.
+ /// </summary>
+ public string Description
+ {
+ get
+ {
+ return Interop.ChromiumEwk.ewk_error_description_get(_handle);
+ }
+ }
+
+ /// <summary>
+ /// Whether the error should be treated as a cancellation.
+ /// </summary>
+ public bool Cancellation
+ {
+ get
+ {
+ return Interop.ChromiumEwk.ewk_error_cancellation_get(_handle);
+ }
+ }
+
+ internal static SmartCallbackLoadErrorArgs CreateFromSmartEvent(IntPtr data, IntPtr obj, IntPtr info)
+ {
+ return new SmartCallbackLoadErrorArgs(info);
+ }
+ }
+}
diff --git a/src/Tizen.WebView/Tizen.WebView/WebView.cs b/src/Tizen.WebView/Tizen.WebView/WebView.cs
new file mode 100644
index 0000000..3b30cd8
--- /dev/null
+++ b/src/Tizen.WebView/Tizen.WebView/WebView.cs
@@ -0,0 +1,342 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using ElmSharp;
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+namespace Tizen.WebView
+{
+ /// <summary>
+ /// A view used to render web contents.
+ /// </summary>
+ public class WebView: EvasObject
+ {
+ private static IDictionary<string, JavaScriptMessageHandler> _javaScriptMessageHandlerMap = new Dictionary<string, JavaScriptMessageHandler>();
+
+ private IntPtr _handle;
+ private IntPtr _realHandle;
+ private Context _context;
+ private Settings _settings;
+
+ // focus dummy
+ private SmartEvent _focusIn;
+ private SmartEvent _focusOut;
+
+ // Smart events
+ private SmartEvent _loadStarted;
+ private SmartEvent _loadFinished;
+ private SmartEvent<SmartCallbackLoadErrorArgs> _loadError;
+ private SmartEvent<SmartCallbackArgs> _titleChanged;
+ private SmartEvent<SmartCallbackArgs> _urlChanged;
+
+
+
+ /// <summary>
+ /// Event that occurs when load started.
+ /// </summary>
+ public event EventHandler LoadStarted;
+
+ /// <summary>
+ /// Event that occurs when load finished.
+ /// </summary>
+ public event EventHandler LoadFinished;
+
+ /// <summary>
+ /// Event that occurs when load error.
+ /// </summary>
+ public event EventHandler<SmartCallbackLoadErrorArgs> LoadError;
+
+ /// <summary>
+ /// Event that occurs when title of main frame was changed.
+ /// </summary>
+ public event EventHandler<SmartCallbackArgs> TitleChanged;
+
+ /// <summary>
+ /// Event that occurs when URL of main frame was changed.
+ /// </summary>
+ public event EventHandler<SmartCallbackArgs> UrlChanged;
+
+ /// <summary>
+ /// Current URL of the main frame.
+ /// </summary>
+ public string Url
+ {
+ get
+ {
+ return Interop.ChromiumEwk.ewk_view_url_get(_realHandle);
+ }
+ }
+
+ /// <summary>
+ /// Current title of the main frame.
+ /// </summary>
+ public string Title
+ {
+ get
+ {
+ return Interop.ChromiumEwk.ewk_view_title_get(_realHandle);
+ }
+ }
+
+ /// <summary>
+ /// Current user agent string of this view.
+ /// </summary>
+ public string UserAgent
+ {
+ get
+ {
+ return Interop.ChromiumEwk.ewk_view_user_agent_get(_realHandle);
+ }
+
+ set
+ {
+ Interop.ChromiumEwk.ewk_view_user_agent_set(_realHandle, value);
+ }
+ }
+
+ /// <summary>
+ /// Whether a view has the focus.
+ /// </summary>
+ public bool HasFocus
+ {
+ get
+ {
+ return Interop.ChromiumEwk.ewk_view_focus_get(_realHandle);
+ }
+ }
+
+ /// <summary>
+ /// Create a WebView object.
+ /// </summary>
+ /// <param name="parent">Parent object of WebView</param>
+ public WebView(EvasObject parent) : base(parent)
+ {
+ InitializeSmartEvent();
+ }
+
+ /// <summary>
+ /// Gets the Context object of this view.
+ /// </summary>
+ /// <returns>The Context object of this view</returns>
+ public Context GetContext()
+ {
+ if (_context == null)
+ {
+ IntPtr contextHandle = Interop.ChromiumEwk.ewk_view_context_get(_realHandle);
+ if (contextHandle == IntPtr.Zero)
+ {
+ return null;
+ }
+ _context = new Context(contextHandle);
+ }
+ return _context;
+ }
+
+ /// <summary>
+ /// Gets the Settings object of this view.
+ /// </summary>
+ /// <returns>The Settings object of this view</returns>
+ public Settings GetSettings()
+ {
+ if (_settings == null)
+ {
+ IntPtr settingsHandle = Interop.ChromiumEwk.ewk_view_settings_get(_realHandle);
+ if (settingsHandle == IntPtr.Zero)
+ {
+ return null;
+ }
+ _settings = new Settings(settingsHandle);
+ }
+ return _settings;
+ }
+
+ /// <summary>
+ /// Asks the object to load the given URL.
+ /// </summary>
+ /// <remarks>
+ /// You can only be sure that url changed after UrlChanged event.
+ /// </remarks>
+ /// <param name="url">The uniform resource identifier to load</param>
+ public void LoadUrl(string url)
+ {
+ Interop.ChromiumEwk.ewk_view_url_set(_realHandle, url);
+ }
+
+ /// <summary>
+ /// Loads the specified html string as the content of the view.
+ /// </summary>
+ /// <param name="html">HTML data to load</param>
+ /// <param name="baseUrl">Base URL used for relative paths to external objects</param>
+ public void LoadHtml(string html, string baseUrl)
+ {
+ Interop.ChromiumEwk.ewk_view_html_string_load(_realHandle, html, baseUrl, null);
+ }
+
+ /// <summary>
+ /// Asks the main frame to stop loading.
+ /// </summary>
+ public void StopLoading()
+ {
+ Interop.ChromiumEwk.ewk_view_stop(_realHandle);
+ }
+
+ /// <summary>
+ /// Asks the main frame to reload the current document.
+ /// </summary>
+ public void Reload()
+ {
+ Interop.ChromiumEwk.ewk_view_reload(_realHandle);
+ }
+
+ /// <summary>
+ /// Asks the main frame to navigate back in history.
+ /// </summary>
+ public void GoBack()
+ {
+ Interop.ChromiumEwk.ewk_view_back(_realHandle);
+ }
+
+ /// <summary>
+ /// Asks the main frame to navigate forward in history.
+ /// </summary>
+ public void GoForward()
+ {
+ Interop.ChromiumEwk.ewk_view_forward(_realHandle);
+ }
+
+ /// <summary>
+ /// Checks whether it is possible to navigate backwards one item in history.
+ /// </summary>
+ /// <returns>Whether it is possible to navigate backwards one item in history</returns>
+ public bool CanGoBack()
+ {
+ return Interop.ChromiumEwk.ewk_view_back_possible(_realHandle);
+ }
+
+ /// <summary>
+ /// Checks whether it is possible to navigate forwards one item in history.
+ /// </summary>
+ /// <returns>Whether it is possible to navigate forwards one item in history</returns>
+ public bool CanGoForward()
+ {
+ return Interop.ChromiumEwk.ewk_view_forward_possible(_realHandle);
+ }
+
+ /// <summary>
+ /// Injects the supplied javascript message handler into the view.
+ /// </summary>
+ /// <param name="name"> The message callback</param>
+ /// <param name="handler">The name used to expose the object in JavaScript</param>
+ /// <returns>'true' on success, otherwise 'false'</returns>
+ public bool AddJavaScriptMessageHandler(string name, JavaScriptMessageHandler handler)
+ {
+ lock (_javaScriptMessageHandlerMap)
+ {
+ if (_javaScriptMessageHandlerMap.ContainsKey(name))
+ {
+ return false;
+ }
+ _javaScriptMessageHandlerMap[name] = handler;
+ }
+ Interop.ChromiumEwk.ScriptMessageCallback callback = (handle, message) =>
+ {
+ JavaScriptMessage convertedMessage = new JavaScriptMessage(message);
+ lock (_javaScriptMessageHandlerMap)
+ {
+ if (_javaScriptMessageHandlerMap.ContainsKey(convertedMessage.Name))
+ {
+ _javaScriptMessageHandlerMap[convertedMessage.Name](convertedMessage);
+ }
+ }
+ };
+ if (!Interop.ChromiumEwk.ewk_view_javascript_message_handler_add(_realHandle, callback, name))
+ {
+ lock (_javaScriptMessageHandlerMap)
+ {
+ _javaScriptMessageHandlerMap.Remove(name);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /// <summary>
+ /// Requests the execution of given name and result to the JavaScript runtime.
+ /// </summary>
+ /// <param name="name">The name used to expose the object in JavaScript</param>
+ /// <param name="result">The result to the JavaScript runtime</param>
+ public void EvalWithResult(string name, string result)
+ {
+ Interop.ChromiumEwk.ewk_view_evaluate_javascript(_realHandle, name, result);
+ }
+
+ /// <summary>
+ /// Requests the execution of the given script.
+ /// </summary>
+ /// <param name="script">The JavaScript code string to execute</param>
+ public void Eval(string script)
+ {
+ Interop.ChromiumEwk.ewk_view_script_execute(_realHandle, script, null, IntPtr.Zero);
+ }
+
+ /// <summary>
+ /// Requests to set or unset a view as the currently focused one.
+ /// </summary>
+ /// <param name="focused">'true' to set the focus on the view, 'false' to remove the focus from the view</param>
+ public void SetFocus(bool focused)
+ {
+ Interop.ChromiumEwk.ewk_view_focus_set(_realHandle, focused);
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ // focus dummy
+ _handle = Interop.Elementary.elm_layout_add((IntPtr)parent);
+ Interop.Elementary.elm_layout_theme_set(_handle, "layout", "elm_widget", "default");
+ Interop.Elementary.elm_object_focus_allow_set(_handle, true);
+
+ IntPtr evas = Interop.Evas.evas_object_evas_get(parent);
+ _realHandle = Interop.ChromiumEwk.ewk_view_add(evas);
+ Interop.Elementary.elm_object_part_content_set(_handle, "elm.swallow.content", _realHandle);
+
+ return _handle;
+ }
+
+ private void InitializeSmartEvent()
+ {
+ // focus dummy
+ _focusIn = new SmartEvent(this, "focused");
+ _focusOut = new SmartEvent(this, "unfocused");
+
+ _focusIn.On += (s, e) => { ((WebView)s).SetFocus(true); };
+ _focusOut.On += (s, e) => { ((WebView)s).SetFocus(false); };
+
+ _loadStarted = new SmartEvent(this, _realHandle, "load,started");
+ _loadFinished = new SmartEvent(this, _realHandle, "load,finished");
+ _loadError = new SmartEvent<SmartCallbackLoadErrorArgs>(this, _realHandle, "load,error", SmartCallbackLoadErrorArgs.CreateFromSmartEvent);
+ _titleChanged = new SmartEvent<SmartCallbackArgs>(this, _realHandle, "title,changed", SmartCallbackArgs.CreateFromSmartEvent);
+ _urlChanged = new SmartEvent<SmartCallbackArgs>(this, _realHandle, "url,changed", SmartCallbackArgs.CreateFromSmartEvent);
+
+ _loadStarted.On += (s, e) => { LoadStarted?.Invoke(this, EventArgs.Empty); };
+ _loadFinished.On += (s, e) => { LoadFinished?.Invoke(this, EventArgs.Empty); };
+ _loadError.On += (s, e) => { LoadError?.Invoke(this, e); };
+ _titleChanged.On += (s, e) => { TitleChanged?.Invoke(this, e); };
+ _urlChanged.On += (s, e) => { UrlChanged?.Invoke(this, e); };
+ }
+ }
+}
diff --git a/src/Tizen/Interop/Interop.CommonError.cs b/src/Tizen/Interop/Interop.CommonError.cs
new file mode 100644
index 0000000..284ba22
--- /dev/null
+++ b/src/Tizen/Interop/Interop.CommonError.cs
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string Base = "libcapi-base-common.so.0";
+ }
+
+ internal static partial class CommonError
+ {
+ [DllImport(Libraries.Base, EntryPoint = "get_last_result")]
+ internal static extern int GetLastResult();
+
+ [DllImport(Libraries.Base, EntryPoint = "get_error_message")]
+ internal static extern IntPtr GetErrorMessage(int errorCode);
+ }
+}
diff --git a/src/Tizen/Interop/Interop.Dlog.cs b/src/Tizen/Interop/Interop.Dlog.cs
new file mode 100644
index 0000000..697daa1
--- /dev/null
+++ b/src/Tizen/Interop/Interop.Dlog.cs
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string Dlog = "libdlog.so.0";
+ }
+
+ internal static partial class Dlog
+ {
+ internal enum LogPriority
+ {
+ DLOG_UNKNOWN = 0,
+ DLOG_DEFAULT,
+ DLOG_VERBOSE,
+ DLOG_DEBUG,
+ DLOG_INFO,
+ DLOG_WARN,
+ DLOG_ERROR,
+ DLOG_FATAL,
+ DLOG_SILENT,
+ DLOG_PRIO_MAX,
+ }
+ [DllImportAttribute(Libraries.Dlog, EntryPoint = "dlog_print", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int Print(LogPriority prio, string tag, string fmt, string msg);
+
+ [DllImportAttribute(Libraries.Dlog, EntryPoint = "dlog_print", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int Print(LogPriority prio, string tag, string fmt, string file, string func, int line, string msg);
+ }
+}
+
diff --git a/src/Tizen/Tizen.Common/Color.cs b/src/Tizen/Tizen.Common/Color.cs
new file mode 100644
index 0000000..53224ae
--- /dev/null
+++ b/src/Tizen/Tizen.Common/Color.cs
@@ -0,0 +1,349 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Common
+{
+ /// <summary>
+ /// Structure that represents a color as RGBA.
+ /// </summary>
+ public struct Color : IEquatable<Color>
+ {
+ /// <summary>
+ /// Empty color instance. All components are 0.
+ /// </summary>
+ public static readonly Color Empty = FromRgba(0, 0, 0, 0);
+
+ /// <summary>
+ /// Transparent color instance. All components are 0.
+ /// </summary>
+ public static readonly Color Transparent = FromRgba(0, 0, 0, 0);
+
+ /// <summary>
+ /// Aqua color instance. Its RGB value is (0, 255, 255).
+ /// </summary>
+ public static readonly Color Aqua = FromRgb(0, 255, 255);
+
+ /// <summary>
+ /// Black color instance. Its RGB value is (0, 0, 0).
+ /// </summary>
+ public static readonly Color Black = FromRgb(0, 0, 0);
+
+ /// <summary>
+ /// Blue color instance. Its RGB value is (0, 0, 255).
+ /// </summary>
+ public static readonly Color Blue = FromRgb(0, 0, 255);
+
+ /// <summary>
+ /// Fuchsia color instance. Its RGB value is (255, 0, 255).
+ /// </summary>
+ public static readonly Color Fuchsia = FromRgb(255, 0, 255);
+
+ /// <summary>
+ /// Gray color instance. Its RGB value is (128, 128, 128).
+ /// </summary>
+ public static readonly Color Gray = FromRgb(128, 128, 128);
+
+ /// <summary>
+ /// Green color instance. Its RGB value is (0, 128, 0).
+ /// </summary>
+ public static readonly Color Green = FromRgb(0, 128, 0);
+
+ /// <summary>
+ /// Lime color instance. Its RGB value is (0, 255, 0).
+ /// </summary>
+ public static readonly Color Lime = FromRgb(0, 255, 0);
+
+ /// <summary>
+ /// Maroon color instance. Its RGB value is (128, 0, 0).
+ /// </summary>
+ public static readonly Color Maroon = FromRgb(128, 0, 0);
+
+ /// <summary>
+ /// Navy color instance. Its RGB value is (0, 0, 128).
+ /// </summary>
+ public static readonly Color Navy = FromRgb(0, 0, 128);
+
+ /// <summary>
+ /// Olive color instance. Its RGB value is (128, 128, 0).
+ /// </summary>
+ public static readonly Color Olive = FromRgb(128, 128, 0);
+
+ /// <summary>
+ /// Purple color instance. Its RGB value is (128, 0, 128).
+ /// </summary>
+ public static readonly Color Purple = FromRgb(128, 0, 128);
+
+ /// <summary>
+ /// Pink color instance. Its RGB value is (255, 102, 255).
+ /// </summary>
+ public static readonly Color Pink = FromRgb(255, 102, 255);
+
+ /// <summary>
+ /// Red color instance. Its RGB value is (255, 0, 0).
+ /// </summary>
+ public static readonly Color Red = FromRgb(255, 0, 0);
+
+ /// <summary>
+ /// Silver color instance. Its RGB value is (192, 192, 192).
+ /// </summary>
+ public static readonly Color Silver = FromRgb(192, 192, 192);
+
+ /// <summary>
+ /// Teal color instance. Its RGB value is (0, 128, 128).
+ /// </summary>
+ public static readonly Color Teal = FromRgb(0, 128, 128);
+
+ /// <summary>
+ /// White color instance. Its RGB value is (255, 255, 255).
+ /// </summary>
+ public static readonly Color White = FromRgb(255, 255, 255);
+
+ /// <summary>
+ /// Yellow color instance. Its RGB value is (255, 255, 0).
+ /// </summary>
+ public static readonly Color Yellow = FromRgb(255, 255, 0);
+
+ private int _value;
+
+ /// <summary>
+ /// Initiates new Color with r,g,b,a components.
+ /// </summary>
+ /// <param name="r">Red (0 ~ 255)</param>
+ /// <param name="g">Green (0 ~ 255)</param>
+ /// <param name="b">Blue (0 ~ 255)</param>
+ /// <param name="a">Alpha (0 ~ 255)</param>
+ public Color(int r, int g, int b, int a)
+ {
+ if (r > 255 || r < 0)
+ throw CreateColorArgumentException(r, "red");
+ if (g > 255 || g < 0)
+ throw CreateColorArgumentException(g, "green");
+ if (b > 255 || b < 0)
+ throw CreateColorArgumentException(b, "blue");
+ if (a > 255 || a < 0)
+ throw CreateColorArgumentException(a, "alpha");
+
+ _value = (int)(((uint)r << 24) + ((uint)g << 16) + ((uint)b << 8) + (uint)a);
+ }
+
+ /// <summary>
+ /// Initiates new Color with r,g,b components. The alpha value will be 255 as default.
+ /// </summary>
+ /// <param name="r">Red (0 ~ 255)</param>
+ /// <param name="g">Green (0 ~ 255)</param>
+ /// <param name="b">Blue (0 ~ 255)</param>
+ public Color(int r, int g, int b) : this(r, g, b, 255)
+ {
+ }
+
+ #region Properties
+
+ /// <summary>
+ /// Gets the Red component of the color.
+ /// </summary>
+ public int R
+ {
+ get { return (byte)(_value >> 24); }
+ }
+
+ /// <summary>
+ /// Gets the Green component of the color.
+ /// </summary>
+ public int G
+ {
+ get { return (byte)(_value >> 16); }
+ }
+
+ /// <summary>
+ /// Gets the blue component of the color.
+ /// </summary>
+ public int B
+ {
+ get { return (byte)(_value >> 8); }
+ }
+
+ /// <summary>
+ /// Gets the alpha component of the color.
+ /// </summary>
+ public int A
+ {
+ get { return (byte)_value; }
+ }
+
+ #endregion // Properties
+
+ #region Static Methods
+
+ /// <summary>
+ /// Returns a boolean indicating whether the two given Colors are equal.
+ /// </summary>
+ /// <param name="color1">The first Color to compare.</param>
+ /// <param name="color2">The second Color to compare.</param>
+ /// <returns>True if the Colors are equal; False otherwise.</returns>
+ public static bool operator ==(Color color1, Color color2)
+ {
+ return color1.Equals(color2);
+ }
+
+ /// <summary>
+ /// Returns a boolean indicating whether the two given Colors are not equal.
+ /// </summary>
+ /// <param name="color1">The first Color to compare.</param>
+ /// <param name="color2">The second Color to compare.</param>
+ /// <returns>True if the Colors are not equal; False if they are equal.</returns>
+ public static bool operator !=(Color color1, Color color2)
+ {
+ return !color1.Equals(color2);
+ }
+
+ /// <summary>
+ /// Returns a new RGB color instance.
+ /// </summary>
+ /// <param name="r">The red component of the color.</param>
+ /// <param name="g">The green component of the color.</param>
+ /// <param name="b">The blue component of the color.</param>
+ /// <returns></returns>
+ public static Color FromRgb(int r, int g, int b)
+ {
+ return new Color(r, g, b);
+ }
+
+ /// <summary>
+ /// Returns a new RGBA color instance.
+ /// </summary>
+ /// <param name="r">The red component of the color.</param>
+ /// <param name="g">The green component of the color.</param>
+ /// <param name="b">The blue component of the color.</param>
+ /// <param name="a">The alpha component of the color.</param>
+ /// <returns>the RGBA color instance.</returns>
+ public static Color FromRgba(int r, int g, int b, int a)
+ {
+ return new Color(r, g, b, a);
+ }
+
+ /// <summary>
+ /// Returns a new RGB Color instance with the requested Red, Green, and Blue channels. The Alpha channel is set if hex contains one.
+ /// </summary>
+ /// <param name="hex">A string that contains the hexadecimal RGB(A) color representation.</param>
+ /// <returns>the RGBA color instance.</returns>
+ public static Color FromHex(string hex)
+ {
+ if (hex == null)
+ {
+ throw new ArgumentNullException("hex");
+ }
+
+ // #fff
+ // #ffffff
+ // #ffff
+ // #ffffffff
+ if (hex.Length > 0 && hex[0] == '#') hex = hex.Substring(1);
+ if (hex.Length == 3) hex += "F";
+ if (hex.Length == 4)
+ hex = new String(new char[] { hex[0], hex[0], hex[1], hex[1], hex[2], hex[2], hex[3], hex[3] });
+ if (hex.Length == 6) hex += "FF";
+ if (hex.Length != 8)
+ {
+ throw new ArgumentException(@"Hex string is not valid color. length of hex should be 3, 4, 6, 8");
+ }
+ Color c = new Color();
+ c._value = Convert.ToInt32(hex, 16);
+ return c;
+ }
+
+ private static ArgumentException CreateColorArgumentException(int value, string color)
+ {
+ return new ArgumentException(string.Format("'{0}' is not a valid" +
+ " value for '{1}'. '{1}' should be greater or equal to 0 and" +
+ " less than or equal to 255.", value, color));
+ }
+
+ #endregion // Static Methods
+
+ #region Methods
+
+ /// <summary>
+ /// Gets the 32-bits RGBA value of the color.
+ /// </summary>
+ public int GetRgba()
+ {
+ return _value;
+ }
+
+ /// <summary>
+ /// Gets the 32-bits ARGB value of the color.
+ /// </summary>
+ public int GetArgb()
+ {
+ return (int)((uint)A << 24 | (uint)R << 16 | (uint)G << 8 | (uint)B);
+ }
+
+ /// <summary>
+ /// Returns a string representation in Hex. (ex: \#FFFFFFFF in RGBA order)
+ /// </summary>
+ /// <returns>The string representation in Hex.</returns>
+ public string ToHex()
+ {
+ return "#" + _value.ToString("X8");
+ }
+
+ /// <summary>
+ /// Returns a boolean indicating whether the given Color is equal to this Color instance.
+ /// </summary>
+ /// <param name="other">The Color to compare this instance to.</param>
+ /// <returns>True if the other Color is equal to this instance; False otherwise.</returns>
+ public bool Equals(Color other)
+ {
+ return _value == other._value;
+ }
+
+ /// <summary>
+ /// Returns a boolean indicating whether the given Object is equal to this Color instance.
+ /// </summary>
+ /// <param name="obj">The Object to compare against.</param>
+ /// <returns>True if the Object is equal to this Color; False otherwise.</returns>
+ public override bool Equals(object obj)
+ {
+ if (obj is Color)
+ {
+ return Equals((Color)obj);
+ }
+ return false;
+ }
+
+ /// <summary>
+ /// Returns a string representation of the Color.
+ /// </summary>
+ /// <returns>The string representation.</returns>
+ public override string ToString()
+ {
+ return string.Format("Color [R={0}, G={1}, B={2}, A={3}]", R, G, B, A);
+ }
+
+ /// <summary>
+ /// Returns the hash code for this instance.
+ /// </summary>
+ /// <returns>The hash code.</returns>
+ public override int GetHashCode()
+ {
+ return _value.GetHashCode();
+ }
+
+ #endregion // Methods
+ }
+}
diff --git a/src/Tizen/Tizen.Internals.Errors/ErrorCode.cs b/src/Tizen/Tizen.Internals.Errors/ErrorCode.cs
new file mode 100644
index 0000000..c21dc60
--- /dev/null
+++ b/src/Tizen/Tizen.Internals.Errors/ErrorCode.cs
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Internals.Errors
+{
+ public enum ErrorCode : int
+ {
+ None = 0, // 0, /**< Successful */
+ NotPermitted = -1, // -EPERM, /**< Operation not permitted */
+ NoSuchFile = -2, // -ENOENT, /**< No such file or directory */
+ NoSuchProcess = -3, // -ESRCH, /**< No such process */
+ InterruptedSysCall = -4, // -EINTR, /**< Interrupted system call */
+ IoError = -5, // -EIO, /**< I/O error */
+ NoSuchDevice = -6, // -ENXIO, /**< No such device or address */
+ ArgumentListTooLong = -7, // -E2BIG, /**< Argument list too long */
+ ExecFormatError = -8, // -ENOEXEC, /**< Exec format error */
+ BadFileNumber = -9, // -EBADF, /**< Bad file number */
+ TryAgain = -11, // -EAGAIN, /**< Try again */
+ OutOfMemory = -12, // -ENOMEM, /**< Out of memory */
+ PermissionDenied = -13, // -EACCES, /**< Permission denied */
+ BadAddress = -14, // -EFAULT, /**< Bad address */
+ BlockDeviceRequired = -15, // -ENOTBLK, /**< Block device required */
+ ResourceBusy = -16, // -EBUSY, /**< Device or resource busy */
+ FileExists = -17, // -EEXIST, /**< File exists */
+ CrossDeviceLink = -18, // -EXDEV, /**< Cross-device link */
+ NotaDirectory = -20, // -ENOTDIR, /**< Not a directory */
+ IsADirectory = -21, // -EISDIR, /**< Is a directory */
+ InvalidParameter = -22, // -EINVAL, /**< Invalid function parameter */
+ FileTableOverflow = -23, // -ENFILE, /**< File table overflow */
+ TooManyOpenFiles = -24, // -EMFILE, /**< Too many open files */
+ TooNotaTerminal = -25, // -ENOTTY, /**< Not a terminal */
+ TooTextFileBusy = -26, // -ETXTBSY, /**< Not a terminal */
+ FileTooLarge = -27, // -EFBIG, /**< File too large */
+ FileNoSpaceOnDevice = -28, // -ENOSPC, /**< No space left on device */
+ IllegalSeek = -29, // -ESPIPE, /**< Illegal seek */
+ ReadOnlyFilesystem = -30, // -EROFS, /**< Read-only file system */
+ NoData = -61, // -ENODATA, /**< No data available */
+ TooManyLinks = -31, // -EMLINK, /**< Too many links */
+ BrokenPipe = -32, // -EPIPE, /**< Broken pipe */
+ ArgumentOutOfDomain = -33, // -EDOM, /**< Math argument out of domain of func */
+ ResultOutOfRange = -34, // -ERANGE, /**< Math result not representable */
+ WouldCauseDeadlock = -35, // -EDEADLK, /**< Resource deadlock would occur */
+ FileNameTooLong = -36, // -ENAMETOOLONG,/**< File name too long */
+ FileNoLocksAvailable = -37, // -ENOLCK, /**< No record locks available */
+ InvalidOperation = -38, // -ENOSYS, /**< Function not implemented */
+ DirNotEmpty = -39, // -ENOTEMPTY, /**< Directory not empty */
+ TooManySymbolicLinks = -40, // -ELOOP, /**< Too many symbolic links encountered */
+ WouldBlock = -11, // TryAgain (-EAGAIN), /**< Operation would block */
+ CorruptedSharedLib = -80, // -ELIBBAD, /**< Accessing a corrupted shared library */
+ LibSectionCorrupted = -81, // -ELIBSCN, /**< .lib section in a.out corrupted */
+ LinkTooManySharedLib = -82, // -ELIBMAX, /**< Attempting to link in too many shared libraries */
+ SharedLibExec = -83, // -ELIBEXEC, /**< Cannot exec a shared library directly */
+ IllegalByteSeq = -84, // -EILSEQ, /**< Illegal byte sequence */
+ SystemCallRestart = -85, // -ERESTART, /**< Interrupted system call should be restarted */
+ StreamsPipe = -86, // -ESTRPIPE, /**< Streams pipe error */
+ TooManyUsers = -87, // -EUSERS, /**< Too many users */
+ NonSocket = -88, // -ENOTSOCK, /**< Socket operation on non-socket */
+ NoDestAddress = -89, // -EDESTADDRREQ, /**< Destination address required */
+ MsgTooLong = -90, // -EMSGSIZE, /**< Message too long */
+ ProtocolWrongType = -91, // -EPROTOTYPE, /**< Protocol wrong type for socket */
+ ProtocolNotAvaliable = -92, // -ENOPROTOOPT, /**< Protocol not available */
+ ProtocolNotSupported = -93, // -EPROTONOSUPPORT, /**< Protocol not supported */
+ SocketTypeNotSupported = -94, // -ESOCKTNOSUPPORT, /**< Socket type not supported */
+ EndpointOperatinNotSupported = -95, // -EOPNOTSUPP, /**< Operation not supported on transport endpoint */
+ ProtocolFamilyNotSupported = -96, // -EPFNOSUPPORT, /**< Protocol family not supported */
+ AddressFamilyNotSupported = -97, // -EAFNOSUPPORT, /**< Address family not supported by protocol */
+ AddresInUse = -98, // -EADDRINUSE, /**< Address already in use */
+ CannotAssignAddress = -99, // -EADDRNOTAVAIL, /**< Cannot assign requested address */
+ Networkdown = -100, // -ENETDOWN, /**< Network is down */
+ NetworkUnreachable = -101, // -ENETUNREACH, /**< Network is unreachable */
+ NetworkReset = -102, // -ENETRESET, /**< Network dropped connection because of reset */
+ ConnectionAborted = -103, // -ECONNABORTED, /**< Software caused connection abort */
+ ConnectionResetByPeer = -104, // -ECONNRESET, /**< Connection reset by peer */
+ BufferSpace = -105, // -ENOBUFS, /**< No buffer space available */
+ EndpointConnected = -106, // -EISCONN, /**< Transport endpoint is already connected */
+ EndpointNotConnected = -107, // -ENOTCONN, /**< Transport endpoint is not connected */
+ EndpointShutdown = -108, // -ESHUTDOWN, /**< Cannot send after transport endpoint shutdown */
+ TooManyReferences = -109, // -ETOOMANYREFS, /**< Too many references: cannot splice */
+ ConnectionTimeout = -110, // -ETIMEDOUT, /**< Connection timed out */
+ ConnectionRefused = -111, // -ECONNREFUSED, /**< Connection refused */
+ Hostdown = -112, // -EHOSTDOWN, /**< Host is down */
+ NoRouteToHost = -113, // -EHOSTUNREACH, /**< No route to host */
+ AlreadyInProgress = -114, // -EALREADY, /**< Operation already in progress */
+ NowInProgress = -115, // -EINPROGRESS, /**< Operation now in progress */
+ StaleNfsFileHandle = -116, // -ESTALE, /**< Stale NFS file handle */
+ StructureUnclean = -117, // -EUCLEAN, /**< Structure needs cleaning */
+ NotXenixNamedTypeFile = -118, // -ENOTNAM, /**< Not a XENIX named type file */
+ NoXenixSemaphoresAvailable = -119, // -ENAVAIL, /**< No XENIX semaphores available */
+ IsNamedTypeFile = -120, // -EISNAM, /**< Is a named type file */
+ RemoteIo = -121, // -EREMOTEIO, /**< Remote I/O error */
+ QuotaExceeded = -122, // -EDQUOT, /**< Quota exceeded */
+ NoMedium = -123, // -ENOMEDIUM, /**< No medium found */
+ WrongMediumType = -124, // -EMEDIUMTYPE, /**< Wrong medium type */
+ Canceled = -125, // -ECANCELED, /**< Operation Canceled */
+ KeyNotAvailable = -126, // -ENOKEY, /**< Required key not available */
+ KeyExpired = -127, // -EKEYEXPIRED, /**< Key has expired */
+ KeyRevoked = -128, // -EKEYREVOKED, /**< Key has been revoked */
+ KeyRejected = -129, // -EKEYREJECTED, /**< Key was rejected by service */
+
+ OwnerDead = -130, // -EOWNERDEAD, /**< Owner died (for robust mutexes) */
+
+ Unknown = -1073741824, // TIZEN_ERROR_MIN_PLATFORM_ERROR, /**< Unknown error */
+
+ TimedOut, // /**< Time out */
+ NotSupported, // /**< Not Supported */
+ UserNotConsented,// /**< Not Consented */
+ EndofCollection //
+ }
+}
diff --git a/src/Tizen/Tizen.Internals.Errors/ErrorFacts.cs b/src/Tizen/Tizen.Internals.Errors/ErrorFacts.cs
new file mode 100644
index 0000000..f5ec90d
--- /dev/null
+++ b/src/Tizen/Tizen.Internals.Errors/ErrorFacts.cs
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Internals.Errors
+{
+ /// <summary>
+ ///
+ /// </summary>
+ public static class ErrorFacts
+ {
+ /// <summary>
+ ///
+ /// </summary>
+ /// <returns></returns>
+ public static int GetLastResult()
+ {
+ return Interop.CommonError.GetLastResult();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="errorCode"></param>
+ /// <returns></returns>
+ public static string GetErrorMessage(int errorCode)
+ {
+ IntPtr errorPtr = Interop.CommonError.GetErrorMessage(errorCode);
+ return Marshal.PtrToStringAnsi(errorPtr);
+ }
+ }
+}
diff --git a/src/Tizen/Tizen.csproj b/src/Tizen/Tizen.csproj
new file mode 100644
index 0000000..88c3f81
--- /dev/null
+++ b/src/Tizen/Tizen.csproj
@@ -0,0 +1,9 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="../../build/common.props" />
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.6</TargetFramework>
+ </PropertyGroup>
+
+ <Import Project="../../build/common.targets" />
+</Project>