Eric Holk | c4239ac | 2018-09-05 10:43:31 -0700 | [diff] [blame] | 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 | |
Eric Holk | 4273457 | 2018-12-17 15:46:18 -0800 | [diff] [blame] | 70 | void JavaLangViewBuilder::StartView(const string& class_name, bool /*is_viewgroup*/) { |
Eric Holk | c4239ac | 2018-09-05 10:43:31 -0700 | [diff] [blame] | 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 | } |