| /* |
| * Copyright (C) 2018 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "java_lang_builder.h" |
| |
| #include "android-base/stringprintf.h" |
| |
| using android::base::StringPrintf; |
| using std::string; |
| |
| void JavaLangViewBuilder::Start() const { |
| out_ << StringPrintf("package %s;\n", package_.c_str()) |
| << "import android.content.Context;\n" |
| "import android.content.res.Resources;\n" |
| "import android.content.res.XmlResourceParser;\n" |
| "import android.util.AttributeSet;\n" |
| "import android.util.Xml;\n" |
| "import android.view.*;\n" |
| "import android.widget.*;\n" |
| "\n" |
| "public final class CompiledView {\n" |
| "\n" |
| "static <T extends View> T createView(Context context, AttributeSet attrs, View parent, " |
| "String name, LayoutInflater.Factory factory, LayoutInflater.Factory2 factory2) {" |
| "\n" |
| " if (factory2 != null) {\n" |
| " return (T)factory2.onCreateView(parent, name, context, attrs);\n" |
| " } else if (factory != null) {\n" |
| " return (T)factory.onCreateView(name, context, attrs);\n" |
| " }\n" |
| // TODO: find a way to call the private factory |
| " return null;\n" |
| "}\n" |
| "\n" |
| " public static View inflate(Context context) {\n" |
| " try {\n" |
| " LayoutInflater inflater = LayoutInflater.from(context);\n" |
| " LayoutInflater.Factory factory = inflater.getFactory();\n" |
| " LayoutInflater.Factory2 factory2 = inflater.getFactory2();\n" |
| " Resources res = context.getResources();\n" |
| << StringPrintf(" XmlResourceParser xml = res.getLayout(%s.R.layout.%s);\n", |
| package_.c_str(), |
| layout_name_.c_str()) |
| << " AttributeSet attrs = Xml.asAttributeSet(xml);\n" |
| // The Java-language XmlPullParser needs a call to next to find the start document tag. |
| " xml.next(); // start document\n"; |
| } |
| |
| void JavaLangViewBuilder::Finish() const { |
| out_ << " } catch (Exception e) {\n" |
| " return null;\n" |
| " }\n" // end try |
| " }\n" // end inflate |
| "}\n"; // end CompiledView |
| } |
| |
| void JavaLangViewBuilder::StartView(const string& class_name, bool /*is_viewgroup*/) { |
| const string view_var = MakeVar("view"); |
| const string layout_var = MakeVar("layout"); |
| std::string parent = "null"; |
| if (!view_stack_.empty()) { |
| const StackEntry& parent_entry = view_stack_.back(); |
| parent = parent_entry.view_var; |
| } |
| out_ << " xml.next(); // <" << class_name << ">\n" |
| << StringPrintf(" %s %s = createView(context, attrs, %s, \"%s\", factory, factory2);\n", |
| class_name.c_str(), |
| view_var.c_str(), |
| parent.c_str(), |
| class_name.c_str()) |
| << StringPrintf(" if (%s == null) %s = new %s(context, attrs);\n", |
| view_var.c_str(), |
| view_var.c_str(), |
| class_name.c_str()); |
| if (!view_stack_.empty()) { |
| out_ << StringPrintf(" ViewGroup.LayoutParams %s = %s.generateLayoutParams(attrs);\n", |
| layout_var.c_str(), |
| parent.c_str()); |
| } |
| view_stack_.push_back({class_name, view_var, layout_var}); |
| } |
| |
| void JavaLangViewBuilder::FinishView() { |
| const StackEntry var = view_stack_.back(); |
| view_stack_.pop_back(); |
| if (!view_stack_.empty()) { |
| const string& parent = view_stack_.back().view_var; |
| out_ << StringPrintf(" xml.next(); // </%s>\n", var.class_name.c_str()) |
| << StringPrintf(" %s.addView(%s, %s);\n", |
| parent.c_str(), |
| var.view_var.c_str(), |
| var.layout_params_var.c_str()); |
| } else { |
| out_ << StringPrintf(" return %s;\n", var.view_var.c_str()); |
| } |
| } |
| |
| const std::string JavaLangViewBuilder::MakeVar(std::string prefix) { |
| std::stringstream v; |
| v << prefix << view_id_++; |
| return v.str(); |
| } |