diff options
author | jongmyeongko <jongmyeong.ko@samsung.com> | 2017-02-15 21:55:03 +0900 |
---|---|---|
committer | jongmyeong ko <jongmyeong.ko@samsung.com> | 2017-03-16 17:55:48 -0700 |
commit | 560622fee016e2c34aafaa27eaa9db98389592a3 (patch) | |
tree | 6603eff23a595f8222f43d851e82a194f3e777a7 | |
parent | 28ce0b9215b092555e1dab6ed77d9ad563d2575f (diff) | |
download | application-560622fee016e2c34aafaa27eaa9db98389592a3.tar.gz application-560622fee016e2c34aafaa27eaa9db98389592a3.tar.bz2 application-560622fee016e2c34aafaa27eaa9db98389592a3.zip |
Add missing API and fix wrong behavior
1. Add request-callback feature
Usage)
PackageManager.Install(packagePath, MyCallback1);
PackageManager.Install(packagePath, tepPath, MyCallback1);
PackageManager.Install(packagePath, tepPath, pkgType, MyCallback1);
...
PackageManager.Move(packageID, PackageType.TPK, StorageType.External, MyCallbackMove1);
PackageManager.Move(packageID, PackageType.TPK, StorageType.Internal, MyCallbackMove2);
PackageManager.Uninstall(packageID, PackageType.TPK, MyCallback2);
...
2. Add Move, ClearData event
usage)
private static EventHandler<PackageManagerEventArgs> PackageEventCallback;
PackageEventCallback = (s, e) => { Log.Debug(TAG, "callback called"); };
// set cb
PackageManger.MoveProgressChanged += PackageEventCallback;
PackageManger.ClearDataProgressChanged += PackageEventCallback;
// unset cb
PackageManger.MoveProgressChanged -= PackageEventCallback;
PackageManger.ClearDataProgressChanged -= PackageEventCallback;
3. Fix wrong behavior of package-event handling.
Requires:
https://review.tizen.org/gerrit/#/c/116315/
https://review.tizen.org/gerrit/#/c/117332/
Change-Id: I31fa3eb35e7e56599e794221cd0e0120b297fb21
Signed-off-by: jongmyeongko <jongmyeong.ko@samsung.com>
8 files changed, 532 insertions, 93 deletions
diff --git a/Tizen.Applications.PackageManager/Interop/Interop.PackageManager.cs b/Tizen.Applications.PackageManager/Interop/Interop.PackageManager.cs index 5d726c8..e8fac2d 100644 --- a/Tizen.Applications.PackageManager/Interop/Interop.PackageManager.cs +++ b/Tizen.Applications.PackageManager/Interop/Interop.PackageManager.cs @@ -34,6 +34,9 @@ internal static partial class Interop [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 { @@ -60,15 +63,20 @@ internal static partial class Interop { All = 0x00, Install = 0x01, - Unstall = 0x02, - Upgrade = 0x24, + Uninstall = 0x02, + Upgrade = 0x04, + Move = 0x08, + ClearData = 0x10, + Progress = 0x20, } internal enum EventType { Install = 0, Uninstall = 1, - Update = 2 + Update = 2, + Move = 3, + ClearData = 4 } internal enum CertCompareResultType @@ -164,25 +172,25 @@ internal static partial class Interop internal static extern ErrorCode PackageSizeInfoGetExtAppSize(IntPtr handle, out long extAppSize); [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_request_create")] - internal static extern ErrorCode PackageManagerRequestCreate(out IntPtr request); + internal static extern ErrorCode PackageManagerRequestCreate(out SafePackageManagerRequestHandle requestHandle); [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_request_destroy")] - internal static extern ErrorCode PackageManagerRequestDestroy(IntPtr request); + internal static extern ErrorCode PackageManagerRequestDestroy(IntPtr requestHandle); [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_request_set_type")] - internal static extern ErrorCode PackageManagerRequestSetType(IntPtr request, string type); + internal static extern ErrorCode PackageManagerRequestSetType(SafePackageManagerRequestHandle requestHandle, string type); [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_request_set_tep")] - internal static extern ErrorCode PackageManagerRequestSetTepPath(IntPtr request, string tepPath); + internal static extern ErrorCode PackageManagerRequestSetTepPath(SafePackageManagerRequestHandle requestHandle, string tepPath); [DllImport(Libraries.PackageManager, EntryPoint = "package_manager_request_install")] - internal static extern ErrorCode PackageManagerRequestInstall(IntPtr request, string path, out int id); + 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(IntPtr request, string name, out int id); + 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(IntPtr request, string name, StorageType moveToStorageType); + 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); @@ -204,5 +212,14 @@ internal static partial class Interop [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/Tizen.Applications.PackageManager/Tizen.Applications.PackageManager.csproj b/Tizen.Applications.PackageManager/Tizen.Applications.PackageManager.csproj index 4fa2cb5..826da96 100644 --- a/Tizen.Applications.PackageManager/Tizen.Applications.PackageManager.csproj +++ b/Tizen.Applications.PackageManager/Tizen.Applications.PackageManager.csproj @@ -55,6 +55,7 @@ <Compile Include="Tizen.Applications\PackageEventState.cs" /> <Compile Include="Tizen.Applications\Package.cs" /> <Compile Include="Tizen.Applications\PackageCertificate.cs" /> + <Compile Include="Tizen.Applications\PackageEventType.cs" /> <Compile Include="Tizen.Applications\PackageFilter.cs" /> <Compile Include="Tizen.Applications\PackageManager.cs" /> <Compile Include="Tizen.Applications\PackageManagerEventArgs.cs" /> @@ -62,6 +63,7 @@ <Compile Include="Tizen.Applications\PackageType.cs" /> <Compile Include="Tizen.Applications\PermissionType.cs" /> <Compile Include="Tizen.Applications\SafePackageManagerHandle.cs" /> + <Compile Include="Tizen.Applications\SafePackageManagerRequestHandle.cs" /> <Compile Include="Tizen.Applications\StorageType.cs" /> </ItemGroup> <ItemGroup> diff --git a/Tizen.Applications.PackageManager/Tizen.Applications/PackageEventType.cs b/Tizen.Applications.PackageManager/Tizen.Applications/PackageEventType.cs new file mode 100755 index 0000000..25b9d61 --- /dev/null +++ b/Tizen.Applications.PackageManager/Tizen.Applications/PackageEventType.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 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 + } +} diff --git a/Tizen.Applications.PackageManager/Tizen.Applications/PackageManager.cs b/Tizen.Applications.PackageManager/Tizen.Applications/PackageManager.cs index 6329204..738e3c3 100644 --- a/Tizen.Applications.PackageManager/Tizen.Applications/PackageManager.cs +++ b/Tizen.Applications.PackageManager/Tizen.Applications/PackageManager.cs @@ -30,16 +30,22 @@ namespace Tizen.Applications /// </remarks> public static class PackageManager { - private const string LogTag = "Tizen.Applications"; - private static SafePackageManagerHandle s_handle = new SafePackageManagerHandle(); + private const string LogTag = "Tizen.Applications.PackageManager"; - private static Interop.PackageManager.EventStatus s_eventStatus; + 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; + 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> @@ -47,7 +53,7 @@ namespace Tizen.Applications { add { - SetPackageManagerEventStatus(); + SetPackageManagerEventStatus(Interop.PackageManager.EventStatus.Install); RegisterPackageManagerEventIfNeeded(); s_installEventHandler += value; } @@ -55,7 +61,7 @@ namespace Tizen.Applications { s_installEventHandler -= value; UnregisterPackageManagerEventIfNeeded(); - SetPackageManagerEventStatus(); + UnsetPackageManagerEventStatus(); } } @@ -66,7 +72,7 @@ namespace Tizen.Applications { add { - SetPackageManagerEventStatus(); + SetPackageManagerEventStatus(Interop.PackageManager.EventStatus.Uninstall); RegisterPackageManagerEventIfNeeded(); s_uninstallEventHandler += value; } @@ -74,7 +80,7 @@ namespace Tizen.Applications { s_uninstallEventHandler -= value; UnregisterPackageManagerEventIfNeeded(); - SetPackageManagerEventStatus(); + UnsetPackageManagerEventStatus(); } } @@ -85,7 +91,7 @@ namespace Tizen.Applications { add { - SetPackageManagerEventStatus(); + SetPackageManagerEventStatus(Interop.PackageManager.EventStatus.Upgrade); RegisterPackageManagerEventIfNeeded(); s_updateEventHandler += value; } @@ -93,7 +99,45 @@ namespace Tizen.Applications { s_updateEventHandler -= value; UnregisterPackageManagerEventIfNeeded(); - SetPackageManagerEventStatus(); + 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(); } } @@ -113,6 +157,19 @@ namespace Tizen.Applications } } + private static Interop.PackageManager.PackageManagerRequestEventCallback internalRequestEventCallback = (id, packageType, packageId, eventType, eventState, progress, error, userData) => + { + if (RequestCallbacks.ContainsKey(id)) + { + 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(); + } + } + }; + /// <summary> /// Gets the package ID for the given app ID. /// </summary> @@ -303,11 +360,47 @@ namespace Tizen.Applications /// 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 is successful, false otherwise.</returns> + /// <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); + 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> @@ -315,23 +408,49 @@ namespace Tizen.Applications /// </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 is successful, false otherwise.</returns> + /// <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; - string extension = Path.GetExtension(packagePath); + return Install(packagePath, expansionPackagePath, PackageType.UNKNOWN, null); + } - if (extension.Contains("tpk")) - { - type = PackageType.TPK; - } - else - { - type = PackageType.WGT; - } + /// <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); + } - return Install(packagePath, expansionPackagePath, type); + /// <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> @@ -339,53 +458,90 @@ namespace Tizen.Applications /// </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">Package type for the package to be installed</param> - /// <returns>Returns true if installtion is successful, false otherwise.</returns> + /// <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) { - IntPtr requestHandle; - var err = Interop.PackageManager.PackageManagerRequestCreate(out requestHandle); + 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 = new SafePackageManagerRequestHandle(); + var err = Interop.PackageManager.PackageManagerRequestCreate(out RequestHandle); if (err != Interop.PackageManager.ErrorCode.None) { - Log.Warn(LogTag, string.Format("Failed to install package. Error in creating request handle. err = {0}", err)); + Log.Warn(LogTag, string.Format("Failed to create package manager request handle. err = {0}", err)); return false; } - err = Interop.PackageManager.PackageManagerRequestSetType(requestHandle, type.ToString().ToLower()); - if (err != Interop.PackageManager.ErrorCode.None) + if (type != PackageType.UNKNOWN) { - Log.Warn(LogTag, string.Format("Failed to install package. Error in setting request package type. err = {0}", err)); - Interop.PackageManager.PackageManagerRequestDestroy(requestHandle); - return false; + err = Interop.PackageManager.PackageManagerRequestSetType(RequestHandle, type.ToString().ToLower()); + if (err != Interop.PackageManager.ErrorCode.None) + { + Log.Warn(LogTag, string.Format("Failed to install package. Error in setting request package type. err = {0}", err)); + RequestHandle.Dispose(); + return false; + } } if (!string.IsNullOrEmpty(expansionPackagePath)) { - err = Interop.PackageManager.PackageManagerRequestSetTepPath(requestHandle, expansionPackagePath); + err = Interop.PackageManager.PackageManagerRequestSetTepPath(RequestHandle, expansionPackagePath); if (err != Interop.PackageManager.ErrorCode.None) { Log.Warn(LogTag, string.Format("Failed to install package. Error in setting request package mode. err = {0}", err)); - Interop.PackageManager.PackageManagerRequestDestroy(requestHandle); + RequestHandle.Dispose(); return false; } } int requestId; - err = Interop.PackageManager.PackageManagerRequestInstall(requestHandle, packagePath, out requestId); - if (err != Interop.PackageManager.ErrorCode.None) + if (eventCallback != null) { - Log.Warn(LogTag, string.Format("Failed to install package. err = {0}", err)); - Interop.PackageManager.PackageManagerRequestDestroy(requestHandle); - return false; + 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. err = {0}", err)); + RequestHandle.Dispose(); + return false; + } } - - err = Interop.PackageManager.PackageManagerRequestDestroy(requestHandle); - if (err != Interop.PackageManager.ErrorCode.None) + else { - Log.Warn(LogTag, string.Format("Failed to destroy package manager request handle. err = {0}", err)); - // This method returns true if all other operations are completed and error occured in destroying request handle. + err = Interop.PackageManager.PackageManagerRequestInstall(RequestHandle, packagePath, out requestId); + if (err != Interop.PackageManager.ErrorCode.None) + { + Log.Warn(LogTag, string.Format("Failed to install package. err = {0}", err)); + return false; + } + RequestHandle.Dispose(); } + return true; } @@ -393,42 +549,106 @@ namespace Tizen.Applications /// Uninstalls package with the given name. /// </summary> /// <param name="packageId">Id of the package to be uninstalled</param> - /// <param name="type">Package type for the package to be uninstalled</param> - /// <returns>Returns true if installtion is successful, false otherwise.</returns> + /// <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) { - IntPtr requestHandle; - var err = Interop.PackageManager.PackageManagerRequestCreate(out requestHandle); + 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 = new SafePackageManagerRequestHandle(); + var err = Interop.PackageManager.PackageManagerRequestCreate(out RequestHandle); if (err != Interop.PackageManager.ErrorCode.None) { - Log.Warn(LogTag, string.Format("Failed to uninstall package. Error in creating request handle. err = {0}", err)); + Log.Warn(LogTag, string.Format("Failed to create package manager request handle. err = {0}", err)); return false; } - err = Interop.PackageManager.PackageManagerRequestSetType(requestHandle, type.ToString().ToLower()); + err = Interop.PackageManager.PackageManagerRequestSetType(RequestHandle, type.ToString().ToLower()); if (err != Interop.PackageManager.ErrorCode.None) { Log.Warn(LogTag, string.Format("Failed to uninstall package. Error in setting request package type. err = {0}", err)); - Interop.PackageManager.PackageManagerRequestDestroy(requestHandle); + RequestHandle.Dispose(); return false; } int requestId; - err = Interop.PackageManager.PackageManagerRequestUninstall(requestHandle, packageId, out requestId); - if (err != Interop.PackageManager.ErrorCode.None) + if (eventCallback != null) { - Log.Warn(LogTag, string.Format("Failed to uninstall package. err = {0}", err)); - Interop.PackageManager.PackageManagerRequestDestroy(requestHandle); - return false; + 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. err = {0}", err)); + RequestHandle.Dispose(); + return false; + } } - - err = Interop.PackageManager.PackageManagerRequestDestroy(requestHandle); - if (err != Interop.PackageManager.ErrorCode.None) + else { - Log.Warn(LogTag, string.Format("Failed to destroy package manager request handle. err = {0}", err)); - // This method returns true if all other operations are completed and error occured in destroying request handle. + 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)); + return false; + } + RequestHandle.Dispose(); } + return true; } @@ -436,41 +656,109 @@ namespace Tizen.Applications /// Move package to given storage. /// </summary> /// <param name="packageId">Id of the package to be moved</param> - /// <param name="type">Package type for the package to be moved</param> /// <param name="newStorage">Storage, package should be moved to</param> - /// <returns>Returns true if installtion is successful, false otherwise.</returns> + /// <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) { - IntPtr request; - Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerRequestCreate(out request); + 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 = new SafePackageManagerRequestHandle(); + var err = Interop.PackageManager.PackageManagerRequestCreate(out RequestHandle); if (err != Interop.PackageManager.ErrorCode.None) { - Log.Warn(LogTag, string.Format("Failed to create request handle. err = {0}", err)); + Log.Warn(LogTag, string.Format("Failed to create package manager request handle. err = {0}", err)); return false; } - err = Interop.PackageManager.PackageManagerRequestSetType(request, type.ToString().ToLower()); + 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)); - Interop.PackageManager.PackageManagerRequestDestroy(request); + RequestHandle.Dispose(); return false; } bool result = true; - err = Interop.PackageManager.PackageManagerRequestMove(request, packageId, (Interop.PackageManager.StorageType)newStorage); - if (err != Interop.PackageManager.ErrorCode.None) + if (eventCallback != null) { - Log.Warn(LogTag, string.Format("Failed to move package to requested location. err = {0}", err)); - result = false; + 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; + } } - - err = Interop.PackageManager.PackageManagerRequestDestroy(request); - if (err != Interop.PackageManager.ErrorCode.None) + else { - Log.Warn(LogTag, string.Format("Failed to destroy package manager request handle. err = {0}", err)); - // This method returns true if all other operations are completed and error occured in destroying request handle. + 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)); + result = false; + } + RequestHandle.Dispose(); } return result; @@ -621,14 +909,41 @@ namespace Tizen.Applications } } - private static void SetPackageManagerEventStatus() + 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.Unstall; + 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) @@ -646,7 +961,7 @@ namespace Tizen.Applications private static void RegisterPackageManagerEventIfNeeded() { - if (s_installEventHandler != null || s_uninstallEventHandler != null || s_updateEventHandler != null) + if (s_installEventHandler != null && s_uninstallEventHandler != null && s_updateEventHandler != null && s_moveEventHandler != null && s_clearDataEventHandler != null) { return; } @@ -668,6 +983,14 @@ namespace Tizen.Applications { 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) { @@ -677,6 +1000,13 @@ namespace Tizen.Applications 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) @@ -687,7 +1017,7 @@ namespace Tizen.Applications private static void UnregisterPackageManagerEventIfNeeded() { - if (Handle.IsInvalid || s_installEventHandler != null || s_uninstallEventHandler != null || s_updateEventHandler != null) + if (Handle.IsInvalid || s_installEventHandler != null || s_uninstallEventHandler != null || s_updateEventHandler != null || s_moveEventHandler != null || s_clearDataEventHandler != null) { return; } diff --git a/Tizen.Applications.PackageManager/Tizen.Applications/PackageType.cs b/Tizen.Applications.PackageManager/Tizen.Applications/PackageType.cs index b62a049..97089b9 100755 --- a/Tizen.Applications.PackageManager/Tizen.Applications/PackageType.cs +++ b/Tizen.Applications.PackageManager/Tizen.Applications/PackageType.cs @@ -23,6 +23,7 @@ namespace Tizen.Applications /// </summary> public enum PackageType { + UNKNOWN, /// <summary> /// Tizen native application package /// </summary> diff --git a/Tizen.Applications.PackageManager/Tizen.Applications/SafePackageManagerRequestHandle.cs b/Tizen.Applications.PackageManager/Tizen.Applications/SafePackageManagerRequestHandle.cs new file mode 100755 index 0000000..add74f5 --- /dev/null +++ b/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/Tizen.Applications.UI/Tizen.Applications.UI.csproj b/Tizen.Applications.UI/Tizen.Applications.UI.csproj index 1773b61..2ae4d16 100755 --- a/Tizen.Applications.UI/Tizen.Applications.UI.csproj +++ b/Tizen.Applications.UI/Tizen.Applications.UI.csproj @@ -81,4 +81,4 @@ <_FullFrameworkReferenceAssemblyPaths>$(MSBuildThisFileDirectory)</_FullFrameworkReferenceAssemblyPaths> <AutoUnifyAssemblyReferences>true</AutoUnifyAssemblyReferences> </PropertyGroup> -</Project>
\ No newline at end of file +</Project> diff --git a/Tizen.Applications/Tizen.Applications.csproj b/Tizen.Applications/Tizen.Applications.csproj index 62b1fba..48adeff 100755 --- a/Tizen.Applications/Tizen.Applications.csproj +++ b/Tizen.Applications/Tizen.Applications.csproj @@ -106,6 +106,7 @@ <Compile Include="../Tizen.Applications.PackageManager/Tizen.Applications/Package.cs" /> <Compile Include="../Tizen.Applications.PackageManager/Tizen.Applications/PackageCertificate.cs" /> <Compile Include="../Tizen.Applications.PackageManager/Tizen.Applications/PackageEventState.cs" /> + <Compile Include="../Tizen.Applications.PackageManager/Tizen.Applications/PackageEventType.cs" /> <Compile Include="../Tizen.Applications.PackageManager/Tizen.Applications/PackageFilter.cs" /> <Compile Include="../Tizen.Applications.PackageManager/Tizen.Applications/PackageManager.cs" /> <Compile Include="../Tizen.Applications.PackageManager/Tizen.Applications/PackageManagerEventArgs.cs" /> @@ -121,6 +122,7 @@ <Compile Include="../Tizen.Applications.Common/Tizen.Applications/SafeAppControlHandle.cs" /> <Compile Include="../Tizen.Applications.Common/Tizen.Applications/SafeBundleHandle.cs" /> <Compile Include="../Tizen.Applications.PackageManager/Tizen.Applications/SafePackageManagerHandle.cs" /> + <Compile Include="../Tizen.Applications.PackageManager/Tizen.Applications/SafePackageManagerRequestHandle.cs" /> <Compile Include="../Tizen.Applications.Service/Tizen.Applications/ServiceApplication.cs" /> <Compile Include="../Tizen.Applications.Service/Tizen.Applications.CoreBackend/ServiceCoreBackend.cs" /> <Compile Include="../Tizen.Applications.PackageManager/Tizen.Applications/StorageType.cs" /> |