instance_id_android.cc 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. // Copyright 2015 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/gcm_driver/instance_id/instance_id_android.h"
  5. #include <stdint.h>
  6. #include <memory>
  7. #include <numeric>
  8. #include "base/android/jni_android.h"
  9. #include "base/android/jni_string.h"
  10. #include "base/bind.h"
  11. #include "base/location.h"
  12. #include "base/logging.h"
  13. #include "base/threading/thread_task_runner_handle.h"
  14. #include "base/time/time.h"
  15. #include "components/gcm_driver/instance_id/android/jni_headers/InstanceIDBridge_jni.h"
  16. using base::android::AttachCurrentThread;
  17. using base::android::ConvertJavaStringToUTF8;
  18. using base::android::ConvertUTF8ToJavaString;
  19. namespace instance_id {
  20. InstanceIDAndroid::ScopedBlockOnAsyncTasksForTesting::
  21. ScopedBlockOnAsyncTasksForTesting() {
  22. JNIEnv* env = AttachCurrentThread();
  23. previous_value_ =
  24. Java_InstanceIDBridge_setBlockOnAsyncTasksForTesting(env, true);
  25. }
  26. InstanceIDAndroid::ScopedBlockOnAsyncTasksForTesting::
  27. ~ScopedBlockOnAsyncTasksForTesting() {
  28. JNIEnv* env = AttachCurrentThread();
  29. Java_InstanceIDBridge_setBlockOnAsyncTasksForTesting(env, previous_value_);
  30. }
  31. // static
  32. std::unique_ptr<InstanceID> InstanceID::CreateInternal(
  33. const std::string& app_id,
  34. gcm::GCMDriver* gcm_driver) {
  35. return std::make_unique<InstanceIDAndroid>(app_id, gcm_driver);
  36. }
  37. InstanceIDAndroid::InstanceIDAndroid(const std::string& app_id,
  38. gcm::GCMDriver* gcm_driver)
  39. : InstanceID(app_id, gcm_driver) {
  40. DCHECK(thread_checker_.CalledOnValidThread());
  41. DCHECK(!app_id.empty()) << "Empty app_id is not supported";
  42. // The |app_id| is stored in GCM's category field by the desktop InstanceID
  43. // implementation, but because the category is reserved for the app's package
  44. // name on Android the subtype field is used instead.
  45. std::string subtype = app_id;
  46. JNIEnv* env = AttachCurrentThread();
  47. java_ref_.Reset(
  48. Java_InstanceIDBridge_create(env, reinterpret_cast<intptr_t>(this),
  49. ConvertUTF8ToJavaString(env, subtype)));
  50. }
  51. InstanceIDAndroid::~InstanceIDAndroid() {
  52. DCHECK(thread_checker_.CalledOnValidThread());
  53. JNIEnv* env = AttachCurrentThread();
  54. Java_InstanceIDBridge_destroy(env, java_ref_);
  55. }
  56. void InstanceIDAndroid::GetID(GetIDCallback callback) {
  57. DCHECK(thread_checker_.CalledOnValidThread());
  58. int32_t request_id = get_id_callbacks_.Add(
  59. std::make_unique<GetIDCallback>(std::move(callback)));
  60. JNIEnv* env = AttachCurrentThread();
  61. Java_InstanceIDBridge_getId(env, java_ref_, request_id);
  62. }
  63. void InstanceIDAndroid::GetCreationTime(GetCreationTimeCallback callback) {
  64. DCHECK(thread_checker_.CalledOnValidThread());
  65. int32_t request_id = get_creation_time_callbacks_.Add(
  66. std::make_unique<GetCreationTimeCallback>(std::move(callback)));
  67. JNIEnv* env = AttachCurrentThread();
  68. Java_InstanceIDBridge_getCreationTime(env, java_ref_, request_id);
  69. }
  70. void InstanceIDAndroid::GetToken(
  71. const std::string& authorized_entity,
  72. const std::string& scope,
  73. base::TimeDelta time_to_live,
  74. std::set<Flags> flags,
  75. GetTokenCallback callback) {
  76. DCHECK(thread_checker_.CalledOnValidThread());
  77. if (!time_to_live.is_zero()) {
  78. LOG(WARNING) << "Non-zero TTL requested for InstanceID token, while TTLs"
  79. " are not supported by Android Firebase IID API.";
  80. }
  81. int32_t request_id = get_token_callbacks_.Add(
  82. std::make_unique<GetTokenCallback>(std::move(callback)));
  83. int java_flags = std::accumulate(
  84. flags.begin(), flags.end(), 0,
  85. [](int sum, Flags flag) { return sum + static_cast<int>(flag); });
  86. JNIEnv* env = AttachCurrentThread();
  87. Java_InstanceIDBridge_getToken(
  88. env, java_ref_, request_id,
  89. ConvertUTF8ToJavaString(env, authorized_entity),
  90. ConvertUTF8ToJavaString(env, scope), java_flags);
  91. }
  92. void InstanceIDAndroid::ValidateToken(const std::string& authorized_entity,
  93. const std::string& scope,
  94. const std::string& token,
  95. ValidateTokenCallback callback) {
  96. // gcm_driver doesn't store tokens on Android, so assume it's valid.
  97. base::ThreadTaskRunnerHandle::Get()->PostTask(
  98. FROM_HERE, base::BindOnce(std::move(callback), true /* is_valid */));
  99. }
  100. void InstanceIDAndroid::DeleteTokenImpl(const std::string& authorized_entity,
  101. const std::string& scope,
  102. DeleteTokenCallback callback) {
  103. DCHECK(thread_checker_.CalledOnValidThread());
  104. int32_t request_id = delete_token_callbacks_.Add(
  105. std::make_unique<DeleteTokenCallback>(std::move(callback)));
  106. JNIEnv* env = AttachCurrentThread();
  107. Java_InstanceIDBridge_deleteToken(
  108. env, java_ref_, request_id,
  109. ConvertUTF8ToJavaString(env, authorized_entity),
  110. ConvertUTF8ToJavaString(env, scope));
  111. }
  112. void InstanceIDAndroid::DeleteIDImpl(DeleteIDCallback callback) {
  113. DCHECK(thread_checker_.CalledOnValidThread());
  114. int32_t request_id = delete_id_callbacks_.Add(
  115. std::make_unique<DeleteIDCallback>(std::move(callback)));
  116. JNIEnv* env = AttachCurrentThread();
  117. Java_InstanceIDBridge_deleteInstanceID(env, java_ref_, request_id);
  118. }
  119. void InstanceIDAndroid::DidGetID(
  120. JNIEnv* env,
  121. const base::android::JavaParamRef<jobject>& obj,
  122. jint request_id,
  123. const base::android::JavaParamRef<jstring>& jid) {
  124. DCHECK(thread_checker_.CalledOnValidThread());
  125. GetIDCallback* callback = get_id_callbacks_.Lookup(request_id);
  126. DCHECK(callback);
  127. std::move(*callback).Run(ConvertJavaStringToUTF8(jid));
  128. get_id_callbacks_.Remove(request_id);
  129. }
  130. void InstanceIDAndroid::DidGetCreationTime(
  131. JNIEnv* env,
  132. const base::android::JavaParamRef<jobject>& obj,
  133. jint request_id,
  134. jlong creation_time_unix_ms) {
  135. DCHECK(thread_checker_.CalledOnValidThread());
  136. base::Time creation_time;
  137. // If the InstanceID's getId, getToken and deleteToken methods have never been
  138. // called, or deleteInstanceID has cleared it since, creation time will be 0.
  139. if (creation_time_unix_ms) {
  140. creation_time =
  141. base::Time::UnixEpoch() + base::Milliseconds(creation_time_unix_ms);
  142. }
  143. GetCreationTimeCallback* callback =
  144. get_creation_time_callbacks_.Lookup(request_id);
  145. DCHECK(callback);
  146. std::move(*callback).Run(creation_time);
  147. get_creation_time_callbacks_.Remove(request_id);
  148. }
  149. void InstanceIDAndroid::DidGetToken(
  150. JNIEnv* env,
  151. const base::android::JavaParamRef<jobject>& obj,
  152. jint request_id,
  153. const base::android::JavaParamRef<jstring>& jtoken) {
  154. DCHECK(thread_checker_.CalledOnValidThread());
  155. GetTokenCallback* callback = get_token_callbacks_.Lookup(request_id);
  156. DCHECK(callback);
  157. std::string token = ConvertJavaStringToUTF8(jtoken);
  158. std::move(*callback).Run(
  159. token, token.empty() ? InstanceID::UNKNOWN_ERROR : InstanceID::SUCCESS);
  160. get_token_callbacks_.Remove(request_id);
  161. }
  162. void InstanceIDAndroid::DidDeleteToken(
  163. JNIEnv* env,
  164. const base::android::JavaParamRef<jobject>& obj,
  165. jint request_id,
  166. jboolean success) {
  167. DCHECK(thread_checker_.CalledOnValidThread());
  168. DeleteTokenCallback* callback = delete_token_callbacks_.Lookup(request_id);
  169. DCHECK(callback);
  170. std::move(*callback).Run(success ? InstanceID::SUCCESS
  171. : InstanceID::UNKNOWN_ERROR);
  172. delete_token_callbacks_.Remove(request_id);
  173. }
  174. void InstanceIDAndroid::DidDeleteID(
  175. JNIEnv* env,
  176. const base::android::JavaParamRef<jobject>& obj,
  177. jint request_id,
  178. jboolean success) {
  179. DCHECK(thread_checker_.CalledOnValidThread());
  180. DeleteIDCallback* callback = delete_id_callbacks_.Lookup(request_id);
  181. DCHECK(callback);
  182. std::move(*callback).Run(success ? InstanceID::SUCCESS
  183. : InstanceID::UNKNOWN_ERROR);
  184. delete_id_callbacks_.Remove(request_id);
  185. }
  186. } // namespace instance_id