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