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