12a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy/*
22a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy * Copyright (C) 2011 The Android Open Source Project
32a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy *
42a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy * Licensed under the Apache License, Version 2.0 (the "License");
52a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy * you may not use this file except in compliance with the License.
62a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy * You may obtain a copy of the License at
72a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy *
82a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy *      http://www.apache.org/licenses/LICENSE-2.0
92a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy *
102a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy * Unless required by applicable law or agreed to in writing, software
112a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy * distributed under the License is distributed on an "AS IS" BASIS,
122a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy * See the License for the specific language governing permissions and
142a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy * limitations under the License.
152a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy */
162a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy
172a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy
182a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guypackage com.android.test.hwui;
192a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy
202a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guyimport android.app.Activity;
212a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guyimport android.content.Context;
222a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guyimport android.graphics.Canvas;
232a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guyimport android.graphics.Paint;
242a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guyimport android.os.Bundle;
252a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guyimport android.util.Log;
262a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guyimport android.view.Gravity;
272a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guyimport android.view.View;
282a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guyimport android.widget.Button;
292a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guyimport android.widget.LinearLayout;
302a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy
312a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guyimport static android.view.View.LAYER_TYPE_HARDWARE;
322a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guyimport static android.view.View.LAYER_TYPE_SOFTWARE;
332a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guyimport static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
342a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy
352a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy@SuppressWarnings({"UnusedDeclaration"})
362a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guypublic class DisplayListLayersActivity extends Activity {
372a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy    private static final int VERTICAL_MARGIN = 12;
382a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy
392a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy    @Override
402a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy    protected void onCreate(Bundle savedInstanceState) {
412a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        super.onCreate(savedInstanceState);
422a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy
432a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        LinearLayout root = createContainer();
442a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        addChild(root, new LayerView(this, 0xffff0000, LAYER_TYPE_HARDWARE, "hardware"),
452a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy                WRAP_CONTENT, WRAP_CONTENT);
462a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        addChild(root, new LayerView(this, 0xff0000ff, LAYER_TYPE_SOFTWARE, "software"),
472a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy                WRAP_CONTENT, WRAP_CONTENT);
482a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        addChild(root, createButton(root), WRAP_CONTENT, WRAP_CONTENT);
492a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy
502a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        setContentView(root);
512a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy    }
522a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy
532a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy    private Button createButton(final LinearLayout root) {
542a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        Button button = new Button(this);
552a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        button.setText("Invalidate");
562a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        button.setOnClickListener(new View.OnClickListener() {
572a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy            @Override
582a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy            public void onClick(View v) {
592a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy                for (int i = 0; i < root.getChildCount(); i++) {
602a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy                    View child = root.getChildAt(i);
612a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy                    if (child != v) {
622a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy                        child.invalidate();
632a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy                    }
642a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy                }
652a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy            }
662a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        });
672a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy
682a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        return button;
692a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy    }
702a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy
712a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy    private void addChild(LinearLayout root, View child, int width, int height) {
722a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(width, height);
732a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        params.gravity = Gravity.CENTER_HORIZONTAL;
742a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        params.setMargins(0, dipToPx(VERTICAL_MARGIN), 0, 0);
752a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        root.addView(child, params);
762a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy    }
772a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy
782a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy    private int dipToPx(int size) {
792a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        return (int) (getResources().getDisplayMetrics().density * size + 0.5f);
802a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy    }
812a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy
822a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy    private LinearLayout createContainer() {
832a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        LinearLayout layout = new LinearLayout(this);
842a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        layout.setOrientation(LinearLayout.VERTICAL);
852a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        return layout;
862a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy    }
872a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy
882a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy    private class LayerView extends View {
892a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        private static final String LOG_TAG = "LayerView";
902a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        private final Paint mPaint = new Paint();
912a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy
922a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        private final String mTag;
932a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy
942a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        LayerView(Context context, int color, int layerType, String tag) {
952a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy            super(context);
962a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy
972a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy            mTag = tag;
982a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy
992a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy            mPaint.setColor(color);
1002a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy            setLayerType(layerType, null);
1012a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        }
1022a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy
1032a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        private void log(String tag) {
1042a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy            Log.d(LOG_TAG, mTag + ": " + tag);
1052a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        }
1062a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy
1072a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        @Override
1082a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        public void invalidate() {
1092a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy            log("invalidate");
1102a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy            super.invalidate();
1112a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        }
1122a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy
1132a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        @Override
1142a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        protected void onDraw(Canvas canvas) {
1152a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy            log("draw");
1162a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy            canvas.drawRect(0, 0, getWidth(), getHeight(), mPaint);
1172a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        }
1182a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy
1192a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        @Override
1202a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
1212a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy            setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec) / 3,
1222a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy                    MeasureSpec.getSize(heightMeasureSpec) / 3);
1232a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy        }
1242a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy    }
1252a9fa89643ce796ee6dc7edae2742b291b6c5f40Romain Guy}
126