From: masensio Date: Tue, 13 Aug 2013 10:08:46 +0000 (+0200) Subject: Move WebView to Dialog X-Git-Tag: oc-android-1.4.6~18^2~13 X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/commitdiff_plain/9dacdbec0b54e2255700747c7f6076024f7b5717?ds=inline;hp=--cc Move WebView to Dialog --- 9dacdbec0b54e2255700747c7f6076024f7b5717 diff --git a/res/values/setup.xml b/res/values/setup.xml index 3e39fabb..06ae804f 100644 --- a/res/values/setup.xml +++ b/res/values/setup.xml @@ -1,6 +1,6 @@ - https://bwlsdf-owncloud1.lsdf.kit.edu/oc-shib + https://bwlsdf-owncloud1.lsdf.kit.edu/oc-shib-test true diff --git a/src/com/owncloud/android/authentication/AccountAuthenticatorActivity.java b/src/com/owncloud/android/authentication/AccountAuthenticatorActivity.java new file mode 100644 index 00000000..62c8825f --- /dev/null +++ b/src/com/owncloud/android/authentication/AccountAuthenticatorActivity.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2009 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.owncloud.android.authentication; + +import android.accounts.AccountAuthenticatorResponse; +import android.accounts.AccountManager; +import android.os.Bundle; + +import com.actionbarsherlock.app.SherlockFragmentActivity; + + +/* + * Base class for implementing an Activity that is used to help implement an AbstractAccountAuthenticator. + * If the AbstractAccountAuthenticator needs to use an activity to handle the request then it can have the activity extend + * AccountAuthenticatorActivity. The AbstractAccountAuthenticator passes in the response to the intent using the following: + * intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response); + * + * The activity then sets the result that is to be handed to the response via setAccountAuthenticatorResult(android.os.Bundle). + * This result will be sent as the result of the request when the activity finishes. If this is never set or if it is set to null + * then error AccountManager.ERROR_CODE_CANCELED will be called on the response. + */ + +public class AccountAuthenticatorActivity extends SherlockFragmentActivity { + + private AccountAuthenticatorResponse mAccountAuthenticatorResponse = null; + private Bundle mResultBundle = null; + + + /** + * Set the result that is to be sent as the result of the request that caused this Activity to be launched. + * If result is null or this method is never called then the request will be canceled. + * + * @param result this is returned as the result of the AbstractAccountAuthenticator request + */ + public final void setAccountAuthenticatorResult(Bundle result) { + mResultBundle = result; + } + + /** + * Retreives the AccountAuthenticatorResponse from either the intent of the icicle, if the + * icicle is non-zero. + * @param icicle the save instance data of this Activity, may be null + */ + protected void onCreate(Bundle icicle) { + super.onCreate(icicle); + + mAccountAuthenticatorResponse = + getIntent().getParcelableExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE); + + if (mAccountAuthenticatorResponse != null) { + mAccountAuthenticatorResponse.onRequestContinued(); + } + } + + /** + * Sends the result or a Constants.ERROR_CODE_CANCELED error if a result isn't present. + */ + public void finish() { + if (mAccountAuthenticatorResponse != null) { + // send the result bundle back if set, otherwise send an error. + if (mResultBundle != null) { + mAccountAuthenticatorResponse.onResult(mResultBundle); + } else { + mAccountAuthenticatorResponse.onError(AccountManager.ERROR_CODE_CANCELED, + "canceled"); + } + mAccountAuthenticatorResponse = null; + } + super.finish(); + } +} diff --git a/src/com/owncloud/android/authentication/AuthenticatorActivity.java b/src/com/owncloud/android/authentication/AuthenticatorActivity.java index 50360c0e..852f1d52 100644 --- a/src/com/owncloud/android/authentication/AuthenticatorActivity.java +++ b/src/com/owncloud/android/authentication/AuthenticatorActivity.java @@ -18,24 +18,8 @@ package com.owncloud.android.authentication; -import com.owncloud.android.Log_OC; -import com.owncloud.android.ui.dialog.SslValidatorDialog; -import com.owncloud.android.ui.dialog.SslValidatorDialog.OnSslValidatorListener; -import com.owncloud.android.utils.OwnCloudVersion; -import com.owncloud.android.authentication.SsoWebViewClient.SsoWebViewClientListener; -import com.owncloud.android.network.OwnCloudClientUtils; -import com.owncloud.android.operations.OwnCloudServerCheckOperation; -import com.owncloud.android.operations.ExistenceCheckOperation; -import com.owncloud.android.operations.OAuth2GetAccessToken; -import com.owncloud.android.operations.OnRemoteOperationListener; -import com.owncloud.android.operations.RemoteOperation; -import com.owncloud.android.operations.RemoteOperationResult; -import com.owncloud.android.operations.RemoteOperationResult.ResultCode; - import android.accounts.Account; -import android.accounts.AccountAuthenticatorActivity; import android.accounts.AccountManager; -import android.annotation.SuppressLint; import android.app.AlertDialog; import android.app.Dialog; import android.app.ProgressDialog; @@ -49,6 +33,7 @@ import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.preference.PreferenceManager; +import android.support.v4.app.FragmentManager; import android.text.Editable; import android.text.InputType; import android.text.TextWatcher; @@ -59,17 +44,27 @@ import android.view.View.OnFocusChangeListener; import android.view.View.OnTouchListener; import android.view.Window; import android.view.inputmethod.EditorInfo; -import android.webkit.CookieManager; -import android.webkit.WebSettings; -import android.webkit.WebView; +import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; -import android.widget.Button; import android.widget.TextView; -import android.widget.Toast; import android.widget.TextView.OnEditorActionListener; +import android.widget.Toast; +import com.owncloud.android.Log_OC; import com.owncloud.android.R; +import com.owncloud.android.network.OwnCloudClientUtils; +import com.owncloud.android.operations.ExistenceCheckOperation; +import com.owncloud.android.operations.OAuth2GetAccessToken; +import com.owncloud.android.operations.OnRemoteOperationListener; +import com.owncloud.android.operations.OwnCloudServerCheckOperation; +import com.owncloud.android.operations.RemoteOperation; +import com.owncloud.android.operations.RemoteOperationResult; +import com.owncloud.android.operations.RemoteOperationResult.ResultCode; +import com.owncloud.android.ui.dialog.SamlWebViewDialog; +import com.owncloud.android.ui.dialog.SslValidatorDialog; +import com.owncloud.android.ui.dialog.SslValidatorDialog.OnSslValidatorListener; +import com.owncloud.android.utils.OwnCloudVersion; import eu.alefzero.webdav.WebdavClient; @@ -80,7 +75,7 @@ import eu.alefzero.webdav.WebdavClient; * @author David A. Velasco */ public class AuthenticatorActivity extends AccountAuthenticatorActivity -implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeListener, OnEditorActionListener, SsoWebViewClientListener { +implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeListener, OnEditorActionListener { private static final String TAG = AuthenticatorActivity.class.getSimpleName(); @@ -116,6 +111,8 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList public static final byte ACTION_CREATE = 0; public static final byte ACTION_UPDATE_TOKEN = 1; + private static final String TAG_SAML_DIALOG = "samlWebViewDialog"; + private String mHostBaseUrl; private OwnCloudVersion mDiscoveredVersion; @@ -152,8 +149,7 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList private TextView mOAuthTokenEndpointText; private TextView mAccountNameInput; - private WebView mSsoWebView; - private SsoWebViewClient mWebViewClient; + private SamlWebViewDialog mSamlDialog; private View mOkButton; @@ -180,7 +176,6 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList mOAuthTokenEndpointText = (TextView)findViewById(R.id.oAuthEntryPoint_2); mOAuth2Check = (CheckBox) findViewById(R.id.oauth_onOff_check); mAccountNameInput = (EditText) findViewById(R.id.account_name); - mSsoWebView = (WebView) findViewById(R.id.web_sso_view); mOkButton = findViewById(R.id.buttonOK); mAuthStatusLayout = (TextView) findViewById(R.id.auth_status_text); @@ -331,23 +326,17 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList } }); +// FragmentManager fm = getSupportFragmentManager(); +// +// // try to find searching by tag name +// mSamlDialog = (SamlWebViewDialog) fm.findFragmentByTag(TAG_SAML_DIALOG); +// +// if (mSamlDialog != null) { +// mSamlDialog.show(fm, TAG_SAML_DIALOG); +// Log_OC.d(TAG_SAML_DIALOG, "mSamlDialog not null"); +// } } - @SuppressLint("SetJavaScriptEnabled") - private void initWebView() { - CookieManager cookieManager = CookieManager.getInstance(); - cookieManager.setAcceptCookie(true); - //cookieManager.removeSessionCookie(); - - mWebViewClient = new SsoWebViewClient(mHandler, this); - mSsoWebView.setWebViewClient(mWebViewClient); - WebSettings webSettings = mSsoWebView.getSettings(); - webSettings.setJavaScriptEnabled(true); - webSettings.setBuiltInZoomControls(true); - webSettings.setLoadWithOverviewMode(false); - webSettings.setSavePassword(false); - webSettings.setUserAgentString(WebdavClient.USER_AGENT); - } private void initAuthorizationMethod() { boolean oAuthRequired = false; @@ -421,6 +410,7 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList // refresh button enabled outState.putBoolean(KEY_REFRESH_BUTTON_ENABLED, (mRefreshButton.getVisibility() == View.VISIBLE)); + } @@ -461,6 +451,16 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList } mJustCreated = false; + + + // try to find searching by tag name +// FragmentManager fm = getSupportFragmentManager(); +// mSamlDialog = (SamlWebViewDialog) fm.findFragmentByTag(TAG_SAML_DIALOG); +// +// if (mSamlDialog != null) { +// // mSamlDialog.show(fm, TAG_SAML_DIALOG); +// mSamlDialog.setRetainInstance(true); +// } } @@ -757,11 +757,14 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList } catch (IllegalArgumentException e) { // NOTHING TO DO ; can't find out what situation that leads to the exception in this code, but user logs signal that it happens } - + if (result.isTemporalRedirection()) { String url = result.getRedirectedLocation(); - mWebViewClient.setTargetUrl(mHostBaseUrl + AccountUtils.getWebdavPath(mDiscoveredVersion, mCurrentAuthTokenType)); - mSsoWebView.loadUrl(url); + String targetUrl = mHostBaseUrl + AccountUtils.getWebdavPath(mDiscoveredVersion, mCurrentAuthTokenType); + + // Show dialog + mSamlDialog = SamlWebViewDialog.newInstance(mHandler, url, targetUrl); + mSamlDialog.show(getSupportFragmentManager(), TAG_SAML_DIALOG); mAuthStatusIcon = android.R.drawable.ic_secure; mAuthStatusText = R.string.auth_follow_auth_server; @@ -1408,7 +1411,6 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList mUsernameInput.setVisibility(View.GONE); mPasswordInput.setVisibility(View.GONE); mAccountNameInput.setVisibility(View.GONE); - mSsoWebView.setVisibility(View.GONE); } else if (AccountAuthenticator.AUTH_TOKEN_TYPE_SAML_WEB_SSO_SESSION_COOKIE.equals(mCurrentAuthTokenType)) { // SAML-based web Single Sign On @@ -1417,8 +1419,6 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList mUsernameInput.setVisibility(View.GONE); mPasswordInput.setVisibility(View.GONE); mAccountNameInput.setVisibility(View.VISIBLE); - mSsoWebView.setVisibility(View.VISIBLE); - initWebView(); } else { // basic HTTP authorization @@ -1427,7 +1427,6 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList mUsernameInput.setVisibility(View.VISIBLE); mPasswordInput.setVisibility(View.VISIBLE); mAccountNameInput.setVisibility(View.GONE); - mSsoWebView.setVisibility(View.GONE); } } @@ -1498,26 +1497,22 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList } - @Override - public void onSsoFinished(String sessionCookie) { - //Toast.makeText(this, "got cookies: " + sessionCookie, Toast.LENGTH_LONG).show(); + public void onSamlDialogSuccess(String sessionCookie){ + mAuthToken = sessionCookie; if (sessionCookie != null && sessionCookie.length() > 0) { - Log_OC.d(TAG, "Successful SSO - time to save the account"); - mAuthToken = sessionCookie; - if (mAction == ACTION_CREATE) { - createAccount(); + Log_OC.d(TAG, "Successful SSO - time to save the account"); + mAuthToken = sessionCookie; + if (mAction == ACTION_CREATE) { + createAccount(); - } else { - updateToken(); - } + } else { + updateToken(); + } - finish(); + finish(); - } else { - // TODO - show fail - Log_OC.d(TAG, "SSO failed"); - } + } } } diff --git a/src/com/owncloud/android/ui/dialog/SamlWebViewDialog.java b/src/com/owncloud/android/ui/dialog/SamlWebViewDialog.java new file mode 100644 index 00000000..2d0ac94a --- /dev/null +++ b/src/com/owncloud/android/ui/dialog/SamlWebViewDialog.java @@ -0,0 +1,150 @@ +package com.owncloud.android.ui.dialog; + +import android.annotation.SuppressLint; +import android.app.AlertDialog; +import android.app.Dialog; +import android.os.Bundle; +import android.os.Handler; +import android.support.v4.app.DialogFragment; +import android.webkit.CookieManager; +import android.webkit.WebSettings; +import android.webkit.WebView; + +import com.owncloud.android.Log_OC; +import com.owncloud.android.authentication.AuthenticatorActivity; +import com.owncloud.android.authentication.SsoWebViewClient; +import com.owncloud.android.authentication.SsoWebViewClient.SsoWebViewClientListener; + +import eu.alefzero.webdav.WebdavClient; + +/** + * Dialog to show the WebView for SAML Authentication + * + * @author Maria Asensio + */ +public class SamlWebViewDialog extends DialogFragment + implements SsoWebViewClientListener{ + + public final String SAML_DIALOG_TAG = "SamlWebViewDialog"; + + private final static String TAG = SamlWebViewDialog.class.getSimpleName(); + + private WebView mSsoWebView; + private SsoWebViewClient mWebViewClient; + + private static String mUrl; + private static String mTargetUrl; + + private static Handler mHandler; + + + /** + * Public factory method to get dialog instances. + * + * @param handler + * @param Url Url to open at WebView + * @param targetURL mHostBaseUrl + AccountUtils.getWebdavPath(mDiscoveredVersion, mCurrentAuthTokenType) + * @return New dialog instance, ready to show. + */ + public static SamlWebViewDialog newInstance(Handler handler,String url, String targetUrl) { + SamlWebViewDialog fragment = new SamlWebViewDialog(); + mHandler = handler; + mUrl = url; + mTargetUrl = targetUrl; + return fragment; + } + + + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + + // Save the state of the WebView + mSsoWebView.saveState(outState); + } + + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + Log_OC.d(TAG, "On Create Dialog"); + + /// load the dialog + initWebView(savedInstanceState); + setRetainInstance(true); + /// build the dialog + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + + Dialog dialog = builder.setView(mSsoWebView).create(); + + return dialog; + } + + + @SuppressLint("SetJavaScriptEnabled") + private void initWebView(Bundle savedInstanceState) { + CookieManager cookieManager = CookieManager.getInstance(); + cookieManager.setAcceptCookie(true); + //cookieManager.removeSessionCookie(); + + mWebViewClient = new SsoWebViewClient(mHandler, this); + mWebViewClient.setTargetUrl(mTargetUrl); + if (savedInstanceState == null) { + + Log_OC.d(TAG, "Saved Instance State NULL"); + mSsoWebView = new WebView(getActivity()) { + @Override + public boolean onCheckIsTextEditor() { + return true; + } + }; + + mSsoWebView.setWebViewClient(mWebViewClient); + mSsoWebView.setFocusable(true); + mSsoWebView.setFocusableInTouchMode(true); + mSsoWebView.setClickable(true); + + WebSettings webSettings = mSsoWebView.getSettings(); + webSettings.setJavaScriptEnabled(true); + webSettings.setBuiltInZoomControls(true); + webSettings.setLoadWithOverviewMode(false); + webSettings.setSavePassword(false); + webSettings.setUserAgentString(WebdavClient.USER_AGENT); + + mSsoWebView.loadUrl(mUrl); + } + else { + Log_OC.d(TAG, "Saved Instance State NOT NULL"); + + mSsoWebView.restoreState(savedInstanceState); + } + + } + + @Override + public void onDestroyView() { + Dialog dialog = getDialog(); + Log_OC.d(TAG, "On Destroy"); + // Work around bug: http://code.google.com/p/android/issues/detail?id=17423 + if ((dialog != null) && getRetainInstance()) + getDialog().setOnDismissListener(null); + + super.onDestroyView(); + } + + + @Override + public void onSsoFinished(String sessionCookie) { + //Toast.makeText(this, "got cookies: " + sessionCookie, Toast.LENGTH_LONG).show(); + + if (sessionCookie != null && sessionCookie.length() > 0) { + Log_OC.d(TAG, "Successful SSO - time to save the account"); + ((AuthenticatorActivity) getActivity()).onSamlDialogSuccess(sessionCookie); + dismiss(); + + } else { + // TODO - show fail + Log_OC.d(TAG, "SSO failed"); + } + } + +} \ No newline at end of file