Home | History | Annotate | Download | only in browserpowertest
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.browserpowertest;
     18 
     19 import android.app.Activity;
     20 import android.app.ActivityThread;
     21 import android.graphics.Bitmap;
     22 import android.os.Bundle;
     23 import android.os.Handler;
     24 import android.os.Looper;
     25 import android.os.Message;
     26 import android.util.Log;
     27 import android.view.ViewGroup;
     28 import android.webkit.WebChromeClient;
     29 import android.webkit.WebView;
     30 import android.webkit.WebViewClient;
     31 import android.webkit.WebSettings.LayoutAlgorithm;
     32 import android.widget.LinearLayout;
     33 import android.widget.LinearLayout.LayoutParams;
     34 
     35 public class PowerTestActivity extends Activity {
     36 
     37     public static final String LOGTAG = "PowerTestActivity";
     38     public static final String PARAM_URL = "URL";
     39     public static final String PARAM_TIMEOUT = "Timeout";
     40     public static final int RESULT_TIMEOUT = 0xDEAD;
     41     public static final int MSG_TIMEOUT = 0xC001;
     42     public static final int MSG_NAVIGATE = 0xC002;
     43     public static final String MSG_NAV_URL = "url";
     44     public static final String MSG_NAV_LOGTIME = "logtime";
     45 
     46     private WebView webView;
     47     private SimpleWebViewClient webViewClient;
     48     private SimpleChromeClient chromeClient;
     49     private Handler handler;
     50     private boolean timeoutFlag;
     51     private boolean logTime;
     52     private boolean pageDone;
     53     private Object pageDoneLock;
     54     private int pageStartCount;
     55     private int manualDelay;
     56     private long startTime;
     57     private long pageLoadTime;
     58     private PageDoneRunner pageDoneRunner = new PageDoneRunner();
     59 
     60     public PowerTestActivity() {
     61     }
     62 
     63     @Override
     64     protected void onCreate(Bundle savedInstanceState) {
     65         super.onCreate(savedInstanceState);
     66 
     67         Log.v(LOGTAG, "onCreate, inst=" + Integer.toHexString(hashCode()));
     68 
     69         LinearLayout contentView = new LinearLayout(this);
     70         contentView.setOrientation(LinearLayout.VERTICAL);
     71         setContentView(contentView);
     72         setTitle("Idle");
     73 
     74         webView = new WebView(this);
     75         webView.getSettings().setJavaScriptEnabled(true);
     76         webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(false);
     77         webView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.NORMAL);
     78 
     79         webViewClient = new SimpleWebViewClient();
     80         chromeClient = new SimpleChromeClient();
     81         webView.setWebViewClient(webViewClient);
     82         webView.setWebChromeClient(chromeClient);
     83 
     84         contentView.addView(webView, new LayoutParams(
     85                 ViewGroup.LayoutParams.MATCH_PARENT,
     86                 ViewGroup.LayoutParams.MATCH_PARENT, 0.0f));
     87 
     88         handler = new Handler() {
     89             @Override
     90             public void handleMessage(Message msg) {
     91                 switch (msg.what) {
     92                     case MSG_TIMEOUT:
     93                         handleTimeout();
     94                         return;
     95                     case MSG_NAVIGATE:
     96                         manualDelay = msg.arg2;
     97                         navigate(msg.getData().getString(MSG_NAV_URL), msg.arg1);
     98                         logTime = msg.getData().getBoolean(MSG_NAV_LOGTIME);
     99                         return;
    100                 }
    101             }
    102         };
    103 
    104         pageDoneLock = new Object();
    105     }
    106 
    107     public void reset() {
    108         synchronized (pageDoneLock) {
    109             pageDone = false;
    110         }
    111         timeoutFlag = false;
    112         pageStartCount = 0;
    113         chromeClient.resetJsTimeout();
    114     }
    115 
    116     private void navigate(String url, int timeout) {
    117         if(url == null) {
    118             Log.v(LOGTAG, "URL is null, cancelling...");
    119             finish();
    120         }
    121         webView.stopLoading();
    122         if(logTime) {
    123             webView.clearCache(true);
    124         }
    125         startTime = System.currentTimeMillis();
    126         Log.v(LOGTAG, "Navigating to URL: " + url);
    127         webView.loadUrl(url);
    128 
    129         if(timeout != 0) {
    130             //set a timer with specified timeout (in ms)
    131             handler.sendMessageDelayed(handler.obtainMessage(MSG_TIMEOUT),
    132                     timeout);
    133         }
    134     }
    135 
    136     @Override
    137     protected void onDestroy() {
    138         super.onDestroy();
    139         Log.v(LOGTAG, "onDestroy, inst=" + Integer.toHexString(hashCode()));
    140         webView.clearCache(true);
    141         webView.destroy();
    142     }
    143 
    144     private boolean isPageDone() {
    145         synchronized (pageDoneLock) {
    146             return pageDone;
    147         }
    148     }
    149 
    150     private void setPageDone(boolean pageDone) {
    151         synchronized (pageDoneLock) {
    152             this.pageDone = pageDone;
    153             pageDoneLock.notifyAll();
    154         }
    155     }
    156 
    157     private void handleTimeout() {
    158         int progress = webView.getProgress();
    159         webView.stopLoading();
    160         Log.v(LOGTAG, "Page timeout triggered, progress = " + progress);
    161         timeoutFlag = true;
    162         handler.postDelayed(pageDoneRunner, manualDelay);
    163     }
    164 
    165     public boolean waitUntilDone() {
    166         validateNotAppThread();
    167         synchronized (pageDoneLock) {
    168             while(!isPageDone()) {
    169                 try {
    170                     pageDoneLock.wait();
    171                 } catch (InterruptedException ie) {
    172                     //no-op
    173                 }
    174             }
    175         }
    176         return timeoutFlag;
    177     }
    178 
    179     public Handler getHandler() {
    180         return handler;
    181     }
    182 
    183     private final void validateNotAppThread() {
    184         if (Looper.myLooper() == Looper.getMainLooper()) {
    185             throw new RuntimeException(
    186                 "This method can not be called from the main application thread");
    187         }
    188     }
    189 
    190     public long getPageLoadTime() {
    191         return pageLoadTime;
    192     }
    193 
    194     public boolean getPageError() {
    195         return webViewClient.getPageErrorFlag();
    196     }
    197 
    198     class SimpleWebViewClient extends WebViewClient {
    199 
    200         private boolean pageErrorFlag = false;
    201 
    202         @Override
    203         public void onReceivedError(WebView view, int errorCode, String description,
    204                 String failingUrl) {
    205             pageErrorFlag = true;
    206             Log.v(LOGTAG, "WebCore error: code=" + errorCode
    207                     + ", description=" + description
    208                     + ", url=" + failingUrl);
    209         }
    210 
    211         @Override
    212         public void onPageStarted(WebView view, String url, Bitmap favicon) {
    213             pageStartCount++;
    214             Log.v(LOGTAG, "onPageStarted: " + url);
    215         }
    216 
    217         @Override
    218         public void onPageFinished(WebView view, String url) {
    219             Log.v(LOGTAG, "onPageFinished: " + url);
    220             // let handleTimeout take care of finishing the page
    221             if(!timeoutFlag)
    222                 handler.postDelayed(new WebViewStatusChecker(), 500);
    223         }
    224 
    225         // return true if the URL is not available or the page is down
    226         public boolean getPageErrorFlag() {
    227             return pageErrorFlag;
    228         }
    229     }
    230 
    231     class SimpleChromeClient extends WebChromeClient {
    232 
    233         private int timeoutCounter = 0;
    234 
    235         public void resetJsTimeout() {
    236             timeoutCounter = 0;
    237         }
    238 
    239         @Override
    240         public void onReceivedTitle(WebView view, String title) {
    241             PowerTestActivity.this.setTitle(title);
    242         }
    243     }
    244 
    245     class WebViewStatusChecker implements Runnable {
    246 
    247         private int initialStartCount;
    248 
    249         public WebViewStatusChecker() {
    250             initialStartCount = pageStartCount;
    251         }
    252 
    253         public void run() {
    254             if (initialStartCount == pageStartCount && !isPageDone()) {
    255                 handler.removeMessages(MSG_TIMEOUT);
    256                 webView.stopLoading();
    257                 handler.postDelayed(pageDoneRunner, manualDelay);
    258             }
    259         }
    260     }
    261 
    262     class PageDoneRunner implements Runnable {
    263 
    264         public void run() {
    265             Log.v(LOGTAG, "Finishing URL: " + webView.getUrl());
    266             pageLoadTime = System.currentTimeMillis() - startTime;
    267             setPageDone(true);
    268         }
    269     }
    270 }
    271