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