1 // Copyright 2014 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.
5 #include "components/invalidation/invalidation_service_android.h"
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_array.h"
9 #include "base/android/jni_string.h"
10 #include "base/callback.h"
11 #include "components/invalidation/object_id_invalidation_map.h"
12 #include "google/cacheinvalidation/types.pb.h"
13 #include "jni/InvalidationService_jni.h"
15 using base::android::ConvertJavaStringToUTF8
;
16 using base::android::ConvertUTF8ToJavaString
;
18 namespace invalidation
{
20 InvalidationServiceAndroid::InvalidationServiceAndroid(jobject context
)
21 : invalidator_state_(syncer::INVALIDATIONS_ENABLED
),
23 DCHECK(CalledOnValidThread());
24 JNIEnv
* env
= base::android::AttachCurrentThread();
25 base::android::ScopedJavaLocalRef
<jobject
> local_java_ref
=
26 Java_InvalidationService_create(env
,
28 reinterpret_cast<intptr_t>(this));
29 java_ref_
.Reset(env
, local_java_ref
.obj());
32 InvalidationServiceAndroid::~InvalidationServiceAndroid() { }
34 void InvalidationServiceAndroid::RegisterInvalidationHandler(
35 syncer::InvalidationHandler
* handler
) {
36 DCHECK(CalledOnValidThread());
37 invalidator_registrar_
.RegisterHandler(handler
);
38 logger_
.OnRegistration(handler
->GetOwnerName());
41 bool InvalidationServiceAndroid::UpdateRegisteredInvalidationIds(
42 syncer::InvalidationHandler
* handler
,
43 const syncer::ObjectIdSet
& ids
) {
44 DCHECK(CalledOnValidThread());
45 JNIEnv
* env
= base::android::AttachCurrentThread();
48 if (!invalidator_registrar_
.UpdateRegisteredIds(handler
, ids
))
50 const syncer::ObjectIdSet
& registered_ids
=
51 invalidator_registrar_
.GetAllRegisteredIds();
53 // To call the corresponding method on the Java invalidation service, split
54 // the object ids into object source and object name arrays.
55 std::vector
<int> sources
;
56 std::vector
<std::string
> names
;
57 syncer::ObjectIdSet::const_iterator id
;
58 for (id
= registered_ids
.begin(); id
!= registered_ids
.end(); ++id
) {
59 sources
.push_back(id
->source());
60 names
.push_back(id
->name());
63 Java_InvalidationService_setRegisteredObjectIds(
66 base::android::ToJavaIntArray(env
, sources
).obj(),
67 base::android::ToJavaArrayOfStrings(env
, names
).obj());
69 logger_
.OnUpdateIds(invalidator_registrar_
.GetSanitizedHandlersIdsMap());
73 void InvalidationServiceAndroid::UnregisterInvalidationHandler(
74 syncer::InvalidationHandler
* handler
) {
75 DCHECK(CalledOnValidThread());
76 invalidator_registrar_
.UnregisterHandler(handler
);
77 logger_
.OnUnregistration(handler
->GetOwnerName());
80 syncer::InvalidatorState
81 InvalidationServiceAndroid::GetInvalidatorState() const {
82 DCHECK(CalledOnValidThread());
83 return invalidator_state_
;
86 std::string
InvalidationServiceAndroid::GetInvalidatorClientId() const {
87 DCHECK(CalledOnValidThread());
88 JNIEnv
* env
= base::android::AttachCurrentThread();
91 // Ask the Java code to for the invalidator ID it's currently using.
92 base::android::ScopedJavaLocalRef
<_jbyteArray
*> id_bytes_java
=
93 Java_InvalidationService_getInvalidatorClientId(env
, java_ref_
.obj());
95 // Convert it into a more convenient format for C++.
96 std::vector
<uint8_t> id_bytes
;
97 base::android::JavaByteArrayToByteVector(env
, id_bytes_java
.obj(), &id_bytes
);
98 std::string
id(id_bytes
.begin(), id_bytes
.end());
103 InvalidationLogger
* InvalidationServiceAndroid::GetInvalidationLogger() {
107 void InvalidationServiceAndroid::RequestDetailedStatus(
108 base::Callback
<void(const base::DictionaryValue
&)> return_callback
) const {
111 IdentityProvider
* InvalidationServiceAndroid::GetIdentityProvider() {
115 void InvalidationServiceAndroid::TriggerStateChangeForTest(
116 syncer::InvalidatorState state
) {
117 DCHECK(CalledOnValidThread());
118 invalidator_state_
= state
;
119 invalidator_registrar_
.UpdateInvalidatorState(invalidator_state_
);
122 void InvalidationServiceAndroid::Invalidate(JNIEnv
* env
,
125 jstring java_object_id
,
127 jstring java_payload
) {
128 syncer::ObjectIdInvalidationMap object_invalidation_map
;
129 if (!java_object_id
) {
130 syncer::ObjectIdSet sync_ids
;
131 if (object_source
== 0) {
132 sync_ids
= invalidator_registrar_
.GetAllRegisteredIds();
134 for (const auto& id
: invalidator_registrar_
.GetAllRegisteredIds()) {
135 if (id
.source() == object_source
)
139 object_invalidation_map
=
140 syncer::ObjectIdInvalidationMap::InvalidateAll(sync_ids
);
142 invalidation::ObjectId
object_id(
143 object_source
, ConvertJavaStringToUTF8(env
, java_object_id
));
144 syncer::ObjectIdInvalidationMap object_invalidation_map
;
146 if (version
== ipc::invalidation::Constants::UNKNOWN
) {
147 object_invalidation_map
.Insert(
148 syncer::Invalidation::InitUnknownVersion(object_id
));
150 ObjectIdVersionMap::iterator it
=
151 max_invalidation_versions_
.find(object_id
);
152 if ((it
!= max_invalidation_versions_
.end()) && (version
<= it
->second
)) {
153 DVLOG(1) << "Dropping redundant invalidation with version " << version
;
156 max_invalidation_versions_
[object_id
] = version
;
157 object_invalidation_map
.Insert(syncer::Invalidation::Init(
158 object_id
, version
, ConvertJavaStringToUTF8(env
, java_payload
)));
162 invalidator_registrar_
.DispatchInvalidationsToHandlers(
163 object_invalidation_map
);
164 logger_
.OnInvalidation(object_invalidation_map
);
168 bool InvalidationServiceAndroid::RegisterJni(JNIEnv
* env
) {
169 return RegisterNativesImpl(env
);
172 } // namespace invalidation