diff --git a/src/com/owncloud/android/authentication/PassCodeManager.java b/src/com/owncloud/android/authentication/PassCodeManager.java index e60233df2..cd4fbba42 100644 --- a/src/com/owncloud/android/authentication/PassCodeManager.java +++ b/src/com/owncloud/android/authentication/PassCodeManager.java @@ -19,12 +19,12 @@ */ package com.owncloud.android.authentication; +import android.accounts.Account; +import android.accounts.AccountManager; import android.app.Activity; import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; import android.os.PowerManager; -import android.preference.PreferenceManager; import android.view.WindowManager; import com.owncloud.android.MainApp; @@ -43,7 +43,7 @@ public class PassCodeManager { // other activities may be exempted, if needed } - private static int PASS_CODE_TIMEOUT = 1000; + private static int PASS_CODE_TIMEOUT = 0; // keeping a "low" positive value is the easiest way to prevent the pass code is requested on rotations public static PassCodeManager mPassCodeManagerInstance = null; @@ -74,7 +74,7 @@ public void onActivityStarted(Activity activity) { ){ Intent i = new Intent(MainApp.getAppContext(), PassCodeActivity.class); - i.setAction(PassCodeActivity.ACTION_REQUEST); + i.setAction(PassCodeActivity.ACTION_CHECK); i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); activity.startActivity(i); @@ -108,8 +108,11 @@ private boolean passCodeShouldBeRequested(){ } private boolean passCodeIsEnabled() { - SharedPreferences appPrefs = PreferenceManager.getDefaultSharedPreferences(MainApp.getAppContext()); - return (appPrefs.getBoolean("set_pincode", false)); + Account account = AccountUtils.getCurrentOwnCloudAccount(MainApp.getAppContext()); + AccountManager accountManager = AccountManager.get(MainApp.getAppContext()); + String hasPin = accountManager.getUserData(account, "HASPIN"); + boolean result = hasPin != null && Boolean.parseBoolean(hasPin); + return result; } } diff --git a/src/com/owncloud/android/ui/activity/PassCodeActivity.java b/src/com/owncloud/android/ui/activity/PassCodeActivity.java index 16974394c..a6bc4f4b5 100644 --- a/src/com/owncloud/android/ui/activity/PassCodeActivity.java +++ b/src/com/owncloud/android/ui/activity/PassCodeActivity.java @@ -24,11 +24,15 @@ import java.util.Arrays; +import android.accounts.Account; +import android.accounts.AccountManager; +import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.preference.PreferenceManager; import android.support.v7.app.AppCompatActivity; import android.text.Editable; +import android.text.TextUtils; import android.text.TextWatcher; import android.view.KeyEvent; import android.view.View; @@ -39,24 +43,25 @@ import android.widget.Toast; import com.owncloud.android.R; +import com.owncloud.android.authentication.AccountUtils; import com.owncloud.android.lib.common.utils.Log_OC; public class PassCodeActivity extends AppCompatActivity { private static final String TAG = PassCodeActivity.class.getSimpleName(); - public final static String ACTION_ENABLE = PassCodeActivity.class.getCanonicalName() + - ".ENABLE"; - public final static String ACTION_DISABLE = PassCodeActivity.class.getCanonicalName() + - ".DISABLE"; - public final static String ACTION_REQUEST = PassCodeActivity.class.getCanonicalName() + - ".REQUEST"; + public final static String ACTION_REQUEST_WITH_RESULT = "ACTION_REQUEST_WITH_RESULT"; + public final static String ACTION_CHECK_WITH_RESULT = "ACTION_CHECK_WITH_RESULT"; + public final static String ACTION_CHECK = "ACTION_CHECK"; + + public final static String KEY_PASSCODE = "KEY_PASSCODE"; + public final static String KEY_CHECK_RESULT = "KEY_CHECK_RESULT"; private Button mBCancel; private TextView mPassCodeHdr; private TextView mPassCodeHdrExplanation; private EditText[] mPassCodeEditTexts = new EditText[4]; - + private String [] mPassCodeDigits = {"","","",""}; private static String KEY_PASSCODE_DIGITS = "PASSCODE_DIGITS"; private boolean mConfirmingPassCode = false; @@ -88,13 +93,13 @@ protected void onCreate(Bundle savedInstanceState) { mPassCodeEditTexts[2] = (EditText) findViewById(R.id.txt2); mPassCodeEditTexts[3] = (EditText) findViewById(R.id.txt3); - if (ACTION_REQUEST.equals(getIntent().getAction())) { + if (ACTION_CHECK.equals(getIntent().getAction())) { /// this is a pass code request; the user has to input the right value mPassCodeHdr.setText(R.string.pass_code_enter_pass_code); mPassCodeHdrExplanation.setVisibility(View.INVISIBLE); setCancelButtonEnabled(false); // no option to cancel - } else if (ACTION_ENABLE.equals(getIntent().getAction())) { + } else if (ACTION_REQUEST_WITH_RESULT.equals(getIntent().getAction())) { if (savedInstanceState != null) { mConfirmingPassCode = savedInstanceState.getBoolean(PassCodeActivity.KEY_CONFIRMING_PASSCODE); mPassCodeDigits = savedInstanceState.getStringArray(PassCodeActivity.KEY_PASSCODE_DIGITS); @@ -112,7 +117,7 @@ protected void onCreate(Bundle savedInstanceState) { setCancelButtonEnabled(true); } - } else if (ACTION_DISABLE.equals(getIntent().getAction())) { + } else if (ACTION_CHECK_WITH_RESULT.equals(getIntent().getAction())) { /// pass code preference has just been disabled in Preferences; // will confirm user knows pass code, then remove it mPassCodeHdr.setText(R.string.pass_code_remove_your_pass_code); @@ -284,8 +289,8 @@ public void onFocusChange(View v, boolean hasFocus) { * the previously typed pass code, if any. */ private void processFullPassCode() { - if (ACTION_REQUEST.equals(getIntent().getAction())) { - if (checkPassCode()) { + if (ACTION_CHECK.equals(getIntent().getAction())) { + if (checkPassCodeFromAccountSettings()) { /// pass code accepted in request, user is allowed to access the app finish(); @@ -294,24 +299,20 @@ private void processFullPassCode() { View.INVISIBLE); } - } else if (ACTION_DISABLE.equals(getIntent().getAction())) { - if (checkPassCode()) { - /// pass code accepted when disabling, pass code is removed - SharedPreferences.Editor appPrefs = PreferenceManager - .getDefaultSharedPreferences(getApplicationContext()).edit(); - appPrefs.putBoolean("set_pincode", false); // TODO remove; this should be - // unnecessary, was done before entering in the activity - appPrefs.commit(); + } else if (ACTION_CHECK_WITH_RESULT.equals(getIntent().getAction())) { + if (checkPassCodeFromAccountSettings()) { - Toast.makeText(PassCodeActivity.this, R.string.pass_code_removed, Toast.LENGTH_LONG).show(); - finish(); + Intent resultIntent = new Intent(); + resultIntent.putExtra(KEY_CHECK_RESULT, true); + setResult(RESULT_OK, resultIntent); + finish(); } else { showErrorAndRestart(R.string.pass_code_wrong, R.string.pass_code_enter_pass_code, View.INVISIBLE); } - } else if (ACTION_ENABLE.equals(getIntent().getAction())) { + } else if (ACTION_REQUEST_WITH_RESULT.equals(getIntent().getAction())) { /// enabling pass code if (!mConfirmingPassCode) { requestPassCodeConfirmation(); @@ -351,6 +352,15 @@ protected void requestPassCodeConfirmation(){ mConfirmingPassCode = true; } + + boolean checkPassCodeFromAccountSettings() { + Account account = AccountUtils.getCurrentOwnCloudAccount(this); + AccountManager accountManager = AccountManager.get(this); + + String pin = accountManager.getUserData(account, "PIN"); + return pin != null && pin.equals(TextUtils.join("", mPassCodeDigits)); + } + /** * Compares pass code entered by the user with the value currently saved in the app. * @@ -403,7 +413,7 @@ protected void clearBoxes(){ /** * Overrides click on the BACK arrow to correctly cancel ACTION_ENABLE or ACTION_DISABLE, while - * preventing than ACTION_REQUEST may be worked around. + * preventing than ACTION_CHECK may be worked around. * * @param keyCode Key code of the key that triggered the down event. * @param event Event triggered. @@ -412,8 +422,8 @@ protected void clearBoxes(){ @Override public boolean onKeyDown(int keyCode, KeyEvent event){ if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount()== 0){ - if (ACTION_ENABLE.equals(getIntent().getAction()) || - ACTION_DISABLE.equals(getIntent().getAction())) { + if (ACTION_REQUEST_WITH_RESULT.equals(getIntent().getAction()) || + ACTION_CHECK_WITH_RESULT.equals(getIntent().getAction())) { revertActionAndExit(); } return true; @@ -427,16 +437,12 @@ public boolean onKeyDown(int keyCode, KeyEvent event){ protected void savePassCodeAndExit() { SharedPreferences.Editor appPrefs = PreferenceManager .getDefaultSharedPreferences(getApplicationContext()).edit(); - - appPrefs.putString("PrefPinCode1", mPassCodeDigits[0]); - appPrefs.putString("PrefPinCode2", mPassCodeDigits[1]); - appPrefs.putString("PrefPinCode3", mPassCodeDigits[2]); - appPrefs.putString("PrefPinCode4", mPassCodeDigits[3]); - appPrefs.putBoolean("set_pincode", true); /// TODO remove; unnecessary, - // Preferences did it before entering here - appPrefs.commit(); - - Toast.makeText(this, R.string.pass_code_stored, Toast.LENGTH_LONG).show(); + + Intent resultIntent = new Intent(); + resultIntent.putExtra(KEY_PASSCODE, + mPassCodeDigits[0] + mPassCodeDigits[1] + mPassCodeDigits[2] + mPassCodeDigits[3]); + + setResult(RESULT_OK, resultIntent); finish(); } @@ -467,7 +473,6 @@ public void onSaveInstanceState(Bundle outState) { outState.putStringArray(PassCodeActivity.KEY_PASSCODE_DIGITS, mPassCodeDigits); } - private class PassCodeDigitTextWatcher implements TextWatcher { private int mIndex = -1; diff --git a/src/com/owncloud/android/ui/activity/Preferences.java b/src/com/owncloud/android/ui/activity/Preferences.java index d76d696ec..bf7e56eaa 100644 --- a/src/com/owncloud/android/ui/activity/Preferences.java +++ b/src/com/owncloud/android/ui/activity/Preferences.java @@ -62,6 +62,7 @@ import android.widget.ArrayAdapter; import android.widget.ListAdapter; import android.widget.ListView; +import android.widget.Toast; import com.owncloud.android.BuildConfig; import com.owncloud.android.MainApp; @@ -93,6 +94,8 @@ public class Preferences extends PreferenceActivity private static final int ACTION_SELECT_UPLOAD_PATH = 1; private static final int ACTION_SELECT_UPLOAD_VIDEO_PATH = 2; + private static final int ACTION_REQUEST_PASSCODE = 5; + private static final int ACTION_CONFIRM_PASSCODE = 6; private DbHandler mDbHandler; private CheckBoxPreference pCode; @@ -118,6 +121,7 @@ public class Preferences extends PreferenceActivity protected FileUploader.FileUploaderBinder mUploaderBinder = null; private ServiceConnection mDownloadServiceConnection, mUploadServiceConnection = null; + @SuppressWarnings("deprecation") @Override public void onCreate(Bundle savedInstanceState) { @@ -220,24 +224,30 @@ public void onItemClick(AdapterView parent, View view, int position, long id) registerForContextMenu(getListView()); pCode = (CheckBoxPreference) findPreference("set_pincode"); - if (pCode != null){ + if (pCode != null) { pCode.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { Intent i = new Intent(getApplicationContext(), PassCodeActivity.class); - Boolean enable = (Boolean) newValue; + Boolean incoming = (Boolean) newValue; + i.setAction( - enable.booleanValue() ? PassCodeActivity.ACTION_ENABLE : - PassCodeActivity.ACTION_DISABLE + incoming.booleanValue() ? PassCodeActivity.ACTION_REQUEST_WITH_RESULT : + PassCodeActivity.ACTION_CHECK_WITH_RESULT ); - startActivity(i); - - return true; + + startActivityForResult(i, incoming.booleanValue() ? ACTION_REQUEST_PASSCODE : + ACTION_CONFIRM_PASSCODE); + + // Don't update just yet, we will decide on it in onActivityResult + return false; } - }); + }); } + + PreferenceCategory preferenceCategory = (PreferenceCategory) findPreference("more"); boolean helpEnabled = getResources().getBoolean(R.bool.help_enabled); @@ -599,6 +609,39 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { mPrefInstantVideoUploadPath.setSummary(mUploadVideoPath); saveInstantUploadVideoPathOnPreferences(); + } else if (requestCode == ACTION_REQUEST_PASSCODE && resultCode == RESULT_OK) { + String passcode = data.getStringExtra(PassCodeActivity.KEY_PASSCODE); + if (passcode != null && passcode.length() == 4) { + + AccountManager accountManager = AccountManager.get(this); + Account account = AccountUtils.getCurrentOwnCloudAccount(this); + accountManager.setUserData(account, "PIN", passcode); + accountManager.setUserData(account, "HASPIN", Boolean.TRUE.toString()); + + SharedPreferences.Editor appPrefs = PreferenceManager + .getDefaultSharedPreferences(getApplicationContext()).edit(); + + for (int i = 1; i <= 4; ++i) { + appPrefs.putString("PrefPinCode" + i, passcode.substring(i-1, i)); + } + appPrefs.putBoolean("set_pincode", true); + appPrefs.commit(); + Toast.makeText(this, R.string.pass_code_stored, Toast.LENGTH_LONG).show(); + } + } else if (requestCode == ACTION_CONFIRM_PASSCODE && resultCode == RESULT_OK) { + if (data.getBooleanExtra(PassCodeActivity.KEY_CHECK_RESULT, false)) { + + SharedPreferences.Editor appPrefs = PreferenceManager + .getDefaultSharedPreferences(getApplicationContext()).edit(); + appPrefs.putBoolean("set_pincode", false); + appPrefs.commit(); + + AccountManager accountManager = AccountManager.get(this); + Account account = AccountUtils.getCurrentOwnCloudAccount(this); + accountManager.setUserData(account, "HASPIN", Boolean.FALSE.toString()); + + Toast.makeText(this, R.string.pass_code_removed, Toast.LENGTH_LONG).show(); + } } }