PageRenderTime 42ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/PushSharp.Android/C2dm/C2dmPushChannel.cs

https://github.com/mustafagenc/PushSharp
C# | 143 lines | 112 code | 22 blank | 9 comment | 13 complexity | e3c69a7e473d367260765b827c8f3e61 MD5 | raw file
Possible License(s): Apache-2.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.Specialized;
  4. using System.Linq;
  5. using System.Net;
  6. using System.Text;
  7. using System.Threading;
  8. using PushSharp.Common;
  9. namespace PushSharp.Android
  10. {
  11. [Obsolete("Google has Deprecated C2DM, and you should now use GCM Instead.")]
  12. public class C2dmPushChannel : PushChannelBase
  13. {
  14. C2dmPushChannelSettings androidSettings = null;
  15. string googleAuthToken = string.Empty;
  16. C2dmMessageTransportAsync transport;
  17. long waitCounter = 0;
  18. public C2dmPushChannel(C2dmPushChannelSettings channelSettings, PushServiceSettings serviceSettings = null) : base(channelSettings, serviceSettings)
  19. {
  20. androidSettings = channelSettings;
  21. //Go get the auth token from google
  22. try
  23. {
  24. RefreshGoogleAuthToken();
  25. }
  26. catch (GoogleLoginAuthorizationException glaex)
  27. {
  28. this.Events.RaiseChannelException(glaex, PlatformType.AndroidC2dm);
  29. }
  30. transport = new C2dmMessageTransportAsync();
  31. transport.UpdateGoogleClientAuthToken += new Action<string>((newToken) =>
  32. {
  33. this.googleAuthToken = newToken;
  34. });
  35. transport.MessageResponseReceived += new Action<C2dmMessageTransportResponse>(transport_MessageResponseReceived);
  36. transport.UnhandledException += new Action<C2dmNotification, Exception>(transport_UnhandledException);
  37. }
  38. public override PlatformType PlatformType
  39. {
  40. get { return PlatformType.AndroidC2dm; }
  41. }
  42. void transport_UnhandledException(C2dmNotification notification, Exception exception)
  43. {
  44. this.Events.RaiseChannelException(exception, PlatformType.AndroidC2dm);
  45. Interlocked.Decrement(ref waitCounter);
  46. }
  47. void transport_MessageResponseReceived(C2dmMessageTransportResponse response)
  48. {
  49. //Check if our token was expired and refresh/requeue if need be
  50. if (response.ResponseCode == MessageTransportResponseCode.InvalidAuthToken)
  51. {
  52. this.QueueNotification(response.Message, false);
  53. this.RefreshGoogleAuthToken();
  54. return;
  55. }
  56. if (response.ResponseStatus == MessageTransportResponseStatus.Ok)
  57. this.Events.RaiseNotificationSent(response.Message); //Msg ok!
  58. else if (response.ResponseStatus == MessageTransportResponseStatus.InvalidRegistration)
  59. {
  60. //Device subscription is no good!
  61. this.Events.RaiseDeviceSubscriptionExpired(PlatformType.AndroidC2dm, response.Message.RegistrationId, response.Message);
  62. }
  63. else if (response.ResponseStatus == MessageTransportResponseStatus.NotRegistered)
  64. {
  65. //Device must have uninstalled app
  66. this.Events.RaiseDeviceSubscriptionExpired(PlatformType.AndroidC2dm, response.Message.RegistrationId, response.Message);
  67. }
  68. else
  69. {
  70. //Message Failed some other way
  71. this.Events.RaiseNotificationSendFailure(response.Message, new Exception(response.ResponseStatus.ToString()));
  72. }
  73. Interlocked.Decrement(ref waitCounter);
  74. }
  75. protected override void SendNotification(Notification notification)
  76. {
  77. Interlocked.Increment(ref waitCounter);
  78. transport.Send(notification as C2dmNotification, this.googleAuthToken, androidSettings.SenderID, androidSettings.ApplicationID);
  79. }
  80. public override void Stop(bool waitForQueueToDrain)
  81. {
  82. base.Stop(waitForQueueToDrain);
  83. var slept = 0;
  84. while (Interlocked.Read(ref waitCounter) > 0 && slept <= 30000)
  85. {
  86. slept += 100;
  87. Thread.Sleep(100);
  88. }
  89. }
  90. /// <summary>
  91. /// Explicitly refreshes the Google Auth Token. Usually not necessary.
  92. /// </summary>
  93. public void RefreshGoogleAuthToken()
  94. {
  95. string authUrl = "https://www.google.com/accounts/ClientLogin";
  96. var data = new NameValueCollection();
  97. data.Add("Email", this.androidSettings.SenderID);
  98. data.Add("Passwd", this.androidSettings.Password);
  99. data.Add("accountType", "GOOGLE_OR_HOSTED");
  100. data.Add("service", "ac2dm");
  101. data.Add("source", this.androidSettings.ApplicationID);
  102. var wc = new WebClient();
  103. try
  104. {
  105. var authStr = Encoding.ASCII.GetString(wc.UploadValues(authUrl, data));
  106. //Only care about the Auth= part at the end
  107. if (authStr.Contains("Auth="))
  108. googleAuthToken = authStr.Substring(authStr.IndexOf("Auth=") + 5);
  109. else
  110. throw new GoogleLoginAuthorizationException("Missing Auth Token");
  111. }
  112. catch (WebException ex)
  113. {
  114. var result = "Unknown Error";
  115. try { result = (new System.IO.StreamReader(ex.Response.GetResponseStream())).ReadToEnd(); }
  116. catch { }
  117. throw new GoogleLoginAuthorizationException(result);
  118. }
  119. }
  120. }
  121. }