15888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik/*
25888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * Copyright (C) 2011 The Android Open Source Project
35888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik *
45888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * Licensed under the Apache License, Version 2.0 (the "License");
55888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * you may not use this file except in compliance with the License.
65888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * You may obtain a copy of the License at
75888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik *
85888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik *      http://www.apache.org/licenses/LICENSE-2.0
95888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik *
105888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * Unless required by applicable law or agreed to in writing, software
115888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * distributed under the License is distributed on an "AS IS" BASIS,
125888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * See the License for the specific language governing permissions and
145888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * limitations under the License.
155888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik */
165888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
175888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikpackage com.test.tilebenchmark;
185888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
195888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.app.Activity;
205888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.os.AsyncTask;
215888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.os.Bundle;
225888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.view.GestureDetector.SimpleOnGestureListener;
235888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.view.MotionEvent;
245888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.view.View;
255888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.view.View.OnClickListener;
265888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.widget.Button;
275888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.widget.SeekBar;
285888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.widget.SeekBar.OnSeekBarChangeListener;
295888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.widget.TextView;
3021555abad7ba5f5377052e2644974d3ce8c37869Chris Craikimport android.widget.Toast;
315888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
325888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport java.io.FileInputStream;
335888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport java.io.IOException;
345888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport java.io.ObjectInputStream;
355888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
365888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik/**
375888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * Interface for playing back WebView tile rendering status. Draws viewport and
385888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * states of tiles and statistics for off-line analysis.
395888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik */
405888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikpublic class PlaybackActivity extends Activity {
415888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    private static final float SCROLL_SCALER = 0.125f;
425888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
435888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    PlaybackView mPlaybackView;
445888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    SeekBar mSeekBar;
455888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    Button mForward;
465888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    Button mBackward;
475888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    TextView mFrameDisplay;
485888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
495888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    private int mFrame = -1;
505888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    private int mFrameMax;
515888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
525888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    private class TouchFrameChangeListener extends SimpleOnGestureListener {
535888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        float mDist = 0;
545888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
555888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        @Override
565888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        public boolean onScroll(MotionEvent e1, MotionEvent e2,
575888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                float distanceX, float distanceY) {
585888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            // aggregate scrolls so that small ones can add up
595888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            mDist += distanceY * SCROLL_SCALER;
605888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            int intComponent = (int) Math.floor(Math.abs(mDist));
615888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            if (intComponent >= 1) {
625888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                int scrollDist = (mDist > 0) ? intComponent : -intComponent;
635888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                setFrame(null, mFrame + scrollDist);
645888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                mDist -= scrollDist;
655888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            }
665888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            return super.onScroll(e1, e2, distanceX, distanceY);
675888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        }
685888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    };
695888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
705888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    private class SeekFrameChangeListener implements OnSeekBarChangeListener {
715888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        @Override
725888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        public void onStopTrackingTouch(SeekBar seekBar) {
735888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        }
745888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
755888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        @Override
765888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        public void onStartTrackingTouch(SeekBar seekBar) {
775888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        }
785888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
795888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        @Override
805888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        public void onProgressChanged(SeekBar seekBar, int progress,
815888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                boolean fromUser) {
825888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            setFrame(seekBar, progress);
835888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        }
845888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    };
855888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
86555c55ed65056e2236430f92e81c1fb6acd05dcdChris Craik    private class LoadFileTask extends AsyncTask<String, Void, RunData> {
875888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        @Override
88555c55ed65056e2236430f92e81c1fb6acd05dcdChris Craik        protected RunData doInBackground(String... params) {
89555c55ed65056e2236430f92e81c1fb6acd05dcdChris Craik            RunData data = null;
905888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            try {
915888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                FileInputStream fis = openFileInput(params[0]);
925888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                ObjectInputStream in = new ObjectInputStream(fis);
93555c55ed65056e2236430f92e81c1fb6acd05dcdChris Craik                data = (RunData) in.readObject();
945888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                in.close();
955888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            } catch (IOException ex) {
965888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                ex.printStackTrace();
975888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            } catch (ClassNotFoundException ex) {
985888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                ex.printStackTrace();
995888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            }
1005888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            return data;
1015888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        }
1025888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
1035888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        @Override
104555c55ed65056e2236430f92e81c1fb6acd05dcdChris Craik        protected void onPostExecute(RunData data) {
1055888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            if (data == null) {
10621555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                Toast.makeText(getApplicationContext(),
10721555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                        getResources().getString(R.string.error_no_data),
10821555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                        Toast.LENGTH_LONG).show();
10921555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                return;
1105888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            }
1115888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            mPlaybackView.setData(data);
1125888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
113555c55ed65056e2236430f92e81c1fb6acd05dcdChris Craik            mFrameMax = data.frames.length - 1;
1145888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            mSeekBar.setMax(mFrameMax);
1155888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
1165888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            setFrame(null, 0);
1175888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        }
1185888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    }
1195888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
1205888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    private void setFrame(View changer, int f) {
1215888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        if (f < 0) {
1225888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            f = 0;
1235888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        } else if (f > mFrameMax) {
1245888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            f = mFrameMax;
1255888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        }
1265888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
1275888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        if (mFrame == f) {
1285888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            return;
1295888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        }
1305888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
1315888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        mFrame = f;
1325888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        mForward.setEnabled(mFrame != mFrameMax);
1335888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        mBackward.setEnabled(mFrame != 0);
1345888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        if (changer != mSeekBar) {
1355888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            mSeekBar.setProgress(mFrame);
1365888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        }
1375888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        mFrameDisplay.setText(Integer.toString(mFrame));
1385888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        mPlaybackView.setFrame(mFrame);
1395888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    };
1405888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
1415888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    /** Called when the activity is first created. */
1425888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    @Override
1435888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    public void onCreate(Bundle savedInstanceState) {
1445888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        super.onCreate(savedInstanceState);
1455888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        setContentView(R.layout.playback);
1465888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
1475888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        mPlaybackView = (PlaybackView) findViewById(R.id.playback);
1485888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        mSeekBar = (SeekBar) findViewById(R.id.seek_bar);
1495888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        mForward = (Button) findViewById(R.id.forward);
1505888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        mBackward = (Button) findViewById(R.id.backward);
1515888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        mFrameDisplay = (TextView) findViewById(R.id.frame_display);
1525888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
1535888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        mForward.setOnClickListener(new OnClickListener() {
1545888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            @Override
1555888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            public void onClick(View v) {
1565888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                setFrame(v, mFrame + 1);
1575888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            }
1585888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        });
1595888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
1605888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        mBackward.setOnClickListener(new OnClickListener() {
1615888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            @Override
1625888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            public void onClick(View v) {
1635888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                setFrame(v, mFrame - 1);
1645888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            }
1655888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        });
1665888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
1675888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        mSeekBar.setOnSeekBarChangeListener(new SeekFrameChangeListener());
1685888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
1695888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        mPlaybackView.setOnGestureListener(new TouchFrameChangeListener());
1705888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
1715888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        new LoadFileTask().execute(ProfileActivity.TEMP_FILENAME);
1725888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    }
1735888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik}
174