Release 4.0.0-preview1-00051
[platform/core/csapi/tizenfx.git] / src / Tizen.Context / Tizen.Context.AppHistory / UsageStatistics.cs
1 /*
2  * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 using System;
18 using System.Collections.Generic;
19
20 namespace Tizen.Context.AppHistory
21 {
22     /// <summary>
23     /// This class provides APIs to query application launch history.
24     /// </summary>
25     public class UsageStatistics : AppStatistics
26     {
27         private const string AppStatsDuration = "TotalDuration";
28         private const string AppStatsLaunchCount = "TotalCount";
29         private const string AppStatsLastLaunchTime = "LastTime";
30
31         /// <summary>
32         /// The default constructor of UsageStatistics class.
33         /// </summary>
34         /// <exception cref="InvalidOperationException">Thrown when method fail due to internal error.</exception>
35         public UsageStatistics()
36         {
37             SortOrder = SortOrderType.LastLaunchTimeNewest;
38             Uri = ConvertSortOrderToString((int)SortOrder);
39
40             bool isSupported = false;
41             int error = Interop.CtxHistory.IsSupported(Uri, out isSupported);
42             if ((AppHistoryError)error != AppHistoryError.None)
43             {
44                 throw AppHistoryErrorFactory.CheckAndThrowException((AppHistoryError)error, Uri);
45             }
46
47             if (!isSupported)
48             {
49                 throw AppHistoryErrorFactory.CheckAndThrowException(AppHistoryError.OperationFailed, Uri);
50             }
51         }
52
53         /// <summary>
54         /// The constructor of UsageStatistics class.
55         /// </summary>
56         /// <param name="order">The criteria of the usage statistics sorted by.</param>
57         /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
58         /// <exception cref="InvalidOperationException">Thrown when method fail due to internal error.</exception>
59         public UsageStatistics(SortOrderType order)
60         {
61             SortOrder = order;
62             Uri = ConvertSortOrderToString((int)SortOrder);
63
64             if (Uri== null)
65             {
66                 throw AppHistoryErrorFactory.CheckAndThrowException(AppHistoryError.InvalidParameter, "Invalid SortOrderType");
67             }
68
69             bool isSupported = false;
70             int error = Interop.CtxHistory.IsSupported(Uri, out isSupported);
71             if ((AppHistoryError)error != AppHistoryError.None)
72             {
73                 throw AppHistoryErrorFactory.CheckAndThrowException((AppHistoryError)error, Uri);
74             }
75
76             if (!isSupported)
77             {
78                 throw AppHistoryErrorFactory.CheckAndThrowException(AppHistoryError.OperationFailed, Uri);
79             }
80         }
81
82         /// <summary>
83         /// Retrieves a given type of usage statistics.
84         /// </summary>
85         /// <param name="startTime">The start time of the data to be aggregated.</param>
86         /// <param name="endTime">The end time of the data to be aggregated.</param>
87         /// <returns>Usage statistics data retrieved.</returns>
88         /// <privilege>http://tizen.org/privilege/apphistory.read</privilege>
89         /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
90         /// <exception cref="InvalidOperationException">Thrown when invalid operation occurs.</exception>
91         /// <exception cref="UnauthorizedAccessException">Thrown when the app has no privilege to retrieve app history.</exception>
92         public IReadOnlyList<UsageStatisticsData> Query(DateTime startTime, DateTime endTime)
93         {
94             CheckTimeSpan(startTime, endTime);
95
96             return Query(startTime, endTime, DefaultResultSize);
97         }
98
99         /// <summary>
100         /// Retrieves a given type of usage statistics.
101         /// </summary>
102         /// <param name="startTime">The start time of the data to be aggregated.</param>
103         /// <param name="endTime">The end time of the data to be aggregated.</param>
104         /// <param name="resultSize">The number of data records to be retrieved.</param>
105         /// <returns>Usage statistics data retrieved.</returns>
106         /// <privilege>http://tizen.org/privilege/apphistory.read</privilege>
107         /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
108         /// <exception cref="InvalidOperationException">Thrown when invalid operation occurs.</exception>
109         /// <exception cref="UnauthorizedAccessException">Thrown when the app has no privilege to retrieve app history.</exception>
110         public IReadOnlyList<UsageStatisticsData> Query(DateTime startTime, DateTime endTime, uint resultSize)
111         {
112             CheckTimeSpan(startTime, endTime);
113             CheckResultSize(resultSize);
114
115             List<UsageStatisticsData> result = new List<UsageStatisticsData>();
116
117             IntPtr cursor = IntPtr.Zero;
118             int error = Interop.CtxHistory.Query(Uri, ConvertDateTimeToUnixTimestamp(startTime), ConvertDateTimeToUnixTimestamp(endTime), resultSize, out cursor);
119             if ((AppHistoryError)error == AppHistoryError.NoData)
120             {
121                 return result.AsReadOnly();
122             } else if ((AppHistoryError)error != AppHistoryError.None)
123             {
124                 Log.Error(AppHistoryErrorFactory.LogTag, "Failed to request query usage statistics");
125                 throw AppHistoryErrorFactory.CheckAndThrowException((AppHistoryError)error, "Failed to request query usage statistics");
126             }
127
128             int size;
129             error = Interop.CtxHistoryCursor.GetCount(cursor, out size);
130             Interop.CtxHistoryCursor.First(cursor);
131
132             for (int i = 0; i < size; i++)
133             {
134                 result.Add(ConvertOutputToStatsData(cursor));
135                 Interop.CtxHistoryCursor.Next(cursor);
136             }
137             Interop.CtxHistoryCursor.Destroy(cursor);
138
139             return result.AsReadOnly();
140         }
141
142         internal override string ConvertSortOrderToString(int order)
143         {
144             switch ((SortOrderType)order)
145             {
146                 case SortOrderType.LastLaunchTimeNewest:
147                     return "stats/app/recently";
148                 case SortOrderType.LaunchCountMost:
149                     return "stats/app/often";
150                 default:
151                     return null;
152             }
153         }
154
155         private static UsageStatisticsData ConvertOutputToStatsData(IntPtr cursor)
156         {
157             string appId;
158             Int64 duration = 1;
159             Int64 launchCount = 1;
160             Int64 lastLaunchTime;
161
162             Interop.CtxHistoryCursor.GetString(cursor, AppStatsAppId, out appId);
163             Interop.CtxHistoryCursor.GetInt64(cursor, AppStatsDuration, out duration);
164             Interop.CtxHistoryCursor.GetInt64(cursor, AppStatsLaunchCount, out launchCount);
165             Interop.CtxHistoryCursor.GetInt64(cursor, AppStatsLastLaunchTime, out lastLaunchTime);
166
167             return new UsageStatisticsData(appId, (int)duration, (int)launchCount, ConvertUnixTimestampToDateTime(lastLaunchTime));
168         }
169
170         /// <summary>
171         /// Gets the criteria of usage statistics sorted by.
172         /// </summary>
173         /// <value>The criteria of usage statistics sorted by.</value>
174         public SortOrderType SortOrder { get; private set; }
175
176         /// <summary>
177         /// Sort order type of usage statistics
178         /// </summary>
179         public enum SortOrderType
180         {
181             /// <summary>
182             /// Sorts apps by the last launch time, the most recently launched apps appear first. (Default)
183             /// </summary>
184             LastLaunchTimeNewest = 0,
185             /// <summary>
186             /// Sorts apps by the launch count of being launched, the most frequently launched apps appear first.
187             /// </summary>
188             LaunchCountMost
189         }
190     }
191 }