On master: Current working dir changes

This commit is contained in:
AlexVallat 2013-07-25 13:47:05 +01:00
commit d678c711fa
30 changed files with 628 additions and 712 deletions

25
.gitignore vendored
View File

@ -1,3 +1,28 @@
PCtest
*.suo
*.userprefs
*.user
*.designer.cs
src/java/kp2akeytransform/kp2akeytransform.zip
src/Kp2aKeyboardBinding/bin
src/Kp2aKeyboardBinding/obj
src/kp2akeytransform/bin
src/kp2akeytransform/obj
src/Kp2aBusinessLogic/bin
src/Kp2aBusinessLogic/obj
src/Kp2aUnitTests/bin
src/Kp2aUnitTests/obj
src/monodroid-unittesting/MonoDroidUnitTesting/bin
src/monodroid-unittesting/MonoDroidUnitTesting/obj
/src/keepass2android/todos.cs
/src/keepass2android/obj
/src/keepass2android/bin

View File

@ -1,4 +1,5 @@
using System;
using System.IO;
using Android.Content;
using Android.OS;
using KeePassLib.Serialization;
@ -12,11 +13,15 @@ namespace keepass2android
/// This also contains methods which are UI specific and should be replacable for testing.
public interface IKp2aApp
{
/// <summary>
/// Locks the currently open database, quicklocking if available (unless false is passed for allowQuickUnlock)
/// </summary>
void LockDatabase(bool allowQuickUnlock = true);
/// <summary>
/// Set the flag that the database needs to be locked.
/// Loads the specified data as the currently open database, as unlocked.
/// </summary>
void SetShutdown();
void LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, string s, string keyFile, ProgressDialogStatusLogger statusLogger);
/// <summary>
/// Returns the current database
@ -69,6 +74,5 @@ namespace keepass2android
IProgressDialog CreateProgressDialog(Context ctx);
IFileStorage GetFileStorage(IOConnectionInfo iocInfo);
}
}

View File

@ -88,7 +88,7 @@
<Name>KeePassLib2Android</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Novell\Novell.MonoDroid.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">

View File

@ -72,25 +72,6 @@ namespace keepass2android
set { _loaded = value; }
}
public bool Open
{
get { return Loaded && (!Locked); }
}
bool _locked;
public bool Locked
{
get
{
return _locked;
}
set
{
Kp2aLog.Log("Locked=" + _locked);
_locked = value;
}
}
public bool DidOpenFileChange()
{
if (Loaded == false)
@ -102,6 +83,9 @@ namespace keepass2android
}
/// <summary>
/// Do not call this method directly. Call App.Kp2a.LoadDatabase instead.
/// </summary>
public void LoadData(IKp2aApp app, IOConnectionInfo iocInfo, MemoryStream databaseData, String password, String keyfile, ProgressDialogStatusLogger status)
{
PwDatabase pwDatabase = new PwDatabase();
@ -153,15 +137,6 @@ namespace keepass2android
SearchHelper = new SearchDbHelper(app);
}
public bool QuickUnlockEnabled { get; set; }
//KeyLength of QuickUnlock at time of loading the database.
//This is important to not allow an attacker to set the length to 1 when QuickUnlock is started already.
public int QuickUnlockKeyLength
{
get;
set;
}
public PwGroup SearchForText(String str) {
PwGroup group = SearchHelper.SearchForText(this, str);
@ -227,7 +202,6 @@ namespace keepass2android
Root = null;
KpDatabase = null;
_loaded = false;
_locked = false;
_reloadRequested = false;
}

View File

@ -79,7 +79,7 @@ namespace keepass2android
else
{
// Let's not bother recovering from a failure to save a deleted entry. It is too much work.
App.SetShutdown();
App.LockDatabase();
}
}, OnFinishToRun);
}
@ -99,7 +99,7 @@ namespace keepass2android
Db.Dirty.Add(pgRecycleBin);
} else {
// Let's not bother recovering from a failure to save a deleted entry. It is too much work.
App.SetShutdown();
App.LockDatabase();
}
}, OnFinishToRun);

View File

@ -108,7 +108,7 @@ namespace keepass2android
Db.Dirty.Add(pgParent);
} else {
// Let's not bother recovering from a failure to save a deleted group. It is too much work.
App.SetShutdown();
App.LockDatabase();
}
}, OnFinishToRun);
}
@ -146,7 +146,7 @@ namespace keepass2android
}
} else {
// Let's not bother recovering from a failure to save a deleted group. It is too much work.
_app.SetShutdown();
_app.LockDatabase();
}
base.Run();

View File

@ -47,7 +47,7 @@ namespace keepass2android
try
{
StatusLogger.UpdateMessage(UiStringKey.loading_database);
_app.GetDb().LoadData (_app, _ioc, _databaseData, _pass, _key, StatusLogger);
_app.LoadDatabase(_ioc, _databaseData, _pass, _key, StatusLogger);
SaveFileData (_ioc, _key);
} catch (KeyFileException) {

View File

@ -613,9 +613,7 @@ namespace keepass2android
}
return true;
case Resource.Id.menu_lock:
App.Kp2a.SetShutdown();
SetResult(KeePass.ExitLock);
Finish();
App.Kp2a.LockDatabase();
return true;
case Resource.Id.menu_translate:
try {

View File

@ -92,8 +92,7 @@ namespace keepass2android
_closeForReload = false;
// Likely the app has been killed exit the activity
Database db = App.Kp2a.GetDb();
if (! db.Open)
if (!App.Kp2a.DatabaseIsUnlocked)
{
Finish();
return;
@ -107,6 +106,8 @@ namespace keepass2android
} else
{
Database db = App.Kp2a.GetDb();
App.Kp2a.EntryEditActivityState = new EntryEditActivityState();
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(this);
State.ShowPassword = ! prefs.GetBoolean(GetString(Resource.String.maskpass_key), Resources.GetBoolean(Resource.Boolean.maskpass_default));

View File

@ -240,9 +240,7 @@ namespace keepass2android
return true;
case Resource.Id.menu_lock:
App.Kp2a.SetShutdown();
SetResult(KeePass.ExitLock);
Finish();
App.Kp2a.LockDatabase();
return true;
case Resource.Id.menu_search:
@ -353,8 +351,7 @@ namespace keepass2android
Toast.MakeText(_act, "Unrecoverable error: " + Message, ToastLength.Long).Show();
});
App.Kp2a.SetShutdown();
_act.Finish();
App.Kp2a.LockDatabase();
}
}

View File

@ -56,8 +56,7 @@ namespace keepass2android
}
else
{
Kp2aLog.Log(" Loaded=" + App.Kp2a.GetDb().Loaded + ", Locked=" + App.Kp2a.GetDb().Locked
+ ", shutdown=" + App.Kp2a.IsShutdown());
Kp2aLog.Log(" DatabaseIsUnlocked=" + App.Kp2a.DatabaseIsUnlocked);
}
}

View File

@ -15,7 +15,10 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using Android.Content;
using Android.OS;
using Android.App;
using KeePassLib.Serialization;
namespace keepass2android
@ -26,12 +29,25 @@ namespace keepass2android
/// Checks in OnResume whether the timeout occured and the database must be locked/closed.
public class LockCloseActivity : LockingActivity {
IOConnectionInfo _ioc;
private IOConnectionInfo _ioc;
private BroadcastReceiver _intentReceiver;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
_ioc = App.Kp2a.GetDb().Ioc;
_intentReceiver = new LockCloseActivityBroadcastReceiver(this);
IntentFilter filter = new IntentFilter();
filter.AddAction(Intents.LockDatabase);
RegisterReceiver(_intentReceiver, filter);
}
protected override void OnDestroy()
{
UnregisterReceiver(_intentReceiver);
base.OnDestroy();
}
@ -49,9 +65,32 @@ namespace keepass2android
App.Kp2a.CheckForOpenFileChanged(this);
}
private void OnLockDatabase()
{
Kp2aLog.Log("Finishing " + ComponentName.ClassName + " due to database lock");
SetResult(KeePass.ExitLock);
Finish();
}
private class LockCloseActivityBroadcastReceiver : BroadcastReceiver
{
readonly LockCloseActivity _service;
public LockCloseActivityBroadcastReceiver(LockCloseActivity service)
{
_service = service;
}
public override void OnReceive(Context context, Intent intent)
{
switch (intent.Action)
{
case Intents.LockDatabase:
_service.OnLockDatabase();
break;
}
}
}
}
}

View File

@ -16,6 +16,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
*/
using System;
using Android.Content;
using Android.OS;
using Android.Runtime;
using KeePassLib.Serialization;
@ -33,11 +34,18 @@ namespace keepass2android
}
IOConnectionInfo _ioc;
private BroadcastReceiver _intentReceiver;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
_ioc = App.Kp2a.GetDb().Ioc;
_intentReceiver = new LockCloseListActivityBroadcastReceiver(this);
IntentFilter filter = new IntentFilter();
filter.AddAction(Intents.LockDatabase);
RegisterReceiver(_intentReceiver, filter);
}
public LockCloseListActivity (IntPtr javaReference, JniHandleOwnership transfer)
@ -57,6 +65,39 @@ namespace keepass2android
App.Kp2a.CheckForOpenFileChanged(this);
}
protected override void OnDestroy()
{
UnregisterReceiver(_intentReceiver);
base.OnDestroy();
}
private void OnLockDatabase()
{
Kp2aLog.Log("Finishing " + ComponentName.ClassName + " due to database lock");
SetResult(KeePass.ExitLock);
Finish();
}
private class LockCloseListActivityBroadcastReceiver : BroadcastReceiver
{
readonly LockCloseListActivity _service;
public LockCloseListActivityBroadcastReceiver(LockCloseListActivity service)
{
_service = service;
}
public override void OnReceive(Context context, Intent intent)
{
switch (intent.Action)
{
case Intents.LockDatabase:
_service.OnLockDatabase();
break;
}
}
}
}
}

View File

@ -15,6 +15,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
using Android.Content;
using Android.OS;
using KeePassLib.Serialization;
@ -25,11 +26,18 @@ namespace keepass2android
IOConnectionInfo _ioc;
private BroadcastReceiver _intentReceiver;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
_ioc = App.Kp2a.GetDb().Ioc;
_intentReceiver = new LockingClosePreferenceActivityBroadcastReceiver(this);
IntentFilter filter = new IntentFilter();
filter.AddAction(Intents.LockDatabase);
RegisterReceiver(_intentReceiver, filter);
}
protected override void OnResume() {
@ -37,6 +45,41 @@ namespace keepass2android
TimeoutHelper.CheckShutdown(this, _ioc);
}
protected override void OnDestroy()
{
UnregisterReceiver(_intentReceiver);
base.OnDestroy();
}
private void OnLockDatabase()
{
Kp2aLog.Log("Finishing " + ComponentName.ClassName + " due to database lock");
SetResult(KeePass.ExitLock);
Finish();
}
private class LockingClosePreferenceActivityBroadcastReceiver : BroadcastReceiver
{
readonly LockingClosePreferenceActivity _service;
public LockingClosePreferenceActivityBroadcastReceiver(LockingClosePreferenceActivity service)
{
_service = service;
}
public override void OnReceive(Context context, Intent intent)
{
switch (intent.Action)
{
case Intents.LockDatabase:
_service.OnLockDatabase();
break;
}
}
}
}
}

View File

@ -53,6 +53,7 @@ namespace keepass2android
private const String ViewIntent = "android.intent.action.VIEW";
private Task<MemoryStream> _loadDbTask;
private IOConnectionInfo _ioConnection;
private String _keyFile;
private bool _rememberKeyfile;
@ -130,58 +131,14 @@ namespace keepass2android
}
void UnloadDatabase()
void TryStartQuickUnlock()
{
App.Kp2a.GetDb().Clear();
StopService(new Intent(this, typeof(QuickUnlockForegroundService)));
}
void LockDatabase()
if (App.Kp2a.QuickUnlockEnabled && App.Kp2a.QuickLocked)
{
SetResult(KeePass.ExitLock);
SetEditText(Resource.Id.password, "");
if (App.Kp2a.GetDb().QuickUnlockEnabled)
App.Kp2a.GetDb().Locked = true;
else
{
UnloadDatabase();
}
}
void LockAndClose()
{
LockDatabase();
Finish();
}
bool TryStartQuickUnlock()
{
if (!App.Kp2a.GetDb().QuickUnlockEnabled)
return false;
if (App.Kp2a.GetDb().KpDatabase.MasterKey.ContainsType(typeof(KcpPassword)) == false)
return false;
KcpPassword kcpPassword = (KcpPassword)App.Kp2a.GetDb().KpDatabase.MasterKey.GetUserKey(typeof(KcpPassword));
String password = kcpPassword.Password.ReadString();
if (password.Length == 0)
return false;
App.Kp2a.GetDb().Locked = true;
Intent i = new Intent(this, typeof(QuickUnlock));
PutIoConnectionToIntent(_ioConnection, i);
Kp2aLog.Log("Starting QuickUnlock");
StartActivityForResult(i, 0);
return true;
}
public void StartQuickUnlockForegroundService()
{
if (App.Kp2a.GetDb().QuickUnlockEnabled)
{
StartService(new Intent(this, typeof(QuickUnlockForegroundService)));
}
}
@ -194,45 +151,27 @@ namespace keepass2android
_startedWithActivityResult = true;
Kp2aLog.Log("PasswordActivity.OnActivityResult "+resultCode+"/"+requestCode);
if (resultCode != KeePass.ExitCloseAfterTaskComplete)
{
//Stop service when app activity is left
StopService(new Intent(this, typeof(CopyToClipboardService)));
}
//NOTE: original code from k eepassdroid used switch ((Android.App.Result)requestCode) { (but doesn't work here, although k eepassdroid works)
switch(resultCode) {
case KeePass.ExitNormal:
if (!TryStartQuickUnlock())
{
SetEditText(Resource.Id.password, "");
}
break;
case KeePass.ExitLock:
if (!TryStartQuickUnlock())
{
LockAndClose();
}
// The database has already been locked, just show the quick unlock screen if appropriate
TryStartQuickUnlock();
break;
case KeePass.ExitForceLock:
SetEditText(Resource.Id.password, "");
UnloadDatabase();
App.Kp2a.LockDatabase(false);
break;
case KeePass.ExitForceLockAndChangeDb:
UnloadDatabase();
Finish();
break;
case KeePass.ExitChangeDb:
LockAndClose();
case KeePass.ExitChangeDb: // What's the difference between this and ExitForceLockAndChangeDb?
case KeePass.ExitNormal: // Returned to this screen using the Back key, treat as exiting the database
App.Kp2a.LockDatabase(false, Finish);
break;
case KeePass.ExitCloseAfterTaskComplete:
SetResult(KeePass.ExitCloseAfterTaskComplete);
Finish();
break;
case KeePass.ExitQuickUnlock:
App.Kp2a.GetDb().Locked = false;
App.Kp2a.UnlockDatabase();
LaunchNextActivity();
break;
case KeePass.ExitReloadDb:
@ -256,7 +195,6 @@ namespace keepass2android
SetEditText(Resource.Id.pass_keyfile, kcpKeyfile.Path);
}
}
UnloadDatabase();
break;
case Result.Ok:
if (requestCode == Intents.RequestCodeFileBrowseForKeyfile) {
@ -277,6 +215,17 @@ namespace keepass2android
}
protected override void OnDestroy()
{
base.OnDestroy();
if (!App.Kp2a.QuickUnlockEnabled)
{
// We're exiting (probably task-killed), so stop the service, if it's still running - don't want it hanging around with an icon shown.
StopService(new Intent(this, typeof(Keepass2AndroidService)));
}
}
internal AppTask AppTask;
protected override void OnCreate(Bundle savedInstanceState)
@ -335,9 +284,6 @@ namespace keepass2android
}
}
// Create task to kick off file loading while the user enters the password
var loadDbTask = new Task<MemoryStream>(LoadDbFile);
AppTask = AppTask.GetTaskInOnCreate(savedInstanceState, Intent);
SetContentView(Resource.Layout.password);
@ -360,18 +306,13 @@ namespace keepass2android
return;
}
// Clear before we load
UnloadDatabase();
// Clear the shutdown flag
App.Kp2a.ClearShutdown();
CheckBox cbQuickUnlock = (CheckBox)FindViewById(Resource.Id.enable_quickunlock);
App.Kp2a.GetDb().QuickUnlockEnabled = cbQuickUnlock.Checked;
App.Kp2a.GetDb().QuickUnlockKeyLength = int.Parse(_prefs.GetString(GetString(Resource.String.QuickUnlockLength_key), GetString(Resource.String.QuickUnlockLength_default)));
App.Kp2a.SetQuickUnlockEnabled(cbQuickUnlock.Checked);
Handler handler = new Handler();
LoadDb task = new LoadDb(App.Kp2a, _ioConnection, loadDbTask.Result, pass, key, new AfterLoad(handler, this));
var stream = _loadDbTask.Result;
_loadDbTask = null; // prevent accidental re-use
LoadDb task = new LoadDb(App.Kp2a, _ioConnection, stream, pass, key, new AfterLoad(handler, this));
ProgressTask pt = new ProgressTask(App.Kp2a, this, task);
pt.Run();
};
@ -445,13 +386,19 @@ namespace keepass2android
};
RetrieveSettings();
}
loadDbTask.Start();
protected override void OnStart()
{
base.OnStart();
// Create task to kick off file loading while the user enters the password
_loadDbTask = Task.Factory.StartNew<MemoryStream>(LoadDbFile);
}
private MemoryStream LoadDbFile()
{
System.Diagnostics.Debug.WriteLine("LoadDbFile Started");
Kp2aLog.Log("Pre-loading database file starting");
var fileStorage = App.Kp2a.GetFileStorage(_ioConnection);
var stream = fileStorage.OpenFileForRead(_ioConnection);
@ -463,7 +410,6 @@ namespace keepass2android
if (stream.CanSeek)
{
capacity = (int)stream.Length;
System.Diagnostics.Debug.WriteLine("LoadDbFile, data size: " + capacity);
}
memoryStream = new MemoryStream(capacity);
MemUtil.CopyStream(stream, memoryStream);
@ -471,7 +417,7 @@ namespace keepass2android
memoryStream.Seek(0, System.IO.SeekOrigin.Begin);
}
System.Diagnostics.Debug.WriteLine("LoadDbFile Done");
Kp2aLog.Log("Pre-loading database file completed");
return memoryStream;
}
@ -485,22 +431,13 @@ namespace keepass2android
protected override void OnResume() {
base.OnResume();
// If the application was shutdown make sure to clear the password field, if it
// was saved in the instance state
if (App.Kp2a.IsShutdown()) {
LockDatabase();
}
// Clear the shutdown flag
App.Kp2a.ClearShutdown();
if (_startedWithActivityResult)
return;
if (App.Kp2a.GetDb().Loaded && (App.Kp2a.GetDb().Ioc != null)
&& (_ioConnection != null) && (App.Kp2a.GetDb().Ioc.GetDisplayName() == _ioConnection.GetDisplayName()))
{
if (App.Kp2a.GetDb().Locked == false)
if (App.Kp2a.QuickLocked == false)
{
LaunchNextActivity();
}
@ -596,7 +533,8 @@ namespace keepass2android
public override void Run() {
if ( Success ) {
_act.StartQuickUnlockForegroundService();
_act.SetEditText(Resource.Id.password, "");
_act.LaunchNextActivity();
} else {
DisplayMessage(_act);

View File

@ -61,7 +61,7 @@ namespace keepass2android
TextView txtLabel = (TextView)FindViewById(Resource.Id.QuickUnlock_label);
int quickUnlockLength = App.Kp2a.GetDb().QuickUnlockKeyLength;
int quickUnlockLength = App.Kp2a.QuickUnlockKeyLength;
txtLabel.Text = GetString(Resource.String.QuickUnlock_label, new Java.Lang.Object[]{quickUnlockLength});

View File

@ -1,29 +1,24 @@
#pragma warning disable 1591
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:4.0.30319.18051
// This code was generated by a tool.
// Runtime Version:4.0.30319.2012
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
[assembly: global::Android.Runtime.ResourceDesignerAttribute("keepass2android.Resource", IsApplication=true)]
[assembly: Android.Runtime.ResourceDesignerAttribute("keepass2android.Resource", IsApplication=true)]
namespace keepass2android
{
[System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")]
[System.CodeDom.Compiler.GeneratedCodeAttribute("Novell.MonoDroid.Build.Tasks", "1.0.0.0")]
public partial class Resource
{
static Resource()
{
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
}
public static void UpdateIdValues()
{
KeePassLib2Android.Resource.String.library_name = keepass2android.Resource.String.library_name;
@ -44,11 +39,6 @@ namespace keepass2android
// aapt resource value: 0x7f040003
public const int anim_leave_back = 2130968579;
static Animation()
{
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
}
private Animation()
{
}
@ -72,11 +62,6 @@ namespace keepass2android
// aapt resource value: 0x7f0a0001
public const int list_size_values = 2131361793;
static Array()
{
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
}
private Array()
{
}
@ -85,11 +70,6 @@ namespace keepass2android
public partial class Attribute
{
static Attribute()
{
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
}
private Attribute()
{
}
@ -104,6 +84,9 @@ namespace keepass2android
// aapt resource value: 0x7f090008
public const int OpenKp2aKeyboardAutomatically_default = 2131296264;
// aapt resource value: 0x7f090009
public const int ShowUnlockedNotification_default = 2131296265;
// aapt resource value: 0x7f090005
public const int ShowUsernameInList_default = 2131296261;
@ -125,11 +108,6 @@ namespace keepass2android
// aapt resource value: 0x7f090002
public const int sort_default = 2131296258;
static Boolean()
{
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
}
private Boolean()
{
}
@ -180,11 +158,6 @@ namespace keepass2android
// aapt resource value: 0x7f06000c
public const int light_gray = 2131099660;
static Color()
{
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
}
private Color()
{
}
@ -202,11 +175,6 @@ namespace keepass2android
// aapt resource value: 0x7f070000
public const int key_height = 2131165184;
static Dimension()
{
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
}
private Dimension()
{
}
@ -480,75 +448,76 @@ namespace keepass2android
public const int ic_launcher_offline = 2130837591;
// aapt resource value: 0x7f020058
public const int ic_menu_add_field_holo_light = 2130837592;
public const int ic_launcher_red = 2130837592;
// aapt resource value: 0x7f020059
public const int ic_menu_remove_field_holo_light = 2130837593;
public const int ic_menu_add_field_holo_light = 2130837593;
// aapt resource value: 0x7f02005a
public const int ic_menu_view = 2130837594;
public const int ic_menu_remove_field_holo_light = 2130837594;
// aapt resource value: 0x7f02005b
public const int location_web_site = 2130837595;
public const int ic_menu_view = 2130837595;
// aapt resource value: 0x7f02005c
public const int navigation_accept = 2130837596;
public const int ic_unlocked_gray = 2130837596;
// aapt resource value: 0x7f02005d
public const int navigation_accept_dark = 2130837597;
public const int location_web_site = 2130837597;
// aapt resource value: 0x7f02005e
public const int navigation_cancel = 2130837598;
public const int navigation_accept = 2130837598;
// aapt resource value: 0x7f02005f
public const int navigation_previous_item = 2130837599;
public const int navigation_accept_dark = 2130837599;
// aapt resource value: 0x7f020060
public const int navigation_previous_item_dark = 2130837600;
public const int navigation_cancel = 2130837600;
// aapt resource value: 0x7f020061
public const int notify = 2130837601;
public const int navigation_previous_item = 2130837601;
// aapt resource value: 0x7f020062
public const int notify_keyboard = 2130837602;
public const int navigation_previous_item_dark = 2130837602;
// aapt resource value: 0x7f020063
public const int RedButton = 2130837603;
public const int notify = 2130837603;
// aapt resource value: 0x7f020064
public const int section_header = 2130837604;
public const int notify_keyboard = 2130837604;
// aapt resource value: 0x7f020065
public const int sym_keyboard = 2130837605;
public const int RedButton = 2130837605;
// aapt resource value: 0x7f020066
public const int sym_keyboard_delete = 2130837606;
public const int section_header = 2130837606;
// aapt resource value: 0x7f020067
public const int sym_keyboard_done = 2130837607;
public const int sym_keyboard = 2130837607;
// aapt resource value: 0x7f020068
public const int sym_keyboard_kp2a = 2130837608;
public const int sym_keyboard_delete = 2130837608;
// aapt resource value: 0x7f020069
public const int sym_keyboard_return = 2130837609;
public const int sym_keyboard_done = 2130837609;
// aapt resource value: 0x7f02006a
public const int sym_keyboard_search = 2130837610;
public const int sym_keyboard_kp2a = 2130837610;
// aapt resource value: 0x7f02006b
public const int sym_keyboard_shift = 2130837611;
public const int sym_keyboard_return = 2130837611;
// aapt resource value: 0x7f02006c
public const int sym_keyboard_space = 2130837612;
public const int sym_keyboard_search = 2130837612;
// aapt resource value: 0x7f02006d
public const int YellowButton = 2130837613;
public const int sym_keyboard_shift = 2130837613;
static Drawable()
{
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
}
// aapt resource value: 0x7f02006e
public const int sym_keyboard_space = 2130837614;
// aapt resource value: 0x7f02006f
public const int YellowButton = 2130837615;
private Drawable()
{
@ -1074,11 +1043,6 @@ namespace keepass2android
// aapt resource value: 0x7f0d0002
public const int version_title = 2131558402;
static Id()
{
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
}
private Id()
{
}
@ -1201,11 +1165,6 @@ namespace keepass2android
// aapt resource value: 0x7f030025
public const int url_credentials = 2130903077;
static Layout()
{
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
}
private Layout()
{
}
@ -1229,11 +1188,6 @@ namespace keepass2android
// aapt resource value: 0x7f0c0004
public const int password = 2131492868;
static Menu()
{
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
}
private Menu()
{
}
@ -1245,53 +1199,53 @@ namespace keepass2android
// aapt resource value: 0x7f080034
public const int AboutText = 2131230772;
// aapt resource value: 0x7f080123
public const int AddingEntry = 2131231011;
// aapt resource value: 0x7f080124
public const int AddingGroup = 2131231012;
public const int AddingEntry = 2131231012;
// aapt resource value: 0x7f080119
public const int AskDeletePermanentlyEntry = 2131231001;
// aapt resource value: 0x7f080125
public const int AddingGroup = 2131231013;
// aapt resource value: 0x7f08011a
public const int AskDeletePermanentlyGroup = 2131231002;
public const int AskDeletePermanentlyEntry = 2131231002;
// aapt resource value: 0x7f08011b
public const int AskDeletePermanently_title = 2131231003;
// aapt resource value: 0x7f08011e
public const int AskDiscardChanges = 2131231006;
// aapt resource value: 0x7f08011f
public const int AskDiscardChanges_title = 2131231007;
// aapt resource value: 0x7f080113
public const int AskOverwriteBinary = 2131230995;
// aapt resource value: 0x7f080116
public const int AskOverwriteBinary_no = 2131230998;
// aapt resource value: 0x7f080114
public const int AskOverwriteBinary_title = 2131230996;
// aapt resource value: 0x7f080115
public const int AskOverwriteBinary_yes = 2131230997;
// aapt resource value: 0x7f08011d
public const int AskReloadFile = 2131231005;
public const int AskDeletePermanentlyGroup = 2131231003;
// aapt resource value: 0x7f08011c
public const int AskReloadFile_title = 2131231004;
public const int AskDeletePermanently_title = 2131231004;
// aapt resource value: 0x7f08011f
public const int AskDiscardChanges = 2131231007;
// aapt resource value: 0x7f080120
public const int AskDiscardChanges_title = 2131231008;
// aapt resource value: 0x7f080114
public const int AskOverwriteBinary = 2131230996;
// aapt resource value: 0x7f080117
public const int AttachFailed = 2131230999;
public const int AskOverwriteBinary_no = 2131230999;
// aapt resource value: 0x7f080022
public const int BinaryDirectory_default = 2131230754;
// aapt resource value: 0x7f080115
public const int AskOverwriteBinary_title = 2131230997;
// aapt resource value: 0x7f080116
public const int AskOverwriteBinary_yes = 2131230998;
// aapt resource value: 0x7f08011e
public const int AskReloadFile = 2131231006;
// aapt resource value: 0x7f08011d
public const int AskReloadFile_title = 2131231005;
// aapt resource value: 0x7f080118
public const int AttachFailed = 2131231000;
// aapt resource value: 0x7f080021
public const int BinaryDirectory_key = 2131230753;
public const int BinaryDirectory_default = 2131230753;
// aapt resource value: 0x7f080020
public const int BinaryDirectory_key = 2131230752;
// aapt resource value: 0x7f0800f8
public const int BinaryDirectory_summary = 2131230968;
@ -1299,62 +1253,62 @@ namespace keepass2android
// aapt resource value: 0x7f0800f7
public const int BinaryDirectory_title = 2131230967;
// aapt resource value: 0x7f08013b
public const int ChangeLog = 2131231035;
// aapt resource value: 0x7f08013a
public const int ChangeLog = 2131231034;
// aapt resource value: 0x7f080139
public const int ChangeLog_0_7 = 2131231033;
// aapt resource value: 0x7f080137
public const int ChangeLog_0_8 = 2131231031;
// aapt resource value: 0x7f080136
public const int ChangeLog_0_8_1 = 2131231030;
// aapt resource value: 0x7f080135
public const int ChangeLog_0_8_2 = 2131231029;
// aapt resource value: 0x7f080134
public const int ChangeLog_0_8_3 = 2131231028;
// aapt resource value: 0x7f080133
public const int ChangeLog_0_8_4 = 2131231027;
public const int ChangeLog_0_7 = 2131231034;
// aapt resource value: 0x7f080138
public const int ChangeLog_keptDonate = 2131231032;
public const int ChangeLog_0_8 = 2131231032;
// aapt resource value: 0x7f080132
public const int ChangeLog_title = 2131231026;
// aapt resource value: 0x7f080137
public const int ChangeLog_0_8_1 = 2131231031;
// aapt resource value: 0x7f080029
public const int CheckForFileChangesOnSave_key = 2131230761;
// aapt resource value: 0x7f080136
public const int ChangeLog_0_8_2 = 2131231030;
// aapt resource value: 0x7f080135
public const int ChangeLog_0_8_3 = 2131231029;
// aapt resource value: 0x7f080134
public const int ChangeLog_0_8_4 = 2131231028;
// aapt resource value: 0x7f080139
public const int ChangeLog_keptDonate = 2131231033;
// aapt resource value: 0x7f080133
public const int ChangeLog_title = 2131231027;
// aapt resource value: 0x7f080028
public const int CheckForFileChangesOnSave_key = 2131230760;
// aapt resource value: 0x7f08010d
public const int CheckForFileChangesOnSave_summary = 2131230989;
// aapt resource value: 0x7f08010c
public const int CheckForFileChangesOnSave_summary = 2131230988;
public const int CheckForFileChangesOnSave_title = 2131230988;
// aapt resource value: 0x7f08010b
public const int CheckForFileChangesOnSave_title = 2131230987;
// aapt resource value: 0x7f08012c
public const int CheckingTargetFileForChanges = 2131231020;
// aapt resource value: 0x7f08012d
public const int CheckingTargetFileForChanges = 2131231021;
// aapt resource value: 0x7f080049
public const int ClearClipboard = 2131230793;
// aapt resource value: 0x7f08002d
public const int CopyToClipboardNotification_key = 2131230765;
// aapt resource value: 0x7f08002c
public const int CopyToClipboardNotification_key = 2131230764;
// aapt resource value: 0x7f080035
public const int CreditsText = 2131230773;
// aapt resource value: 0x7f08012a
public const int DecodingDatabase = 2131231018;
// aapt resource value: 0x7f080125
public const int DeletingEntry = 2131231013;
// aapt resource value: 0x7f08012b
public const int DecodingDatabase = 2131231019;
// aapt resource value: 0x7f080126
public const int DeletingGroup = 2131231014;
public const int DeletingEntry = 2131231014;
// aapt resource value: 0x7f080127
public const int DeletingGroup = 2131231015;
// aapt resource value: 0x7f080082
public const int FileNotFound = 2131230850;
@ -1362,35 +1316,35 @@ namespace keepass2android
// aapt resource value: 0x7f080095
public const int InvalidPassword = 2131230869;
// aapt resource value: 0x7f080027
public const int LastInfoVersionCode_key = 2131230759;
// aapt resource value: 0x7f080026
public const int LastInfoVersionCode_key = 2131230758;
// aapt resource value: 0x7f08002a
public const int MarketURL = 2131230762;
// aapt resource value: 0x7f080029
public const int MarketURL = 2131230761;
// aapt resource value: 0x7f08009f
public const int MaskedPassword = 2131230879;
// aapt resource value: 0x7f08012e
public const int MessageSyncQuestion = 2131231022;
// aapt resource value: 0x7f08012f
public const int MessageSyncQuestion = 2131231023;
// aapt resource value: 0x7f080131
public const int NoOverwrite = 2131231025;
// aapt resource value: 0x7f080132
public const int NoOverwrite = 2131231026;
// aapt resource value: 0x7f08002f
public const int OpenKp2aKeyboardAutomatically_key = 2131230767;
// aapt resource value: 0x7f08002e
public const int OpenKp2aKeyboardAutomatically_key = 2131230766;
// aapt resource value: 0x7f080113
public const int OpenKp2aKeyboardAutomatically_summary = 2131230995;
// aapt resource value: 0x7f080112
public const int OpenKp2aKeyboardAutomatically_summary = 2131230994;
public const int OpenKp2aKeyboardAutomatically_title = 2131230994;
// aapt resource value: 0x7f080111
public const int OpenKp2aKeyboardAutomatically_title = 2131230993;
// aapt resource value: 0x7f08012c
public const int ParsingDatabase = 2131231020;
// aapt resource value: 0x7f08012b
public const int ParsingDatabase = 2131231019;
// aapt resource value: 0x7f080023
public const int QuickUnlockDefaultEnabled_key = 2131230755;
// aapt resource value: 0x7f080022
public const int QuickUnlockDefaultEnabled_key = 2131230754;
// aapt resource value: 0x7f0800f3
public const int QuickUnlockDefaultEnabled_summary = 2131230963;
@ -1398,11 +1352,11 @@ namespace keepass2android
// aapt resource value: 0x7f0800f2
public const int QuickUnlockDefaultEnabled_title = 2131230962;
// aapt resource value: 0x7f080025
public const int QuickUnlockLength_default = 2131230757;
// aapt resource value: 0x7f080024
public const int QuickUnlockLength_key = 2131230756;
public const int QuickUnlockLength_default = 2131230756;
// aapt resource value: 0x7f080023
public const int QuickUnlockLength_key = 2131230755;
// aapt resource value: 0x7f0800f5
public const int QuickUnlockLength_summary = 2131230965;
@ -1422,8 +1376,8 @@ namespace keepass2android
// aapt resource value: 0x7f0800f1
public const int QuickUnlock_lockButton = 2131230961;
// aapt resource value: 0x7f080118
public const int RecycleBin = 2131231000;
// aapt resource value: 0x7f080119
public const int RecycleBin = 2131231001;
// aapt resource value: 0x7f0800fc
public const int SaveAttachmentDialog_open = 2131230972;
@ -1443,23 +1397,26 @@ namespace keepass2android
// aapt resource value: 0x7f0800fd
public const int SaveAttachment_doneMessage = 2131230973;
// aapt resource value: 0x7f080127
public const int SettingPassword = 2131231015;
// aapt resource value: 0x7f08010e
public const int ShowCopyToClipboardNotification_summary = 2131230990;
// aapt resource value: 0x7f08010d
public const int ShowCopyToClipboardNotification_title = 2131230989;
// aapt resource value: 0x7f080110
public const int ShowKp2aKeyboardNotification_summary = 2131230992;
// aapt resource value: 0x7f080128
public const int SettingPassword = 2131231016;
// aapt resource value: 0x7f08010f
public const int ShowKp2aKeyboardNotification_title = 2131230991;
public const int ShowCopyToClipboardNotification_summary = 2131230991;
// aapt resource value: 0x7f08001e
public const int ShowUsernameInList_key = 2131230750;
// aapt resource value: 0x7f08010e
public const int ShowCopyToClipboardNotification_title = 2131230990;
// aapt resource value: 0x7f080111
public const int ShowKp2aKeyboardNotification_summary = 2131230993;
// aapt resource value: 0x7f080110
public const int ShowKp2aKeyboardNotification_title = 2131230992;
// aapt resource value: 0x7f080031
public const int ShowUnlockedNotification_key = 2131230769;
// aapt resource value: 0x7f08001d
public const int ShowUsernameInList_key = 2131230749;
// aapt resource value: 0x7f0800e3
public const int ShowUsernameInList_summary = 2131230947;
@ -1467,14 +1424,14 @@ namespace keepass2android
// aapt resource value: 0x7f0800e2
public const int ShowUsernameInList_title = 2131230946;
// aapt resource value: 0x7f08002b
public const int SuggestionsURL = 2131230763;
// aapt resource value: 0x7f08002a
public const int SuggestionsURL = 2131230762;
// aapt resource value: 0x7f08012f
public const int SynchronizingDatabase = 2131231023;
// aapt resource value: 0x7f080130
public const int SynchronizingDatabase = 2131231024;
// aapt resource value: 0x7f08001d
public const int TanExpiresOnUse_key = 2131230749;
// aapt resource value: 0x7f08001c
public const int TanExpiresOnUse_key = 2131230748;
// aapt resource value: 0x7f0800e1
public const int TanExpiresOnUse_summary = 2131230945;
@ -1482,35 +1439,35 @@ namespace keepass2android
// aapt resource value: 0x7f0800e0
public const int TanExpiresOnUse_title = 2131230944;
// aapt resource value: 0x7f08012d
public const int TitleSyncQuestion = 2131231021;
// aapt resource value: 0x7f08012e
public const int TitleSyncQuestion = 2131231022;
// aapt resource value: 0x7f08012a
public const int TransformingKey = 2131231018;
// aapt resource value: 0x7f08002b
public const int TranslationURL = 2131230763;
// aapt resource value: 0x7f080129
public const int TransformingKey = 2131231017;
public const int UndoingChanges = 2131231017;
// aapt resource value: 0x7f08002c
public const int TranslationURL = 2131230764;
// aapt resource value: 0x7f080025
public const int UsageCount_key = 2131230757;
// aapt resource value: 0x7f080128
public const int UndoingChanges = 2131231016;
// aapt resource value: 0x7f080027
public const int UseFileTransactions_key = 2131230759;
// aapt resource value: 0x7f080026
public const int UsageCount_key = 2131230758;
// aapt resource value: 0x7f080028
public const int UseFileTransactions_key = 2131230760;
// aapt resource value: 0x7f08010b
public const int UseFileTransactions_summary = 2131230987;
// aapt resource value: 0x7f08010a
public const int UseFileTransactions_summary = 2131230986;
public const int UseFileTransactions_title = 2131230986;
// aapt resource value: 0x7f080109
public const int UseFileTransactions_title = 2131230985;
// aapt resource value: 0x7f08002d
public const int UseKp2aKeyboard_key = 2131230765;
// aapt resource value: 0x7f08002e
public const int UseKp2aKeyboard_key = 2131230766;
// aapt resource value: 0x7f080130
public const int YesSynchronize = 2131231024;
// aapt resource value: 0x7f080131
public const int YesSynchronize = 2131231025;
// aapt resource value: 0x7f080032
public const int about_feedback = 2131230770;
@ -1596,8 +1553,8 @@ namespace keepass2android
// aapt resource value: 0x7f08004a
public const int clipboard_timeout = 2131230794;
// aapt resource value: 0x7f080030
public const int clipboard_timeout_default = 2131230768;
// aapt resource value: 0x7f08002f
public const int clipboard_timeout_default = 2131230767;
// aapt resource value: 0x7f080014
public const int clipboard_timeout_key = 2131230740;
@ -1614,8 +1571,8 @@ namespace keepass2android
// aapt resource value: 0x7f080051
public const int creating_db_key = 2131230801;
// aapt resource value: 0x7f080108
public const int credentials_dialog_title = 2131230984;
// aapt resource value: 0x7f080109
public const int credentials_dialog_title = 2131230985;
// aapt resource value: 0x7f080052
public const int current_group = 2131230802;
@ -1629,11 +1586,14 @@ namespace keepass2android
// aapt resource value: 0x7f080107
public const int database_loaded_quickunlock_enabled = 2131230983;
// aapt resource value: 0x7f080108
public const int database_loaded_unlocked = 2131230984;
// aapt resource value: 0x7f0800ca
public const int database_name = 2131230922;
// aapt resource value: 0x7f080020
public const int database_name_key = 2131230752;
// aapt resource value: 0x7f08001f
public const int database_name_key = 2131230751;
// aapt resource value: 0x7f080015
public const int db_key = 2131230741;
@ -1653,8 +1613,8 @@ namespace keepass2android
// aapt resource value: 0x7f0800cb
public const int default_username = 2131230923;
// aapt resource value: 0x7f08001f
public const int default_username_key = 2131230751;
// aapt resource value: 0x7f08001e
public const int default_username_key = 2131230750;
// aapt resource value: 0x7f080106
public const int delete_extra_string = 2131230982;
@ -1914,8 +1874,8 @@ namespace keepass2android
// aapt resource value: 0x7f080009
public const int library_name = 2131230729;
// aapt resource value: 0x7f080031
public const int list_size_default = 2131230769;
// aapt resource value: 0x7f080030
public const int list_size_default = 2131230768;
// aapt resource value: 0x7f08001a
public const int list_size_key = 2131230746;
@ -2058,8 +2018,8 @@ namespace keepass2android
// aapt resource value: 0x7f080103
public const int protection = 2131230979;
// aapt resource value: 0x7f080121
public const int rate_app = 2131231009;
// aapt resource value: 0x7f080122
public const int rate_app = 2131231010;
// aapt resource value: 0x7f0800df
public const int regular_expression = 2131230943;
@ -2151,14 +2111,11 @@ namespace keepass2android
// aapt resource value: 0x7f0800ea
public const int start_open_url = 2131230954;
// aapt resource value: 0x7f080120
public const int suggest_improvements = 2131231008;
// aapt resource value: 0x7f080121
public const int suggest_improvements = 2131231009;
// aapt resource value: 0x7f08001c
public const int timeout_key = 2131230748;
// aapt resource value: 0x7f080122
public const int translate_app = 2131231010;
// aapt resource value: 0x7f080123
public const int translate_app = 2131231011;
// aapt resource value: 0x7f0800d8
public const int twofish = 2131230936;
@ -2187,11 +2144,6 @@ namespace keepass2android
// aapt resource value: 0x7f0800b6
public const int yes = 2131230902;
static String()
{
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
}
private String()
{
}
@ -2281,11 +2233,6 @@ namespace keepass2android
// aapt resource value: 0x7f0b000d
public const int WhiteOnDarkSmall = 2131427341;
static Style()
{
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
}
private Style()
{
}
@ -2315,11 +2262,6 @@ namespace keepass2android
// aapt resource value: 0x7f050006
public const int symbols_shift = 2131034118;
static Xml()
{
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
}
private Xml()
{
}

View File

@ -39,7 +39,6 @@
<string name="omitbackup_key">omitbackup</string>
<string name="list_size_key">list_size</string>
<string name="sort_key">sort_key</string>
<string name="timeout_key">timeout_key</string>
<string name="TanExpiresOnUse_key">TanExpiresOnUse_key</string>
<string name="ShowUsernameInList_key">ShowUsernameInList_key</string>
<string name="default_username_key">defaultUsername</string>
@ -89,4 +88,8 @@
<item>20</item>
<item>28</item>
</string-array>
<string name="ShowUnlockedNotification_key">ShowUnlockedNotification</string>
<bool name="ShowUnlockedNotification_default">true</bool>
</resources>

View File

@ -215,7 +215,8 @@
<string name="add_binary">Add file attachment...</string>
<string name="add_extra_string">Add additional string</string>
<string name="delete_extra_string">Delete additional string</string>
<string name="database_loaded_quickunlock_enabled">Database loaded, QuickUnlock enabled.</string>
<string name="database_loaded_quickunlock_enabled">%1$s: Locked. QuickUnlock enabled.</string>
<string name="database_loaded_unlocked">%1$s: Unlocked. Tap to lock.</string>
<string name="credentials_dialog_title">Enter server credentials</string>
<string name="UseFileTransactions_title">File transactions</string>
<string name="UseFileTransactions_summary">Use file transactions for writing databases</string>

View File

@ -71,7 +71,7 @@ namespace keepass2android
Finish();
}
else if (_db.Locked)
else if (App.Kp2a.QuickLocked)
{
PasswordActivity.Launch(this,_db.Ioc, AppTask);
Finish();

View File

@ -16,10 +16,13 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
*/
using System;
using System.Collections.Generic;
using System.IO;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using KeePassLib.Keys;
using KeePassLib.Serialization;
using Android.Preferences;
using keepass2android.Io;
@ -59,25 +62,138 @@ namespace keepass2android
/// </summary>
public class Kp2aApp: IKp2aApp
{
public bool IsShutdown()
public void LockDatabase(bool allowQuickUnlock = true)
{
return _shutdown;
if (!allowQuickUnlock)
{
QuickUnlockEnabled = false;
}
public void SetShutdown()
{
Kp2aLog.Log("set shutdown");
_shutdown = true;
Application.Context.SendBroadcast(new Intent(Intents.LockDatabase));
}
public void ClearShutdown()
/// <summary>
/// Locks the database, then runs the specified action once the locking has completed.
/// </summary>
/// <param name="allowQuickUnlock"></param>
/// <param name="runAfterLocked"></param>
internal void LockDatabase(bool allowQuickUnlock, Action runAfterLocked)
{
Kp2aLog.Log("clear shutdown");
_shutdown = false;
_actionsToRunAfterLock.Enqueue(runAfterLocked);
LockDatabase(allowQuickUnlock);
}
private readonly Queue<Action> _actionsToRunAfterLock = new Queue<Action>();
/// <summary>
/// Do not call this directly, instead call LockDatabase
/// </summary>
internal void LockDatabaseInternal(Keepass2AndroidService service)
{
if (_db.Loaded)
{
if (QuickUnlockEnabled &&
_db.KpDatabase.MasterKey.ContainsType(typeof(KcpPassword)) &&
!((KcpPassword)App.Kp2a.GetDb().KpDatabase.MasterKey.GetUserKey(typeof(KcpPassword))).Password.IsEmpty)
{
if (!QuickLocked)
{
Kp2aLog.Log("QuickLocking database");
QuickLocked = true;
// Start the service to show the quicklock icon
var ctx = Application.Context;
ctx.StartService(new Intent(ctx, typeof(Keepass2AndroidService)));
}
else
{
Kp2aLog.Log("Database already QuickLocked");
}
}
else
{
Kp2aLog.Log("Locking database");
// Couldn't quick-lock, so unload database instead
_db.Clear();
QuickLocked = false;
}
}
else
{
Kp2aLog.Log("Database not loaded, couldn't lock");
}
while (_actionsToRunAfterLock.Count > 0)
{
var action = _actionsToRunAfterLock.Dequeue();
action();
}
}
public void LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, string password, string keyFile, ProgressDialogStatusLogger statusLogger)
{
_db.LoadData(this, ioConnectionInfo, memoryStream, password, keyFile, statusLogger);
var ctx = Application.Context;
ctx.StartService(new Intent(ctx, typeof(Keepass2AndroidService)));
}
public void UnlockDatabase(Action runAfterUnlocked)
{
_actionsToRunAfterUnlock.Enqueue(runAfterUnlocked);
Application.Context.SendBroadcast(new Intent(Intents.UnlockDatabase));
}
private readonly Queue<Action> _actionsToRunAfterUnlock = new Queue<Action>();
/// <summary>
/// Do not call this directly, instead call UnlockDatabase
/// </summary>
internal void UnlockDatabaseInternal(Keepass2AndroidService service)
{
QuickLocked = false;
while (_actionsToRunAfterUnlock.Count > 0)
{
var action = _actionsToRunAfterUnlock.Dequeue();
action();
}
}
public bool DatabaseIsUnlocked
{
get { return _db.Loaded && !QuickLocked; }
}
#region QuickUnlock
public void SetQuickUnlockEnabled(bool enabled)
{
if (enabled)
{
//Set KeyLength of QuickUnlock at time of enabling.
//This is important to not allow an attacker to set the length to 1 when QuickUnlock is started already.
var ctx = Application.Context;
var prefs = PreferenceManager.GetDefaultSharedPreferences(ctx);
QuickUnlockKeyLength = Math.Max(1, int.Parse(prefs.GetString(ctx.GetString(Resource.String.QuickUnlockLength_key), ctx.GetString(Resource.String.QuickUnlockLength_default))));
}
QuickUnlockEnabled = enabled;
}
public bool QuickUnlockEnabled { get; private set; }
public int QuickUnlockKeyLength { get; private set; }
/// <summary>
/// If true, the database must be regarded as locked and not exposed to the user.
/// </summary>
public bool QuickLocked { get; private set; }
#endregion
private Database _db;
private bool _shutdown;
/// <summary>
/// See comments to EntryEditActivityState.
@ -216,7 +332,7 @@ namespace keepass2android
public RealProgressDialog(Context ctx)
{
this._pd = new ProgressDialog(ctx);
_pd = new ProgressDialog(ctx);
}
public void SetTitle(string title)

View File

@ -24,6 +24,8 @@ namespace keepass2android
/// </summary>
public class Intents {
public const String Timeout = "keepass2android.timeout";
public const String LockDatabase = "keepass2android.lock_database";
public const String UnlockDatabase = "keepass2android.unlock_database";
public const String CopyUsername = "keepass2android.copy_username";
public const String CopyPassword = "keepass2android.copy_password";

View File

@ -86,6 +86,7 @@
<Compile Include="fileselect\FileSelectActivity.cs" />
<Compile Include="fileselect\FileDbHelper.cs" />
<Compile Include="search\SearchProvider.cs" />
<Compile Include="services\Keepass2AndroidService.cs" />
<Compile Include="Utils\Util.cs" />
<Compile Include="intents\Intents.cs" />
<Compile Include="fileselect\BrowserDialog.cs" />
@ -127,12 +128,10 @@
<Compile Include="compat\EditorCompat.cs" />
<Compile Include="compat\ActivityCompat.cs" />
<Compile Include="ShareUrlResults.cs" />
<Compile Include="services\TimeoutService.cs" />
<Compile Include="services\CopyToClipboardService.cs" />
<Compile Include="search\SearchActivity.cs" />
<Compile Include="QuickUnlock.cs" />
<Compile Include="LifecycleDebugActivity.cs" />
<Compile Include="services\QuickUnlockForegroundService.cs" />
<Compile Include="AssemblyInfo.cs" />
<Compile Include="views\FileSelectButtons.cs" />
<Compile Include="EntryEditActivityState.cs" />
@ -703,4 +702,25 @@
<SubType>Designer</SubType>
</AndroidResource>
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\ic_unlocked_gray.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-v11\ic_unlocked_gray.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-mdpi\ic_launcher_red.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\ic_launcher_red.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\ic_launcher_red.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\ic_launcher_red.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\ic_launcher_red.png" />
</ItemGroup>
</Project>

View File

@ -70,7 +70,7 @@ namespace keepass2android.search
public override Android.Database.ICursor Query(Android.Net.Uri uri, string[] projection, string selection, string[] selectionArgs, string sortOrder)
{
if (_db.Open) // Can't show suggestions if the database is locked!
if (App.Kp2a.DatabaseIsUnlocked) // Can't show suggestions if the database is locked!
{
switch ((UriMatches)UriMatcher.Match(uri))
{

View File

@ -56,11 +56,9 @@ namespace keepass2android.search
private void ProcessIntent(Intent intent)
{
_db = App.Kp2a.GetDb();
// Likely the app has been killed exit the activity
if ( ! _db.Open ) {
if (!App.Kp2a.DatabaseIsUnlocked)
{
Finish();
}

View File

@ -57,7 +57,7 @@ namespace keepass2android
CopyToClipboardBroadcastReceiver _copyToClipBroadcastReceiver;
NotificationDeletedBroadcastReceiver _notificationDeletedBroadcastReceiver;
StopOnLockBroadcastReceiver _stopOnLockBroadcastReceiver;
public CopyToClipboardService()
{
@ -74,6 +74,11 @@ namespace keepass2android
{
Kp2aLog.Log("Received intent to provide access to entry");
_stopOnLockBroadcastReceiver = new StopOnLockBroadcastReceiver(this);
IntentFilter filter = new IntentFilter();
filter.AddAction(Intents.LockDatabase);
RegisterReceiver(_stopOnLockBroadcastReceiver, filter);
String uuidBytes = intent.GetStringExtra(EntryActivity.KeyEntry);
bool closeAfterCreate = intent.GetBooleanExtra(EntryActivity.KeyCloseAfterCreate, false);
@ -99,12 +104,23 @@ namespace keepass2android
return StartCommandResult.RedeliverIntent;
}
private void OnLockDatabase()
{
Kp2aLog.Log("Stopping clipboard service due to database lock");
StopSelf();
}
private NotificationManager _notificationManager;
private int _numElementsToWaitFor;
public override void OnDestroy()
{
// These members might never get initialized if the app timed out
if (_stopOnLockBroadcastReceiver != null)
{
UnregisterReceiver(_stopOnLockBroadcastReceiver);
}
if (_copyToClipBroadcastReceiver != null)
{
UnregisterReceiver(_copyToClipBroadcastReceiver);
@ -358,7 +374,24 @@ namespace keepass2android
return notify;
}
private class StopOnLockBroadcastReceiver : BroadcastReceiver
{
readonly CopyToClipboardService _service;
public StopOnLockBroadcastReceiver(CopyToClipboardService service)
{
_service = service;
}
public override void OnReceive(Context context, Intent intent)
{
switch (intent.Action)
{
case Intents.LockDatabase:
_service.OnLockDatabase();
break;
}
}
}
class CopyToClipboardBroadcastReceiver: BroadcastReceiver
{
@ -429,7 +462,7 @@ namespace keepass2android
if (currentIme == kp2aIme)
{
imeManager.ToggleSoftInput(ShowFlags.Forced, HideSoftInputFlags.None);
imeManager.ToggleSoftInput(ShowSoftInputFlags.Forced, HideSoftInputFlags.None);
}
else
{

View File

@ -1,79 +0,0 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
using Android.App;
using Android.Content;
using Android.OS;
using Android.Support.V4.App;
using Android.Graphics;
namespace keepass2android
{
/// <summary>
/// This service is started as soon as a Database with QuickUnlock enabled is opened.
/// Its only purpose is to be a foreground service which prevents the App from being killed (in most situations)
/// </summary>
[Service]
public class QuickUnlockForegroundService : Service
{
public override IBinder OnBind(Intent intent)
{
return null;
}
const int QuickUnlockForegroundServiceId = 238787;
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
Kp2aLog.Log("Starting QuickUnlockForegroundService");
//create notification item
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.SetSmallIcon(Resource.Drawable.ic_launcher_gray)
.SetLargeIcon(BitmapFactory.DecodeResource(Resources, AppNames.LauncherIcon))
.SetContentTitle(GetText(Resource.String.app_name))
.SetContentText(GetText(Resource.String.database_loaded_quickunlock_enabled));
Intent startKp2aIntent = new Intent(this, typeof(KeePass));
startKp2aIntent.SetAction(Intent.ActionMain);
startKp2aIntent.AddCategory(Intent.CategoryLauncher);
PendingIntent startKp2APendingIntent =
PendingIntent.GetActivity(this, 0, startKp2aIntent, PendingIntentFlags.UpdateCurrent);
mBuilder.SetContentIntent(startKp2APendingIntent);
StartForeground(QuickUnlockForegroundServiceId , mBuilder.Build());
return StartCommandResult.NotSticky;
}
public override void OnCreate()
{
base.OnCreate();
Kp2aLog.Log("Creating QuickUnlockForegroundService");
}
public override void OnDestroy()
{
base.OnDestroy();
Kp2aLog.Log("Destroying QuickUnlockForegroundService");
}
}
}

View File

@ -1,129 +0,0 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Util;
namespace keepass2android
{
/// <summary>
/// Manages timeout to lock the database after some idle time
/// </summary>
[Service]
public class TimeoutService : Service {
private const String Tag = "KeePass2Android Timer";
private BroadcastReceiver _intentReceiver;
public TimeoutService (IntPtr javaReference, JniHandleOwnership transfer)
: base(javaReference, transfer)
{
_binder = new TimeoutBinder(this);
}
public TimeoutService()
{
_binder = new TimeoutBinder(this);
}
public override void OnCreate() {
base.OnCreate();
_intentReceiver = new MyBroadcastReceiver(this);
IntentFilter filter = new IntentFilter();
filter.AddAction(Intents.Timeout);
RegisterReceiver(_intentReceiver, filter);
}
public override void OnStart(Intent intent, int startId) {
base.OnStart(intent, startId);
Log.Debug(Tag, "Timeout service started");
}
private void Timeout() {
Log.Debug(Tag, "Timeout");
App.Kp2a.SetShutdown();
NotificationManager nm = (NotificationManager) GetSystemService(NotificationService);
nm.CancelAll();
StopService(new Intent(this, typeof(CopyToClipboardService)));
StopSelf();
}
public override void OnDestroy() {
base.OnDestroy();
Log.Debug(Tag, "Timeout service stopped");
UnregisterReceiver(_intentReceiver);
}
public class TimeoutBinder : Binder
{
readonly TimeoutService _service;
public TimeoutBinder(TimeoutService service)
{
_service = service;
}
public TimeoutService GetService() {
return _service;
}
}
private readonly IBinder _binder;
public override IBinder OnBind(Intent intent) {
return _binder;
}
[BroadcastReceiver]
public class MyBroadcastReceiver: BroadcastReceiver
{
public MyBroadcastReceiver()
{
//dummy constructor required for MonoForAndroid, not called.
throw new NotImplementedException();
}
readonly TimeoutService _timeoutService;
public MyBroadcastReceiver (TimeoutService timeoutService)
{
_timeoutService = timeoutService;
}
public override void OnReceive(Context context, Intent intent) {
String action = intent.Action;
if ( action.Equals(Intents.Timeout) ) {
_timeoutService.Timeout();
}
}
}
}
}

View File

@ -56,13 +56,12 @@ namespace keepass2android
}
};
Database db = App.Kp2a.GetDb();
if ( db.Open ) {
Preference rounds = FindPreference(GetString(Resource.String.rounds_key));
rounds.PreferenceChange += (sender, e) =>
if (App.Kp2a.DatabaseIsUnlocked)
{
setRounds(App.Kp2a.GetDb(), e.Preference);
};
Database db = App.Kp2a.GetDb();
Preference rounds = FindPreference(GetString(Resource.String.rounds_key));
rounds.PreferenceChange += (sender, e) => setRounds(db, e.Preference);
Preference defaultUser = FindPreference(GetString(Resource.String.default_username_key));
((EditTextPreference)defaultUser).EditText.Text = db.KpDatabase.DefaultUserName;

View File

@ -44,8 +44,6 @@ namespace keepass2android
public static void Start(Context ctx)
{
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(ctx);
String sTimeout = prefs.GetString(ctx.GetString(Resource.String.app_timeout_key), ctx.GetString(Resource.String.clipboard_timeout_default));
@ -61,8 +59,6 @@ namespace keepass2android
return;
}
ctx.StartService(new Intent(ctx, typeof(TimeoutService)));
long triggerTime = Java.Lang.JavaSystem.CurrentTimeMillis() + timeout;
AlarmManager am = (AlarmManager)ctx.GetSystemService(Context.AlarmService);
@ -76,69 +72,25 @@ namespace keepass2android
Kp2aLog.Log("Timeout cancel");
am.Cancel(BuildIntent(ctx));
ctx.StopService(new Intent(ctx, typeof(TimeoutService)));
}
}
public static void Pause(Activity act) {
// Record timeout time in case timeout service is killed
long time = Java.Lang.JavaSystem.CurrentTimeMillis();
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(act);
ISharedPreferencesEditor edit = prefs.Edit();
edit.PutLong(act.GetString(Resource.String.timeout_key), time);
Kp2aLog.Log("Pause: start at " + time);
EditorCompat.Apply(edit);
if ( App.Kp2a.GetDb().Open ) {
public static void Pause(Activity act)
{
if ( App.Kp2a.DatabaseIsUnlocked )
{
Timeout.Start(act);
}
}
public static void Resume(Activity act) {
if ( App.Kp2a.GetDb().Loaded ) {
public static void Resume(Activity act)
{
if ( App.Kp2a.GetDb().Loaded )
{
Timeout.Cancel(act);
}
// Check whether the timeout has expired
long curTime = Java.Lang.JavaSystem.CurrentTimeMillis();
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(act);
long timeoutStart = prefs.GetLong(act.GetString(Resource.String.timeout_key), -1);
Kp2aLog.Log("timeoutStart=" + timeoutStart);
// The timeout never started
if (timeoutStart == -1) {
return;
}
String sTimeout = prefs.GetString(act.GetString(Resource.String.app_timeout_key), act.GetString(Resource.String.clipboard_timeout_default));
long timeout;
if (!long.TryParse(sTimeout, out timeout) || (timeout == -1))
{
Kp2aLog.Log("exit with timeout=" + timeout + "/"+sTimeout);
// We are set to never timeout
return;
}
long diff = curTime - timeoutStart;
if (diff >= timeout)
{
// We have timed out
Kp2aLog.Log("Shutdown due to " + diff + ">=" + timeout);
App.Kp2a.SetShutdown();
}
else
{
Kp2aLog.Log("No shutdown due to " + diff + "<" + timeout);
}
}
static bool IocChanged(IOConnectionInfo ioc, IOConnectionInfo other)
@ -148,11 +100,10 @@ namespace keepass2android
}
public static bool CheckShutdown(Activity act, IOConnectionInfo ioc) {
if (( App.Kp2a.GetDb().Loaded && (App.Kp2a.IsShutdown() || App.Kp2a.GetDb().Locked) )
if (( !App.Kp2a.DatabaseIsUnlocked )
|| (IocChanged(ioc, App.Kp2a.GetDb().Ioc))) //file was changed from ActionSend-Intent
{
act.SetResult(KeePass.ExitLock);
act.Finish();
App.Kp2a.LockDatabase();
return true;
}
return false;