1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.android_webview.shell; 6 7 import android.app.Activity; 8 import android.content.Context; 9 import android.content.Intent; 10 import android.content.SharedPreferences; 11 import android.os.Bundle; 12 import android.text.TextUtils; 13 import android.view.Gravity; 14 import android.view.KeyEvent; 15 import android.view.View; 16 import android.view.View.OnClickListener; 17 import android.view.View.OnFocusChangeListener; 18 import android.view.ViewGroup; 19 import android.view.ViewGroup.LayoutParams; 20 import android.view.WindowManager; 21 import android.view.inputmethod.EditorInfo; 22 import android.view.inputmethod.InputMethodManager; 23 import android.webkit.WebChromeClient; 24 import android.widget.EditText; 25 import android.widget.FrameLayout; 26 import android.widget.ImageButton; 27 import android.widget.LinearLayout; 28 import android.widget.TextView; 29 import android.widget.TextView.OnEditorActionListener; 30 31 import org.chromium.android_webview.AwBrowserContext; 32 import org.chromium.android_webview.AwBrowserProcess; 33 import org.chromium.android_webview.AwContents; 34 import org.chromium.android_webview.AwContentsClient; 35 import org.chromium.android_webview.AwDevToolsServer; 36 import org.chromium.android_webview.AwSettings; 37 import org.chromium.android_webview.test.AwTestContainerView; 38 import org.chromium.android_webview.test.NullContentsClient; 39 import org.chromium.content.browser.LoadUrlParams; 40 41 /** 42 * This is a lightweight activity for tests that only require WebView functionality. 43 */ 44 public class AwShellActivity extends Activity { 45 private static final String PREFERENCES_NAME = "AwShellPrefs"; 46 private static final String INITIAL_URL = "about:blank"; 47 private AwBrowserContext mBrowserContext; 48 private AwDevToolsServer mDevToolsServer; 49 private AwTestContainerView mAwTestContainerView; 50 private EditText mUrlTextView; 51 private ImageButton mPrevButton; 52 private ImageButton mNextButton; 53 54 @Override onCreate(Bundle savedInstanceState)55 public void onCreate(Bundle savedInstanceState) { 56 super.onCreate(savedInstanceState); 57 58 setContentView(R.layout.testshell_activity); 59 60 mAwTestContainerView = createAwTestContainerView(); 61 62 LinearLayout contentContainer = (LinearLayout) findViewById(R.id.content_container); 63 mAwTestContainerView.setLayoutParams(new LinearLayout.LayoutParams( 64 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 1f)); 65 contentContainer.addView(mAwTestContainerView); 66 mAwTestContainerView.requestFocus(); 67 68 initializeUrlField(); 69 initializeNavigationButtons(); 70 71 String startupUrl = getUrlFromIntent(getIntent()); 72 if (TextUtils.isEmpty(startupUrl)) { 73 startupUrl = INITIAL_URL; 74 } 75 76 mAwTestContainerView.getAwContents().loadUrl(new LoadUrlParams(startupUrl)); 77 AwContents.setShouldDownloadFavicons(); 78 mUrlTextView.setText(startupUrl); 79 } 80 createAwTestContainerView()81 private AwTestContainerView createAwTestContainerView() { 82 AwBrowserProcess.start(this); 83 AwTestContainerView testContainerView = new AwTestContainerView(this); 84 AwContentsClient awContentsClient = new NullContentsClient() { 85 private View mCustomView; 86 87 @Override 88 public void onPageStarted(String url) { 89 if (mUrlTextView != null) { 90 mUrlTextView.setText(url); 91 } 92 } 93 94 @Override 95 public void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback) { 96 getWindow().setFlags( 97 WindowManager.LayoutParams.FLAG_FULLSCREEN, 98 WindowManager.LayoutParams.FLAG_FULLSCREEN); 99 100 getWindow().addContentView(view, 101 new FrameLayout.LayoutParams( 102 ViewGroup.LayoutParams.MATCH_PARENT, 103 ViewGroup.LayoutParams.MATCH_PARENT, 104 Gravity.CENTER)); 105 mCustomView = view; 106 } 107 108 @Override 109 public void onHideCustomView() { 110 getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); 111 FrameLayout decorView = (FrameLayout) getWindow().getDecorView(); 112 decorView.removeView(mCustomView); 113 mCustomView = null; 114 } 115 116 @Override 117 public boolean shouldOverrideKeyEvent(KeyEvent event) { 118 if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) { 119 return true; 120 } 121 return false; 122 } 123 }; 124 125 SharedPreferences sharedPreferences = 126 getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE); 127 if (mBrowserContext == null) { 128 mBrowserContext = new AwBrowserContext(sharedPreferences); 129 } 130 final AwSettings awSettings = new AwSettings(this /*context*/, 131 false /*isAccessFromFileURLsGrantedByDefault*/, true /*supportsLegacyQuirks*/); 132 testContainerView.initialize(new AwContents(mBrowserContext, testContainerView, 133 testContainerView.getContext(), testContainerView.getInternalAccessDelegate(), 134 testContainerView.getNativeGLDelegate(), awContentsClient, awSettings)); 135 testContainerView.getAwContents().getSettings().setJavaScriptEnabled(true); 136 if (mDevToolsServer == null) { 137 mDevToolsServer = new AwDevToolsServer(); 138 mDevToolsServer.setRemoteDebuggingEnabled(true); 139 } 140 return testContainerView; 141 } 142 getUrlFromIntent(Intent intent)143 private static String getUrlFromIntent(Intent intent) { 144 return intent != null ? intent.getDataString() : null; 145 } 146 setKeyboardVisibilityForUrl(boolean visible)147 private void setKeyboardVisibilityForUrl(boolean visible) { 148 InputMethodManager imm = (InputMethodManager) getSystemService( 149 Context.INPUT_METHOD_SERVICE); 150 if (visible) { 151 imm.showSoftInput(mUrlTextView, InputMethodManager.SHOW_IMPLICIT); 152 } else { 153 imm.hideSoftInputFromWindow(mUrlTextView.getWindowToken(), 0); 154 } 155 } 156 initializeUrlField()157 private void initializeUrlField() { 158 mUrlTextView = (EditText) findViewById(R.id.url); 159 mUrlTextView.setOnEditorActionListener(new OnEditorActionListener() { 160 @Override 161 public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 162 if ((actionId != EditorInfo.IME_ACTION_GO) && (event == null || 163 event.getKeyCode() != KeyEvent.KEYCODE_ENTER || 164 event.getAction() != KeyEvent.ACTION_DOWN)) { 165 return false; 166 } 167 168 mAwTestContainerView.getAwContents().loadUrl( 169 new LoadUrlParams(mUrlTextView.getText().toString())); 170 mUrlTextView.clearFocus(); 171 setKeyboardVisibilityForUrl(false); 172 mAwTestContainerView.requestFocus(); 173 return true; 174 } 175 }); 176 mUrlTextView.setOnFocusChangeListener(new OnFocusChangeListener() { 177 @Override 178 public void onFocusChange(View v, boolean hasFocus) { 179 setKeyboardVisibilityForUrl(hasFocus); 180 mNextButton.setVisibility(hasFocus ? View.GONE : View.VISIBLE); 181 mPrevButton.setVisibility(hasFocus ? View.GONE : View.VISIBLE); 182 if (!hasFocus) { 183 mUrlTextView.setText(mAwTestContainerView.getContentViewCore().getUrl()); 184 } 185 } 186 }); 187 } 188 initializeNavigationButtons()189 private void initializeNavigationButtons() { 190 mPrevButton = (ImageButton) findViewById(R.id.prev); 191 mPrevButton.setOnClickListener(new OnClickListener() { 192 @Override 193 public void onClick(View v) { 194 if (mAwTestContainerView.getContentViewCore().canGoBack()) { 195 mAwTestContainerView.getContentViewCore().goBack(); 196 } 197 } 198 }); 199 200 mNextButton = (ImageButton) findViewById(R.id.next); 201 mNextButton.setOnClickListener(new OnClickListener() { 202 @Override 203 public void onClick(View v) { 204 if (mAwTestContainerView.getContentViewCore().canGoForward()) { 205 mAwTestContainerView.getContentViewCore().goForward(); 206 } 207 } 208 }); 209 } 210 211 @Override onKeyUp(int keyCode, KeyEvent event)212 public boolean onKeyUp(int keyCode, KeyEvent event) { 213 if (keyCode == KeyEvent.KEYCODE_BACK) { 214 if (mAwTestContainerView.getContentViewCore().canGoBack()) { 215 mAwTestContainerView.getContentViewCore().goBack(); 216 return true; 217 } 218 } 219 220 return super.onKeyUp(keyCode, event); 221 } 222 } 223