/*
* Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the License);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF 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
{
///
/// PackageManager class. This class has the methods and events of the PackageManager.
///
///
/// The package manager is one of the core modules of the Tizen application framework and responsible for getting their information.
/// You can also retrieve information related to the packages that are installed on the device.
///
/// 3
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 s_installEventHandler;
private static event EventHandler s_uninstallEventHandler;
private static event EventHandler s_updateEventHandler;
private static event EventHandler s_moveEventHandler;
private static event EventHandler s_clearDataEventHandler;
private static readonly object s_pkgEventLock = new object();
private static Interop.PackageManager.PackageManagerEventCallback s_packageManagerEventCallback;
private static Dictionary s_totalSizeInfoCallbackDict = new Dictionary();
private static int s_callbackId = 0;
///
/// Event callback method for the request.
///
/// Type of the package which was requested.
/// ID of the package which was requested.
/// Event type of the request.
/// Current event state of the request.
/// Progress for the request being processed by the package manager (in percent).
/// 3
public delegate void RequestEventCallback(string type, string packageId, PackageEventType eventType, PackageEventState eventState, int progress);
private static Dictionary RequestCallbacks = new Dictionary();
private static Dictionary RequestHandles = new Dictionary();
private delegate Interop.PackageManager.ErrorCode InstallMethodWithCallback(SafePackageManagerRequestHandle requestHandle, string pkgPath, Interop.PackageManager.PackageManagerRequestEventCallback requestCallback, IntPtr userData, out int requestID);
private delegate Interop.PackageManager.ErrorCode InstallMethod(SafePackageManagerRequestHandle requestHandle, string pkgPath, out int requestID);
///
/// InstallProgressChanged event. This event occurs when a package is getting installed and the progress of the request to the package manager is changed.
///
/// 3
public static event EventHandler InstallProgressChanged
{
add
{
lock (s_pkgEventLock)
{
SetPackageManagerEventStatus(Interop.PackageManager.EventStatus.Install);
RegisterPackageManagerEventIfNeeded();
s_installEventHandler += value;
}
}
remove
{
lock (s_pkgEventLock)
{
s_installEventHandler -= value;
UnregisterPackageManagerEventIfNeeded();
UnsetPackageManagerEventStatus();
}
}
}
///
/// UninstallProgressChanged event. This event occurs when a package is getting uninstalled and the progress of the request to the package manager is changed.
///
/// 3
public static event EventHandler UninstallProgressChanged
{
add
{
lock (s_pkgEventLock)
{
SetPackageManagerEventStatus(Interop.PackageManager.EventStatus.Uninstall);
RegisterPackageManagerEventIfNeeded();
s_uninstallEventHandler += value;
}
}
remove
{
lock (s_pkgEventLock)
{
s_uninstallEventHandler -= value;
UnregisterPackageManagerEventIfNeeded();
UnsetPackageManagerEventStatus();
}
}
}
///
/// UpdateProgressChanged event. This event occurs when a package is getting updated and the progress of the request to the package manager is changed.
///
/// 3
public static event EventHandler UpdateProgressChanged
{
add
{
lock (s_pkgEventLock)
{
SetPackageManagerEventStatus(Interop.PackageManager.EventStatus.Upgrade);
RegisterPackageManagerEventIfNeeded();
s_updateEventHandler += value;
}
}
remove
{
lock (s_pkgEventLock)
{
s_updateEventHandler -= value;
UnregisterPackageManagerEventIfNeeded();
UnsetPackageManagerEventStatus();
}
}
}
///
/// MoveProgressChanged event. This event occurs when a package is getting moved and the progress of the request to the package manager is changed.
///
/// 3
public static event EventHandler MoveProgressChanged
{
add
{
lock (s_pkgEventLock)
{
SetPackageManagerEventStatus(Interop.PackageManager.EventStatus.Move);
RegisterPackageManagerEventIfNeeded();
s_moveEventHandler += value;
}
}
remove
{
lock (s_pkgEventLock)
{
s_moveEventHandler -= value;
UnregisterPackageManagerEventIfNeeded();
UnsetPackageManagerEventStatus();
}
}
}
///
/// ClearDataProgressChanged event. This event occurs when data directories are cleared in the given package.
///
/// 3
public static event EventHandler ClearDataProgressChanged
{
add
{
lock (s_pkgEventLock)
{
SetPackageManagerEventStatus(Interop.PackageManager.EventStatus.ClearData);
RegisterPackageManagerEventIfNeeded();
s_clearDataEventHandler += value;
}
}
remove
{
lock (s_pkgEventLock)
{
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);
}
}
};
///
/// Gets the package ID for the given application ID.
///
/// The ID of the application.
/// Returns the ID of the package.
/// It returns null if the input is null.
/// Thrown when input application ID does not exist.
/// Thrown when there is not enough memory to continue the execution of the method.
/// Thrown when an application does not have the privilege to access this method.
/// http://tizen.org/privilege/packagemanager.info
/// 3
public static string GetPackageIdByApplicationId(string applicationId)
{
string packageId;
var err = Interop.PackageManager.PackageManagerGetPackageIdByAppId(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;
}
///
/// Gets the package information for the given package.
///
/// The ID of the package.
/// Returns the package information for the given package ID.
/// Thrown when the failed input package ID is invalid.
/// Thrown when there is not enough memory to continue the execution of the method.
/// Thrown when the method fails due to an internal I/O error.
/// Thrown when an application does not have the privilege to access this method.
/// http://tizen.org/privilege/packagemanager.info
/// 3
public static Package GetPackage(string packageId)
{
return Package.GetPackage(packageId);
}
///
/// Clears the application's internal and external cache directories.
///
/// ID of the package.
/// Thrown when there is not enough memory to continue the execution of the method.
/// Thrown when the method fails due to an internal I/O error.
/// Thrown when an application does not have the privilege to access this method.
/// Thrown when the method failed due to an internal system error.
/// http://tizen.org/privilege/packagemanager.clearcache
/// 3
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");
}
}
///
/// Clears all the application's internal and external cache directories.
///
/// Thrown when there is not enough memory to continue the execution of the method.
/// Thrown when the method fails due to an internal IO error.
/// Thrown when an application does not have the privilege to access this method.
/// Thrown when the method failed due to an internal system error.
/// http://tizen.org/privilege/packagemanager.admin
/// platform
/// 3
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");
}
}
///
/// Clears the application's internal and external data directories.
///
///
/// All files under data, shared/data, and shared/trusted in the internal storage are removed.
/// And, if the external storage exists, then all files under data and shared/trusted in the external storage are removed.
///
/// ID of the package.
/// Thrown when there is not enough memory to continue the execution of the method.
/// Thrown when the method failed due to an internal IO error.
/// Thrown when an application does not have the privilege to access this method.
/// Thrown when the method failed due to an internal system error.
/// http://tizen.org/privilege/packagemanager.admin
/// platform
/// 3
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");
}
}
///
/// Retrieves the package information of all installed packages.
///
/// Returns the list of packages.
/// http://tizen.org/privilege/packagemanager.info
/// 3
public static IEnumerable GetPackages()
{
return GetPackages(null);
}
///
/// Retrieves the package information of all the installed packages satisfying the filter conditions.
///
/// Optional - package filters.
/// Returns the list of packages.
/// http://tizen.org/privilege/packagemanager.info
/// 3
public static IEnumerable GetPackages(PackageFilter filter)
{
List packageList = new List();
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 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;
}
///
/// Gets the total package size information.
///
/// Returns the total package size information asynchronously.
/// http://tizen.org/privilege/packagemanager.info
/// 3
public static async Task GetTotalSizeInformationAsync()
{
TaskCompletionSource tcs = new TaskCompletionSource();
Interop.PackageManager.PackageManagerTotalSizeInfoCallback cb = (handle, userData) =>
{
if (handle != IntPtr.Zero)
{
tcs.TrySetResult(PackageSizeInformation.GetPackageSizeInformation(handle));
}
lock (s_totalSizeInfoCallbackDict)
{
s_totalSizeInfoCallbackDict.Remove(userData);
}
};
IntPtr callbackId;
lock (s_totalSizeInfoCallbackDict)
{
callbackId = (IntPtr)s_callbackId++;
s_totalSizeInfoCallbackDict[callbackId] = cb;
}
var err = Interop.PackageManager.PackageManagerGetTotalSizeInfo(cb, callbackId);
if (err != Interop.PackageManager.ErrorCode.None)
{
tcs.TrySetException(PackageManagerErrorFactory.GetException(err, "Failed to get total package size info"));
}
return await tcs.Task.ConfigureAwait(false);
}
///
/// Installs the package located at the given path.
///
/// Absolute path for the package to be installed.
/// Optional parameter to indicate special installation mode.
/// Returns true if the installation request is successful, otherwise false.
///
/// The 'true' means that the request for installation is successful.
/// To check the result of the installation, the caller should check the progress using the InstallProgressChanged event.
///
/// http://tizen.org/privilege/packagemanager.admin
/// platform
/// 3
public static bool Install(string packagePath, InstallationMode installMode = InstallationMode.Normal)
{
return Install(packagePath, null, PackageType.UNKNOWN, null, installMode);
}
///
/// Installs the package located at the given path.
///
/// Absolute path for the package to be installed.
/// The event callback will be invoked only for the current request.
/// Optional parameter to indicate special installation mode.
/// Returns true if installation request is successful, false otherwise.
///
/// The 'true' means that the request for installation is successful.
/// To check the result of installation, the caller should check the progress using the InstallProgressChanged event or eventCallback.
///
/// http://tizen.org/privilege/packagemanager.admin
/// platform
/// 3
public static bool Install(string packagePath, RequestEventCallback eventCallback, InstallationMode installMode = InstallationMode.Normal)
{
return Install(packagePath, null, PackageType.UNKNOWN, eventCallback, installMode);
}
///
/// Installs the package located at the given path.
///
/// Absolute path for the package to be installed.
/// Package type for the package to be installed.
/// Optional parameter to indicate special installation mode.
/// Returns true if installation request is successful, false otherwise.
///
/// The 'true' means that the request for installation is successful.
/// To check the result of installation, the caller should check the progress using the InstallProgressChanged event.
///
/// http://tizen.org/privilege/packagemanager.admin
/// platform
/// 3
public static bool Install(string packagePath, PackageType type, InstallationMode installMode = InstallationMode.Normal)
{
return Install(packagePath, null, type, null, installMode);
}
///
/// Installs the package located at the given path.
///
/// Absolute path for the package to be installed.
/// Absolute path for the expansion package to be installed.
/// Optional parameter to indicate special installation mode.
/// Returns true if installation request is successful, false otherwise.
///
/// The 'true' means that the request for installation is successful.
/// To check the result of installation, the caller should check the progress using the InstallProgressChanged event.
///
/// http://tizen.org/privilege/packagemanager.admin
/// platform
/// 3
public static bool Install(string packagePath, string expansionPackagePath, InstallationMode installMode = InstallationMode.Normal)
{
return Install(packagePath, expansionPackagePath, PackageType.UNKNOWN, null, installMode);
}
///
/// Installs the package located at the given path.
///
/// Absolute path for the package to be installed.
/// Package type for the package to be installed.
/// The event callback will be invoked only for the current request.
/// Optional parameter to indicate special installation mode.
/// Returns true if installation request is successful, false otherwise.
///
/// The 'true' means that the request for installation is successful.
/// To check the result of installation, the caller should check the progress using the InstallProgressChanged event or eventCallback.
///
/// http://tizen.org/privilege/packagemanager.admin
/// platform
/// 3
public static bool Install(string packagePath, PackageType type, RequestEventCallback eventCallback, InstallationMode installMode = InstallationMode.Normal)
{
return Install(packagePath, null, type, eventCallback, installMode);
}
///
/// Installs the package located at the given path.
///
/// Absolute path for the package to be installed.
/// Absolute path for the expansion package to be installed.
/// The event callback will be invoked only for the current request.
/// Optional parameter to indicate special installation mode.
/// Returns true if installation request is successful, false otherwise.
///
/// The 'true' means that the request for installation is successful.
/// To check the result of installation, the caller should check the progress using the InstallProgressChanged event or eventCallback.
///
/// http://tizen.org/privilege/packagemanager.admin
/// platform
/// 3
public static bool Install(string packagePath, string expansionPackagePath, RequestEventCallback eventCallback, InstallationMode installMode = InstallationMode.Normal)
{
return Install(packagePath, expansionPackagePath, PackageType.UNKNOWN, eventCallback, installMode);
}
///
/// Installs the package located at the given path.
///
/// Absolute path for the package to be installed.
/// Absolute path for the expansion package to be installed.
/// Package type for the package to be installed.
/// Optional parameter to indicate special installation mode.
/// Returns true if installation request is successful, false otherwise.
///
/// The 'true' means that the request for installation is successful.
/// To check the result of installation, the caller should check the progress using the InstallProgressChanged event.
///
/// http://tizen.org/privilege/packagemanager.admin
/// platform
/// 3
public static bool Install(string packagePath, string expansionPackagePath, PackageType type, InstallationMode installMode = InstallationMode.Normal)
{
return Install(packagePath, expansionPackagePath, type, null, installMode);
}
///
/// Installs the package located at the given path.
///
/// Absolute path for the package to be installed.
/// Absolute path for the expansion package to be installed.
/// Package type for the package to be installed.
/// The event callback will be invoked only for the current request.
/// Optional parameter to indicate special installation mode.
/// Returns true if installation request is successful, false otherwise.
///
/// The 'true' means that the request for installation is successful.
/// To check the result of installation, the caller should check the progress using the InstallProgressChanged event or eventCallback.
///
/// http://tizen.org/privilege/packagemanager.admin
/// platform
/// 3
public static bool Install(string packagePath, string expansionPackagePath, PackageType type, RequestEventCallback eventCallback, InstallationMode installMode = InstallationMode.Normal)
{
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)
{
InstallMethodWithCallback install;
if (installMode == InstallationMode.Mount)
{
install = Interop.PackageManager.PackageManagerRequestMountInstallWithCB;
}
else
{
install = Interop.PackageManager.PackageManagerRequestInstallWithCB;
}
err = install(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
{
InstallMethod install;
if (installMode == InstallationMode.Mount)
{
install = Interop.PackageManager.PackageManagerRequestMountInstall;
}
else
{
install = Interop.PackageManager.PackageManagerRequestInstall;
}
err = install(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;
}
}
///
/// Uninstalls the package with the given name.
///
/// ID of the package to be uninstalled.
/// Returns true if the uninstallation request is successful, false otherwise.
///
/// The 'true' means that the request for uninstallation is successful.
/// To check the result of uninstallation, the caller should check the progress using the UninstallProgressChanged event.
///
/// http://tizen.org/privilege/packagemanager.admin
/// platform
/// 3
public static bool Uninstall(string packageId)
{
return Uninstall(packageId, PackageType.UNKNOWN, null);
}
///
/// Uninstalls package with the given names.
///
/// ID of the package to be uninstalled.
/// Optional - Package type for the package to be uninstalled.
/// Returns true if the uninstallation request is successful, false otherwise.
///
/// The 'true' means that the request for uninstallation is successful.
/// To check the result of uninstallation, the caller should check the progress using the UninstallProgressChanged event.
///
/// http://tizen.org/privilege/packagemanager.admin
/// platform
/// 3
public static bool Uninstall(string packageId, PackageType type)
{
return Uninstall(packageId, type, null);
}
///
/// Uninstalls the package with the given name.
///
/// ID of the package to be uninstalled.
/// Optional - The event callback will be invoked only for the current request.
/// Returns true if the uninstallation request is successful, false otherwise.
///
/// The 'true' means that the request for uninstallation is successful.
/// To check the result of uninstallation, the caller should check the progress using the UninstallProgressChanged event or eventCallback.
///
/// http://tizen.org/privilege/packagemanager.admin
/// platform
/// 3
public static bool Uninstall(string packageId, RequestEventCallback eventCallback)
{
return Uninstall(packageId, PackageType.UNKNOWN, eventCallback);
}
///
/// Uninstalls the package with the given name.
///
/// ID of the package to be uninstalled
/// Optional - Package type for the package to be uninstalled.
/// Optional - The event callback will be invoked only for the current request.
/// Returns true if the uninstallation request is successful, false otherwise.
///
/// The 'true' means that the request for uninstallation is successful.
/// To check the result of uninstallation, the caller should check the progress using the UninstallProgressChanged event or eventCallback.
///
/// http://tizen.org/privilege/packagemanager.admin
/// platform
/// 3
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;
}
}
///
/// Moves the package to the given storage.
///
/// ID of the package to be moved.
/// Storage package should be moved to.
/// Returns true if the move request is successful, false otherwise.
///
/// The 'true' means that the request for move is successful.
/// To check the result of move, the caller should check the progress using the MoveProgressChanged event.
///
/// http://tizen.org/privilege/packagemanager.admin
/// platform
/// 3
public static bool Move(string packageId, StorageType newStorage)
{
return Move(packageId, PackageType.UNKNOWN, newStorage, null);
}
///
/// Moves the package to the given storage.
///
/// ID of the package to be moved.
/// Optional - Package type for the package to be moved.
/// Storage package should be moved to.
/// Returns true if the move request is successful, false otherwise.
///
/// The 'true' means that the request for move is successful.
/// To check the result of move, the caller should check the progress using the MoveProgressChanged event.
///
/// http://tizen.org/privilege/packagemanager.admin
/// platform
/// 3
public static bool Move(string packageId, PackageType type, StorageType newStorage)
{
return Move(packageId, type, newStorage, null);
}
///
/// Moves the package to the given storage.
///
/// ID of the package to be moved.
/// Storage package should be moved to.
/// Optional - The event callback will be invoked only for the current request.
/// Returns true if move request is successful, false otherwise.
///
/// The 'true' means that the request for move is successful.
/// To check the result of move, the caller should check the progress using the MoveProgressChanged event.
///
/// http://tizen.org/privilege/packagemanager.admin
/// platform
/// 3
public static bool Move(string packageId, StorageType newStorage, RequestEventCallback eventCallback)
{
return Move(packageId, PackageType.UNKNOWN, newStorage, eventCallback);
}
///
/// Moves the package to the given storage.
///
/// ID of the package to be moved.
/// Optional - Package type for the package to be moved.
/// Storage, package should be moved to.
/// Optional - The event callback will be invoked only for the current request.
/// Returns true if move request is successful, false otherwise.
///
/// The 'true' means that the request for move is successful.
/// To check the result of move, the caller should check the progress using the MoveProgressChanged event.
///
/// http://tizen.org/privilege/packagemanager.admin
/// platform
/// 3
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;
}
}
///
/// Gets the permission type of the package which has a given application ID.
///
/// ID of the application.
/// Returns the permission type.
/// http://tizen.org/privilege/packagemanager.info
/// Thrown when the failed input package ID is invalid.
/// Thrown when an application does not have the privilege to access this method.
/// 3
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;
}
///
/// Gets the package's preload attribute which contains a given application ID.
///
/// ID of the application.
/// Returns true if the package is preloaded, otherwise false.
/// http://tizen.org/privilege/packagemanager.info
/// Thrown when the failed input package ID is invalid.
/// Thrown when an application does not have the privilege to access this method.
/// 3
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;
}
///
/// Compares the certificate of the two packages.
///
/// Package ID to compare.
/// Package ID to be compared.
/// Returns certificate comparison result.
/// Thrown when the failed input package ID is invalid.
/// Thrown when the method failed due to an internal I/O error.
/// 3
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;
}
///
/// Compares the certificate of the two packages which contain each given application ID.
///
/// Application ID to compare.
/// Application ID to be compared.
/// Returns certificate comparison result.
/// Thrown when the failed input package ID is invalid.
/// Thrown when the method failed due to an internal I/O error.
/// 3
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;
}
///
/// Gets the package archive's information for the given archive path.
///
/// The path of the package archive.
///
/// Regular 3rd party apps do not need to use this API
///
/// Returns the package archive information for the given archive path.
/// Thrown when the failed input package ID is invalid.
/// Thrown when the method fails due to an internal I/O error.
/// 6
public static PackageArchive GetPackageArchive(string archivePath)
{
return PackageArchive.GetPackageArchive(archivePath);
}
///
/// Drm nested class. This class has the PackageManager's drm related methods.
///
/// 3
public static class Drm
{
///
/// Generates a request for getting the license.
///
/// Response data string of the purchase request.
/// Returns the package DRM information of a given response data which contains the required data and license URL.
/// http://tizen.org/privilege/packagemanager.admin
/// platform
/// Thrown when failed when input package ID is invalid.
/// Thrown when there is not enough memory to continue the execution of the method.
/// Thrown when an application does not have the privilege to access this method.
/// Thrown when the method failed due to an internal system error.
/// 3
public static PackageDrm GenerateLicenseRequest(string responseData)
{
return PackageDrm.GenerateLicenseRequest(responseData);
}
///
/// Registers the encrypted license.
///
/// The response data string of the rights request.
/// Returns true if succeeds, otherwise false.
/// http://tizen.org/privilege/packagemanager.admin
/// platform
/// Thrown when failed when input package ID is invalid.
/// Thrown when there is not enough memory to continue the execution of the method.
/// Thrown when an application does not have the privilege to access this method.
/// Thrown when the method failed due to internal system error.
/// 3
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;
}
///
/// Decrypts the contents which are encrypted.
///
/// Drm file path.
/// Decrypted file path.
/// Returns true if succeeds, otherwise false.
/// http://tizen.org/privilege/packagemanager.admin
/// platform
/// Thrown when failed when input package ID is invalid.
/// Thrown when there is not enough memory to continue the execution of the method.
/// Thrown when an application does not have the privilege to access this method.
/// Thrown when the method failed due to an internal system error.
/// 3
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.PackageManagerSetEventStatus(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.PackageManagerSetEventStatus(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 = new Interop.PackageManager.PackageManagerEventCallback(InternalEventCallback);
if (!Handle.IsInvalid)
{
lock (Handle)
{
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 InternalEventCallback(string packageType, string packageId, Interop.PackageManager.EventType eventType, Interop.PackageManager.PackageEventState eventState, int progress, Interop.PackageManager.ErrorCode error, IntPtr 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);
}
}
private static void UnregisterPackageManagerEventIfNeeded()
{
if (s_packageManagerEventCallback == null || s_installEventHandler != null || s_uninstallEventHandler != null || s_updateEventHandler != null || s_moveEventHandler != null || s_clearDataEventHandler != null)
{
return;
}
s_packageManagerEventCallback = null;
lock (Handle)
{
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);
}
}
}
}