PageRenderTime 51ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/PushSharp.Client/PushSharp.Client.MonoForAndroid.Gcm/GCMRegistrar.cs

https://github.com/mustafagenc/PushSharp
C# | 286 lines | 216 code | 55 blank | 15 comment | 19 complexity | 307f68f0b0d61b1ad23c4592032de0ff MD5 | raw file
Possible License(s): Apache-2.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Android.App;
  6. using Android.Content;
  7. using Android.OS;
  8. using Android.Runtime;
  9. using Android.Views;
  10. using Android.Widget;
  11. using Android.Util;
  12. namespace GCMSharp.Client
  13. {
  14. public class GCMRegistrar
  15. {
  16. const string TAG = "GCMRegistrar";
  17. const string BACKOFF_MS = "backoff_ms";
  18. const string GSF_PACKAGE = "com.google.android.gsf";
  19. const string PREFERENCES = "com.google.android.gcm";
  20. const int DEFAULT_BACKOFF_MS = 3000;
  21. const string PROPERTY_REG_ID = "regId";
  22. const string PROPERTY_APP_VERSION = "appVersion";
  23. const string PROPERTY_ON_SERVER = "onServer";
  24. //static GCMBroadcastReceiver sRetryReceiver;
  25. public static void CheckDevice(Context context)
  26. {
  27. var version = (int)Build.VERSION.SdkInt;
  28. if (version < 8)
  29. throw new InvalidOperationException("Device must be at least API Level 8 (instead of " + version + ")");
  30. var packageManager = context.PackageManager;
  31. try
  32. {
  33. packageManager.GetPackageInfo(GSF_PACKAGE, 0);
  34. }
  35. catch
  36. {
  37. throw new InvalidOperationException("Device does not have package " + GSF_PACKAGE);
  38. }
  39. }
  40. public static void CheckManifest(Context context)
  41. {
  42. var packageManager = context.PackageManager;
  43. var packageName = context.PackageName;
  44. var permissionName = packageName + ".permission.C2D_MESSAGE";
  45. try
  46. {
  47. packageManager.GetPermissionInfo(permissionName, Android.Content.PM.PackageInfoFlags.Permissions);
  48. }
  49. catch
  50. {
  51. throw new AccessViolationException("Application does not define permission: " + permissionName);
  52. }
  53. Android.Content.PM.PackageInfo receiversInfo;
  54. try
  55. {
  56. receiversInfo = packageManager.GetPackageInfo(packageName, Android.Content.PM.PackageInfoFlags.Receivers);
  57. }
  58. catch
  59. {
  60. throw new InvalidOperationException("Could not get receivers for package " + packageName);
  61. }
  62. var receivers = receiversInfo.Receivers;
  63. if (receivers == null || receivers.Count <= 0)
  64. throw new InvalidOperationException("No Receiver for package " + packageName);
  65. if (Log.IsLoggable(TAG, LogPriority.Verbose))
  66. Log.Verbose(TAG, "number of receivers for " + packageName + ": " + receivers.Count);
  67. var allowedReceivers = new HashSet<string>();
  68. foreach (var receiver in receivers)
  69. {
  70. if (GCMConstants.PERMISSION_GCM_INTENTS.Equals(receiver.Permission))
  71. allowedReceivers.Add(receiver.Name);
  72. }
  73. if (allowedReceivers.Count <= 0)
  74. throw new InvalidOperationException("No receiver allowed to receive " + GCMConstants.PERMISSION_GCM_INTENTS);
  75. CheckReceiver(context, allowedReceivers, GCMConstants.INTENT_FROM_GCM_REGISTRATION_CALLBACK);
  76. CheckReceiver(context, allowedReceivers, GCMConstants.INTENT_FROM_GCM_MESSAGE);
  77. }
  78. private static void CheckReceiver(Context context, HashSet<string> allowedReceivers, string action)
  79. {
  80. var pm = context.PackageManager;
  81. var packageName = context.PackageName;
  82. var intent = new Intent(action);
  83. intent.SetPackage(packageName);
  84. var receivers = pm.QueryBroadcastReceivers(intent, Android.Content.PM.PackageInfoFlags.IntentFilters);
  85. if (receivers == null || receivers.Count <= 0)
  86. throw new InvalidOperationException("No receivers for action " + action);
  87. if (Log.IsLoggable(TAG, LogPriority.Verbose))
  88. Log.Verbose(TAG, "Found " + receivers.Count + " receivers for action " + action);
  89. foreach (var receiver in receivers)
  90. {
  91. var name = receiver.ActivityInfo.Name;
  92. if (!allowedReceivers.Contains(name))
  93. throw new InvalidOperationException("Receiver " + name + " is not set with permission " + GCMConstants.PERMISSION_GCM_INTENTS);
  94. }
  95. }
  96. public static void Register(Context context, params string[] senderIds)
  97. {
  98. SetRetryBroadcastReceiver(context);
  99. ResetBackoff(context);
  100. internalRegister(context, senderIds);
  101. }
  102. internal static void internalRegister(Context context, params string[] senderIds)
  103. {
  104. if (senderIds == null || senderIds.Length <= 0)
  105. throw new ArgumentException("No senderIds");
  106. var senders = string.Join(",", senderIds);
  107. Log.Verbose(TAG, "Registering app " + context.PackageName + " of senders " + senders);
  108. var intent = new Intent(GCMConstants.INTENT_TO_GCM_REGISTRATION);
  109. intent.SetPackage(GSF_PACKAGE);
  110. intent.PutExtra(GCMConstants.EXTRA_APPLICATION_PENDING_INTENT,
  111. PendingIntent.GetBroadcast(context, 0, new Intent(), 0));
  112. intent.PutExtra(GCMConstants.EXTRA_SENDER, senders);
  113. context.StartService(intent);
  114. }
  115. public static void UnRegister(Context context)
  116. {
  117. SetRetryBroadcastReceiver(context);
  118. ResetBackoff(context);
  119. internalUnRegister(context);
  120. }
  121. internal static void internalUnRegister(Context context)
  122. {
  123. Log.Verbose(TAG, "Unregistering app " + context.PackageName);
  124. var intent = new Intent(GCMConstants.INTENT_TO_GCM_UNREGISTRATION);
  125. intent.SetPackage(GSF_PACKAGE);
  126. intent.PutExtra(GCMConstants.EXTRA_APPLICATION_PENDING_INTENT,
  127. PendingIntent.GetBroadcast(context, 0, new Intent(), 0));
  128. context.StartService(intent);
  129. }
  130. static void SetRetryBroadcastReceiver(Context context)
  131. {
  132. return;
  133. /*if (sRetryReceiver == null)
  134. {
  135. sRetryReceiver = new GCMBroadcastReceiver();
  136. var category = context.PackageName;
  137. var filter = new IntentFilter(GCMConstants.INTENT_FROM_GCM_LIBRARY_RETRY);
  138. filter.AddCategory(category);
  139. var permission = category + ".permission.C2D_MESSAGE";
  140. Log.Verbose(TAG, "Registering receiver");
  141. context.RegisterReceiver(sRetryReceiver, filter, permission, null);
  142. }*/
  143. }
  144. public static string GetRegistrationId(Context context)
  145. {
  146. var prefs = GetGCMPreferences(context);
  147. var registrationId = prefs.GetString(PROPERTY_REG_ID, "");
  148. int oldVersion = prefs.GetInt(PROPERTY_APP_VERSION, int.MinValue);
  149. int newVersion = GetAppVersion(context);
  150. if (oldVersion != int.MinValue && oldVersion != newVersion)
  151. {
  152. Log.Verbose(TAG, "App version changed from " + oldVersion + " to " + newVersion + "; resetting registration id");
  153. ClearRegistrationId(context);
  154. }
  155. return registrationId;
  156. }
  157. public static bool IsRegistered(Context context)
  158. {
  159. var registrationId = GetRegistrationId(context);
  160. return !string.IsNullOrEmpty(registrationId);
  161. }
  162. internal static string ClearRegistrationId(Context context)
  163. {
  164. return SetRegistrationId(context, "");
  165. }
  166. internal static string SetRegistrationId(Context context, string registrationId)
  167. {
  168. var prefs = GetGCMPreferences(context);
  169. var oldRegistrationId = prefs.GetString(PROPERTY_REG_ID, "");
  170. int appVersion = GetAppVersion(context);
  171. Log.Verbose(TAG, "Saving registrationId on app version " + appVersion);
  172. var editor = prefs.Edit();
  173. editor.PutString(PROPERTY_REG_ID, registrationId);
  174. editor.PutInt(PROPERTY_APP_VERSION, appVersion);
  175. editor.Commit();
  176. return oldRegistrationId;
  177. }
  178. public static void SetRegisteredOnServer(Context context, bool flag)
  179. {
  180. var prefs = GetGCMPreferences(context);
  181. Log.Verbose(TAG, "Setting registered on server status as: " + flag);
  182. var editor = prefs.Edit();
  183. editor.PutBoolean(PROPERTY_ON_SERVER, flag);
  184. editor.Commit();
  185. }
  186. public static bool IsRegisteredOnServer(Context context)
  187. {
  188. var prefs = GetGCMPreferences(context);
  189. bool isRegistered = prefs.GetBoolean(PROPERTY_ON_SERVER, false);
  190. Log.Verbose(TAG, "Is registered on server: " + isRegistered);
  191. return isRegistered;
  192. }
  193. static int GetAppVersion(Context context)
  194. {
  195. try
  196. {
  197. var packageInfo = context.PackageManager.GetPackageInfo(context.PackageName, 0);
  198. return packageInfo.VersionCode;
  199. }
  200. catch
  201. {
  202. throw new InvalidOperationException("Could not get package name");
  203. }
  204. }
  205. internal static void ResetBackoff(Context context)
  206. {
  207. Log.Debug(TAG, "resetting backoff for " + context.PackageName);
  208. SetBackoff(context, DEFAULT_BACKOFF_MS);
  209. }
  210. internal static int GetBackoff(Context context)
  211. {
  212. var prefs = GetGCMPreferences(context);
  213. return prefs.GetInt(BACKOFF_MS, DEFAULT_BACKOFF_MS);
  214. }
  215. internal static void SetBackoff(Context context, int backoff)
  216. {
  217. var prefs = GetGCMPreferences(context);
  218. var editor = prefs.Edit();
  219. editor.PutInt(BACKOFF_MS, backoff);
  220. editor.Commit();
  221. }
  222. static ISharedPreferences GetGCMPreferences(Context context)
  223. {
  224. return context.GetSharedPreferences(PREFERENCES, FileCreationMode.Private);
  225. }
  226. }
  227. }