summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDeepanshu Gupta <deepanshu@google.com>2015-08-26 20:20:58 +0000
committerAndroid Git Automerger <android-git-automerger@android.com>2015-08-26 20:20:58 +0000
commit5eaa09ff9e4cbf71fd8ca312029987c0c3d43f9e (patch)
treea5a08bad9b1c5b80c401d51d0cf9927bcd9c44ef
parent1f2c15ca8e976f3378c9e4cf63b55de3484bb2cc (diff)
parentd1dde055060d63f8981ba51aeb75ab8a459db9b4 (diff)
downloadframeworks_base-5eaa09ff9e4cbf71fd8ca312029987c0c3d43f9e.zip
frameworks_base-5eaa09ff9e4cbf71fd8ca312029987c0c3d43f9e.tar.gz
frameworks_base-5eaa09ff9e4cbf71fd8ca312029987c0c3d43f9e.tar.bz2
am d1dde055: am e5afc311: Move the layout code out of RenderSessionImpl. [DO NOT MERGE]
* commit 'd1dde055060d63f8981ba51aeb75ab8a459db9b4': Move the layout code out of RenderSessionImpl. [DO NOT MERGE]
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java6
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java10
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java20
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java15
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java12
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBarWrapper.java2
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java8
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java11
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java3
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Layout.java449
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java465
11 files changed, 511 insertions, 490 deletions
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index d07f19f..a0813c5 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -593,9 +593,13 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
/**
* Returns the integer id of a framework resource, from a given resource type and resource name.
+ * <p/>
+ * If no resource is found, it creates a dynamic id for the resource.
+ *
* @param type the type of the resource
* @param name the name of the resource.
- * @return an {@link Integer} containing the resource id, or null if no resource were found.
+ *
+ * @return an {@link Integer} containing the resource id.
*/
@NonNull
public static Integer getResourceId(ResourceType type, String name) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
index 8b8cc38..7f2d3b4 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
@@ -31,7 +31,6 @@ import android.graphics.drawable.Drawable;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
-import android.view.ViewGroup;
import android.widget.FrameLayout;
import java.lang.reflect.InvocationTargetException;
@@ -51,9 +50,8 @@ public class AppCompatActionBar extends BridgeActionBar {
/**
* Inflate the action bar and attach it to {@code parentView}
*/
- public AppCompatActionBar(@NonNull BridgeContext context, @NonNull SessionParams params,
- @NonNull ViewGroup parentView) {
- super(context, params, parentView);
+ public AppCompatActionBar(@NonNull BridgeContext context, @NonNull SessionParams params) {
+ super(context, params);
int contentRootId = context.getProjectResourceValue(ResourceType.ID,
"action_bar_activity_content", 0);
View contentView = getDecorContent().findViewById(contentRootId);
@@ -64,7 +62,9 @@ public class AppCompatActionBar extends BridgeActionBar {
// Something went wrong. Create a new FrameLayout in the enclosing layout.
FrameLayout contentRoot = new FrameLayout(context);
setMatchParent(contentRoot);
- mEnclosingLayout.addView(contentRoot);
+ if (mEnclosingLayout != null) {
+ mEnclosingLayout.addView(contentRoot);
+ }
setContentRoot(contentRoot);
}
try {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java
index a19b689..f900b45 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java
@@ -24,6 +24,7 @@ import com.android.ide.common.rendering.api.SessionParams;
import com.android.layoutlib.bridge.android.BridgeContext;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -39,7 +40,7 @@ public abstract class BridgeActionBar {
@NonNull protected final BridgeContext mBridgeContext;
@NonNull protected final SessionParams mParams;
// A Layout that contains the inflated action bar. The menu popup is added to this layout.
- @NonNull protected final ViewGroup mEnclosingLayout;
+ @Nullable protected final ViewGroup mEnclosingLayout;
private final View mDecorContent;
private final ActionBarCallback mCallback;
@@ -47,8 +48,7 @@ public abstract class BridgeActionBar {
@SuppressWarnings("NullableProblems") // Should be initialized by subclasses.
@NonNull private FrameLayout mContentRoot;
- public BridgeActionBar(@NonNull BridgeContext context, @NonNull SessionParams params,
- @NonNull ViewGroup parentView) {
+ public BridgeActionBar(@NonNull BridgeContext context, @NonNull SessionParams params) {
mBridgeContext = context;
mParams = params;
mCallback = params.getLayoutlibCallback().getActionBarCallback();
@@ -75,14 +75,13 @@ public abstract class BridgeActionBar {
// added.
mEnclosingLayout = new RelativeLayout(mBridgeContext);
setMatchParent(mEnclosingLayout);
- parentView.addView(mEnclosingLayout);
} else {
- mEnclosingLayout = parentView;
+ mEnclosingLayout = null;
}
// Inflate action bar layout.
- mDecorContent = getInflater(context).inflate(layoutId, mEnclosingLayout, true);
-
+ mDecorContent =
+ getInflater(context).inflate(layoutId, mEnclosingLayout, mEnclosingLayout != null);
}
/**
@@ -153,6 +152,13 @@ public abstract class BridgeActionBar {
public abstract void createMenuPopup();
+ /**
+ * The root view that represents the action bar and possibly the content included in it.
+ */
+ public View getRootView() {
+ return mEnclosingLayout == null ? mDecorContent : mEnclosingLayout;
+ }
+
public ActionBarCallback getCallBack() {
return mCallback;
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
index 90a1c75..c95fd74 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
@@ -68,7 +68,7 @@ abstract class CustomBar extends LinearLayout {
protected abstract TextView getStyleableTextView();
protected CustomBar(BridgeContext context, int orientation, String layoutPath,
- String name, int simulatedPlatformVersion) throws XmlPullParserException {
+ String name, int simulatedPlatformVersion) {
super(context);
mSimulatedPlatformVersion = simulatedPlatformVersion;
setOrientation(orientation);
@@ -81,11 +81,16 @@ abstract class CustomBar extends LinearLayout {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
- XmlPullParser parser = ParserFactory.create(getClass().getResourceAsStream(layoutPath),
- name);
+ XmlPullParser parser;
+ try {
+ parser = ParserFactory.create(getClass().getResourceAsStream(layoutPath), name);
+ } catch (XmlPullParserException e) {
+ // Should not happen as the resource is bundled with the jar, and ParserFactory should
+ // have been initialized.
+ throw new AssertionError(e);
+ }
- BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser(
- parser, (BridgeContext) context, false /*platformFile*/);
+ BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser(parser, context, false);
try {
inflater.inflate(bridgeParser, this, true);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java
index bb3d13f..d2a5117 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java
@@ -60,23 +60,24 @@ public class FrameworkActionBar extends BridgeActionBar {
/**
* Inflate the action bar and attach it to {@code parentView}
*/
- public FrameworkActionBar(@NonNull BridgeContext context, @NonNull SessionParams params,
- @NonNull ViewGroup parentView) {
- super(context, params, parentView);
+ public FrameworkActionBar(@NonNull BridgeContext context, @NonNull SessionParams params) {
+ super(context, params);
View decorContent = getDecorContent();
mActionBar = FrameworkActionBarWrapper.getActionBarWrapper(context, getCallBack(),
decorContent);
- FrameLayout contentRoot = (FrameLayout) mEnclosingLayout.findViewById(android.R.id.content);
+ FrameLayout contentRoot = (FrameLayout) decorContent.findViewById(android.R.id.content);
// If something went wrong and we were not able to initialize the content root,
// just add a frame layout inside this and return.
if (contentRoot == null) {
contentRoot = new FrameLayout(context);
setMatchParent(contentRoot);
- mEnclosingLayout.addView(contentRoot);
+ if (mEnclosingLayout != null) {
+ mEnclosingLayout.addView(contentRoot);
+ }
setContentRoot(contentRoot);
} else {
setContentRoot(contentRoot);
@@ -162,6 +163,7 @@ public class FrameworkActionBar extends BridgeActionBar {
listView.setDivider(a.getDrawable(R.attr.actionBarDivider));
a.recycle();
listView.setElevation(mActionBar.getMenuPopupElevation());
+ assert mEnclosingLayout != null : "Unable to find view to attach ActionMenuPopup.";
mEnclosingLayout.addView(listView);
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBarWrapper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBarWrapper.java
index daad602..af6ba24 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBarWrapper.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBarWrapper.java
@@ -79,7 +79,7 @@ public abstract class FrameworkActionBarWrapper {
}
}
- FrameworkActionBarWrapper(@NonNull BridgeContext context, ActionBarCallback callback,
+ FrameworkActionBarWrapper(@NonNull BridgeContext context, @NonNull ActionBarCallback callback,
@NonNull ActionBar actionBar) {
mActionBar = actionBar;
mCallback = callback;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java
index 04aadff..b543ca6 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java
@@ -19,8 +19,6 @@ package com.android.layoutlib.bridge.bars;
import com.android.layoutlib.bridge.android.BridgeContext;
import com.android.resources.Density;
-import org.xmlpull.v1.XmlPullParserException;
-
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.util.AttributeSet;
@@ -37,8 +35,8 @@ public class NavigationBar extends CustomBar {
* Constructor to be used when creating the {@link NavigationBar} as a regular control.
* This is currently used by the theme editor.
*/
- public NavigationBar(Context context, AttributeSet attrs)
- throws XmlPullParserException {
+ @SuppressWarnings("unused")
+ public NavigationBar(Context context, AttributeSet attrs) {
this((BridgeContext) context,
Density.getEnum(((BridgeContext) context).getMetrics().densityDpi),
LinearLayout.HORIZONTAL, // In this mode, it doesn't need to be render vertically
@@ -49,7 +47,7 @@ public class NavigationBar extends CustomBar {
}
public NavigationBar(BridgeContext context, Density density, int orientation, boolean isRtl,
- boolean rtlEnabled, int simulatedPlatformVersion) throws XmlPullParserException {
+ boolean rtlEnabled, int simulatedPlatformVersion) {
super(context, orientation, "/bars/navigation_bar.xml", "navigation_bar.xml",
simulatedPlatformVersion);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
index a0ed0e8..b77f140 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
@@ -26,6 +26,7 @@ import com.android.resources.Density;
import org.xmlpull.v1.XmlPullParserException;
import android.content.Context;
+import android.content.pm.ApplicationInfo;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.Gravity;
@@ -47,17 +48,19 @@ public class StatusBar extends CustomBar {
* Constructor to be used when creating the {@link StatusBar} as a regular control. This
* is currently used by the theme editor.
*/
- public StatusBar(Context context, AttributeSet attrs) throws XmlPullParserException {
+ @SuppressWarnings("UnusedParameters")
+ public StatusBar(Context context, AttributeSet attrs) {
this((BridgeContext) context,
Density.getEnum(((BridgeContext) context).getMetrics().densityDpi),
- LinearLayout.HORIZONTAL, // In this mode, it doesn't need to be render vertically
((BridgeContext) context).getConfiguration().getLayoutDirection() ==
View.LAYOUT_DIRECTION_RTL,
+ (context.getApplicationInfo().flags & ApplicationInfo.FLAG_SUPPORTS_RTL) != 0,
context.getApplicationInfo().targetSdkVersion);
}
- public StatusBar(BridgeContext context, Density density, int direction, boolean RtlEnabled,
- int simulatedPlatformVersion) throws XmlPullParserException {
+ @SuppressWarnings("UnusedParameters")
+ public StatusBar(BridgeContext context, Density density, boolean isRtl, boolean rtlEnabled,
+ int simulatedPlatformVersion) {
// FIXME: if direction is RTL but it's not enabled in application manifest, mirror this bar.
super(context, LinearLayout.HORIZONTAL, "/bars/status_bar.xml", "status_bar.xml",
simulatedPlatformVersion);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java
index c610601..4fe1001 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java
@@ -27,8 +27,7 @@ public class TitleBar extends CustomBar {
private TextView mTextView;
- public TitleBar(BridgeContext context, String label, int simulatedPlatformVersion)
- throws XmlPullParserException {
+ public TitleBar(BridgeContext context, String label, int simulatedPlatformVersion) {
super(context, LinearLayout.HORIZONTAL, "/bars/title_bar.xml", "title_bar.xml",
simulatedPlatformVersion);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Layout.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Layout.java
new file mode 100644
index 0000000..0798716
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Layout.java
@@ -0,0 +1,449 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+package com.android.layoutlib.bridge.impl;
+
+import com.android.ide.common.rendering.api.HardwareConfig;
+import com.android.ide.common.rendering.api.RenderResources;
+import com.android.ide.common.rendering.api.ResourceValue;
+import com.android.ide.common.rendering.api.SessionParams;
+import com.android.ide.common.rendering.api.StyleResourceValue;
+import com.android.internal.util.XmlUtils;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.android.BridgeContext;
+import com.android.layoutlib.bridge.bars.AppCompatActionBar;
+import com.android.layoutlib.bridge.bars.BridgeActionBar;
+import com.android.layoutlib.bridge.bars.Config;
+import com.android.layoutlib.bridge.bars.FrameworkActionBar;
+import com.android.layoutlib.bridge.bars.NavigationBar;
+import com.android.layoutlib.bridge.bars.StatusBar;
+import com.android.layoutlib.bridge.bars.TitleBar;
+import com.android.resources.Density;
+import com.android.resources.ResourceType;
+import com.android.resources.ScreenOrientation;
+
+import android.annotation.NonNull;
+import android.graphics.drawable.Drawable;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static android.widget.LinearLayout.VERTICAL;
+
+/**
+ * The Layout used to create the system decor.
+ *
+ * The layout inflated will contain a content frame where the user's layout can be inflated.
+ * <pre>
+ * +-------------------------------------------------+---+
+ * | Status bar | N |
+ * +-------------------------------------------------+ a |
+ * | Title/Action bar (optional) | v |
+ * +-------------------------------------------------+ |
+ * | Content, vertical extending | b |
+ * | | a |
+ * | | r |
+ * +-------------------------------------------------+---+
+ * </pre>
+ * or
+ * <pre>
+ * +-------------------------------------+
+ * | Status bar |
+ * +-------------------------------------+
+ * | Title/Action bar (optional) |
+ * +-------------------------------------+
+ * | Content, vertical extending |
+ * | |
+ * | |
+ * +-------------------------------------+
+ * | Nav bar |
+ * +-------------------------------------+
+ * </pre>
+ *
+ */
+class Layout extends RelativeLayout {
+
+ // Theme attributes used for configuring appearance of the system decor.
+ private static final String ATTR_WINDOW_FLOATING = "windowIsFloating";
+ private static final String ATTR_WINDOW_BACKGROUND = "windowBackground";
+ private static final String ATTR_WINDOW_FULL_SCREEN = "windowFullScreen";
+ private static final String ATTR_NAV_BAR_HEIGHT = "navigation_bar_height";
+ private static final String ATTR_NAV_BAR_WIDTH = "navigation_bar_width";
+ private static final String ATTR_STATUS_BAR_HEIGHT = "status_bar_height";
+ private static final String ATTR_WINDOW_ACTION_BAR = "windowActionBar";
+ private static final String ATTR_ACTION_BAR_SIZE = "actionBarSize";
+ private static final String ATTR_WINDOW_NO_TITLE = "windowNoTitle";
+ private static final String ATTR_WINDOW_TITLE_SIZE = "windowTitleSize";
+ private static final String PREFIX_THEME_APPCOMPAT = "Theme.AppCompat";
+
+ // Default sizes
+ private static final int DEFAULT_STATUS_BAR_HEIGHT = 25;
+ private static final int DEFAULT_TITLE_BAR_HEIGHT = 25;
+ private static final int DEFAULT_NAV_BAR_SIZE = 48;
+
+ // Ids assigned to components created. This is so that we can refer to other components in
+ // layout params.
+ private static final String ID_NAV_BAR = "navBar";
+ private static final String ID_STATUS_BAR = "statusBar";
+ private static final String ID_TITLE_BAR = "titleBar";
+ // Prefix used with the above ids in order to make them unique in framework namespace.
+ private static final String ID_PREFIX = "android_layoutlib_";
+
+ /**
+ * Temporarily store the builder so that it doesn't have to be passed to all methods used
+ * during inflation.
+ */
+ private Builder mBuilder;
+
+ /**
+ * This holds user's layout.
+ */
+ private FrameLayout mContentRoot;
+
+ public Layout(@NonNull Builder builder) {
+ super(builder.mContext);
+ mBuilder = builder;
+ if (builder.mWindowBackground != null) {
+ Drawable d = ResourceHelper.getDrawable(builder.mWindowBackground, builder.mContext);
+ setBackground(d);
+ }
+
+ int simulatedPlatformVersion = getParams().getSimulatedPlatformVersion();
+ HardwareConfig hwConfig = getParams().getHardwareConfig();
+ Density density = hwConfig.getDensity();
+ boolean isRtl = Bridge.isLocaleRtl(getParams().getLocale());
+
+ NavigationBar navBar = null;
+ if (Config.showOnScreenNavBar(simulatedPlatformVersion) && mBuilder.hasSoftwareButtons() &&
+ builder.isNavBarVertical()) {
+ navBar = createNavBar(getContext(), density, isRtl, getParams().isRtlSupported(),
+ simulatedPlatformVersion);
+ }
+
+ StatusBar statusBar = null;
+ if (builder.mStatusBarSize > 0) {
+ statusBar = createStatusBar(getContext(), density, isRtl, getParams().isRtlSupported(),
+ simulatedPlatformVersion);
+ }
+
+ View actionBar = null;
+ TitleBar titleBar = null;
+ if (builder.mActionBarSize > 0) {
+ BridgeActionBar bar = createActionBar(getContext(), getParams());
+ mContentRoot = bar.getContentRoot();
+ actionBar = bar.getRootView();
+ } else if (mBuilder.mTitleBarSize > 0) {
+ titleBar = createTitleBar(getContext(), getParams().getAppLabel(),
+ simulatedPlatformVersion);
+ }
+
+ addViews(titleBar, mContentRoot == null ? (mContentRoot = createContentFrame()) : actionBar,
+ statusBar, navBar);
+ // Done with the builder. Don't hold a reference to it.
+ mBuilder = null;
+ }
+
+ @NonNull
+ private FrameLayout createContentFrame() {
+ FrameLayout contentRoot = new FrameLayout(getContext());
+ LayoutParams params =
+ new LayoutParams(MATCH_PARENT, MATCH_PARENT);
+ int rule = mBuilder.isNavBarVertical() ? START_OF : ABOVE;
+ if (mBuilder.mNavBarSize > 0) {
+ params.addRule(rule, getId(ID_NAV_BAR));
+ }
+ int below = -1;
+ if (mBuilder.mActionBarSize <= 0 && mBuilder.mTitleBarSize > 0) {
+ below = getId(ID_TITLE_BAR);
+ } else if (mBuilder.mStatusBarSize > 0) {
+ below = getId(ID_STATUS_BAR);
+ }
+ if (below != -1) {
+ params.addRule(BELOW, below);
+ }
+
+ return contentRoot;
+ }
+
+ @NonNull
+ public FrameLayout getContentRoot() {
+ return mContentRoot;
+ }
+
+ @NonNull
+ private SessionParams getParams() {
+ return mBuilder.mParams;
+ }
+
+ @NonNull
+ @Override
+ public BridgeContext getContext(){
+ return (BridgeContext) super.getContext();
+ }
+
+ /**
+ * @param isRtl whether the current locale is an RTL locale.
+ * @param isRtlSupported whether the applications supports RTL (i.e. has supportsRtl=true
+ * in the manifest and targetSdkVersion >= 17.
+ */
+ @NonNull
+ private StatusBar createStatusBar(BridgeContext context, Density density, boolean isRtl,
+ boolean isRtlSupported, int simulatedPlatformVersion) {
+ StatusBar statusBar =
+ new StatusBar(context, density, isRtl, isRtlSupported, simulatedPlatformVersion);
+ LayoutParams params = new LayoutParams(MATCH_PARENT, mBuilder.mStatusBarSize);
+ if (mBuilder.isNavBarVertical()) {
+ params.addRule(START_OF, getId(ID_NAV_BAR));
+ }
+ statusBar.setLayoutParams(params);
+ statusBar.setId(getId(ID_STATUS_BAR));
+ return statusBar;
+ }
+
+ private BridgeActionBar createActionBar(@NonNull BridgeContext context,
+ @NonNull SessionParams params) {
+ BridgeActionBar actionBar;
+ if (mBuilder.isThemeAppCompat()) {
+ actionBar = new AppCompatActionBar(context, params);
+ } else {
+ actionBar = new FrameworkActionBar(context, params);
+ }
+ LayoutParams layoutParams = new LayoutParams(MATCH_PARENT, MATCH_PARENT);
+ int rule = mBuilder.isNavBarVertical() ? START_OF : ABOVE;
+ if (mBuilder.mNavBarSize > 0) {
+ layoutParams.addRule(rule, getId(ID_NAV_BAR));
+ }
+ if (mBuilder.mStatusBarSize > 0) {
+ layoutParams.addRule(BELOW, getId(ID_STATUS_BAR));
+ }
+ actionBar.getRootView().setLayoutParams(layoutParams);
+ actionBar.createMenuPopup();
+ return actionBar;
+ }
+
+
+ @NonNull
+ private TitleBar createTitleBar(BridgeContext context, String title,
+ int simulatedPlatformVersion) {
+ TitleBar titleBar = new TitleBar(context, title, simulatedPlatformVersion);
+ LayoutParams params = new LayoutParams(MATCH_PARENT, mBuilder.mTitleBarSize);
+ if (mBuilder.mStatusBarSize > 0) {
+ params.addRule(BELOW, getId(ID_STATUS_BAR));
+ }
+ if (mBuilder.isNavBarVertical()) {
+ params.addRule(START_OF, getId(ID_NAV_BAR));
+ }
+ titleBar.setLayoutParams(params);
+ titleBar.setId(getId(ID_TITLE_BAR));
+ return titleBar;
+ }
+
+ /**
+ * @param isRtl whether the current locale is an RTL locale.
+ * @param isRtlSupported whether the applications supports RTL (i.e. has supportsRtl=true
+ * in the manifest and targetSdkVersion >= 17.
+ */
+ @NonNull
+ private NavigationBar createNavBar(BridgeContext context, Density density, boolean isRtl,
+ boolean isRtlSupported, int simulatedPlatformVersion) {
+ int orientation = mBuilder.mNavBarOrientation;
+ int size = mBuilder.mNavBarSize;
+ NavigationBar navBar = new NavigationBar(context, density, orientation, isRtl,
+ isRtlSupported, simulatedPlatformVersion);
+ boolean isVertical = mBuilder.isNavBarVertical();
+ int w = isVertical ? size : MATCH_PARENT;
+ int h = isVertical ? MATCH_PARENT : size;
+ LayoutParams params = new LayoutParams(w, h);
+ params.addRule(isVertical ? ALIGN_PARENT_END : ALIGN_PARENT_BOTTOM);
+ navBar.setLayoutParams(params);
+ navBar.setId(getId(ID_NAV_BAR));
+ return navBar;
+ }
+
+ private void addViews(@NonNull View... views) {
+ for (View view : views) {
+ if (view != null) {
+ addView(view);
+ }
+ }
+ }
+
+ private int getId(String name) {
+ return Bridge.getResourceId(ResourceType.ID, ID_PREFIX + name);
+ }
+
+ /**
+ * A helper class to help initialize the Layout.
+ */
+ static class Builder {
+ @NonNull
+ private final SessionParams mParams;
+ @NonNull
+ private final BridgeContext mContext;
+ private final RenderResources mResources;
+
+ private final boolean mWindowIsFloating;
+ private ResourceValue mWindowBackground;
+ private int mStatusBarSize;
+ private int mNavBarSize;
+ private int mNavBarOrientation;
+ private int mActionBarSize;
+ private int mTitleBarSize;
+
+ private Boolean mIsThemeAppCompat;
+
+ public Builder(@NonNull SessionParams params, @NonNull BridgeContext context) {
+ mParams = params;
+ mContext = context;
+ mResources = mParams.getResources();
+ mWindowIsFloating = getBooleanThemeValue(mResources, ATTR_WINDOW_FLOATING, true, true);
+
+ findBackground();
+ findStatusBar();
+ findActionBar();
+ findNavBar();
+ }
+
+ public boolean isNavBarVertical() {
+ return mNavBarOrientation == VERTICAL;
+ }
+
+ private void findBackground() {
+ if (!mParams.isBgColorOverridden()) {
+ mWindowBackground = mResources.findItemInTheme(ATTR_WINDOW_BACKGROUND, true);
+ mWindowBackground = mResources.resolveResValue(mWindowBackground);
+ }
+ }
+
+ private void findStatusBar() {
+ boolean windowFullScreen =
+ getBooleanThemeValue(mResources, ATTR_WINDOW_FULL_SCREEN, true, false);
+ if (!windowFullScreen && !mWindowIsFloating) {
+ mStatusBarSize =
+ getDimension(ATTR_STATUS_BAR_HEIGHT, true, DEFAULT_STATUS_BAR_HEIGHT);
+ }
+ }
+
+ private void findActionBar() {
+ if (mWindowIsFloating) {
+ return;
+ }
+ // Check if an actionbar is needed
+ boolean windowActionBar = getBooleanThemeValue(mResources, ATTR_WINDOW_ACTION_BAR,
+ isThemeAppCompat(), true);
+ if (windowActionBar) {
+ mActionBarSize = getDimension(ATTR_ACTION_BAR_SIZE, true, DEFAULT_TITLE_BAR_HEIGHT);
+ } else {
+ // Maybe the gingerbread era title bar is needed
+ boolean windowNoTitle =
+ getBooleanThemeValue(mResources, ATTR_WINDOW_NO_TITLE, true, false);
+ if (!windowNoTitle) {
+ mTitleBarSize =
+ getDimension(ATTR_WINDOW_TITLE_SIZE, true, DEFAULT_TITLE_BAR_HEIGHT);
+ }
+ }
+ }
+
+ private void findNavBar() {
+ if (hasSoftwareButtons() && !mWindowIsFloating) {
+
+ // get orientation
+ HardwareConfig hwConfig = mParams.getHardwareConfig();
+ boolean barOnBottom = true;
+
+ if (hwConfig.getOrientation() == ScreenOrientation.LANDSCAPE) {
+ int shortSize = hwConfig.getScreenHeight();
+ int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT /
+ hwConfig.getDensity().getDpiValue();
+
+ // 0-599dp: "phone" UI with bar on the side
+ // 600+dp: "tablet" UI with bar on the bottom
+ barOnBottom = shortSizeDp >= 600;
+ }
+
+ mNavBarOrientation = barOnBottom ? LinearLayout.HORIZONTAL : VERTICAL;
+ mNavBarSize = getDimension(barOnBottom ? ATTR_NAV_BAR_HEIGHT : ATTR_NAV_BAR_WIDTH,
+ true, DEFAULT_NAV_BAR_SIZE);
+ }
+ }
+
+ private int getDimension(String attr, boolean isFramework, int defaultValue) {
+ ResourceValue value = mResources.findItemInTheme(attr, isFramework);
+ value = mResources.resolveResValue(value);
+ if (value != null) {
+ TypedValue typedValue = ResourceHelper.getValue(attr, value.getValue(), true);
+ if (typedValue != null) {
+ return (int) typedValue.getDimension(mContext.getMetrics());
+ }
+ }
+ return defaultValue;
+ }
+
+ /**
+ * Looks for an attribute in the current theme.
+ *
+ * @param resources the render resources
+ * @param name the name of the attribute
+ * @param defaultValue the default value.
+ * @param isFrameworkAttr if the attribute is in android namespace
+ * @return the value of the attribute or the default one if not found.
+ */
+ static boolean getBooleanThemeValue(@NonNull RenderResources resources, String name,
+ boolean isFrameworkAttr, boolean defaultValue) {
+ ResourceValue value = resources.findItemInTheme(name, isFrameworkAttr);
+ value = resources.resolveResValue(value);
+ if (value == null) {
+ return defaultValue;
+ }
+ return XmlUtils.convertValueToBoolean(value.getValue(), defaultValue);
+ }
+
+ private boolean hasSoftwareButtons() {
+ return mParams.getHardwareConfig().hasSoftwareButtons();
+ }
+
+ private boolean isThemeAppCompat() {
+ // If a cached value exists, return it.
+ if (mIsThemeAppCompat != null) {
+ return mIsThemeAppCompat;
+ }
+ // Ideally, we should check if the corresponding activity extends
+ // android.support.v7.app.ActionBarActivity, and not care about the theme name at all.
+ StyleResourceValue defaultTheme = mResources.getDefaultTheme();
+ // We can't simply check for parent using resources.themeIsParentOf() since the
+ // inheritance structure isn't really what one would expect. The first common parent
+ // between Theme.AppCompat.Light and Theme.AppCompat is Theme.Material (for v21).
+ boolean isThemeAppCompat = false;
+ for (int i = 0; i < 50; i++) {
+ if (defaultTheme == null) {
+ break;
+ }
+ // for loop ensures that we don't run into cyclic theme inheritance.
+ if (defaultTheme.getName().startsWith(PREFIX_THEME_APPCOMPAT)) {
+ isThemeAppCompat = true;
+ break;
+ }
+ defaultTheme = mResources.getParent(defaultTheme);
+ }
+ mIsThemeAppCompat = isThemeAppCompat;
+ return isThemeAppCompat;
+ }
+ }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
index 6a9d5dd..15d14cb 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -29,10 +29,8 @@ import com.android.ide.common.rendering.api.Result;
import com.android.ide.common.rendering.api.Result.Status;
import com.android.ide.common.rendering.api.SessionParams;
import com.android.ide.common.rendering.api.SessionParams.RenderingMode;
-import com.android.ide.common.rendering.api.StyleResourceValue;
import com.android.ide.common.rendering.api.ViewInfo;
import com.android.ide.common.rendering.api.ViewType;
-import com.android.internal.util.XmlUtils;
import com.android.internal.view.menu.ActionMenuItemView;
import com.android.internal.view.menu.BridgeMenuItemImpl;
import com.android.internal.view.menu.IconMenuItemView;
@@ -45,22 +43,11 @@ import com.android.layoutlib.bridge.android.BridgeLayoutParamsMapAttributes;
import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
import com.android.layoutlib.bridge.android.RenderParamsFlags;
import com.android.layoutlib.bridge.android.support.DesignLibUtil;
-import com.android.layoutlib.bridge.bars.AppCompatActionBar;
-import com.android.layoutlib.bridge.bars.BridgeActionBar;
-import com.android.layoutlib.bridge.bars.Config;
-import com.android.layoutlib.bridge.bars.FrameworkActionBar;
-import com.android.layoutlib.bridge.bars.NavigationBar;
-import com.android.layoutlib.bridge.bars.StatusBar;
-import com.android.layoutlib.bridge.bars.TitleBar;
import com.android.layoutlib.bridge.impl.binding.FakeAdapter;
import com.android.layoutlib.bridge.impl.binding.FakeExpandableAdapter;
-import com.android.resources.Density;
import com.android.resources.ResourceType;
-import com.android.resources.ScreenOrientation;
import com.android.util.Pair;
-import org.xmlpull.v1.XmlPullParserException;
-
import android.animation.AnimationThread;
import android.animation.Animator;
import android.animation.AnimatorInflater;
@@ -72,10 +59,7 @@ import android.app.Fragment_Delegate;
import android.graphics.Bitmap;
import android.graphics.Bitmap_Delegate;
import android.graphics.Canvas;
-import android.graphics.drawable.Drawable;
import android.preference.Preference_Delegate;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
import android.view.AttachInfo_Accessor;
import android.view.BridgeInflater;
import android.view.IWindowManager;
@@ -126,33 +110,22 @@ import static com.android.layoutlib.bridge.util.ReflectionUtils.isInstanceOf;
*/
public class RenderSessionImpl extends RenderAction<SessionParams> {
- private static final int DEFAULT_TITLE_BAR_HEIGHT = 25;
- private static final int DEFAULT_STATUS_BAR_HEIGHT = 25;
-
// scene state
private RenderSession mScene;
private BridgeXmlBlockParser mBlockParser;
private BridgeInflater mInflater;
- private ResourceValue mWindowBackground;
private ViewGroup mViewRoot;
private FrameLayout mContentRoot;
private Canvas mCanvas;
private int mMeasuredScreenWidth = -1;
private int mMeasuredScreenHeight = -1;
private boolean mIsAlphaChannelImage;
- private boolean mWindowIsFloating;
- private Boolean mIsThemeAppCompat;
-
- private int mStatusBarSize;
- private int mNavigationBarSize;
- private int mNavigationBarOrientation = LinearLayout.HORIZONTAL;
- private int mTitleBarSize;
- private int mActionBarSize;
// information being returned through the API
private BufferedImage mImage;
private List<ViewInfo> mViewInfoList;
private List<ViewInfo> mSystemViewInfoList;
+ private Layout.Builder mLayoutBuilder;
private static final class PostInflateException extends Exception {
private static final long serialVersionUID = 1L;
@@ -196,34 +169,24 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
SessionParams params = getParams();
BridgeContext context = getContext();
-
- RenderResources resources = getParams().getResources();
- DisplayMetrics metrics = getContext().getMetrics();
-
// use default of true in case it's not found to use alpha by default
- mIsAlphaChannelImage = getBooleanThemeValue(resources, "windowIsFloating", true, true);
- // FIXME: Find out why both variables are taking the same value.
- mWindowIsFloating = getBooleanThemeValue(resources, "windowIsFloating", true, true);
+ mIsAlphaChannelImage = Layout.Builder.getBooleanThemeValue(params.getResources(),
+ "windowIsFloating", true, true);
- findBackground(resources);
- findStatusBar(resources, metrics);
- findActionBar(resources, metrics);
- findNavigationBar(resources, metrics);
+ mLayoutBuilder = new Layout.Builder(params, context);
// FIXME: find those out, and possibly add them to the render params
boolean hasNavigationBar = true;
//noinspection ConstantConditions
IWindowManager iwm = new IWindowManagerImpl(getContext().getConfiguration(),
- metrics, Surface.ROTATION_0,
- hasNavigationBar);
+ context.getMetrics(), Surface.ROTATION_0, hasNavigationBar);
WindowManagerGlobal_Delegate.setWindowManagerService(iwm);
// build the inflater and parser.
mInflater = new BridgeInflater(context, params.getLayoutlibCallback());
context.setBridgeInflater(mInflater);
- mBlockParser = new BridgeXmlBlockParser(
- params.getLayoutDescription(), context, false /* platformResourceFlag */);
+ mBlockParser = new BridgeXmlBlockParser(params.getLayoutDescription(), context, false);
return SUCCESS.createResult();
}
@@ -240,164 +203,11 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
checkLock();
try {
-
+ mViewRoot = new Layout(mLayoutBuilder);
+ mLayoutBuilder = null; // Done with the builder.
+ mContentRoot = ((Layout) mViewRoot).getContentRoot();
SessionParams params = getParams();
- HardwareConfig hardwareConfig = params.getHardwareConfig();
BridgeContext context = getContext();
- boolean isRtl = Bridge.isLocaleRtl(params.getLocale());
- int layoutDirection = isRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR;
-
- // the view group that receives the window background.
- ViewGroup backgroundView;
-
- if (mWindowIsFloating || params.isForceNoDecor()) {
- backgroundView = mViewRoot = mContentRoot = new FrameLayout(context);
- mViewRoot.setLayoutDirection(layoutDirection);
- } else {
- int simulatedPlatformVersion = params.getSimulatedPlatformVersion();
- if (hasSoftwareButtons() && mNavigationBarOrientation == LinearLayout.VERTICAL) {
- /*
- * This is a special case where the navigation bar is on the right.
- +-------------------------------------------------+---+
- | Status bar (always) | |
- +-------------------------------------------------+ |
- | (Layout with background drawable) | |
- | +---------------------------------------------+ | |
- | | Title/Action bar (optional) | | |
- | +---------------------------------------------+ | |
- | | Content, vertical extending | | |
- | | | | |
- | +---------------------------------------------+ | |
- +-------------------------------------------------+---+
-
- So we create a horizontal layout, with the nav bar on the right,
- and the left part is the normal layout below without the nav bar at
- the bottom
- */
- LinearLayout topLayout = new LinearLayout(context);
- topLayout.setLayoutDirection(layoutDirection);
- mViewRoot = topLayout;
- topLayout.setOrientation(LinearLayout.HORIZONTAL);
-
- if (Config.showOnScreenNavBar(simulatedPlatformVersion)) {
- try {
- NavigationBar navigationBar = createNavigationBar(context,
- hardwareConfig.getDensity(), isRtl, params.isRtlSupported(),
- simulatedPlatformVersion);
- topLayout.addView(navigationBar);
- } catch (XmlPullParserException ignored) {
- }
- }
- }
-
- /*
- * we're creating the following layout
- *
- +-------------------------------------------------+
- | Status bar (always) |
- +-------------------------------------------------+
- | (Layout with background drawable) |
- | +---------------------------------------------+ |
- | | Title/Action bar (optional) | |
- | +---------------------------------------------+ |
- | | Content, vertical extending | |
- | | | |
- | +---------------------------------------------+ |
- +-------------------------------------------------+
- | Navigation bar for soft buttons, maybe see above|
- +-------------------------------------------------+
-
- */
-
- LinearLayout topLayout = new LinearLayout(context);
- topLayout.setOrientation(LinearLayout.VERTICAL);
- topLayout.setLayoutDirection(layoutDirection);
- // if we don't already have a view root this is it
- if (mViewRoot == null) {
- mViewRoot = topLayout;
- } else {
- int topLayoutWidth =
- params.getHardwareConfig().getScreenWidth() - mNavigationBarSize;
- LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
- topLayoutWidth, LayoutParams.MATCH_PARENT);
- topLayout.setLayoutParams(layoutParams);
-
- // this is the case of soft buttons + vertical bar.
- // this top layout is the first layout in the horizontal layout. see above)
- if (isRtl && params.isRtlSupported()) {
- // If RTL is enabled, layoutlib will mirror the layouts. So, add the
- // topLayout to the right of Navigation Bar and layoutlib will draw it
- // to the left.
- mViewRoot.addView(topLayout);
- } else {
- // Add the top layout to the left of the Navigation Bar.
- mViewRoot.addView(topLayout, 0);
- }
- }
-
- if (mStatusBarSize > 0) {
- // system bar
- try {
- StatusBar statusBar = createStatusBar(context, hardwareConfig.getDensity(),
- layoutDirection, params.isRtlSupported(),
- simulatedPlatformVersion);
- topLayout.addView(statusBar);
- } catch (XmlPullParserException ignored) {
-
- }
- }
-
- LinearLayout backgroundLayout = new LinearLayout(context);
- backgroundView = backgroundLayout;
- backgroundLayout.setOrientation(LinearLayout.VERTICAL);
- LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
- LayoutParams.MATCH_PARENT, 0);
- layoutParams.weight = 1;
- backgroundLayout.setLayoutParams(layoutParams);
- topLayout.addView(backgroundLayout);
-
-
- // if the theme says no title/action bar, then the size will be 0
- if (mActionBarSize > 0) {
- BridgeActionBar actionBar = createActionBar(context, params, backgroundLayout);
- actionBar.createMenuPopup();
- mContentRoot = actionBar.getContentRoot();
- } else if (mTitleBarSize > 0) {
- try {
- TitleBar titleBar = createTitleBar(context,
- params.getAppLabel(),
- simulatedPlatformVersion);
- backgroundLayout.addView(titleBar);
- } catch (XmlPullParserException ignored) {
-
- }
- }
-
- // content frame
- if (mContentRoot == null) {
- mContentRoot = new FrameLayout(context);
- layoutParams = new LinearLayout.LayoutParams(
- LayoutParams.MATCH_PARENT, 0);
- layoutParams.weight = 1;
- mContentRoot.setLayoutParams(layoutParams);
- backgroundLayout.addView(mContentRoot);
- }
-
- if (Config.showOnScreenNavBar(simulatedPlatformVersion) &&
- mNavigationBarOrientation == LinearLayout.HORIZONTAL &&
- mNavigationBarSize > 0) {
- // system bar
- try {
- NavigationBar navigationBar = createNavigationBar(context,
- hardwareConfig.getDensity(), isRtl, params.isRtlSupported(),
- simulatedPlatformVersion);
- topLayout.addView(navigationBar);
- } catch (XmlPullParserException ignored) {
-
- }
- }
- }
-
// Sets the project callback (custom view loader) to the fragment delegate so that
// it can instantiate the custom Fragment.
@@ -408,7 +218,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
View view;
if (isPreference) {
view = Preference_Delegate.inflatePreference(getContext(), mBlockParser,
- mContentRoot);
+ mContentRoot);
} else {
view = mInflater.inflate(mBlockParser, mContentRoot);
}
@@ -427,12 +237,6 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
setActiveToolbar(view, context, params);
- // get the background drawable
- if (mWindowBackground != null) {
- Drawable d = ResourceHelper.getDrawable(mWindowBackground, context);
- backgroundView.setBackground(d);
- }
-
return SUCCESS.createResult();
} catch (PostInflateException e) {
return ERROR_INFLATION.createResult(e.getMessage(), e);
@@ -1073,198 +877,6 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
}
}
-
- private void findBackground(RenderResources resources) {
- if (!getParams().isBgColorOverridden()) {
- mWindowBackground = resources.findItemInTheme("windowBackground",
- true /*isFrameworkAttr*/);
- if (mWindowBackground != null) {
- mWindowBackground = resources.resolveResValue(mWindowBackground);
- }
- }
- }
-
- private boolean hasSoftwareButtons() {
- return getParams().getHardwareConfig().hasSoftwareButtons();
- }
-
- private void findStatusBar(RenderResources resources, DisplayMetrics metrics) {
- boolean windowFullscreen = getBooleanThemeValue(resources,
- "windowFullscreen", false, true);
-
- if (!windowFullscreen && !mWindowIsFloating) {
- // default value
- mStatusBarSize = DEFAULT_STATUS_BAR_HEIGHT;
-
- // get the real value
- ResourceValue value = resources.getFrameworkResource(ResourceType.DIMEN,
- "status_bar_height");
-
- if (value != null) {
- TypedValue typedValue = ResourceHelper.getValue("status_bar_height",
- value.getValue(), true /*requireUnit*/);
- if (typedValue != null) {
- // compute the pixel value based on the display metrics
- mStatusBarSize = (int)typedValue.getDimension(metrics);
- }
- }
- }
- }
-
- private void findActionBar(RenderResources resources, DisplayMetrics metrics) {
- if (mWindowIsFloating) {
- return;
- }
-
- boolean windowActionBar = getBooleanThemeValue(resources,
- "windowActionBar", true, !isThemeAppCompat(resources));
-
- // if there's a value and it's false (default is true)
- if (windowActionBar) {
-
- // default size of the window title bar
- mActionBarSize = DEFAULT_TITLE_BAR_HEIGHT;
-
- // get value from the theme.
- ResourceValue value = resources.findItemInTheme("actionBarSize",
- true /*isFrameworkAttr*/);
-
- // resolve it
- value = resources.resolveResValue(value);
-
- if (value != null) {
- // get the numerical value, if available
- TypedValue typedValue = ResourceHelper.getValue("actionBarSize", value.getValue(),
- true /*requireUnit*/);
- if (typedValue != null) {
- // compute the pixel value based on the display metrics
- mActionBarSize = (int)typedValue.getDimension(metrics);
- }
- }
- } else {
- // action bar overrides title bar so only look for this one if action bar is hidden
- boolean windowNoTitle = getBooleanThemeValue(resources, "windowNoTitle", false, true);
-
- if (!windowNoTitle) {
-
- // default size of the window title bar
- mTitleBarSize = DEFAULT_TITLE_BAR_HEIGHT;
-
- // get value from the theme.
- ResourceValue value = resources.findItemInTheme("windowTitleSize",
- true /*isFrameworkAttr*/);
-
- // resolve it
- value = resources.resolveResValue(value);
-
- if (value != null) {
- // get the numerical value, if available
- TypedValue typedValue = ResourceHelper.getValue("windowTitleSize",
- value.getValue(), true /*requireUnit*/);
- if (typedValue != null) {
- // compute the pixel value based on the display metrics
- mTitleBarSize = (int)typedValue.getDimension(metrics);
- }
- }
- }
-
- }
- }
-
- private void findNavigationBar(RenderResources resources, DisplayMetrics metrics) {
- if (hasSoftwareButtons() && !mWindowIsFloating) {
-
- // default value
- mNavigationBarSize = 48; // ??
-
- HardwareConfig hardwareConfig = getParams().getHardwareConfig();
-
- boolean barOnBottom = true;
-
- if (hardwareConfig.getOrientation() == ScreenOrientation.LANDSCAPE) {
- // compute the dp of the screen.
- int shortSize = hardwareConfig.getScreenHeight();
-
- // compute in dp
- int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT /
- hardwareConfig.getDensity().getDpiValue();
-
- // 0-599dp: "phone" UI with bar on the side
- // 600+dp: "tablet" UI with bar on the bottom
- barOnBottom = shortSizeDp >= 600;
- }
-
- if (barOnBottom) {
- mNavigationBarOrientation = LinearLayout.HORIZONTAL;
- } else {
- mNavigationBarOrientation = LinearLayout.VERTICAL;
- }
-
- // get the real value
- ResourceValue value = resources.getFrameworkResource(ResourceType.DIMEN,
- barOnBottom ? "navigation_bar_height" : "navigation_bar_width");
-
- if (value != null) {
- TypedValue typedValue = ResourceHelper.getValue("navigation_bar_height",
- value.getValue(), true /*requireUnit*/);
- if (typedValue != null) {
- // compute the pixel value based on the display metrics
- mNavigationBarSize = (int)typedValue.getDimension(metrics);
- }
- }
- }
- }
-
- private boolean isThemeAppCompat(RenderResources resources) {
- // Ideally, we should check if the corresponding activity extends
- // android.support.v7.app.ActionBarActivity, and not care about the theme name at all.
- if (mIsThemeAppCompat == null) {
- StyleResourceValue defaultTheme = resources.getDefaultTheme();
- // We can't simply check for parent using resources.themeIsParentOf() since the
- // inheritance structure isn't really what one would expect. The first common parent
- // between Theme.AppCompat.Light and Theme.AppCompat is Theme.Material (for v21).
- boolean isThemeAppCompat = false;
- for (int i = 0; i < 50; i++) {
- if (defaultTheme == null) {
- break;
- }
- // for loop ensures that we don't run into cyclic theme inheritance.
- if (defaultTheme.getName().startsWith("Theme.AppCompat")) {
- isThemeAppCompat = true;
- break;
- }
- defaultTheme = resources.getParent(defaultTheme);
- }
- mIsThemeAppCompat = isThemeAppCompat;
- }
- return mIsThemeAppCompat;
- }
-
- /**
- * Looks for an attribute in the current theme.
- *
- * @param resources the render resources
- * @param name the name of the attribute
- * @param defaultValue the default value.
- * @param isFrameworkAttr if the attribute is in android namespace
- * @return the value of the attribute or the default one if not found.
- */
- private boolean getBooleanThemeValue(RenderResources resources,
- String name, boolean defaultValue, boolean isFrameworkAttr) {
-
- ResourceValue value = resources.findItemInTheme(name, isFrameworkAttr);
-
- // because it may reference something else, we resolve it.
- value = resources.resolveResValue(value);
-
- // if there's no value, return the default.
- if (value == null || value.getValue() == null) {
- return defaultValue;
- }
-
- return XmlUtils.convertValueToBoolean(value.getValue(), defaultValue);
- }
-
/**
* Post process on a view hierarchy that was just inflated.
* <p/>
@@ -1737,63 +1349,6 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
mMeasuredScreenWidth = mMeasuredScreenHeight = -1;
}
- /**
- * Creates the status bar with wifi and battery icons.
- */
- private StatusBar createStatusBar(BridgeContext context, Density density, int direction,
- boolean isRtlSupported, int platformVersion) throws XmlPullParserException {
- StatusBar statusBar = new StatusBar(context, density,
- direction, isRtlSupported, platformVersion);
- statusBar.setLayoutParams(
- new LinearLayout.LayoutParams(
- LayoutParams.MATCH_PARENT, mStatusBarSize));
- return statusBar;
- }
-
- /**
- * Creates the navigation bar with back, home and recent buttons.
- *
- * @param isRtl true if the current locale is right-to-left
- * @param isRtlSupported true is the project manifest declares that the application
- * is RTL aware.
- */
- private NavigationBar createNavigationBar(BridgeContext context, Density density,
- boolean isRtl, boolean isRtlSupported, int simulatedPlatformVersion)
- throws XmlPullParserException {
- NavigationBar navigationBar = new NavigationBar(context,
- density, mNavigationBarOrientation, isRtl,
- isRtlSupported, simulatedPlatformVersion);
- if (mNavigationBarOrientation == LinearLayout.VERTICAL) {
- navigationBar.setLayoutParams(new LinearLayout.LayoutParams(mNavigationBarSize,
- LayoutParams.MATCH_PARENT));
- } else {
- navigationBar.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
- mNavigationBarSize));
- }
- return navigationBar;
- }
-
- private TitleBar createTitleBar(BridgeContext context, String title,
- int simulatedPlatformVersion)
- throws XmlPullParserException {
- TitleBar titleBar = new TitleBar(context, title, simulatedPlatformVersion);
- titleBar.setLayoutParams(
- new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, mTitleBarSize));
- return titleBar;
- }
-
- /**
- * Creates the action bar. Also queries the project callback for missing information.
- */
- private BridgeActionBar createActionBar(BridgeContext context, SessionParams params,
- ViewGroup parentView) {
- if (mIsThemeAppCompat == Boolean.TRUE) {
- return new AppCompatActionBar(context, params, parentView);
- } else {
- return new FrameworkActionBar(context, params, parentView);
- }
- }
-
public BufferedImage getImage() {
return mImage;
}