blob: 219184531af23851d9412d4e74a650bd930eee69 [file] [log] [blame]
# Copyright 2023 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
def Generate(jni_obj, *, gen_jni_class, script_name):
visibility = 'public ' if jni_obj.proxy_interface.is_public else ''
interface_name = jni_obj.proxy_interface.name_with_dots
impl_name = f'{jni_obj.java_class.name}Jni'
gen_jni = gen_jni_class.name
sb = []
sb.append(f"""\
//
// This file was generated by {script_name}
//
package {jni_obj.java_class.package_with_dots};
import org.chromium.build.annotations.CheckDiscard;
import org.chromium.base.JniStaticTestMocker;
import org.chromium.base.NativeLibraryLoadedStatus;
import {gen_jni_class.full_name_with_dots};
""")
# Copy over all imports (some will be unused, but oh well).
for java_class in jni_obj.type_resolver.imports:
sb.append(f'import {java_class.full_name_with_dots};\n')
sb.append(f"""
@CheckDiscard("crbug.com/993421")
{visibility}class {impl_name} implements {interface_name} {{
private static {interface_name} testInstance;
public static final JniStaticTestMocker<{interface_name}> TEST_HOOKS =
new JniStaticTestMocker<{interface_name}>() {{
@Override
public void setInstanceForTesting({interface_name} instance) {{
if (!{gen_jni}.TESTING_ENABLED) {{
throw new RuntimeException(
"Tried to set a JNI mock when mocks aren't enabled!");
}}
testInstance = instance;
}}
}};
""")
for native in jni_obj.proxy_natives:
call_params = ', '.join(p.name for p in native.params)
sig_params = ', '.join(f'{p.datatype} {p.name}' for p in native.params)
return_prefix = ''
if native.return_type != 'void':
return_prefix = f'return ({native.return_type}) '
sb.append(f"""
@Override
public {native.return_type} {native.name}({sig_params}) {{
{return_prefix}{gen_jni}.{native.proxy_name}({call_params});
}}
""")
sb.append(f"""
public static {interface_name} get() {{
if ({gen_jni}.TESTING_ENABLED) {{
if (testInstance != null) {{
return testInstance;
}}
if ({gen_jni}.REQUIRE_MOCK) {{
throw new UnsupportedOperationException(
"No mock found for the native implementation of {interface_name}. "
+ "The current configuration requires implementations be mocked.");
}}
}}
NativeLibraryLoadedStatus.checkLoaded();
return new {impl_name}();
}}
}}
""")
return ''.join(sb)