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 void InvalidationServiceAndroid::UpdateRegisteredInvalidationIds(
42 syncer::InvalidationHandler
* handler
,
43 const syncer::ObjectIdSet
& ids
) {
44 DCHECK(CalledOnValidThread());
45 JNIEnv
* env
= base::android::AttachCurrentThread();
48 invalidator_registrar_
.UpdateRegisteredIds(handler
, ids
);
49 const syncer::ObjectIdSet
& registered_ids
=
50 invalidator_registrar_
.GetAllRegisteredIds();
52 // To call the corresponding method on the Java invalidation service, split
53 // the object ids into object source and object name arrays.
54 std::vector
<int> sources
;
55 std::vector
<std::string
> names
;
56 syncer::ObjectIdSet::const_iterator id
;
57 for (id
= registered_ids
.begin(); id
!= registered_ids
.end(); ++id
) {
58 sources
.push_back(id
->source());
59 names
.push_back(id
->name());
62 Java_InvalidationService_setRegisteredObjectIds(
65 base::android::ToJavaIntArray(env
, sources
).obj(),
66 base::android::ToJavaArrayOfStrings(env
, names
).obj());
68 logger_
.OnUpdateIds(invalidator_registrar_
.GetSanitizedHandlersIdsMap());
71 void InvalidationServiceAndroid::UnregisterInvalidationHandler(
72 syncer::InvalidationHandler
* handler
) {
73 DCHECK(CalledOnValidThread());
74 invalidator_registrar_
.UnregisterHandler(handler
);
75 logger_
.OnUnregistration(handler
->GetOwnerName());
78 syncer::InvalidatorState
79 InvalidationServiceAndroid::GetInvalidatorState() const {
80 DCHECK(CalledOnValidThread());
81 return invalidator_state_
;
84 std::string
InvalidationServiceAndroid::GetInvalidatorClientId() const {
85 DCHECK(CalledOnValidThread());
86 JNIEnv
* env
= base::android::AttachCurrentThread();
89 // Ask the Java code to for the invalidator ID it's currently using.
90 base::android::ScopedJavaLocalRef
<_jbyteArray
*> id_bytes_java
=
91 Java_InvalidationService_getInvalidatorClientId(env
, java_ref_
.obj());
93 // Convert it into a more convenient format for C++.
94 std::vector
<uint8_t> id_bytes
;
95 base::android::JavaByteArrayToByteVector(env
, id_bytes_java
.obj(), &id_bytes
);
96 std::string
id(id_bytes
.begin(), id_bytes
.end());
101 InvalidationLogger
* InvalidationServiceAndroid::GetInvalidationLogger() {
105 void InvalidationServiceAndroid::RequestDetailedStatus(
106 base::Callback
<void(const base::DictionaryValue
&)> return_callback
) const {
109 IdentityProvider
* InvalidationServiceAndroid::GetIdentityProvider() {
113 void InvalidationServiceAndroid::TriggerStateChangeForTest(
114 syncer::InvalidatorState state
) {
115 DCHECK(CalledOnValidThread());
116 invalidator_state_
= state
;
117 invalidator_registrar_
.UpdateInvalidatorState(invalidator_state_
);
120 void InvalidationServiceAndroid::RequestSync(JNIEnv
* env
,
123 jstring java_object_id
,
125 jstring java_state
) {
126 invalidation::ObjectId
object_id(object_source
,
127 ConvertJavaStringToUTF8(env
, java_object_id
));
129 syncer::ObjectIdInvalidationMap object_ids_with_states
;
131 if (version
== ipc::invalidation::Constants::UNKNOWN
) {
132 object_ids_with_states
.Insert(
133 syncer::Invalidation::InitUnknownVersion(object_id
));
135 ObjectIdVersionMap::iterator it
=
136 max_invalidation_versions_
.find(object_id
);
137 if ((it
!= max_invalidation_versions_
.end()) &&
138 (version
<= it
->second
)) {
139 DVLOG(1) << "Dropping redundant invalidation with version " << version
;
142 max_invalidation_versions_
[object_id
] = version
;
143 object_ids_with_states
.Insert(
144 syncer::Invalidation::Init(object_id
, version
,
145 ConvertJavaStringToUTF8(env
, java_state
)));
148 DispatchInvalidations(object_ids_with_states
);
151 void InvalidationServiceAndroid::RequestSyncForAllTypes(JNIEnv
* env
,
153 syncer::ObjectIdInvalidationMap object_ids_with_states
;
154 DispatchInvalidations(object_ids_with_states
);
157 void InvalidationServiceAndroid::DispatchInvalidations(
158 syncer::ObjectIdInvalidationMap
& object_invalidation_map
) {
159 // An empty map implies that we should invalidate all.
160 const syncer::ObjectIdInvalidationMap
& effective_invalidation_map
=
161 object_invalidation_map
.Empty() ?
162 syncer::ObjectIdInvalidationMap::InvalidateAll(
163 invalidator_registrar_
.GetAllRegisteredIds()) :
164 object_invalidation_map
;
166 invalidator_registrar_
.DispatchInvalidationsToHandlers(
167 effective_invalidation_map
);
168 logger_
.OnInvalidation(effective_invalidation_map
);
172 bool InvalidationServiceAndroid::RegisterJni(JNIEnv
* env
) {
173 return RegisterNativesImpl(env
);
176 } // namespace invalidation