XML Completion and APIInfo are now not dependent on Gradle build

This commit is contained in:
Akash Yadav
2021-10-08 19:08:16 +05:30
parent e87a6ec32b
commit 9e7da7011d
31 changed files with 98641 additions and 172 deletions
-1
View File
@@ -1 +0,0 @@
<manifest package="com.itsaky.apiinfo"/>
+1 -1
View File
@@ -135,7 +135,7 @@ dependencies {
implementation 'com.google.firebase:firebase-messaging'
// Local projects
implementation project(':api-info')
implementation project(':sdk-info')
implementation project(':treeview')
implementation project(':emulator')
implementation project(':emulatorview')
@@ -913,8 +913,6 @@ public class EditorActivity extends StudioActivity implements FileTreeFragment.F
public void createServices() {
new TaskExecutor().executeAsync(() -> {
getApp().createCompletionService();
IDELanguageServer javaServer = LSPProvider.getServerForLanguage(LSPProvider.LANGUAGE_JAVA);
if(javaServer == null) return null;
@@ -82,6 +82,9 @@ public class StudioApp extends MultiDexApplication
FirebaseMessaging.getInstance().subscribeToTopic(MessagingService.TOPIC_UPDATE);
FirebaseMessaging.getInstance().subscribeToTopic(MessagingService.TOPIC_DEV_MSGS);
startXmlCompletor();
initializeApiInformation();
}
private void handleLog(CharSequence seq) {
@@ -136,14 +139,10 @@ public class StudioApp extends MultiDexApplication
*/
public void initializeApiInformation() {
if(mApiInfo == null || !mApiInfo.hasRead()) {
File apiVersions = new File(Environment.BOOTCLASSPATH.getParentFile(), "data/api-versions.xml");
if(apiVersions.exists() && apiVersions.isFile()) {
mApiInfo = new ApiInfo(apiVersions);
try {
mApiInfo.readAsync(null);
} catch (Exception e) {
LOG.error("Failed to read API version information", e);
}
try {
mApiInfo = new ApiInfo(this);
} catch (Exception e) {
LOG.error("Failed to read API version information", e);
}
}
}
@@ -152,7 +151,7 @@ public class StudioApp extends MultiDexApplication
newShell(null).bgAppend("gradle --stop");
}
public void createCompletionService() {
public void startXmlCompletor() {
this.mXmlCompletionService = new XMLCompletionService();
}
@@ -14,7 +14,6 @@ import java.io.File;
import java.io.StringReader;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.Token;
import com.itsaky.androidide.lsp.LanguageServerWrapper;
public class XMLLanguage extends BaseLanguage {
@@ -70,6 +69,7 @@ public class XMLLanguage extends BaseLanguage {
switch (token.getType()) {
case XMLLexer.OPEN:
case XMLLexer.OPEN_SLASH :
case XMLLexer.XMLDeclOpen :
advance++;
break;
case XMLLexer.CLOSE:
@@ -1,14 +1,13 @@
package com.itsaky.androidide.language.xml.completion;
import com.itsaky.androidide.app.StudioApp;
import com.itsaky.androidide.language.xml.lexer.XMLLexer;
import com.itsaky.androidide.utils.Environment;
import com.itsaky.androidide.utils.FileUtil;
import java.io.File;
import com.itsaky.attrinfo.AttrInfo;
import com.itsaky.attrinfo.models.Attr;
import com.itsaky.widgets.WidgetInfo;
import com.itsaky.widgets.models.Widget;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -18,37 +17,26 @@ import org.antlr.v4.runtime.Token;
import org.eclipse.lsp4j.CompletionItem;
import org.eclipse.lsp4j.CompletionItemKind;
import org.eclipse.lsp4j.InsertTextFormat;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class XMLCompletionService {
private HashMap<String, Attr> attrs;
private List<Widget> widgets;
private final File ANDROID_ATTRS;
private final File ANDROID_WIDGETS;
private boolean initiated = false;
private final AttrInfo attrs;
private final WidgetInfo widgets;
private boolean attrsInitialized = false;
private boolean widgetsInitialized = false;
private static final String INITIAL_TAG_ATTRIBUTES =
"android:layout_width=\"wrap_content\"\n" +
"android:layout_height=\"wrap_content\"";
public XMLCompletionService() {
this.ANDROID_ATTRS = new File(Environment.BOOTCLASSPATH.getParentFile(), "data/res/values/attrs.xml");
this.ANDROID_WIDGETS = new File(Environment.BOOTCLASSPATH.getParentFile(), "data/widgets.txt");
this.attrs = new HashMap<>();
this.widgets = new ArrayList<>();
if(ANDROID_ATTRS.exists() && ANDROID_ATTRS.isFile()) {
addAttributesFrom(ANDROID_ATTRS, true);
}
if(ANDROID_WIDGETS.exists()) {
processWidgetNames();
}
initiated = true;
this.attrs = new AttrInfo(StudioApp.getInstance(), () -> attrsInitialized = true);
this.widgets = new WidgetInfo(StudioApp.getInstance(), () -> widgetsInitialized = true);
}
public boolean isInitiated() {
return initiated;
return attrsInitialized && widgetsInitialized;
}
public List<CompletionItem> complete(CharSequence content, int index, int line, int column, String prefix) {
@@ -60,7 +48,7 @@ public class XMLCompletionService {
slash = true;
prefix = prefix.substring(1);
}
for(Widget view : widgets) {
for(Widget view : widgets.getWidgets()) {
if(view.simpleName.toLowerCase(Locale.US).startsWith(prefix))
result.add(widgetNameAsCompletion(view, slash));
}
@@ -70,8 +58,8 @@ public class XMLCompletionService {
final String name = scanner.scan(content);
if(name != null) {
final String attrName = name.contains(":") ? name.substring(name.indexOf(":") + 1) : name;
if (attrs.containsKey(attrName)) {
Attr attr = attrs.get(attrName);
if (attrs.getAttrs().containsKey(attrName)) {
Attr attr = attrs.getAttrs().get(attrName);
if(attr.hasPossibleValues()) {
Set<String> values = attr.possibleValues;
for(String value : values)
@@ -80,7 +68,7 @@ public class XMLCompletionService {
}
}
} else {
for(Map.Entry<String, Attr> entry : attrs.entrySet()) {
for(Map.Entry<String, Attr> entry : attrs.getAttrs().entrySet()) {
Attr attr = entry.getValue();
if(attr.name.toLowerCase(Locale.US).startsWith(prefix))
result.add(attrAsCompletion(attr));
@@ -151,6 +139,8 @@ public class XMLCompletionService {
sb.append(view.simpleName);
if(!closing) {
sb.append("\n");
sb.append(INITIAL_TAG_ATTRIBUTES);
if(view.isViewGroup) {
sb.append(">$0</");
sb.append(view.simpleName);
@@ -164,72 +154,10 @@ public class XMLCompletionService {
return sb.toString();
}
private String simpleName(String name) {
return name.substring(name.lastIndexOf(".") + 1);
}
private List<CompletionItem> handleResults(List<CompletionItem> result) {
return result;
}
private void processWidgetNames() {
String read = FileUtil.readFile(ANDROID_WIDGETS.getAbsolutePath());
if(read != null && read.length() > 0) {
widgets.clear();
for(String line : read.split("\\n")) {
final String name = line.split("\\s")[0];
if(name == null || name.trim().isEmpty()) continue;
final char code = name.charAt(0);
final String viewName = name.substring(1);
final String simpleViewName = simpleName(viewName);
final boolean isViewGroup = code == 'L'; // L -> Layout, W -> Widget, P -> LayoutParam
// Don't add layout params
if(code != 'P') {
widgets.add(new Widget(viewName, simpleViewName, isViewGroup));
}
}
Collections.sort(widgets);
}
}
private void addAttributesFrom(File f, boolean isAndroid) {
try {
Document doc = Jsoup.parse(f, null);
Elements attrs = doc.getElementsByTag("resources").first().getElementsByTag("attr");
for(Element attr : attrs) {
Attr a = new Attr(attr.attr("name"), isAndroid);
if(a.name.contains(":")) {
String[] split = a.name.split(":");
a.prefix = split[0];
a.name = split[1];
}
if(attr.hasAttr("format") && attr.attr("format").contains("boolean")) {
a.possibleValues.add("true");
a.possibleValues.add("false");
}
Elements enums = attr.getElementsByTag("enum");
Elements flags = attr.getElementsByTag("flag");
if(enums != null && enums.size() > 0) {
for(Element e : enums)
a.possibleValues.add(e.attr("name"));
}
if(flags != null && flags.size() > 0) {
for(Element e : flags)
a.possibleValues.add(e.attr("name"));
}
if(this.attrs.containsKey(a.name)) {
Attr b = this.attrs.get(a.name);
if(b != null && b.hasPossibleValues())
a.possibleValues.addAll(b.possibleValues);
}
this.attrs.put(a.name, a);
}
} catch (Throwable th) {}
}
private class IsInValueScanner {
private int cursorIndex;
@@ -263,47 +191,4 @@ public class XMLCompletionService {
}
}
class Attr {
public String prefix;
public String name;
public Set<String> possibleValues;
public Attr(String name, boolean isAndroid) {
this.name = name;
this.prefix = isAndroid ? "android" : "app";
this.possibleValues = new HashSet<>();
}
public boolean hasPossibleValues() {
return possibleValues != null && possibleValues.size() > 0;
}
@Override
public String toString() {
return String.format("[%s=%s]", name, possibleValues.toString());
}
}
class Widget implements Comparable {
String name;
String simpleName;
boolean isViewGroup;
public Widget(String name, String simpleName, boolean isViewGroup) {
this.name = name;
this.simpleName = simpleName;
this.isViewGroup = isViewGroup;
}
@Override
public int compareTo(Object p1) {
if(p1 instanceof Widget) {
final Widget that = (Widget) p1;
return this.simpleName.compareTo(that.simpleName);
}
return -1;
}
}
}
@@ -1,4 +1,3 @@
// Generated from XMLLexer.g4 by ANTLR 4.9.2
package com.itsaky.androidide.language.xml.lexer;
// Generated from XMLLexer.g4 by ANTLR 4.9.2
@@ -114,8 +114,6 @@ public final class Environment {
public static void setBootClasspath(File file) {
BOOTCLASSPATH = new File(file.getAbsolutePath());
StudioApp.getInstance().initializeApiInformation();
}
public static Map<String, String> getEnvironment(boolean publicUse) {
+1
View File
@@ -0,0 +1 @@
<manifest package="com.itsaky.sdkinfo"/>
@@ -1,10 +1,14 @@
package com.itsaky.apiinfo;
import com.blankj.utilcode.util.FileIOUtils;
import android.content.Context;
import android.content.res.Resources;
import com.itsaky.apiinfo.models.ClassInfo;
import com.itsaky.apiinfo.models.FieldInfo;
import com.itsaky.apiinfo.models.MethodInfo;
import java.io.File;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import org.jsoup.Jsoup;
@@ -14,8 +18,6 @@ import org.jsoup.select.Elements;
public class ApiInfo {
private final File versionsXml;
private boolean read = false;
private final Map<String, ClassInfo> classInfos;
@@ -29,9 +31,10 @@ public class ApiInfo {
public static final String FIELD = "field";
public static final String METHOD = "method";
public ApiInfo(File versionsXml) {
this.versionsXml = versionsXml;
public ApiInfo(Context ctx) throws Exception {
this.classInfos = new HashMap<String, ClassInfo>();
readAsync(ctx.getResources(), null);
}
public boolean hasRead() {
@@ -42,12 +45,13 @@ public class ApiInfo {
return classInfos.get(qualifiedName);
}
public void readAsync(Runnable onFinish) throws Exception{
public void readAsync(Resources resources, Runnable onFinish) throws Exception {
final InputStream in = resources.openRawResource(com.itsaky.sdkinfo.R.raw.versions);
if(in == null)
throw new Resources.NotFoundException("Cannot find versions.xml");
new Thread(() -> {
String contents = FileIOUtils.readFile2String(versionsXml);
if(contents != null) {
contents = contents.substring(contents.indexOf("<api"));
Document doc = Jsoup.parse(contents);
try {
Document doc = Jsoup.parse(readStream(in));
Elements classes = doc.getElementsByTag("api").first().getElementsByTag("class");
if(classes == null || classes.size() <= 0) {
return;
@@ -58,14 +62,25 @@ public class ApiInfo {
if(info != null)
classInfos.put(info.name, info);
}
read = true;
if(onFinish != null)
onFinish.run();
}
} catch (Throwable th) {}
}).start();
}
private String readStream(InputStream in) throws IOException {
final StringBuilder sb = new StringBuilder();
final BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line;
while((line = reader.readLine()) != null) {
sb.append(line.trim());
sb.append("\n");
}
return sb.substring(sb.indexOf("<api"));
}
private ClassInfo parseClassInfo(Element clazz) {
if(!clazz.hasAttr(NAME)) return null;
ClassInfo info = new ClassInfo();
@@ -0,0 +1,69 @@
package com.itsaky.attrinfo;
import android.content.Context;
import android.content.res.Resources;
import com.itsaky.attrinfo.models.Attr;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class AttrInfo {
private final Map<String, Attr> attrs;
public AttrInfo(Context ctx, Runnable onFinish) {
this.attrs = new HashMap<>();
readAttributes(ctx.getResources(), onFinish);
}
public Map<String, Attr> getAttrs() {
return this.attrs;
}
private void readAttributes(Resources resources, final Runnable onFinish) {
final InputStream in = resources.openRawResource(com.itsaky.sdkinfo.R.raw.attrs);
if(in == null) return;
try {
Document doc = Jsoup.parse(in, null, "file://android_res/");
Elements attrs = doc.getElementsByTag("resources").first().getElementsByTag("attr");
for(Element attr : attrs) {
Attr a = new Attr(attr.attr("name"), true);
if(a.name.contains(":")) {
String[] split = a.name.split(":");
a.prefix = split[0];
a.name = split[1];
}
if(attr.hasAttr("format") && attr.attr("format").contains("boolean")) {
a.possibleValues.add("true");
a.possibleValues.add("false");
}
Elements enums = attr.getElementsByTag("enum");
Elements flags = attr.getElementsByTag("flag");
if(enums != null && enums.size() > 0) {
for(Element e : enums)
a.possibleValues.add(e.attr("name"));
}
if(flags != null && flags.size() > 0) {
for(Element e : flags)
a.possibleValues.add(e.attr("name"));
}
if(this.attrs.containsKey(a.name)) {
Attr b = this.attrs.get(a.name);
if(b != null && b.hasPossibleValues())
a.possibleValues.addAll(b.possibleValues);
}
this.attrs.put(a.name, a);
}
if(onFinish != null) {
onFinish.run();
}
} catch (Throwable th) {}
}
}
@@ -0,0 +1,26 @@
package com.itsaky.attrinfo.models;
import java.util.HashSet;
import java.util.Set;
public class Attr {
public String prefix;
public String name;
public Set<String> possibleValues;
public Attr(String name, boolean isAndroid) {
this.name = name;
this.prefix = isAndroid ? "android" : "app";
this.possibleValues = new HashSet<>();
}
public boolean hasPossibleValues() {
return possibleValues != null && possibleValues.size() > 0;
}
@Override
public String toString() {
return String.format("[%s=%s]", name, possibleValues.toString());
}
}
@@ -0,0 +1,62 @@
package com.itsaky.widgets;
import android.content.Context;
import android.content.res.Resources;
import com.itsaky.widgets.models.Widget;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class WidgetInfo {
private final List<Widget> widgets;
public WidgetInfo (final Context ctx, final Runnable onFinish) {
this.widgets = new ArrayList<>();
readWidgets(ctx.getResources(), onFinish);
}
public List<Widget> getWidgets() {
return this.widgets;
}
private void readWidgets(final Resources resources, final Runnable onFinish) {
final InputStream in = resources.openRawResource(com.itsaky.sdkinfo.R.raw.widgets);
if(in == null) return;
// It's good not to block the UI Thread.
new Thread(() -> {
try {
final BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line;
while((line = reader.readLine()) != null) {
final String name = line.split("\\s")[0];
if(name == null || name.trim().isEmpty()) continue;
final char code = name.charAt(0);
final String viewName = name.substring(1);
final String simpleViewName = simpleName(viewName);
final boolean isViewGroup = code == 'L'; // L -> Layout, W -> Widget, P -> LayoutParam
// Don't add layout params
if(code != 'P') {
widgets.add(new Widget(viewName, simpleViewName, isViewGroup));
}
}
if(onFinish != null) {
onFinish.run();
}
} catch (IOException e) {}
}).start();
}
private String simpleName(String name) {
return name.substring(name.lastIndexOf(".") + 1);
}
}
@@ -0,0 +1,24 @@
package com.itsaky.widgets.models;
public class Widget implements Comparable {
public String name;
public String simpleName;
public boolean isViewGroup;
public Widget(String name, String simpleName, boolean isViewGroup) {
this.name = name;
this.simpleName = simpleName;
this.isViewGroup = isViewGroup;
}
@Override
public int compareTo(Object p1) {
if(p1 instanceof Widget) {
Widget that = (Widget) p1;
return this.simpleName.compareTo(that.simpleName);
}
return -1;
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+74
View File
@@ -0,0 +1,74 @@
Wandroid.gesture.GestureOverlayView android.widget.FrameLayout android.view.ViewGroup android.view.View java.lang.Object
Wandroid.view.SurfaceView android.view.View java.lang.Object
Wandroid.view.TextureView android.view.View java.lang.Object
Wandroid.view.View java.lang.Object
Wandroid.view.ViewStub android.view.View java.lang.Object
Wandroid.webkit.WebView android.widget.AbsoluteLayout android.view.ViewGroup android.view.View java.lang.Object
Wandroid.widget.AnalogClock android.view.View java.lang.Object
Wandroid.widget.AutoCompleteTextView android.widget.EditText android.widget.TextView android.view.View java.lang.Object
Wandroid.widget.Button android.widget.TextView android.view.View java.lang.Object
Wandroid.widget.CalendarView android.widget.FrameLayout android.view.ViewGroup android.view.View java.lang.Object
Wandroid.widget.CheckBox android.widget.CompoundButton android.widget.Button android.widget.TextView android.view.View java.lang.Object
Wandroid.widget.CheckedTextView android.widget.TextView android.view.View java.lang.Object
Wandroid.widget.Chronometer android.widget.TextView android.view.View java.lang.Object
Wandroid.widget.DatePicker android.widget.FrameLayout android.view.ViewGroup android.view.View java.lang.Object
Wandroid.widget.DigitalClock android.widget.TextView android.view.View java.lang.Object
Wandroid.widget.EditText android.widget.TextView android.view.View java.lang.Object
Wandroid.widget.Gallery android.widget.AbsSpinner android.widget.AdapterView android.view.ViewGroup android.view.View java.lang.Object
Wandroid.widget.ImageButton android.widget.ImageView android.view.View java.lang.Object
Wandroid.widget.ImageView android.view.View java.lang.Object
Wandroid.widget.MultiAutoCompleteTextView android.widget.AutoCompleteTextView android.widget.EditText android.widget.TextView android.view.View java.lang.Object
Wandroid.widget.NumberPicker android.widget.LinearLayout android.view.ViewGroup android.view.View java.lang.Object
Wandroid.widget.ProgressBar android.view.View java.lang.Object
Wandroid.widget.QuickContactBadge android.widget.ImageView android.view.View java.lang.Object
Wandroid.widget.RadioButton android.widget.CompoundButton android.widget.Button android.widget.TextView android.view.View java.lang.Object
Wandroid.widget.RatingBar android.widget.AbsSeekBar android.widget.ProgressBar android.view.View java.lang.Object
Wandroid.widget.SeekBar android.widget.AbsSeekBar android.widget.ProgressBar android.view.View java.lang.Object
Wandroid.widget.Space android.view.View java.lang.Object
Wandroid.widget.Spinner android.widget.AbsSpinner android.widget.AdapterView android.view.ViewGroup android.view.View java.lang.Object
Wandroid.widget.Switch android.widget.CompoundButton android.widget.Button android.widget.TextView android.view.View java.lang.Object
Wandroid.widget.TextClock android.widget.TextView android.view.View java.lang.Object
Wandroid.widget.TextView android.view.View java.lang.Object
Wandroid.widget.TimePicker android.widget.FrameLayout android.view.ViewGroup android.view.View java.lang.Object
Wandroid.widget.ToggleButton android.widget.CompoundButton android.widget.Button android.widget.TextView android.view.View java.lang.Object
Wandroid.widget.TwoLineListItem android.widget.RelativeLayout android.view.ViewGroup android.view.View java.lang.Object
Wandroid.widget.VideoView android.view.SurfaceView android.view.View java.lang.Object
Wandroid.widget.ZoomButton android.widget.ImageButton android.widget.ImageView android.view.View java.lang.Object
Wandroid.widget.ZoomControls android.widget.LinearLayout android.view.ViewGroup android.view.View java.lang.Object
Pandroid.widget.AbsoluteLayout.LayoutParams android.view.ViewGroup.LayoutParams java.lang.Object
Pandroid.widget.ActionMenuView.LayoutParams android.widget.LinearLayout.LayoutParams android.view.ViewGroup.MarginLayoutParams android.view.ViewGroup.LayoutParams java.lang.Object
Pandroid.widget.FrameLayout.LayoutParams android.view.ViewGroup.MarginLayoutParams android.view.ViewGroup.LayoutParams java.lang.Object
Pandroid.widget.GridLayout.LayoutParams android.view.ViewGroup.MarginLayoutParams android.view.ViewGroup.LayoutParams java.lang.Object
Pandroid.widget.LinearLayout.LayoutParams android.view.ViewGroup.MarginLayoutParams android.view.ViewGroup.LayoutParams java.lang.Object
Pandroid.widget.RadioGroup.LayoutParams android.widget.LinearLayout.LayoutParams android.view.ViewGroup.MarginLayoutParams android.view.ViewGroup.LayoutParams java.lang.Object
Pandroid.widget.RelativeLayout.LayoutParams android.view.ViewGroup.MarginLayoutParams android.view.ViewGroup.LayoutParams java.lang.Object
Pandroid.widget.TableLayout.LayoutParams android.widget.LinearLayout.LayoutParams android.view.ViewGroup.MarginLayoutParams android.view.ViewGroup.LayoutParams java.lang.Object
Pandroid.widget.TableRow.LayoutParams android.widget.LinearLayout.LayoutParams android.view.ViewGroup.MarginLayoutParams android.view.ViewGroup.LayoutParams java.lang.Object
Landroid.widget.AbsoluteLayout android.view.ViewGroup android.view.View java.lang.Object
Landroid.widget.ActionMenuView android.widget.LinearLayout android.view.ViewGroup android.view.View java.lang.Object
Landroid.widget.AdapterViewFlipper android.widget.AdapterViewAnimator android.widget.AdapterView android.view.ViewGroup android.view.View java.lang.Object
Landroid.widget.DialerFilter android.widget.RelativeLayout android.view.ViewGroup android.view.View java.lang.Object
Landroid.widget.ExpandableListView android.widget.ListView android.widget.AbsListView android.widget.AdapterView android.view.ViewGroup android.view.View java.lang.Object
Landroid.widget.FrameLayout android.view.ViewGroup android.view.View java.lang.Object
Landroid.widget.GridLayout android.view.ViewGroup android.view.View java.lang.Object
Landroid.widget.GridView android.widget.AbsListView android.widget.AdapterView android.view.ViewGroup android.view.View java.lang.Object
Landroid.widget.HorizontalScrollView android.widget.FrameLayout android.view.ViewGroup android.view.View java.lang.Object
Landroid.widget.ImageSwitcher android.widget.ViewSwitcher android.widget.ViewAnimator android.widget.FrameLayout android.view.ViewGroup android.view.View java.lang.Object
Landroid.widget.LinearLayout android.view.ViewGroup android.view.View java.lang.Object
Landroid.widget.ListView android.widget.AbsListView android.widget.AdapterView android.view.ViewGroup android.view.View java.lang.Object
Landroid.widget.MediaController android.widget.FrameLayout android.view.ViewGroup android.view.View java.lang.Object
Landroid.widget.RadioGroup android.widget.LinearLayout android.view.ViewGroup android.view.View java.lang.Object
Landroid.widget.RelativeLayout android.view.ViewGroup android.view.View java.lang.Object
Landroid.widget.ScrollView android.widget.FrameLayout android.view.ViewGroup android.view.View java.lang.Object
Landroid.widget.SearchView android.widget.LinearLayout android.view.ViewGroup android.view.View java.lang.Object
Landroid.widget.SlidingDrawer android.view.ViewGroup android.view.View java.lang.Object
Landroid.widget.StackView android.widget.AdapterViewAnimator android.widget.AdapterView android.view.ViewGroup android.view.View java.lang.Object
Landroid.widget.TabHost android.widget.FrameLayout android.view.ViewGroup android.view.View java.lang.Object
Landroid.widget.TabWidget android.widget.LinearLayout android.view.ViewGroup android.view.View java.lang.Object
Landroid.widget.TableLayout android.widget.LinearLayout android.view.ViewGroup android.view.View java.lang.Object
Landroid.widget.TableRow android.widget.LinearLayout android.view.ViewGroup android.view.View java.lang.Object
Landroid.widget.TextSwitcher android.widget.ViewSwitcher android.widget.ViewAnimator android.widget.FrameLayout android.view.ViewGroup android.view.View java.lang.Object
Landroid.widget.Toolbar android.view.ViewGroup android.view.View java.lang.Object
Landroid.widget.ViewAnimator android.widget.FrameLayout android.view.ViewGroup android.view.View java.lang.Object
Landroid.widget.ViewFlipper android.widget.ViewAnimator android.widget.FrameLayout android.view.ViewGroup android.view.View java.lang.Object
Landroid.widget.ViewSwitcher android.widget.ViewAnimator android.widget.FrameLayout android.view.ViewGroup android.view.View java.lang.Object
+2 -2
View File
@@ -4,6 +4,6 @@ include ':emulatorview'
include ':emulator'
include ':javapoet'
include ':lsp'
include ':api-info'
include ':sdk-info'
rootProject.name = "Android IDE"
rootProject.name = "AndroidIDE"