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.
5 #include "components/policy/core/browser/android/policy_converter.h"
9 #include "base/android/jni_android.h"
10 #include "base/android/jni_array.h"
11 #include "base/android/jni_string.h"
12 #include "base/json/json_reader.h"
13 #include "base/logging.h"
14 #include "base/strings/string16.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/values.h"
17 #include "components/policy/core/common/policy_bundle.h"
18 #include "components/policy/core/common/policy_map.h"
19 #include "components/policy/core/common/policy_namespace.h"
20 #include "components/policy/core/common/policy_types.h"
21 #include "components/policy/core/common/schema.h"
22 #include "jni/PolicyConverter_jni.h"
24 using base::android::ConvertJavaStringToUTF8
;
29 PolicyConverter::PolicyConverter(const Schema
* policy_schema
)
30 : policy_schema_(policy_schema
), policy_bundle_(new PolicyBundle
) {
31 JNIEnv
* env
= base::android::AttachCurrentThread();
32 java_obj_
.Reset(env
, Java_PolicyConverter_create(
33 env
, reinterpret_cast<long>(this)).obj());
34 DCHECK(!java_obj_
.is_null());
37 PolicyConverter::~PolicyConverter() {
38 Java_PolicyConverter_onNativeDestroyed(base::android::AttachCurrentThread(),
42 scoped_ptr
<PolicyBundle
> PolicyConverter::GetPolicyBundle() {
43 scoped_ptr
<PolicyBundle
> filled_bundle(policy_bundle_
.Pass());
44 policy_bundle_
.reset(new PolicyBundle
);
45 return filled_bundle
.Pass();
48 base::android::ScopedJavaLocalRef
<jobject
> PolicyConverter::GetJavaObject() {
49 return base::android::ScopedJavaLocalRef
<jobject
>(java_obj_
);
52 void PolicyConverter::SetPolicyBoolean(JNIEnv
* env
,
57 ConvertJavaStringToUTF8(env
, policyKey
),
58 make_scoped_ptr(new base::FundamentalValue(static_cast<bool>(value
))));
61 void PolicyConverter::SetPolicyInteger(JNIEnv
* env
,
66 ConvertJavaStringToUTF8(env
, policyKey
),
67 make_scoped_ptr(new base::FundamentalValue(static_cast<int>(value
))));
70 void PolicyConverter::SetPolicyString(JNIEnv
* env
,
74 SetPolicyValue(ConvertJavaStringToUTF8(env
, policyKey
),
75 make_scoped_ptr(new base::StringValue(
76 ConvertJavaStringToUTF8(env
, value
))));
79 void PolicyConverter::SetPolicyStringArray(JNIEnv
* env
,
83 SetPolicyValue(ConvertJavaStringToUTF8(env
, policyKey
),
84 ConvertJavaStringArrayToListValue(env
, array
).Pass());
88 scoped_ptr
<base::ListValue
> PolicyConverter::ConvertJavaStringArrayToListValue(
92 int length
= static_cast<int>(env
->GetArrayLength(array
));
93 DCHECK_GE(length
, 0) << "Invalid array length: " << length
;
95 scoped_ptr
<base::ListValue
> list_value(new base::ListValue());
96 for (int i
= 0; i
< length
; ++i
) {
97 jstring str
= static_cast<jstring
>(env
->GetObjectArrayElement(array
, i
));
98 list_value
->AppendString(ConvertJavaStringToUTF8(env
, str
));
101 return list_value
.Pass();
105 scoped_ptr
<base::Value
> PolicyConverter::ConvertValueToSchema(
106 scoped_ptr
<base::Value
> value
,
107 const Schema
& schema
) {
111 switch (schema
.type()) {
112 case base::Value::TYPE_NULL
:
113 return base::Value::CreateNullValue();
115 case base::Value::TYPE_BOOLEAN
: {
116 std::string string_value
;
117 if (value
->GetAsString(&string_value
)) {
118 if (string_value
.compare("true") == 0)
119 return make_scoped_ptr(new base::FundamentalValue(true));
121 if (string_value
.compare("false") == 0)
122 return make_scoped_ptr(new base::FundamentalValue(false));
127 if (value
->GetAsInteger(&int_value
))
128 return make_scoped_ptr(new base::FundamentalValue(int_value
!= 0));
133 case base::Value::TYPE_INTEGER
: {
134 std::string string_value
;
135 if (value
->GetAsString(&string_value
)) {
137 if (base::StringToInt(string_value
, &int_value
))
138 return make_scoped_ptr(new base::FundamentalValue(int_value
));
143 case base::Value::TYPE_DOUBLE
: {
144 std::string string_value
;
145 if (value
->GetAsString(&string_value
)) {
146 double double_value
= 0;
147 if (base::StringToDouble(string_value
, &double_value
))
148 return make_scoped_ptr(new base::FundamentalValue(double_value
));
153 // String can't be converted from other types.
154 case base::Value::TYPE_STRING
: {
158 // Binary is not a valid schema type.
159 case base::Value::TYPE_BINARY
: {
161 return scoped_ptr
<base::Value
>();
164 // Complex types have to be deserialized from JSON.
165 case base::Value::TYPE_DICTIONARY
:
166 case base::Value::TYPE_LIST
: {
167 std::string string_value
;
168 if (value
->GetAsString(&string_value
)) {
169 scoped_ptr
<base::Value
> decoded_value
=
170 base::JSONReader::Read(string_value
);
172 return decoded_value
.Pass();
179 return scoped_ptr
<base::Value
>();
183 bool PolicyConverter::Register(JNIEnv
* env
) {
184 return RegisterNativesImpl(env
);
187 void PolicyConverter::SetPolicyValue(const std::string
& key
,
188 scoped_ptr
<base::Value
> value
) {
189 const Schema schema
= policy_schema_
->GetKnownProperty(key
);
190 const PolicyNamespace
ns(POLICY_DOMAIN_CHROME
, std::string());
191 policy_bundle_
->Get(ns
)
192 .Set(key
, POLICY_LEVEL_MANDATORY
, POLICY_SCOPE_MACHINE
,
193 ConvertValueToSchema(value
.Pass(), schema
).release(), nullptr);
196 } // namespace android
197 } // namespace policy