1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/*
2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Copyright (C) 2010 The Android Open Source Project
3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *
4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * you may not use this file except in compliance with the License.
6282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * You may obtain a copy of the License at
7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *
8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
9282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *
10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Unless required by applicable law or agreed to in writing, software
11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * See the License for the specific language governing permissions and
14282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * limitations under the License.
15282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */
16282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipackage com.android.layoutlib.bridge;
18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.ide.common.rendering.api.IAnimationListener;
20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.ide.common.rendering.api.ILayoutPullParser;
21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.ide.common.rendering.api.RenderParams;
22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.ide.common.rendering.api.RenderSession;
23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.ide.common.rendering.api.Result;
24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.ide.common.rendering.api.ViewInfo;
25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.layoutlib.bridge.impl.RenderSessionImpl;
2629ed07524ce0fc2e5950f5340d306247145d0efaDiego Perezimport com.android.tools.layoutlib.java.System_Delegate;
27eaf1853b98d7bf2c3d693ad702050968ef0a404cDeepanshu Guptaimport com.android.util.PropertiesMap;
28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.view.View;
30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.view.ViewGroup;
31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.awt.image.BufferedImage;
33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.List;
34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.Map;
35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/**
37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * An implementation of {@link RenderSession}.
38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *
39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * This is a pretty basic class that does almost nothing. All of the work is done in
40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * {@link RenderSessionImpl}.
41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *
42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */
43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipublic class BridgeRenderSession extends RenderSession {
44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    private final RenderSessionImpl mSession;
46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    private Result mLastResult;
47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public Result getResult() {
50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return mLastResult;
51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public BufferedImage getImage() {
55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return mSession.getImage();
56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public boolean isAlphaChannelImage() {
60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return mSession.isAlphaChannelImage();
61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public List<ViewInfo> getRootViews() {
65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return mSession.getViewInfos();
66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
6914bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta    public List<ViewInfo> getSystemRootViews() {
7014bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta        return mSession.getSystemViewInfos();
7114bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta    }
7214bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta
7314bf0cef7eeed572a67c29a328581afac4decc20Deepanshu Gupta    @Override
74eaf1853b98d7bf2c3d693ad702050968ef0a404cDeepanshu Gupta    public Map<Object, PropertiesMap> getDefaultProperties() {
75eaf1853b98d7bf2c3d693ad702050968ef0a404cDeepanshu Gupta        return mSession.getDefaultProperties();
76eaf1853b98d7bf2c3d693ad702050968ef0a404cDeepanshu Gupta    }
77eaf1853b98d7bf2c3d693ad702050968ef0a404cDeepanshu Gupta
78eaf1853b98d7bf2c3d693ad702050968ef0a404cDeepanshu Gupta    @Override
79c13aa0c035cd226d27323bc0e533632ba32f6a84Diego Perez    public Result render(long timeout, boolean forceMeasure) {
80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        try {
81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            Bridge.prepareThread();
82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mLastResult = mSession.acquire(timeout);
83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (mLastResult.isSuccess()) {
84c13aa0c035cd226d27323bc0e533632ba32f6a84Diego Perez                if (forceMeasure) {
85c13aa0c035cd226d27323bc0e533632ba32f6a84Diego Perez                    mSession.invalidateRenderingSize();
86c13aa0c035cd226d27323bc0e533632ba32f6a84Diego Perez                }
87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mLastResult = mSession.render(false /*freshRender*/);
88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } finally {
90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mSession.release();
91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            Bridge.cleanupThread();
92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return mLastResult;
95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public Result animate(Object targetObject, String animationName,
99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            boolean isFrameworkAnimation, IAnimationListener listener) {
100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        try {
101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            Bridge.prepareThread();
102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (mLastResult.isSuccess()) {
104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mLastResult = mSession.animate(targetObject, animationName, isFrameworkAnimation,
105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        listener);
106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } finally {
108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mSession.release();
109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            Bridge.cleanupThread();
110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return mLastResult;
113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public Result insertChild(Object parentView, ILayoutPullParser childXml, int index,
117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            IAnimationListener listener) {
118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (parentView instanceof ViewGroup == false) {
119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            throw new IllegalArgumentException("parentView is not a ViewGroup");
120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        try {
123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            Bridge.prepareThread();
124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (mLastResult.isSuccess()) {
126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mLastResult = mSession.insertChild((ViewGroup) parentView, childXml, index,
127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        listener);
128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } finally {
130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mSession.release();
131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            Bridge.cleanupThread();
132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return mLastResult;
135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public Result moveChild(Object parentView, Object childView, int index,
140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            Map<String, String> layoutParams, IAnimationListener listener) {
141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (parentView instanceof ViewGroup == false) {
142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            throw new IllegalArgumentException("parentView is not a ViewGroup");
143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (childView instanceof View == false) {
145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            throw new IllegalArgumentException("childView is not a View");
146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        try {
149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            Bridge.prepareThread();
150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (mLastResult.isSuccess()) {
152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mLastResult = mSession.moveChild((ViewGroup) parentView, (View) childView, index,
153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        layoutParams, listener);
154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } finally {
156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mSession.release();
157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            Bridge.cleanupThread();
158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return mLastResult;
161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public Result removeChild(Object childView, IAnimationListener listener) {
165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (childView instanceof View == false) {
166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            throw new IllegalArgumentException("childView is not a View");
167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        try {
170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            Bridge.prepareThread();
171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (mLastResult.isSuccess()) {
173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mLastResult = mSession.removeChild((View) childView, listener);
174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } finally {
176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mSession.release();
177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            Bridge.cleanupThread();
178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return mLastResult;
181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
18429ed07524ce0fc2e5950f5340d306247145d0efaDiego Perez    public void setSystemTimeNanos(long nanos) {
18529ed07524ce0fc2e5950f5340d306247145d0efaDiego Perez        System_Delegate.setNanosTime(nanos);
18629ed07524ce0fc2e5950f5340d306247145d0efaDiego Perez    }
18729ed07524ce0fc2e5950f5340d306247145d0efaDiego Perez
18829ed07524ce0fc2e5950f5340d306247145d0efaDiego Perez    @Override
18929ed07524ce0fc2e5950f5340d306247145d0efaDiego Perez    public void setSystemBootTimeNanos(long nanos) {
19029ed07524ce0fc2e5950f5340d306247145d0efaDiego Perez        System_Delegate.setBootTimeNanos(nanos);
19129ed07524ce0fc2e5950f5340d306247145d0efaDiego Perez    }
19229ed07524ce0fc2e5950f5340d306247145d0efaDiego Perez
19329ed07524ce0fc2e5950f5340d306247145d0efaDiego Perez    @Override
19429ed07524ce0fc2e5950f5340d306247145d0efaDiego Perez    public void setElapsedFrameTimeNanos(long nanos) {
19539e540caffca2584aa6c4cb74ce42dceb24a93f7Diego Perez        if (mSession != null) {
19639e540caffca2584aa6c4cb74ce42dceb24a93f7Diego Perez            mSession.setElapsedFrameTimeNanos(nanos);
19739e540caffca2584aa6c4cb74ce42dceb24a93f7Diego Perez        }
19829ed07524ce0fc2e5950f5340d306247145d0efaDiego Perez    }
19929ed07524ce0fc2e5950f5340d306247145d0efaDiego Perez
20029ed07524ce0fc2e5950f5340d306247145d0efaDiego Perez    @Override
201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public void dispose() {
202f5650cf3a3a1a8d6ced9fc7b0f399689c9adc1b8Diego Perez        if (mSession != null) {
203f5650cf3a3a1a8d6ced9fc7b0f399689c9adc1b8Diego Perez            mSession.dispose();
204f5650cf3a3a1a8d6ced9fc7b0f399689c9adc1b8Diego Perez        }
205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /*package*/ BridgeRenderSession(RenderSessionImpl scene, Result lastResult) {
208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mSession = scene;
209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (scene != null) {
210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mSession.setScene(this);
211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mLastResult = lastResult;
213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
215