1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "java_lang_builder.h" 18 19 #include "android-base/stringprintf.h" 20 21 using android::base::StringPrintf; 22 using std::string; 23 24 void JavaLangViewBuilder::Start() const { 25 out_ << StringPrintf("package %s;\n", package_.c_str()) 26 << "import android.content.Context;\n" 27 "import android.content.res.Resources;\n" 28 "import android.content.res.XmlResourceParser;\n" 29 "import android.util.AttributeSet;\n" 30 "import android.util.Xml;\n" 31 "import android.view.*;\n" 32 "import android.widget.*;\n" 33 "\n" 34 "public final class CompiledView {\n" 35 "\n" 36 "static <T extends View> T createView(Context context, AttributeSet attrs, View parent, " 37 "String name, LayoutInflater.Factory factory, LayoutInflater.Factory2 factory2) {" 38 "\n" 39 " if (factory2 != null) {\n" 40 " return (T)factory2.onCreateView(parent, name, context, attrs);\n" 41 " } else if (factory != null) {\n" 42 " return (T)factory.onCreateView(name, context, attrs);\n" 43 " }\n" 44 // TODO: find a way to call the private factory 45 " return null;\n" 46 "}\n" 47 "\n" 48 " public static View inflate(Context context) {\n" 49 " try {\n" 50 " LayoutInflater inflater = LayoutInflater.from(context);\n" 51 " LayoutInflater.Factory factory = inflater.getFactory();\n" 52 " LayoutInflater.Factory2 factory2 = inflater.getFactory2();\n" 53 " Resources res = context.getResources();\n" 54 << StringPrintf(" XmlResourceParser xml = res.getLayout(%s.R.layout.%s);\n", 55 package_.c_str(), 56 layout_name_.c_str()) 57 << " AttributeSet attrs = Xml.asAttributeSet(xml);\n" 58 // The Java-language XmlPullParser needs a call to next to find the start document tag. 59 " xml.next(); // start document\n"; 60 } 61 62 void JavaLangViewBuilder::Finish() const { 63 out_ << " } catch (Exception e) {\n" 64 " return null;\n" 65 " }\n" // end try 66 " }\n" // end inflate 67 "}\n"; // end CompiledView 68 } 69 70 void JavaLangViewBuilder::StartView(const string& class_name, bool /*is_viewgroup*/) { 71 const string view_var = MakeVar("view"); 72 const string layout_var = MakeVar("layout"); 73 std::string parent = "null"; 74 if (!view_stack_.empty()) { 75 const StackEntry& parent_entry = view_stack_.back(); 76 parent = parent_entry.view_var; 77 } 78 out_ << " xml.next(); // <" << class_name << ">\n" 79 << StringPrintf(" %s %s = createView(context, attrs, %s, \"%s\", factory, factory2);\n", 80 class_name.c_str(), 81 view_var.c_str(), 82 parent.c_str(), 83 class_name.c_str()) 84 << StringPrintf(" if (%s == null) %s = new %s(context, attrs);\n", 85 view_var.c_str(), 86 view_var.c_str(), 87 class_name.c_str()); 88 if (!view_stack_.empty()) { 89 out_ << StringPrintf(" ViewGroup.LayoutParams %s = %s.generateLayoutParams(attrs);\n", 90 layout_var.c_str(), 91 parent.c_str()); 92 } 93 view_stack_.push_back({class_name, view_var, layout_var}); 94 } 95 96 void JavaLangViewBuilder::FinishView() { 97 const StackEntry var = view_stack_.back(); 98 view_stack_.pop_back(); 99 if (!view_stack_.empty()) { 100 const string& parent = view_stack_.back().view_var; 101 out_ << StringPrintf(" xml.next(); // </%s>\n", var.class_name.c_str()) 102 << StringPrintf(" %s.addView(%s, %s);\n", 103 parent.c_str(), 104 var.view_var.c_str(), 105 var.layout_params_var.c_str()); 106 } else { 107 out_ << StringPrintf(" return %s;\n", var.view_var.c_str()); 108 } 109 } 110 111 const std::string JavaLangViewBuilder::MakeVar(std::string prefix) { 112 std::stringstream v; 113 v << prefix << view_id_++; 114 return v.str(); 115 } 116