Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9f891300 authored by Chris Craik's avatar Chris Craik Committed by Android (Google) Code Review
Browse files

Merge "Add SlowNestedRecyclerViewActivity"

parents ccbc5c18 58d30ae2
Loading
Loading
Loading
Loading
+12 −4
Original line number Diff line number Diff line
@@ -107,6 +107,14 @@
                <category android:name="com.android.test.uibench.TEST" />
            </intent-filter>
        </activity>
        <activity
            android:name=".SlowNestedRecyclerViewActivity"
            android:label="General/Slow Nested RecyclerView" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="com.android.test.uibench.TEST" />
            </intent-filter>
        </activity>
        <activity
            android:name=".ActivityTransition"
            android:label="Transitions/Activity Transition" >
+181 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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.test.uibench;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.InsetDrawable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;

import com.android.test.uibench.recyclerview.RvCompatListActivity;

import java.util.ArrayList;
import java.util.concurrent.TimeUnit;

public class SlowNestedRecyclerViewActivity extends RvCompatListActivity {
    private static final int OUTER_ITEM_COUNT = 100;
    private static final int INNER_ITEM_COUNT = 20;

    private static final long INNER_ITEM_CREATE_NS = TimeUnit.MILLISECONDS.toNanos(6);
    private static final long INNER_ITEM_BIND_NS = TimeUnit.MILLISECONDS.toNanos(1);
    private static final long INNER_ITEM_ATTACH_NS = TimeUnit.MILLISECONDS.toNanos(1);

    private static final long OUTER_ITEM_CREATE_NS = TimeUnit.MILLISECONDS.toNanos(3);
    private static final long OUTER_ITEM_BIND_NS = TimeUnit.MILLISECONDS.toNanos(1);
    private static final long OUTER_ITEM_ATTACH_NS = TimeUnit.MILLISECONDS.toNanos(1);

    private SizeData mSizeData;

    private static class SizeData {
        final int innerItemWidth;
        final int innerItemHeight;
        final int headerHeight;

        SizeData(Resources resources) {
            innerItemWidth = (int) (resources.getDisplayMetrics().widthPixels / 3.3f);
            innerItemHeight = (int) (innerItemWidth * 1.6f);
            headerHeight = (int) (resources.getDisplayMetrics().heightPixels * 0.5f);
        }
    }

    private SizeData getSizeData(Resources resources) {
        if (mSizeData == null) {
            mSizeData = new SizeData(resources);
        }
        return mSizeData;
    }

    @Override
    protected RecyclerView.LayoutManager createLayoutManager(Context context) {
        return new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
    }

    @Override
    protected RecyclerView.Adapter createAdapter() {
        return new OuterAdapter();
    }

    private class InnerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            final long start = System.nanoTime();

            final float density = parent.getResources().getDisplayMetrics().density;
            View view = new View(parent.getContext()) {
                @Override
                protected void onAttachedToWindow() {
                    final long start = System.nanoTime();
                    super.onAttachedToWindow();
                    while (System.nanoTime() - start < INNER_ITEM_ATTACH_NS);
                }
            };

            SizeData sizeData = getSizeData(parent.getResources());
            view.setMinimumWidth(sizeData.innerItemWidth);
            view.setMinimumHeight(sizeData.innerItemHeight);

            GradientDrawable bg = new GradientDrawable();
            bg.setCornerRadius(10 * density);
            bg.setColor(Color.BLACK);
            final int pad = (int)(10 * density);
            view.setPadding(pad, pad, pad, pad);
            view.setBackgroundDrawable(new InsetDrawable(bg, pad));
            RecyclerView.ViewHolder holder = new RecyclerView.ViewHolder(view) {};

            while (System.nanoTime() - start < INNER_ITEM_CREATE_NS);
            return holder;
        }

        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            final long start = System.nanoTime();
            while (System.nanoTime() - start < INNER_ITEM_BIND_NS);
        }

        @Override
        public int getItemCount() { return INNER_ITEM_COUNT; }
    }

    private class OuterAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
        static final int TYPE_HEADER = 0;
        static final int TYPE_RECYCLER = 1;

        ArrayList<InnerAdapter> mAdapters = new ArrayList<>();
        RecyclerView.RecycledViewPool mSharedPool = new RecyclerView.RecycledViewPool();

        OuterAdapter() {
            for (int i = 0; i < OUTER_ITEM_COUNT; i++) {
                mAdapters.add(new InnerAdapter());
            }
        }

        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            SizeData sizeData = getSizeData(parent.getResources());
            if (viewType == TYPE_HEADER) {
                View view = new View(parent.getContext());
                view.setMinimumHeight(sizeData.headerHeight);
                return new RecyclerView.ViewHolder(view) {};
            } else {
                final long start = System.nanoTime();

                RecyclerView rv = new RecyclerView(parent.getContext()) {
                    @Override
                    protected void onAttachedToWindow() {
                        final long start = System.nanoTime();
                        super.onAttachedToWindow();
                        while (System.nanoTime() - start < OUTER_ITEM_ATTACH_NS);

                    }
                };

                rv.setLayoutParams(new RecyclerView.LayoutParams(
                        ViewGroup.LayoutParams.MATCH_PARENT, sizeData.innerItemHeight));
                rv.setLayoutManager(new LinearLayoutManager(parent.getContext(),
                        LinearLayoutManager.HORIZONTAL, false));
                rv.setRecycledViewPool(mSharedPool);
                RecyclerView.ViewHolder holder = new RecyclerView.ViewHolder(rv) {};

                while (System.nanoTime() - start < OUTER_ITEM_CREATE_NS);
                return holder;
            }
        }

        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            if (getItemViewType(position) == TYPE_RECYCLER) {
                final long start = System.nanoTime();
                ((RecyclerView)holder.itemView).setAdapter(mAdapters.get(position));
                while (System.nanoTime() - start < OUTER_ITEM_BIND_NS);
            }
        }

        @Override
        public int getItemViewType(int position) {
            return position == 0 ? TYPE_HEADER : TYPE_RECYCLER;
        }

        @Override
        public int getItemCount() {
            return mAdapters.size();
        }
    }
}