Release 4.0.0-preview1-00051
[platform/core/csapi/tizenfx.git] / src / Tizen.System.Information / RuntimeInfo / RuntimeInformation.cs
1 /*
2 * Copyright (c) 2016 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 using System.IO;
20 using System.Linq;
21 using System.Text;
22 using System.Threading.Tasks;
23 using System.ComponentModel;
24
25 namespace Tizen.System
26 {
27     /// <summary>
28     /// The RuntimeInformation provides functions to obtain the runtime information of various system preferences.
29     /// </summary>
30     public static class RuntimeInformation
31     {
32         private static event EventHandler<RuntimeKeyStatusChangedEventArgs> s_bluetoothEnabled;
33         private static event EventHandler<RuntimeKeyStatusChangedEventArgs> s_wifiHotspotEnabled;
34         private static event EventHandler<RuntimeKeyStatusChangedEventArgs> s_bluetoothTetheringEnabled;
35         private static event EventHandler<RuntimeKeyStatusChangedEventArgs> s_usbTetheringEnabled;
36         private static event EventHandler<RuntimeKeyStatusChangedEventArgs> s_packetDataEnabled;
37         private static event EventHandler<RuntimeKeyStatusChangedEventArgs> s_dataRoamingEnabled;
38         private static event EventHandler<RuntimeKeyStatusChangedEventArgs> s_vibrationEnabled;
39         private static event EventHandler<RuntimeKeyStatusChangedEventArgs> s_audioJackConnected;
40         private static event EventHandler<RuntimeKeyStatusChangedEventArgs> s_gpsStatusChanged;
41         private static event EventHandler<RuntimeKeyStatusChangedEventArgs> s_batteryIsCharging;
42         private static event EventHandler<RuntimeKeyStatusChangedEventArgs> s_tvOutConnected;
43         private static event EventHandler<RuntimeKeyStatusChangedEventArgs> s_audioJackConnectorChanged;
44         private static event EventHandler<RuntimeKeyStatusChangedEventArgs> s_chargerConnected;
45         private static event EventHandler<RuntimeKeyStatusChangedEventArgs> s_autoRotationEnabled;
46
47         private static readonly Interop.RuntimeInfo.RuntimeInformationChangedCallback s_runtimeInfoChangedCallback = (RuntimeInformationKey key, IntPtr userData) =>
48         {
49             RuntimeKeyStatusChangedEventArgs eventArgs = new RuntimeKeyStatusChangedEventArgs()
50             {
51                 Key = key
52             };
53             switch (key)
54             {
55                 case RuntimeInformationKey.Bluetooth:
56                     {
57                         s_bluetoothEnabled?.Invoke(null, eventArgs);
58                         break;
59                     };
60                 case RuntimeInformationKey.WifiHotspot:
61                     {
62                         s_wifiHotspotEnabled?.Invoke(null, eventArgs);
63                         break;
64                     };
65                 case RuntimeInformationKey.BluetoothTethering:
66                     {
67                         s_bluetoothTetheringEnabled?.Invoke(null, eventArgs);
68                         break;
69                     };
70                 case RuntimeInformationKey.UsbTethering:
71                     {
72                         s_usbTetheringEnabled?.Invoke(null, eventArgs);
73                         break;
74                     };
75                 case RuntimeInformationKey.PacketData:
76                     {
77                         s_packetDataEnabled?.Invoke(null, eventArgs);
78                         break;
79                     };
80                 case RuntimeInformationKey.DataRoaming:
81                     {
82                         s_dataRoamingEnabled?.Invoke(null, eventArgs);
83                         break;
84                     };
85                 case RuntimeInformationKey.Vibration:
86                     {
87                         s_vibrationEnabled?.Invoke(null, eventArgs);
88                         break;
89                     };
90                 case RuntimeInformationKey.AudioJack:
91                     {
92                         s_audioJackConnected?.Invoke(null, eventArgs);
93                         break;
94                     };
95                 case RuntimeInformationKey.Gps:
96                     {
97                         s_gpsStatusChanged?.Invoke(null, eventArgs);
98                         break;
99                     };
100                 case RuntimeInformationKey.BatteryIsCharging:
101                     {
102                         s_batteryIsCharging?.Invoke(null, eventArgs);
103                         break;
104                     };
105                 case RuntimeInformationKey.TvOut:
106                     {
107                         s_tvOutConnected?.Invoke(null, eventArgs);
108                         break;
109                     };
110                 case RuntimeInformationKey.AudioJackConnector:
111                     {
112                         s_audioJackConnectorChanged?.Invoke(null, eventArgs);
113                         break;
114                     };
115                 case RuntimeInformationKey.Charger:
116                     {
117                         s_chargerConnected?.Invoke(null, eventArgs);
118                         break;
119                     };
120                 case RuntimeInformationKey.AutoRotation:
121                     {
122                         s_autoRotationEnabled?.Invoke(null, eventArgs);
123                         break;
124                     };
125                 default:
126                     break;
127             };
128         };
129
130         internal static readonly Dictionary<RuntimeInformationKey, Type> s_keyDataTypeMapping = new Dictionary<RuntimeInformationKey, Type>
131         {
132             [RuntimeInformationKey.Bluetooth] = typeof(bool),
133             [RuntimeInformationKey.WifiHotspot] = typeof(bool),
134             [RuntimeInformationKey.BluetoothTethering] = typeof(bool),
135             [RuntimeInformationKey.UsbTethering] = typeof(bool),
136             [RuntimeInformationKey.PacketData] = typeof(bool),
137             [RuntimeInformationKey.DataRoaming] = typeof(bool),
138             [RuntimeInformationKey.Vibration] = typeof(bool),
139             [RuntimeInformationKey.AudioJack] = typeof(bool),
140             [RuntimeInformationKey.BatteryIsCharging] = typeof(bool),
141             [RuntimeInformationKey.TvOut] = typeof(bool),
142             [RuntimeInformationKey.Charger] = typeof(bool),
143             [RuntimeInformationKey.AutoRotation] = typeof(bool),
144             [RuntimeInformationKey.Gps] = typeof(int),
145             [RuntimeInformationKey.AudioJackConnector] = typeof(int)
146         };
147
148         internal static readonly Dictionary<RuntimeInformationKey, int> s_keyTVkeyMapping = new Dictionary<RuntimeInformationKey, int>
149         {
150             [RuntimeInformationKey.Bluetooth] = 5,
151             [RuntimeInformationKey.WifiHotspot] = 6,
152             [RuntimeInformationKey.BluetoothTethering] = 7,
153             [RuntimeInformationKey.UsbTethering] = 8,
154             [RuntimeInformationKey.PacketData] = 13,
155             [RuntimeInformationKey.DataRoaming] = 14,
156             [RuntimeInformationKey.Vibration] = 16,
157             [RuntimeInformationKey.AudioJack] = 20,
158             [RuntimeInformationKey.BatteryIsCharging] = 22,
159             [RuntimeInformationKey.TvOut] = 18,
160             [RuntimeInformationKey.Charger] = 26,
161             [RuntimeInformationKey.AutoRotation] = 28,
162             [RuntimeInformationKey.Gps] = 21,
163             [RuntimeInformationKey.AudioJackConnector] = 20
164         };
165
166         internal static int is_TV_product = -1;
167
168         [EditorBrowsable(EditorBrowsableState.Never)]
169         /// This function is for a TV product. It will be removed.
170         internal static RuntimeInformationKey ConvertKeyIfTvProduct(RuntimeInformationKey key)
171         {
172             bool is_key_existed = false;
173             string profile;
174             int key_TV = -1;
175
176             if (is_TV_product == -1)
177             {
178                 is_key_existed = SystemInfo.TryGetValue<string>("http://com.samsung/build_config/product_type", out profile);
179                 if (is_key_existed && String.Compare(profile, "TV") == 0)
180                 {
181                     is_TV_product = 1;
182                 }
183                 else
184                 {
185                     is_TV_product = 0;
186                 }
187             }
188
189             if (is_TV_product == 0)
190             {
191                 return key;
192             }
193             else
194             {
195                 if (!s_keyTVkeyMapping.TryGetValue(key, out key_TV))
196                 {
197                     RuntimeInfoErrorFactory.ThrowException((int)RuntimeInfoError.InvalidParameter);
198                 }
199                 return (RuntimeInformationKey)key_TV;
200             }
201         }
202
203         [EditorBrowsable(EditorBrowsableState.Never)]
204         internal static object GetStatus(RuntimeInformationKey key)
205         {
206             Type value;
207             if (!s_keyDataTypeMapping.TryGetValue(key, out value))
208             {
209                 RuntimeInfoErrorFactory.ThrowException((int)RuntimeInfoError.InvalidParameter);
210             }
211
212             if (s_keyDataTypeMapping[key] == typeof(int))
213             {
214                 int status;
215                 int ret = Interop.RuntimeInfo.GetValue(ConvertKeyIfTvProduct(key), out status);
216                 if (ret != (int)RuntimeInfoError.None)
217                 {
218                     Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to get value for key {0}", key.ToString());
219                     RuntimeInfoErrorFactory.ThrowException(ret);
220                 }
221
222                 return status;
223             }
224             else
225             {
226                 bool status;
227                 int ret = Interop.RuntimeInfo.GetValue(ConvertKeyIfTvProduct(key), out status);
228                 if (ret != (int)RuntimeInfoError.None)
229                 {
230                     Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to get value for key {0}", key.ToString());
231                     RuntimeInfoErrorFactory.ThrowException(ret);
232                 }
233
234                 return status;
235             }
236         }
237
238         /// <summary>
239         /// Validates the data type of the status represented by the runtime key.
240         /// Note that this is a generic method.
241         /// </summary>
242         /// <since_tizen> 3 </since_tizen>
243         /// <typeparam name="T">The generic type to validate.</typeparam>
244         /// <param name="key">The runtime information key for which the status type is validated.</param>
245         /// <returns>True if the data type matches.</returns>
246         /// <exception cref="ArgumentException">Thrown when the <paramref name="key"/> is invalid.</exception>
247         public static bool Is<T>(RuntimeInformationKey key)
248         {
249             if (!s_keyDataTypeMapping.ContainsKey(key))
250             {
251                 Log.Error(RuntimeInfoErrorFactory.LogTag, "Invalid data type");
252                 throw new ArgumentException("Invalid parameter");
253             }
254
255             return s_keyDataTypeMapping[key] == typeof(T);
256         }
257
258         /// <summary>
259         /// Gets the status of runtime key.
260         /// Note that this is a generic method.
261         /// </summary>
262         /// <since_tizen> 3 </since_tizen>
263         /// <typeparam name="T">The generic type to return.</typeparam>
264         /// <param name="key">The runtime information key for which the current should be read.</param>
265         /// <returns>The current status of the given key.</returns>.
266         /// <exception cref="ArgumentException">Thrown when the <paramref name="key"/> is invalid.</exception>
267         /// <exception cref="IOException">Thrown when I/O error occurs while reading from the system.</exception>
268         /// <exception cref="NotSupportedException">Thrown when the feature related <paramref name="key"/> is not supported.</exception>
269         public static T GetStatus<T>(RuntimeInformationKey key)
270         {
271             return (T)GetStatus(key);
272         }
273
274         /// <summary>
275         /// Gets the system memory information.
276         /// </summary>
277         /// <since_tizen> 3 </since_tizen>
278         /// <returns>The system memory information structure.</returns>
279         /// <exception cref="IOException">Thrown when I/O error occurs while reading from the system.</exception>
280         public static SystemMemoryInformation GetSystemMemoryInformation()
281         {
282             Interop.RuntimeInfo.MemoryInfo info = new Interop.RuntimeInfo.MemoryInfo();
283             int ret = Interop.RuntimeInfo.GetSystemMemoryInfo(out info);
284             if (ret != (int)RuntimeInfoError.None)
285             {
286                 Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to get System memory information");
287                 RuntimeInfoErrorFactory.ThrowException(ret);
288             }
289
290             return new SystemMemoryInformation(info);
291         }
292
293         /// <summary>
294         /// Gets the memory information per process.
295         /// </summary>
296         /// <since_tizen> 3 </since_tizen>
297         /// <param name="pid">List of unique process ids.</param>
298         /// <returns>List of memory information per process.</returns>
299         /// <privilege>http://tizen.org/privilege/systemmonitor</privilege>
300         /// <exception cref="ArgumentException">Thrown when the <paramref name="pid"/> is empty.</exception>
301         /// <exception cref="IOException">Thrown when an I/O error occurs while reading from the system or requesting to the resource management daemon.</exception>
302         /// <exception cref="OutOfMemoryException">Thrown when the memory is not enough to allocate.</exception>
303         /// <exception cref="UnauthorizedAccessException">Thrown when the caller does not have privilege to use this method.</exception>
304         public static IDictionary<int, ProcessMemoryInformation> GetProcessMemoryInformation(IEnumerable<int> pid)
305         {
306             int[] processArray = pid.ToArray<int>();
307             Interop.RuntimeInfo.ProcessMemoryInfo[] processMemoryArray = new Interop.RuntimeInfo.ProcessMemoryInfo[pid.Count<int>()];
308             Dictionary<int, ProcessMemoryInformation> map = new Dictionary<int, ProcessMemoryInformation>();
309             int ret = Interop.RuntimeInfo.GetProcessMemoryInfo(processArray, pid.Count<int>(), out processMemoryArray);
310             if (ret != (int)RuntimeInfoError.None)
311             {
312                 Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to get Process memory information");
313                 RuntimeInfoErrorFactory.ThrowException(ret);
314             }
315
316             int idx = 0;
317             foreach (Interop.RuntimeInfo.ProcessMemoryInfo cur in processMemoryArray)
318             {
319                 ProcessMemoryInformation processMemory = new ProcessMemoryInformation(cur);
320                 map.Add(processArray[idx], processMemory);
321                 idx++;
322             }
323
324             return map;
325         }
326
327         /// <summary>
328         /// Gets the system CPU usage time.
329         /// </summary>
330         /// <since_tizen> 3 </since_tizen>
331         /// <returns>The system CPU usage time structure.</returns>
332         /// <exception cref="IOException">Thrown when an I/O error occurs while reading from the system.</exception>
333         public static CpuUsage GetCpuUsage()
334         {
335             Interop.RuntimeInfo.CpuUsage usage = new Interop.RuntimeInfo.CpuUsage();
336             int ret = Interop.RuntimeInfo.GetCpuUsage(out usage);
337             if (ret != (int)RuntimeInfoError.None)
338             {
339                 Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to get cpu usage");
340                 RuntimeInfoErrorFactory.ThrowException(ret);
341             }
342             return new CpuUsage(usage);
343         }
344
345         /// <summary>
346         /// Gets the CPU usage time per process.
347         /// </summary>
348         /// <since_tizen> 3 </since_tizen>
349         /// <param name="pid">List of unique process ids.</param>
350         /// <returns>List of CPU usage information per process.</returns>
351         /// <privilege>http://tizen.org/privilege/systemmonitor</privilege>
352         /// <exception cref="ArgumentException">Thrown when the <paramref name="pid"/> is empty.</exception>
353         /// <exception cref="IOException">Thrown when an I/O error occurs while reading from the system or requesting to the resource management daemon.</exception>
354         /// <exception cref="OutOfMemoryException">Thrown when the memory is not enough to allocate.</exception>
355         /// <exception cref="UnauthorizedAccessException">Thrown when the caller does not have privilege to use this method.</exception>
356         public static IDictionary<int, ProcessCpuUsage> GetProcessCpuUsage(IEnumerable<int> pid)
357         {
358             int[] processArray = pid.ToArray<int>();
359             Interop.RuntimeInfo.ProcessCpuUsage[] processCpuUsageArray = new Interop.RuntimeInfo.ProcessCpuUsage[pid.Count<int>()];
360             Dictionary<int, ProcessCpuUsage> map = new Dictionary<int, ProcessCpuUsage>();
361             int ret = Interop.RuntimeInfo.GetProcessCpuUsage(processArray, pid.Count<int>(), out processCpuUsageArray);
362             if (ret != (int)RuntimeInfoError.None)
363             {
364                 Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to get Process cpu usage");
365                 RuntimeInfoErrorFactory.ThrowException(ret);
366             }
367
368             int idx = 0;
369             foreach (Interop.RuntimeInfo.ProcessCpuUsage cur in processCpuUsageArray)
370             {
371                 ProcessCpuUsage processUsage = new ProcessCpuUsage(cur);
372                 map.Add(processArray[idx], processUsage);
373                 idx++;
374             }
375
376             return map;
377         }
378
379         /// <summary>
380         /// Gets the number of processors.
381         /// </summary>
382         /// <value>The number of processors.</value>
383         /// <exception cref="IOException">Thrown when an I/O error occurs while reading from system.</exception>
384         public static int ProcessorCount
385         {
386             get
387             {
388                 int count;
389                 int ret = Interop.RuntimeInfo.GetProcessorCount(out count);
390                 if (ret != (int)RuntimeInfoError.None)
391                 {
392                     Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to get Processor count");
393                     RuntimeInfoErrorFactory.ThrowException(ret);
394                 }
395
396                 return count;
397             }
398         }
399
400         /// <summary>
401         /// Gets the current frequency of the processor.
402         /// </summary>
403         /// <since_tizen> 3 </since_tizen>
404         /// <param name="coreId">The index (from 0) of the CPU core that you want to know the frequency of.</param>
405         /// <returns>The current frequency(MHz) of processor.</returns>
406         /// <exception cref="ArgumentException">Thrown when the <paramref name="coreid"/> is invalid.</exception>
407         /// <exception cref="IOException">Thrown when an I/O error occurs while reading from system.</exception>
408         /// <exception cref="NotSupportedException">Thrown when this system does not store the current CPU frequency.</exception>
409         public static int GetProcessorCurrentFrequency(int coreId)
410         {
411             int frequency;
412             int ret = Interop.RuntimeInfo.GetProcessorCurrentFrequency(coreId, out frequency);
413             if (ret != (int)RuntimeInfoError.None)
414             {
415                 Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to get Processor current frequency");
416                 RuntimeInfoErrorFactory.ThrowException(ret);
417             }
418             return frequency;
419         }
420
421         /// <summary>
422         /// Gets the max frequency of the processor.
423         /// </summary>
424         /// <since_tizen> 3 </since_tizen>
425         /// <param name="coreId">The index (from 0) of CPU core that you want to know the frequency of.</param>
426         /// <returns>The max frequency(MHz) of processor.</returns>
427         /// <exception cref="ArgumentException">Thrown when the <paramref name="coreid"/> is invalid.</exception>
428         /// <exception cref="IOException">Thrown when an I/O error occurs while reading from system.</exception>
429         /// <exception cref="NotSupportedException">Thrown when this system does not store the max CPU frequency.</exception>
430         public static int GetProcessorMaxFrequency(int coreId)
431         {
432             int frequency;
433             int ret = Interop.RuntimeInfo.GetProcessorMaxFrequency(coreId, out frequency);
434             if (ret != (int)RuntimeInfoError.None)
435             {
436                 Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to get  Processor max frequency");
437                 RuntimeInfoErrorFactory.ThrowException(ret);
438             }
439             return frequency;
440         }
441
442         /// <summary>
443         /// (event) BluetoothEnabled is raised when the system preference for Bluetooth is changed.
444         /// </summary>
445         public static event EventHandler<RuntimeKeyStatusChangedEventArgs> BluetoothEnabled
446         {
447             add
448             {
449                 if (s_bluetoothEnabled == null)
450                 {
451                     int ret = Interop.RuntimeInfo.SetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.Bluetooth), s_runtimeInfoChangedCallback, IntPtr.Zero);
452                     if (ret != (int)RuntimeInfoError.None)
453                     {
454                         Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
455                         RuntimeInfoErrorFactory.ThrowException(ret);
456                     }
457                 }
458                 s_bluetoothEnabled += value;
459             }
460             remove
461             {
462                 s_bluetoothEnabled -= value;
463                 if (s_bluetoothEnabled == null)
464                 {
465                     int ret = Interop.RuntimeInfo.UnsetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.Bluetooth));
466                     if (ret != (int)RuntimeInfoError.None)
467                     {
468                         Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
469                         RuntimeInfoErrorFactory.ThrowException(ret);
470                     }
471                 }
472             }
473         }
474         /// <summary>
475         /// (event) WifiHotspotEnabled is raised when the system preference for Wi-Fi is changed.
476         /// </summary>
477         public static event EventHandler<RuntimeKeyStatusChangedEventArgs> WifiHotspotEnabled
478         {
479             add
480             {
481                 if (s_wifiHotspotEnabled == null)
482                 {
483                     int ret = Interop.RuntimeInfo.SetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.WifiHotspot), s_runtimeInfoChangedCallback, IntPtr.Zero);
484                     if (ret != (int)RuntimeInfoError.None)
485                     {
486                         Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
487                         RuntimeInfoErrorFactory.ThrowException(ret);
488                     }
489                 }
490                 s_wifiHotspotEnabled += value;
491             }
492             remove
493             {
494                 s_wifiHotspotEnabled -= value;
495                 if (s_wifiHotspotEnabled == null)
496                 {
497                     int ret = Interop.RuntimeInfo.UnsetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.WifiHotspot));
498                     if (ret != (int)RuntimeInfoError.None)
499                     {
500                         Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
501                         RuntimeInfoErrorFactory.ThrowException(ret);
502                     }
503                 }
504             }
505         }
506         /// <summary>
507         /// (event) BluetoothTetheringEnabled is raised when the system preference for bluetooth tethering is changed.
508         /// </summary>
509         public static event EventHandler<RuntimeKeyStatusChangedEventArgs> BluetoothTetheringEnabled
510         {
511             add
512             {
513                 if (s_bluetoothTetheringEnabled == null)
514                 {
515                     int ret = Interop.RuntimeInfo.SetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.BluetoothTethering), s_runtimeInfoChangedCallback, IntPtr.Zero);
516                     if (ret != (int)RuntimeInfoError.None)
517                     {
518                         Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
519                         RuntimeInfoErrorFactory.ThrowException(ret);
520                     }
521                 }
522                 s_bluetoothTetheringEnabled += value;
523             }
524             remove
525             {
526                 s_bluetoothTetheringEnabled -= value;
527                 if (s_bluetoothTetheringEnabled == null)
528                 {
529                     int ret = Interop.RuntimeInfo.UnsetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.BluetoothTethering));
530                     if (ret != (int)RuntimeInfoError.None)
531                     {
532                         Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
533                         RuntimeInfoErrorFactory.ThrowException(ret);
534                     }
535                 }
536             }
537         }
538         /// <summary>
539         /// (event) UsbTetheringEnabled is raised when the system preference for USB tethering is changed.
540         /// </summary>
541         public static event EventHandler<RuntimeKeyStatusChangedEventArgs> UsbTetheringEnabled
542         {
543             add
544             {
545                 if (s_usbTetheringEnabled == null)
546                 {
547                     int ret = Interop.RuntimeInfo.SetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.UsbTethering), s_runtimeInfoChangedCallback, IntPtr.Zero);
548                     if (ret != (int)RuntimeInfoError.None)
549                     {
550                         Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
551                         RuntimeInfoErrorFactory.ThrowException(ret);
552                     }
553                 }
554                 s_usbTetheringEnabled += value;
555             }
556             remove
557             {
558                 s_usbTetheringEnabled -= value;
559                 if (s_usbTetheringEnabled == null)
560                 {
561                     int ret = Interop.RuntimeInfo.UnsetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.UsbTethering));
562                     if (ret != (int)RuntimeInfoError.None)
563                     {
564                         Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
565                         RuntimeInfoErrorFactory.ThrowException(ret);
566                     }
567                 }
568             }
569         }
570         /// <summary>
571         /// (event) PacketDataEnabled is raised when the system preference for package data through 3G network is changed.
572         /// </summary>
573         public static event EventHandler<RuntimeKeyStatusChangedEventArgs> PacketDataEnabled
574         {
575             add
576             {
577                 if (s_packetDataEnabled == null)
578                 {
579                     int ret = Interop.RuntimeInfo.SetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.PacketData), s_runtimeInfoChangedCallback, IntPtr.Zero);
580                     if (ret != (int)RuntimeInfoError.None)
581                     {
582                         Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
583                         RuntimeInfoErrorFactory.ThrowException(ret);
584                     }
585                 }
586                 s_packetDataEnabled += value;
587             }
588             remove
589             {
590                 s_packetDataEnabled -= value;
591                 if (s_packetDataEnabled == null)
592                 {
593                     int ret = Interop.RuntimeInfo.UnsetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.PacketData));
594                     if (ret != (int)RuntimeInfoError.None)
595                     {
596                         Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
597                         RuntimeInfoErrorFactory.ThrowException(ret);
598                     }
599                 }
600             }
601         }
602         /// <summary>
603         /// (event) DataRoamingEnabled is raised when the system preference for data roaming is changed.
604         /// </summary>
605         public static event EventHandler<RuntimeKeyStatusChangedEventArgs> DataRoamingEnabled
606         {
607             add
608             {
609                 if (s_dataRoamingEnabled == null)
610                 {
611                     int ret = Interop.RuntimeInfo.SetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.DataRoaming), s_runtimeInfoChangedCallback, IntPtr.Zero);
612                     if (ret != (int)RuntimeInfoError.None)
613                     {
614                         Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
615                         RuntimeInfoErrorFactory.ThrowException(ret);
616                     }
617                 }
618                 s_dataRoamingEnabled += value;
619             }
620             remove
621             {
622                 s_dataRoamingEnabled -= value;
623                 if (s_dataRoamingEnabled == null)
624                 {
625                     int ret = Interop.RuntimeInfo.UnsetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.DataRoaming));
626                     if (ret != (int)RuntimeInfoError.None)
627                     {
628                         Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
629                         RuntimeInfoErrorFactory.ThrowException(ret);
630                     }
631                 }
632             }
633         }
634         /// <summary>
635         /// (event) VibrationEnabled is raised when the system preference for vibration is changed.
636         /// </summary>
637         public static event EventHandler<RuntimeKeyStatusChangedEventArgs> VibrationEnabled
638         {
639             add
640             {
641                 if (s_vibrationEnabled == null)
642                 {
643                     int ret = Interop.RuntimeInfo.SetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.Vibration), s_runtimeInfoChangedCallback, IntPtr.Zero);
644                     if (ret != (int)RuntimeInfoError.None)
645                     {
646                         Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
647                         RuntimeInfoErrorFactory.ThrowException(ret);
648                     }
649                 }
650                 s_vibrationEnabled += value;
651             }
652             remove
653             {
654                 s_vibrationEnabled -= value;
655                 if (s_vibrationEnabled == null)
656                 {
657                     int ret = Interop.RuntimeInfo.UnsetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.Vibration));
658                     if (ret != (int)RuntimeInfoError.None)
659                     {
660                         Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
661                         RuntimeInfoErrorFactory.ThrowException(ret);
662                     }
663                 }
664             }
665         }
666         /// <summary>
667         /// (event) AudioJackConnected is raised when the audio jack is connected/disconnected.
668         /// </summary>
669         public static event EventHandler<RuntimeKeyStatusChangedEventArgs> AudioJackConnected
670         {
671             add
672             {
673                 if (s_audioJackConnected == null)
674                 {
675                     int ret = Interop.RuntimeInfo.SetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.AudioJack), s_runtimeInfoChangedCallback, IntPtr.Zero);
676                     if (ret != (int)RuntimeInfoError.None)
677                     {
678                         Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
679                         RuntimeInfoErrorFactory.ThrowException(ret);
680                     }
681                 }
682                 s_audioJackConnected += value;
683             }
684             remove
685             {
686                 s_audioJackConnected -= value;
687                 if (s_audioJackConnected == null)
688                 {
689                     int ret = Interop.RuntimeInfo.UnsetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.AudioJack));
690                     if (ret != (int)RuntimeInfoError.None)
691                     {
692                         Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
693                         RuntimeInfoErrorFactory.ThrowException(ret);
694                     }
695                 }
696             }
697         }
698         /// <summary>
699         /// (event) GpsStatusChanged is raised when the status of GPS is changed.
700         /// </summary>
701         public static event EventHandler<RuntimeKeyStatusChangedEventArgs> GpsStatusChanged
702         {
703             add
704             {
705                 if (s_gpsStatusChanged == null)
706                 {
707                     int ret = Interop.RuntimeInfo.SetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.Gps), s_runtimeInfoChangedCallback, IntPtr.Zero);
708                     if (ret != (int)RuntimeInfoError.None)
709                     {
710                         Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
711                         RuntimeInfoErrorFactory.ThrowException(ret);
712                     }
713                 }
714                 s_gpsStatusChanged += value;
715             }
716             remove
717             {
718                 s_gpsStatusChanged -= value;
719                 if (s_gpsStatusChanged == null)
720                 {
721                     int ret = Interop.RuntimeInfo.UnsetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.Gps));
722                     if (ret != (int)RuntimeInfoError.None)
723                     {
724                         Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
725                         RuntimeInfoErrorFactory.ThrowException(ret);
726                     }
727                 }
728             }
729         }
730         /// <summary>
731         /// (event) BatteryIsCharging is raised when the battery is currently charging.
732         /// </summary>
733         public static event EventHandler<RuntimeKeyStatusChangedEventArgs> BatteryIsCharging
734         {
735             add
736             {
737                 if (s_batteryIsCharging == null)
738                 {
739                     int ret = Interop.RuntimeInfo.SetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.BatteryIsCharging), s_runtimeInfoChangedCallback, IntPtr.Zero);
740                     if (ret != (int)RuntimeInfoError.None)
741                     {
742                         Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
743                         RuntimeInfoErrorFactory.ThrowException(ret);
744                     }
745                 }
746                 s_batteryIsCharging += value;
747             }
748             remove
749             {
750                 s_batteryIsCharging -= value;
751                 if (s_batteryIsCharging == null)
752                 {
753                     int ret = Interop.RuntimeInfo.UnsetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.BatteryIsCharging));
754                     if (ret != (int)RuntimeInfoError.None)
755                     {
756                         Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
757                         RuntimeInfoErrorFactory.ThrowException(ret);
758                     }
759                 }
760             }
761         }
762         /// <summary>
763         /// (event) TvOutConnected is raised when TV out is connected/disconnected.
764         /// </summary>
765         public static event EventHandler<RuntimeKeyStatusChangedEventArgs> TvOutConnected
766         {
767             add
768             {
769                 if (s_tvOutConnected == null)
770                 {
771                     int ret = Interop.RuntimeInfo.SetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.TvOut), s_runtimeInfoChangedCallback, IntPtr.Zero);
772                     if (ret != (int)RuntimeInfoError.None)
773                     {
774                         Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
775                         RuntimeInfoErrorFactory.ThrowException(ret);
776                     }
777                 }
778                 s_tvOutConnected += value;
779             }
780             remove
781             {
782                 s_tvOutConnected -= value;
783                 if (s_tvOutConnected == null)
784                 {
785                     int ret = Interop.RuntimeInfo.UnsetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.TvOut));
786                     if (ret != (int)RuntimeInfoError.None)
787                     {
788                         Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
789                         RuntimeInfoErrorFactory.ThrowException(ret);
790                     }
791                 }
792             }
793         }
794         /// <summary>
795         /// (event) AudioJackConnectorChanged is raised when the audio jack connection changes.
796         /// </summary>
797         public static event EventHandler<RuntimeKeyStatusChangedEventArgs> AudioJackConnectorChanged
798         {
799             add
800             {
801                 if (s_audioJackConnectorChanged == null)
802                 {
803                     int ret = Interop.RuntimeInfo.SetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.AudioJackConnector), s_runtimeInfoChangedCallback, IntPtr.Zero);
804                     if (ret != (int)RuntimeInfoError.None)
805                     {
806                         Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
807                         RuntimeInfoErrorFactory.ThrowException(ret);
808                     }
809                 }
810                 s_audioJackConnectorChanged += value;
811             }
812             remove
813             {
814                 s_audioJackConnectorChanged -= value;
815                 if (s_audioJackConnectorChanged == null)
816                 {
817                     int ret = Interop.RuntimeInfo.UnsetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.AudioJackConnector));
818                     if (ret != (int)RuntimeInfoError.None)
819                     {
820                         Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
821                         RuntimeInfoErrorFactory.ThrowException(ret);
822                     }
823                 }
824             }
825         }
826         /// <summary>
827         /// (event) ChargerConnected is raised when the charger is connected/disconnected.
828         /// </summary>
829         public static event EventHandler<RuntimeKeyStatusChangedEventArgs> ChargerConnected
830         {
831             add
832             {
833                 if (s_chargerConnected == null)
834                 {
835                     int ret = Interop.RuntimeInfo.SetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.Charger), s_runtimeInfoChangedCallback, IntPtr.Zero);
836                     if (ret != (int)RuntimeInfoError.None)
837                     {
838                         Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
839                         RuntimeInfoErrorFactory.ThrowException(ret);
840                     }
841                 }
842                 s_chargerConnected += value;
843             }
844             remove
845             {
846                 s_chargerConnected -= value;
847                 if (s_chargerConnected == null)
848                 {
849                     int ret = Interop.RuntimeInfo.UnsetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.Charger));
850                     if (ret != (int)RuntimeInfoError.None)
851                     {
852                         Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
853                         RuntimeInfoErrorFactory.ThrowException(ret);
854                     }
855                 }
856             }
857         }
858         /// <summary>
859         /// (event) AutoRotationEnabled is raised when the system preference for auto rotation is changed.
860         /// </summary>
861         public static event EventHandler<RuntimeKeyStatusChangedEventArgs> AutoRotationEnabled
862         {
863             add
864             {
865                 if (s_autoRotationEnabled == null)
866                 {
867                     int ret = Interop.RuntimeInfo.SetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.AutoRotation), s_runtimeInfoChangedCallback, IntPtr.Zero);
868                     if (ret != (int)RuntimeInfoError.None)
869                     {
870                         Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
871                         RuntimeInfoErrorFactory.ThrowException(ret);
872                     }
873                 }
874                 s_autoRotationEnabled += value;
875             }
876             remove
877             {
878                 s_autoRotationEnabled -= value;
879                 if (s_autoRotationEnabled == null)
880                 {
881                     int ret = Interop.RuntimeInfo.UnsetRuntimeInfoChangedCallback(ConvertKeyIfTvProduct(RuntimeInformationKey.AutoRotation));
882                     if (ret != (int)RuntimeInfoError.None)
883                     {
884                         Log.Error(RuntimeInfoErrorFactory.LogTag, "Interop failed to add event handler");
885                         RuntimeInfoErrorFactory.ThrowException(ret);
886                     }
887                 }
888             }
889         }
890     }
891 }