mirror of
https://github.com/moparisthebest/keepass2android
synced 2024-12-23 07:28:48 -05:00
refactoring regarding AppTasks:
- AppTasks are now returned by ActivityResult through all AppTask-Related activities (includes ForwardResult) - AppTasks are now passed correctly even when using search (this fixes a problem that AppTasks like SearchUrl were not passed to EntryActivity so the App didn't return to the browser automatically) - AppTasks are deleted by ActivityResult or by checking for LaunchedFromHistory Added option to leave app with db unlocked (this is even the default now!) Added missing EntryActivity files
This commit is contained in:
parent
f613206dab
commit
bcbc225652
60
src/Kp2aBusinessLogic/database/PwEntryOutput.cs
Normal file
60
src/Kp2aBusinessLogic/database/PwEntryOutput.cs
Normal file
@ -0,0 +1,60 @@
|
||||
using System;
|
||||
using KeePass.Util.Spr;
|
||||
using KeePassLib;
|
||||
using KeePassLib.Collections;
|
||||
using KeePassLib.Security;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the strings which are output from a PwEntry.
|
||||
/// </summary>
|
||||
/// In contrast to the original PwEntry, this means that placeholders are replaced. Also, plugins may modify
|
||||
/// or add fields.
|
||||
public class PwEntryOutput
|
||||
{
|
||||
private readonly PwEntry _entry;
|
||||
private readonly PwDatabase _db;
|
||||
private readonly ProtectedStringDictionary _outputStrings = new ProtectedStringDictionary();
|
||||
|
||||
/// <summary>
|
||||
/// Constructs the PwEntryOutput by replacing the placeholders
|
||||
/// </summary>
|
||||
public PwEntryOutput(PwEntry entry, PwDatabase db)
|
||||
{
|
||||
_entry = entry;
|
||||
_db = db;
|
||||
|
||||
foreach (var pair in entry.Strings)
|
||||
{
|
||||
_outputStrings.Set(pair.Key, new ProtectedString(entry.Strings.Get(pair.Key).IsProtected, GetStringAndReplacePlaceholders(pair.Key)));
|
||||
}
|
||||
}
|
||||
|
||||
string GetStringAndReplacePlaceholders(string key)
|
||||
{
|
||||
String value = Entry.Strings.ReadSafe(key);
|
||||
value = SprEngine.Compile(value, new SprContext(Entry, _db, SprCompileFlags.All));
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the ID of the entry
|
||||
/// </summary>
|
||||
public PwUuid Uuid
|
||||
{
|
||||
get { return Entry.Uuid; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The output strings for the represented entry
|
||||
/// </summary>
|
||||
public ProtectedStringDictionary OutputStrings { get { return _outputStrings; } }
|
||||
|
||||
public PwEntry Entry
|
||||
{
|
||||
get { return _entry; }
|
||||
}
|
||||
}
|
||||
}
|
34
src/Kp2aUnitTests/TestIntentsAndBundles.cs
Normal file
34
src/Kp2aUnitTests/TestIntentsAndBundles.cs
Normal file
@ -0,0 +1,34 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Java.IO;
|
||||
using KeePassLib;
|
||||
using KeePassLib.Interfaces;
|
||||
using KeePassLib.Keys;
|
||||
using KeePassLib.Serialization;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using keepass2android;
|
||||
|
||||
namespace Kp2aUnitTests
|
||||
{
|
||||
[TestClass]
|
||||
internal class TestIntentsAndBundles
|
||||
{
|
||||
[TestMethod]
|
||||
public void StringArray()
|
||||
{
|
||||
string[] dataIn = new string[] { "a","bcd"};
|
||||
Intent i= new Intent();
|
||||
i.PutExtra("key", dataIn);
|
||||
|
||||
Bundle extras = i.Extras;
|
||||
var dataOut = extras.GetStringArray("key");
|
||||
Assert.AreEqual(dataIn.Length, dataOut.Length);
|
||||
Assert.AreEqual(dataIn[0], dataOut[0]);
|
||||
Assert.AreEqual(dataIn[1], dataOut[1]);
|
||||
}
|
||||
}
|
||||
}
|
@ -38,7 +38,7 @@ namespace keepass2android
|
||||
ctx.GetString(Resource.String.ChangeLog)
|
||||
};
|
||||
|
||||
builder.SetPositiveButton(Android.Resource.String.Ok, (dlgSender, dlgEvt) => { });
|
||||
builder.SetPositiveButton(Android.Resource.String.Ok, (dlgSender, dlgEvt) => {((AlertDialog)dlgSender).Dismiss(); });
|
||||
builder.SetCancelable(false);
|
||||
|
||||
builder.SetMessage("temp");
|
||||
|
@ -52,16 +52,20 @@ namespace keepass2android
|
||||
public const String KeyRefreshPos = "refresh_pos";
|
||||
public const String KeyCloseAfterCreate = "close_after_create";
|
||||
|
||||
public static void Launch(Activity act, PwEntry pw, int pos, AppTask appTask)
|
||||
public static void Launch(Activity act, PwEntry pw, int pos, AppTask appTask, ActivityFlags? flags = null)
|
||||
{
|
||||
Intent i = new Intent(act, typeof(EntryActivity));
|
||||
|
||||
|
||||
i.PutExtra(KeyEntry, pw.Uuid.ToHexString());
|
||||
i.PutExtra(KeyRefreshPos, pos);
|
||||
|
||||
appTask.ToIntent(i);
|
||||
if (flags != null)
|
||||
i.SetFlags((ActivityFlags) flags);
|
||||
|
||||
appTask.ToIntent(i);
|
||||
if (flags != null && (((ActivityFlags) flags) | ActivityFlags.ForwardResult) == ActivityFlags.ForwardResult)
|
||||
act.StartActivity(i);
|
||||
else
|
||||
act.StartActivityForResult(i, 0);
|
||||
}
|
||||
|
||||
@ -93,6 +97,9 @@ namespace keepass2android
|
||||
private readonly Dictionary<string, IStringView> _stringViews = new Dictionary<string, IStringView>();
|
||||
private readonly List<PluginMenuOption> _pendingMenuOptions = new List<PluginMenuOption>();
|
||||
|
||||
//make sure _timer doesn't go out of scope:
|
||||
private Timer _timer;
|
||||
|
||||
|
||||
protected void SetEntryView()
|
||||
{
|
||||
@ -298,6 +305,7 @@ namespace keepass2android
|
||||
!prefs.GetBoolean(GetString(Resource.String.maskpass_key), Resources.GetBoolean(Resource.Boolean.maskpass_default));
|
||||
|
||||
base.OnCreate(savedInstanceState);
|
||||
RequestWindowFeature(WindowFeatures.IndeterminateProgress);
|
||||
|
||||
new ActivityDesign(this).ApplyTheme();
|
||||
|
||||
@ -342,15 +350,15 @@ namespace keepass2android
|
||||
|
||||
SetupEditButtons();
|
||||
|
||||
//depending on the app task, the final things to do might be delayed, so let the appTask call CompleteOnCreate when appropriate
|
||||
_appTask.OnCompleteCreateEntryActivity(this);
|
||||
|
||||
App.Kp2a.GetDb().LastOpenedEntry = new PwEntryOutput(Entry, App.Kp2a.GetDb().KpDatabase);
|
||||
|
||||
RegisterReceiver(new PluginActionReceiver(this), new IntentFilter(Strings.ActionAddEntryAction));
|
||||
RegisterReceiver(new PluginFieldReceiver(this), new IntentFilter(Strings.ActionSetEntryField));
|
||||
|
||||
new Thread(NotifyPluginsOnOpen).Start();
|
||||
|
||||
//the rest of the things to do depends on the current app task:
|
||||
_appTask.CompleteOnCreateEntryActivity(this);
|
||||
}
|
||||
|
||||
private void NotifyPluginsOnOpen()
|
||||
@ -381,29 +389,17 @@ namespace keepass2android
|
||||
}
|
||||
}
|
||||
|
||||
public void CompleteOnCreate()
|
||||
{
|
||||
|
||||
Intent showNotIntent = new Intent(this, typeof(CopyToClipboardService));
|
||||
|
||||
internal void StartNotificationsService(bool closeAfterCreate)
|
||||
{
|
||||
Intent showNotIntent = new Intent(this, typeof (CopyToClipboardService));
|
||||
showNotIntent.SetAction(Intents.ShowNotification);
|
||||
showNotIntent.PutExtra(KeyEntry, Entry.Uuid.ToHexString());
|
||||
bool closeAfterCreate = _appTask.CloseEntryActivityAfterCreate;
|
||||
|
||||
showNotIntent.PutExtra(KeyCloseAfterCreate, closeAfterCreate);
|
||||
|
||||
StartService(showNotIntent);
|
||||
|
||||
Kp2aLog.Log("Requesting copy to clipboard for Uuid=" + Entry.Uuid.ToHexString());
|
||||
|
||||
/*foreach (PwUuid key in App.Kp2a.GetDb().entries.Keys)
|
||||
{
|
||||
Kp2aLog.Log(this,key.ToHexString() + " -> " + App.Kp2a.GetDb().entries[key].Uuid.ToHexString());
|
||||
}*/
|
||||
|
||||
if (closeAfterCreate)
|
||||
{
|
||||
SetResult(KeePass.ExitCloseAfterTaskComplete);
|
||||
Finish();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -805,12 +801,24 @@ namespace keepass2android
|
||||
{
|
||||
Intent ret = new Intent();
|
||||
ret.PutExtra(KeyRefreshPos, _pos);
|
||||
|
||||
_appTask.ToIntent(ret);
|
||||
SetResult(KeePass.ExitRefresh, ret);
|
||||
}
|
||||
|
||||
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) {
|
||||
base.OnActivityResult(requestCode, resultCode, data);
|
||||
if (AppTask.TryGetFromActivityResult(data, ref _appTask))
|
||||
{
|
||||
//make sure app task is passed to calling activity.
|
||||
//the result code might be modified later.
|
||||
Intent retData = new Intent();
|
||||
_appTask.ToIntent(retData);
|
||||
SetResult(KeePass.ExitNormal, retData);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if ( resultCode == KeePass.ExitRefresh || resultCode == KeePass.ExitRefreshTitle ) {
|
||||
if ( resultCode == KeePass.ExitRefreshTitle ) {
|
||||
RequiresRefresh ();
|
||||
@ -1019,33 +1027,8 @@ namespace keepass2android
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// brings up a dialog asking the user whether he wants to add the given URL to the entry for automatic finding
|
||||
/// </summary>
|
||||
public void AskAddUrlThenCompleteCreate(string url)
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.SetTitle(GetString(Resource.String.AddUrlToEntryDialog_title));
|
||||
|
||||
builder.SetMessage(GetString(Resource.String.AddUrlToEntryDialog_text, new Java.Lang.Object[] {url}));
|
||||
|
||||
builder.SetPositiveButton(GetString(Resource.String.yes), (dlgSender, dlgEvt) =>
|
||||
{
|
||||
|
||||
AddUrlToEntryThenCompleteCreate(url);
|
||||
|
||||
});
|
||||
|
||||
builder.SetNegativeButton(GetString(Resource.String.no), (dlgSender, dlgEvt) =>
|
||||
{
|
||||
CompleteOnCreate();
|
||||
});
|
||||
|
||||
Dialog dialog = builder.Create();
|
||||
dialog.Show();
|
||||
|
||||
}
|
||||
private void AddUrlToEntryThenCompleteCreate(string url)
|
||||
internal void AddUrlToEntry(string url, Action finishAction)
|
||||
{
|
||||
PwEntry initialEntry = Entry.CloneDeep();
|
||||
|
||||
@ -1076,7 +1059,7 @@ namespace keepass2android
|
||||
ActionOnFinish closeOrShowError = new ActionOnFinish((success, message) =>
|
||||
{
|
||||
OnFinish.DisplayMessage(this, message);
|
||||
CompleteOnCreate();
|
||||
finishAction();
|
||||
});
|
||||
|
||||
|
||||
@ -1120,5 +1103,27 @@ namespace keepass2android
|
||||
{
|
||||
PluginHost.AddEntryToIntent(intent, App.Kp2a.GetDb().LastOpenedEntry);
|
||||
}
|
||||
|
||||
public void CloseAfterTaskComplete()
|
||||
{
|
||||
//before closing, wait a little to get plugin updates
|
||||
int numPlugins = new PluginDatabase(this).GetPluginsWithAcceptedScope(Strings.ScopeCurrentEntry).Count();
|
||||
var timeToWait = TimeSpan.FromMilliseconds(500*numPlugins);
|
||||
SetProgressBarIndeterminateVisibility(true);
|
||||
_timer = new Timer(obj =>
|
||||
{
|
||||
RunOnUiThread(() =>
|
||||
{
|
||||
//task is completed -> return NullTask
|
||||
Intent resIntent = new Intent();
|
||||
new NullTask().ToIntent(resIntent);
|
||||
SetResult(KeePass.ExitCloseAfterTaskComplete, resIntent);
|
||||
//close activity:
|
||||
Finish();
|
||||
}
|
||||
);
|
||||
},
|
||||
null, timeToWait, TimeSpan.FromMilliseconds(-1));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
using Android.Content;
|
||||
using Android.Graphics.Drawables;
|
||||
using PluginHostTest;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
/// <summary>
|
||||
/// Reperesents the popup menu item in EntryActivity to copy a string to clipboard
|
||||
/// </summary>
|
||||
class CopyToClipboardPopupMenuIcon : IPopupMenuItem
|
||||
{
|
||||
private readonly Context _context;
|
||||
private readonly IStringView _stringView;
|
||||
|
||||
public CopyToClipboardPopupMenuIcon(Context context, IStringView stringView)
|
||||
{
|
||||
_context = context;
|
||||
_stringView = stringView;
|
||||
|
||||
}
|
||||
|
||||
public Drawable Icon
|
||||
{
|
||||
get
|
||||
{
|
||||
return _context.Resources.GetDrawable(Resource.Drawable.ic_menu_copy_holo_light);
|
||||
}
|
||||
}
|
||||
public string Text
|
||||
{
|
||||
//TODO localize
|
||||
get { return "Copy to clipboard"; }
|
||||
}
|
||||
|
||||
|
||||
public void HandleClick()
|
||||
{
|
||||
CopyToClipboardService.CopyValueToClipboardWithTimeout(_context, _stringView.Text);
|
||||
}
|
||||
}
|
||||
}
|
44
src/keepass2android/EntryActivityClasses/ExtraStringView.cs
Normal file
44
src/keepass2android/EntryActivityClasses/ExtraStringView.cs
Normal file
@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
internal class ExtraStringView : IStringView
|
||||
{
|
||||
private readonly View _container;
|
||||
private readonly TextView _valueView;
|
||||
private readonly TextView _keyView;
|
||||
|
||||
public ExtraStringView(LinearLayout container, TextView valueView, TextView keyView)
|
||||
{
|
||||
_container = container;
|
||||
_valueView = valueView;
|
||||
_keyView = keyView;
|
||||
}
|
||||
|
||||
public View View
|
||||
{
|
||||
get { return _container; }
|
||||
}
|
||||
|
||||
public string Text
|
||||
{
|
||||
get { return _valueView.Text; }
|
||||
set
|
||||
{
|
||||
if (String.IsNullOrEmpty(value))
|
||||
{
|
||||
_valueView.Visibility = ViewStates.Gone;
|
||||
_keyView.Visibility = ViewStates.Gone;
|
||||
}
|
||||
else
|
||||
{
|
||||
_valueView.Visibility = ViewStates.Visible;
|
||||
_keyView.Visibility = ViewStates.Visible;
|
||||
_valueView.Text = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
33
src/keepass2android/EntryActivityClasses/GotoUrlMenuItem.cs
Normal file
33
src/keepass2android/EntryActivityClasses/GotoUrlMenuItem.cs
Normal file
@ -0,0 +1,33 @@
|
||||
using Android.Graphics.Drawables;
|
||||
using PluginHostTest;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
/// <summary>
|
||||
/// Reperesents the popup menu item in EntryActivity to go to the URL in the field
|
||||
/// </summary>
|
||||
class GotoUrlMenuItem : IPopupMenuItem
|
||||
{
|
||||
private readonly EntryActivity _ctx;
|
||||
|
||||
public GotoUrlMenuItem(EntryActivity ctx)
|
||||
{
|
||||
_ctx = ctx;
|
||||
}
|
||||
|
||||
public Drawable Icon
|
||||
{
|
||||
get { return _ctx.Resources.GetDrawable(Android.Resource.Drawable.IcMenuUpload); }
|
||||
}
|
||||
|
||||
public string Text
|
||||
{
|
||||
get { return _ctx.Resources.GetString(Resource.String.menu_url); }
|
||||
}
|
||||
|
||||
public void HandleClick()
|
||||
{
|
||||
_ctx.GotoUrl();
|
||||
}
|
||||
}
|
||||
}
|
17
src/keepass2android/EntryActivityClasses/IPopupMenuItem.cs
Normal file
17
src/keepass2android/EntryActivityClasses/IPopupMenuItem.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using Android.Graphics.Drawables;
|
||||
using KeePassLib;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface for popup menu items in EntryActivity
|
||||
/// </summary>
|
||||
internal interface IPopupMenuItem
|
||||
{
|
||||
Drawable Icon { get; }
|
||||
String Text { get; }
|
||||
|
||||
void HandleClick();
|
||||
}
|
||||
}
|
7
src/keepass2android/EntryActivityClasses/IStringView.cs
Normal file
7
src/keepass2android/EntryActivityClasses/IStringView.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace keepass2android
|
||||
{
|
||||
internal interface IStringView
|
||||
{
|
||||
string Text { set; get; }
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
using Android.Graphics.Drawables;
|
||||
using PluginHostTest;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the popup menu item in EntryActivity to open the associated attachment
|
||||
/// </summary>
|
||||
internal class OpenBinaryPopupItem : IPopupMenuItem
|
||||
{
|
||||
private readonly string _key;
|
||||
private readonly EntryActivity _entryActivity;
|
||||
|
||||
public OpenBinaryPopupItem(string key, EntryActivity entryActivity)
|
||||
{
|
||||
_key = key;
|
||||
_entryActivity = entryActivity;
|
||||
}
|
||||
|
||||
public Drawable Icon
|
||||
{
|
||||
get { return _entryActivity.Resources.GetDrawable(Android.Resource.Drawable.IcMenuShare); }
|
||||
}
|
||||
|
||||
public string Text
|
||||
{
|
||||
get { return _entryActivity.Resources.GetString(Resource.String.SaveAttachmentDialog_open); }
|
||||
}
|
||||
|
||||
public void HandleClick()
|
||||
{
|
||||
Android.Net.Uri newUri = _entryActivity.WriteBinaryToFile(_key, true);
|
||||
if (newUri != null)
|
||||
{
|
||||
_entryActivity.OpenBinaryFile(newUri);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
14
src/keepass2android/EntryActivityClasses/PluginMenuOption.cs
Normal file
14
src/keepass2android/EntryActivityClasses/PluginMenuOption.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using Android.Content;
|
||||
using Android.Graphics.Drawables;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
class PluginMenuOption
|
||||
{
|
||||
public string DisplayText { get; set; }
|
||||
|
||||
public Drawable Icon { get; set; }
|
||||
|
||||
public Intent Intent { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
using Android.Content;
|
||||
using Android.Graphics.Drawables;
|
||||
using Android.OS;
|
||||
using Keepass2android.Pluginsdk;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a popup menu item in EntryActivity which was added by a plugin. The click will therefore broadcast to the plugin.
|
||||
/// </summary>
|
||||
class PluginPopupMenuItem : IPopupMenuItem
|
||||
{
|
||||
private readonly EntryActivity _activity;
|
||||
private readonly string _pluginPackage;
|
||||
private readonly string _fieldId;
|
||||
private readonly string _popupItemId;
|
||||
private readonly string _displayText;
|
||||
private readonly int _iconId;
|
||||
private readonly Bundle _bundleExtra;
|
||||
|
||||
public PluginPopupMenuItem(EntryActivity activity, string pluginPackage, string fieldId, string popupItemId, string displayText, int iconId, Bundle bundleExtra)
|
||||
{
|
||||
_activity = activity;
|
||||
_pluginPackage = pluginPackage;
|
||||
_fieldId = fieldId;
|
||||
_popupItemId = popupItemId;
|
||||
_displayText = displayText;
|
||||
_iconId = iconId;
|
||||
_bundleExtra = bundleExtra;
|
||||
}
|
||||
|
||||
public Drawable Icon
|
||||
{
|
||||
get { return _activity.PackageManager.GetResourcesForApplication(_pluginPackage).GetDrawable(_iconId); }
|
||||
}
|
||||
public string Text
|
||||
{
|
||||
get { return _displayText; }
|
||||
}
|
||||
|
||||
public string PopupItemId
|
||||
{
|
||||
get { return _popupItemId; }
|
||||
}
|
||||
|
||||
public void HandleClick()
|
||||
{
|
||||
Intent i = new Intent(Strings.ActionEntryActionSelected);
|
||||
i.SetPackage(_pluginPackage);
|
||||
i.PutExtra(Strings.ExtraActionData, _bundleExtra);
|
||||
i.PutExtra(Strings.ExtraFieldId, _fieldId);
|
||||
i.PutExtra(Strings.ExtraSender, _activity.PackageName);
|
||||
|
||||
_activity.AddEntryToIntent(i);
|
||||
|
||||
_activity.SendBroadcast(i);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using Android.App;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
internal class StandardStringView : IStringView
|
||||
{
|
||||
private readonly int _viewId;
|
||||
private readonly int _containerViewId;
|
||||
private readonly Activity _activity;
|
||||
|
||||
public StandardStringView(int viewId, int containerViewId, Activity activity)
|
||||
{
|
||||
_viewId = viewId;
|
||||
_containerViewId = containerViewId;
|
||||
_activity = activity;
|
||||
}
|
||||
|
||||
public string Text
|
||||
{
|
||||
set
|
||||
{
|
||||
View container = _activity.FindViewById(_containerViewId);
|
||||
TextView tv = (TextView) _activity.FindViewById(_viewId);
|
||||
if (String.IsNullOrEmpty(value))
|
||||
{
|
||||
container.Visibility = tv.Visibility = ViewStates.Gone;
|
||||
}
|
||||
else
|
||||
{
|
||||
container.Visibility = tv.Visibility = ViewStates.Visible;
|
||||
tv.Text = value;
|
||||
}
|
||||
}
|
||||
get
|
||||
{
|
||||
TextView tv = (TextView) _activity.FindViewById(_viewId);
|
||||
return tv.Text;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
using Android.Graphics.Drawables;
|
||||
using PluginHostTest;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
/// <summary>
|
||||
/// Reperesents the popup menu item in EntryActivity to toggle visibility of all protected strings (e.g. Password)
|
||||
/// </summary>
|
||||
class ToggleVisibilityPopupMenuItem : IPopupMenuItem
|
||||
{
|
||||
private readonly EntryActivity _activity;
|
||||
|
||||
|
||||
public ToggleVisibilityPopupMenuItem(EntryActivity activity)
|
||||
{
|
||||
_activity = activity;
|
||||
|
||||
}
|
||||
|
||||
public Drawable Icon
|
||||
{
|
||||
get
|
||||
{
|
||||
//return new TextDrawable("\uF06E", _activity);
|
||||
return _activity.Resources.GetDrawable(Resource.Drawable.ic_action_eye_open);
|
||||
|
||||
}
|
||||
}
|
||||
public string Text
|
||||
{
|
||||
get
|
||||
{
|
||||
return _activity.Resources.GetString(
|
||||
_activity._showPassword ?
|
||||
Resource.String.menu_hide_password
|
||||
: Resource.String.show_password);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void HandleClick()
|
||||
{
|
||||
_activity.ToggleVisibility();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
using Android.Graphics.Drawables;
|
||||
using PluginHostTest;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the popup menu item in EntryActivity to store the binary attachment on SD card
|
||||
/// </summary>
|
||||
internal class WriteBinaryToFilePopupItem : IPopupMenuItem
|
||||
{
|
||||
private readonly string _key;
|
||||
private readonly EntryActivity _activity;
|
||||
|
||||
public WriteBinaryToFilePopupItem(string key, EntryActivity activity)
|
||||
{
|
||||
_key = key;
|
||||
_activity = activity;
|
||||
}
|
||||
|
||||
public Drawable Icon
|
||||
{
|
||||
get { return _activity.Resources.GetDrawable(Android.Resource.Drawable.IcMenuSave); }
|
||||
}
|
||||
|
||||
public string Text
|
||||
{
|
||||
get { return _activity.Resources.GetString(Resource.String.SaveAttachmentDialog_save); }
|
||||
}
|
||||
|
||||
public void HandleClick()
|
||||
{
|
||||
_activity.WriteBinaryToFile(_key, false);
|
||||
}
|
||||
}
|
||||
}
|
@ -601,7 +601,7 @@ namespace keepass2android
|
||||
Intent intent = Intent;
|
||||
intent.PutExtra(IntentContinueWithEditing, true);
|
||||
OverridePendingTransition(0, 0);
|
||||
intent.AddFlags(ActivityFlags.NoAnimation);
|
||||
intent.AddFlags(ActivityFlags.NoAnimation | ActivityFlags.ForwardResult);
|
||||
_closeForReload = true;
|
||||
SetResult(KeePass.ExitRefreshTitle); //probably the entry will be modified -> let the EditActivity refresh to be safe
|
||||
Finish();
|
||||
|
@ -70,7 +70,11 @@ namespace keepass2android
|
||||
{
|
||||
base.OnActivityResult(requestCode, resultCode, data);
|
||||
|
||||
AppTask.TryGetFromActivityResult(data, ref AppTask);
|
||||
if (AppTask.TryGetFromActivityResult(data, ref AppTask))
|
||||
{
|
||||
//make sure the app task is passed to the calling activity
|
||||
AppTask.SetActivityResult(this, KeePass.ExitNormal);
|
||||
}
|
||||
|
||||
if (resultCode == Result.Ok)
|
||||
{
|
||||
@ -236,17 +240,24 @@ namespace keepass2android
|
||||
class SuggestionListener: Java.Lang.Object, SearchView.IOnSuggestionListener
|
||||
{
|
||||
private readonly CursorAdapter _suggestionsAdapter;
|
||||
private readonly GroupBaseActivity _activity;
|
||||
private readonly IMenuItem _searchItem;
|
||||
|
||||
public SuggestionListener(CursorAdapter suggestionsAdapter)
|
||||
|
||||
public SuggestionListener(CursorAdapter suggestionsAdapter, GroupBaseActivity activity, IMenuItem searchItem)
|
||||
{
|
||||
_suggestionsAdapter = suggestionsAdapter;
|
||||
_activity = activity;
|
||||
_searchItem = searchItem;
|
||||
}
|
||||
|
||||
public bool OnSuggestionClick(int position)
|
||||
{
|
||||
var cursor = _suggestionsAdapter.Cursor;
|
||||
cursor.MoveToPosition(position);
|
||||
var x = cursor.GetString(cursor.GetColumnIndexOrThrow(SearchManager.SuggestColumnIntentDataId));
|
||||
string entryIdAsHexString = cursor.GetString(cursor.GetColumnIndexOrThrow(SearchManager.SuggestColumnIntentDataId));
|
||||
EntryActivity.Launch(_activity, App.Kp2a.GetDb().Entries[new PwUuid(MemUtil.HexStringToByteArray(entryIdAsHexString))],-1,_activity.AppTask);
|
||||
((SearchView) _searchItem.ActionView).Iconified = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -256,6 +267,37 @@ namespace keepass2android
|
||||
}
|
||||
}
|
||||
|
||||
class OnQueryTextListener: Java.Lang.Object, SearchView.IOnQueryTextListener
|
||||
{
|
||||
private readonly GroupBaseActivity _activity;
|
||||
|
||||
public OnQueryTextListener(GroupBaseActivity activity)
|
||||
{
|
||||
_activity = activity;
|
||||
}
|
||||
|
||||
public bool OnQueryTextChange(string newText)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool OnQueryTextSubmit(string query)
|
||||
{
|
||||
if (String.IsNullOrEmpty(query))
|
||||
return false; //let the default happen
|
||||
|
||||
Intent searchIntent = new Intent(_activity, typeof(search.SearchResults));
|
||||
searchIntent.SetAction(Intent.ActionSearch); //currently not necessary to set because SearchResults doesn't care, but let's be as close to the default as possible
|
||||
searchIntent.PutExtra(SearchManager.Query, query);
|
||||
//forward appTask:
|
||||
_activity.AppTask.ToIntent(searchIntent);
|
||||
|
||||
_activity.StartActivityForResult(searchIntent, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnCreateOptionsMenu(IMenu menu) {
|
||||
base.OnCreateOptionsMenu(menu);
|
||||
|
||||
@ -263,11 +305,13 @@ namespace keepass2android
|
||||
inflater.Inflate(Resource.Menu.group, menu);
|
||||
if (Util.HasActionBar(this))
|
||||
{
|
||||
var searchManager = (SearchManager) GetSystemService(Context.SearchService);
|
||||
var searchView = (SearchView) menu.FindItem(Resource.Id.menu_search).ActionView;
|
||||
var searchManager = (SearchManager) GetSystemService(SearchService);
|
||||
IMenuItem searchItem = menu.FindItem(Resource.Id.menu_search);
|
||||
var searchView = (SearchView) searchItem.ActionView;
|
||||
|
||||
searchView.SetSearchableInfo(searchManager.GetSearchableInfo(ComponentName));
|
||||
searchView.SetOnSuggestionListener(new SuggestionListener(searchView.SuggestionsAdapter));
|
||||
searchView.SetOnSuggestionListener(new SuggestionListener(searchView.SuggestionsAdapter, this, searchItem));
|
||||
searchView.SetOnQueryTextListener(new OnQueryTextListener(this));
|
||||
}
|
||||
var item = menu.FindItem(Resource.Id.menu_sync);
|
||||
if (item != null)
|
||||
|
@ -46,6 +46,7 @@ using String = System.String;
|
||||
* (AdvancedSearch Menu) -> Search -> SearchResults -> EntryView -> EntryEdit
|
||||
* (SearchWidget) -> SearchResults -> EntryView -> EntryEdit
|
||||
* Password -> ShareUrlResults -> EntryView
|
||||
* FileSelect -> Group (after Create DB)
|
||||
*
|
||||
*
|
||||
* In each of these activities, an AppTask may be present and must be passed to started activities and ActivityResults
|
||||
@ -84,11 +85,23 @@ namespace keepass2android
|
||||
AppTask _appTask;
|
||||
private ActivityDesign _design;
|
||||
|
||||
protected override void OnCreate (Bundle bundle)
|
||||
protected override void OnCreate(Bundle savedInstanceState)
|
||||
{
|
||||
base.OnCreate (bundle);
|
||||
base.OnCreate(savedInstanceState);
|
||||
_design.ApplyTheme();
|
||||
_appTask = AppTask.GetTaskInOnCreate(bundle, Intent);
|
||||
//see comment to this in PasswordActivity.
|
||||
//Note that this activity is affected even though it's finished when the app is closed because it
|
||||
//seems that the "app launch intent" is re-delivered, so this might end up here.
|
||||
if ((_appTask == null) && (Intent.Flags.HasFlag(ActivityFlags.LaunchedFromHistory)))
|
||||
{
|
||||
_appTask = new NullTask();
|
||||
}
|
||||
else
|
||||
{
|
||||
_appTask = AppTask.GetTaskInOnCreate(savedInstanceState, Intent);
|
||||
}
|
||||
|
||||
|
||||
Kp2aLog.Log("KeePass.OnCreate");
|
||||
}
|
||||
|
||||
@ -274,9 +287,8 @@ namespace keepass2android
|
||||
|
||||
Intent intent = new Intent(this, typeof(FileSelectActivity));
|
||||
_appTask.ToIntent(intent);
|
||||
|
||||
|
||||
StartActivityForResult(intent, 0);
|
||||
intent.AddFlags(ActivityFlags.ForwardResult);
|
||||
StartActivity(intent);
|
||||
Finish();
|
||||
|
||||
}
|
||||
@ -288,11 +300,6 @@ namespace keepass2android
|
||||
}
|
||||
|
||||
|
||||
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) {
|
||||
base.OnActivityResult(requestCode, resultCode, data);
|
||||
|
||||
Finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -179,11 +179,11 @@ namespace keepass2android
|
||||
Intent i = new Intent(act, typeof(PasswordActivity));
|
||||
|
||||
PutIoConnectionToIntent(ioc, i);
|
||||
i.SetFlags(ActivityFlags.ClearTask);
|
||||
i.SetFlags(ActivityFlags.ClearTask | ActivityFlags.ForwardResult);
|
||||
|
||||
appTask.ToIntent(i);
|
||||
|
||||
act.StartActivityForResult(i, 0);
|
||||
act.StartActivity(i);
|
||||
|
||||
}
|
||||
|
||||
@ -198,11 +198,21 @@ namespace keepass2android
|
||||
|
||||
Kp2aLog.Log("PasswordActivity.OnActivityResult "+resultCode+"/"+requestCode);
|
||||
|
||||
AppTask.TryGetFromActivityResult(data, ref AppTask);
|
||||
|
||||
//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: // Returned to this screen using the Back key, treat as locking the database
|
||||
case KeePass.ExitNormal: // Returned to this screen using the Back key
|
||||
if (PreferenceManager.GetDefaultSharedPreferences(this)
|
||||
.GetBoolean(GetString(Resource.String.LockWhenNavigateBack_key), false))
|
||||
{
|
||||
App.Kp2a.LockDatabase();
|
||||
}
|
||||
//by leaving the app with the back button, the user probably wants to cancel the task
|
||||
//The activity might be resumed (through Android's recent tasks list), then use a NullTask:
|
||||
AppTask = new NullTask();
|
||||
Finish();
|
||||
break;
|
||||
case KeePass.ExitLock:
|
||||
// The database has already been locked, and the quick unlock screen will be shown if appropriate
|
||||
@ -266,6 +276,7 @@ namespace keepass2android
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void LoadOtpFile()
|
||||
{
|
||||
new LoadingDialog<object, object, object>(this, true,
|
||||
@ -340,7 +351,19 @@ namespace keepass2android
|
||||
|
||||
Intent i = Intent;
|
||||
|
||||
//only load the AppTask if this is the "first" OnCreate (not because of kill/resume, i.e. savedInstanceState==null)
|
||||
// and if the activity is not launched from history (i.e. recent tasks) because this would mean that
|
||||
// the Activity was closed already (user cancelling the task or task complete) but is restarted due recent tasks.
|
||||
// Don't re-start the task (especially bad if tak was complete already)
|
||||
if ((savedInstanceState == null) && (Intent.Flags.HasFlag(ActivityFlags.LaunchedFromHistory)))
|
||||
{
|
||||
AppTask = new NullTask();
|
||||
}
|
||||
else
|
||||
{
|
||||
AppTask = AppTask.GetTaskInOnCreate(savedInstanceState, Intent);
|
||||
}
|
||||
|
||||
|
||||
String action = i.Action;
|
||||
|
||||
@ -470,7 +493,6 @@ namespace keepass2android
|
||||
|
||||
Toast.MakeText(this, GetString(Resource.String.otp_discarded_because_no_db), ToastLength.Long).Show();
|
||||
GoToFileSelectActivity();
|
||||
Finish();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1096,7 +1118,8 @@ namespace keepass2android
|
||||
Intent intent = new Intent(this, typeof (FileSelectActivity));
|
||||
intent.PutExtra(FileSelectActivity.NoForwardToPasswordActivity, true);
|
||||
AppTask.ToIntent(intent);
|
||||
StartActivityForResult(intent, 0);
|
||||
intent.AddFlags(ActivityFlags.ForwardResult);
|
||||
StartActivity(intent);
|
||||
Finish();
|
||||
}
|
||||
|
||||
|
1921
src/keepass2android/Resources/Resource.designer.cs
generated
1921
src/keepass2android/Resources/Resource.designer.cs
generated
File diff suppressed because it is too large
Load Diff
Binary file not shown.
After Width: | Height: | Size: 199 B |
@ -90,6 +90,8 @@
|
||||
|
||||
<string name="UseFileTransactions_key">UseFileTransactions</string>
|
||||
<string name="LockWhenScreenOff_key">LockWhenScreenOff</string>
|
||||
<string name="LockWhenNavigateBack_key">LockWhenNavigateBack</string>
|
||||
|
||||
<string name="UseOfflineCache_key">UseOfflineCache</string>
|
||||
<string name="AcceptAllServerCertificates_key">AcceptAllServerCertificates</string>
|
||||
<string name="CheckForFileChangesOnSave_key">CheckForFileChangesOnSave</string>
|
||||
|
@ -251,6 +251,11 @@
|
||||
<string name="UseFileTransactions_summary">Use file transactions for writing databases</string>
|
||||
<string name="LockWhenScreenOff_title">Lock when screen off</string>
|
||||
<string name="LockWhenScreenOff_summary">Lock the database when screen is switched off.</string>
|
||||
|
||||
<string name="LockWhenNavigateBack_title">Lock when leaving app</string>
|
||||
<string name="LockWhenNavigateBack_summary">Lock the database when leaving the app by pressing the back button.</string>
|
||||
|
||||
|
||||
<string name="UseOfflineCache_title">Database caching</string>
|
||||
<string name="UseOfflineCache_summary">Keep a copy of remote database files in the application cache directory. This allows to use remote databases even when offline.</string>
|
||||
|
||||
|
@ -88,6 +88,14 @@
|
||||
android:title="@string/LockWhenScreenOff_title"
|
||||
android:key="@string/LockWhenScreenOff_key" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:enabled="true"
|
||||
android:persistent="true"
|
||||
android:summary="@string/LockWhenNavigateBack_summary"
|
||||
android:defaultValue="false"
|
||||
android:title="@string/LockWhenNavigateBack_title"
|
||||
android:key="@string/LockWhenNavigateBack_key" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:key="@string/RememberRecentFiles_key"
|
||||
android:title="@string/RememberRecentFiles_title"
|
||||
|
29
src/keepass2android/Resources/xml/searchable_debug.xml
Normal file
29
src/keepass2android/Resources/xml/searchable_debug.xml
Normal file
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
|
||||
|
||||
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/>.
|
||||
-->
|
||||
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:label="@string/search_label"
|
||||
android:hint="@string/search_hint"
|
||||
android:searchMode="showSearchLabelAsBadge"
|
||||
android:searchSuggestAuthority="keepass2android.keepass2android_debug.SearchProvider"
|
||||
android:searchSuggestSelection=" ?"
|
||||
android:searchSuggestThreshold="2"
|
||||
android:searchSuggestIntentAction="android.intent.action.VIEW"
|
||||
android:searchSuggestIntentData="content://keepass2android.EntryActivity"
|
||||
/>
|
@ -105,11 +105,6 @@ namespace keepass2android
|
||||
{
|
||||
}
|
||||
|
||||
public virtual bool CloseEntryActivityAfterCreate
|
||||
{
|
||||
get { return false;}
|
||||
}
|
||||
|
||||
|
||||
public virtual void PrepareNewEntry(PwEntry newEntry)
|
||||
{
|
||||
@ -233,7 +228,10 @@ namespace keepass2android
|
||||
public static bool TryGetFromActivityResult(Intent data, ref AppTask task)
|
||||
{
|
||||
if (data == null)
|
||||
{
|
||||
Kp2aLog.Log("TryGetFromActivityResult: no data");
|
||||
return false;
|
||||
}
|
||||
AppTask tempTask = CreateFromBundle(data.Extras, null);
|
||||
if (tempTask == null)
|
||||
{
|
||||
@ -253,9 +251,9 @@ namespace keepass2android
|
||||
|
||||
}
|
||||
|
||||
public virtual void OnCompleteCreateEntryActivity(EntryActivity entryActivity)
|
||||
public virtual void CompleteOnCreateEntryActivity(EntryActivity activity)
|
||||
{
|
||||
entryActivity.CompleteOnCreate();
|
||||
activity.StartNotificationsService(false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -310,10 +308,14 @@ namespace keepass2android
|
||||
//act.AppTask = new NullTask();
|
||||
}
|
||||
|
||||
public override bool CloseEntryActivityAfterCreate
|
||||
public override void CompleteOnCreateEntryActivity(EntryActivity activity)
|
||||
{
|
||||
get { return true;}
|
||||
//show the notifications
|
||||
activity.StartNotificationsService(true);
|
||||
//close
|
||||
activity.CloseAfterTaskComplete();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -322,11 +324,12 @@ namespace keepass2android
|
||||
/// </summary>
|
||||
public class SelectEntryTask: AppTask
|
||||
{
|
||||
|
||||
public override bool CloseEntryActivityAfterCreate
|
||||
public override void CompleteOnCreateEntryActivity(EntryActivity activity)
|
||||
{
|
||||
//keypoint here: close the app after selecting the entry
|
||||
get { return true;}
|
||||
//show the notifications
|
||||
activity.StartNotificationsService(true);
|
||||
//close
|
||||
activity.CloseAfterTaskComplete();
|
||||
}
|
||||
}
|
||||
|
||||
@ -369,20 +372,49 @@ namespace keepass2android
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CloseEntryActivityAfterCreate
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override void OnCompleteCreateEntryActivity(EntryActivity entryActivity)
|
||||
public override void CompleteOnCreateEntryActivity(EntryActivity activity)
|
||||
{
|
||||
//if the database is readonly, don't offer to modify the URL
|
||||
if (App.Kp2a.GetDb().CanWrite == false)
|
||||
{
|
||||
base.OnCompleteCreateEntryActivity(entryActivity);
|
||||
ShowNotificationsAndClose(activity);
|
||||
return;
|
||||
}
|
||||
entryActivity.AskAddUrlThenCompleteCreate(UrlToSearchFor);
|
||||
|
||||
|
||||
AskAddUrlThenCompleteCreate(activity, UrlToSearchFor);
|
||||
|
||||
}
|
||||
|
||||
private static void ShowNotificationsAndClose(EntryActivity activity)
|
||||
{
|
||||
activity.StartNotificationsService(true);
|
||||
activity.CloseAfterTaskComplete();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// brings up a dialog asking the user whether he wants to add the given URL to the entry for automatic finding
|
||||
/// </summary>
|
||||
public void AskAddUrlThenCompleteCreate(EntryActivity activity, string url)
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||
builder.SetTitle(activity.GetString(Resource.String.AddUrlToEntryDialog_title));
|
||||
|
||||
builder.SetMessage(activity.GetString(Resource.String.AddUrlToEntryDialog_text, new Java.Lang.Object[] { url }));
|
||||
|
||||
builder.SetPositiveButton(activity.GetString(Resource.String.yes), (dlgSender, dlgEvt) =>
|
||||
{
|
||||
activity.AddUrlToEntry(url, () => ShowNotificationsAndClose(activity));
|
||||
});
|
||||
|
||||
builder.SetNegativeButton(activity.GetString(Resource.String.no), (dlgSender, dlgEvt) =>
|
||||
{
|
||||
ShowNotificationsAndClose(activity);
|
||||
});
|
||||
|
||||
Dialog dialog = builder.Create();
|
||||
dialog.Show();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -499,16 +531,14 @@ namespace keepass2android
|
||||
|
||||
public override void AfterAddNewEntry(EntryEditActivity entryEditActivity, PwEntry newEntry)
|
||||
{
|
||||
EntryActivity.Launch(entryEditActivity, newEntry, -1, new SelectEntryTask());
|
||||
entryEditActivity.SetResult
|
||||
(KeePass.ExitCloseAfterTaskComplete);
|
||||
EntryActivity.Launch(entryEditActivity, newEntry, -1, new SelectEntryTask(), ActivityFlags.ForwardResult);
|
||||
//no need to call Finish here, that's done in EntryEditActivity ("closeOrShowError")
|
||||
}
|
||||
|
||||
public override bool CloseEntryActivityAfterCreate
|
||||
public override void CompleteOnCreateEntryActivity(EntryActivity activity)
|
||||
{
|
||||
//if the user selects an entry before creating the new one, we're not closing the app
|
||||
get { return false;}
|
||||
base.CompleteOnCreateEntryActivity(activity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +83,15 @@ namespace keepass2android
|
||||
}
|
||||
else
|
||||
{
|
||||
AppTask = AppTask.CreateFromIntent(Intent);
|
||||
//see PasswordActivity for an explanation
|
||||
if ((savedInstanceState == null) && (Intent.Flags.HasFlag(ActivityFlags.LaunchedFromHistory)))
|
||||
{
|
||||
AppTask = new NullTask();
|
||||
}
|
||||
else
|
||||
{
|
||||
AppTask = AppTask.GetTaskInOnCreate(savedInstanceState, Intent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -301,8 +309,14 @@ namespace keepass2android
|
||||
{
|
||||
base.OnActivityResult(requestCode, resultCode, data);
|
||||
|
||||
//update app task.
|
||||
//this is important even if we're about to close, because then we should get a NullTask here
|
||||
//in order not to do the same task next time again!
|
||||
AppTask.TryGetFromActivityResult(data, ref AppTask);
|
||||
|
||||
if (resultCode == KeePass.ExitCloseAfterTaskComplete)
|
||||
{
|
||||
//no need to set the result ExitCloseAfterTaskComplete here, there's no parent Activity on the stack
|
||||
Finish();
|
||||
return;
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Android.Content;
|
||||
|
||||
@ -36,6 +37,47 @@ namespace keepass2android
|
||||
|
||||
private readonly Context _cxt;
|
||||
|
||||
public sealed class SecureRandom : Random
|
||||
{
|
||||
|
||||
private readonly RandomNumberGenerator _rng = new RNGCryptoServiceProvider();
|
||||
|
||||
|
||||
public override int Next()
|
||||
{
|
||||
var data = new byte[sizeof(int)];
|
||||
_rng.GetBytes(data);
|
||||
return BitConverter.ToInt32(data, 0) & (int.MaxValue - 1);
|
||||
}
|
||||
|
||||
public override int Next(int maxValue)
|
||||
{
|
||||
return Next(0, maxValue);
|
||||
}
|
||||
|
||||
public override int Next(int minValue, int maxValue)
|
||||
{
|
||||
if (minValue > maxValue)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
return (int)Math.Floor((minValue + (maxValue - minValue) * NextDouble()));
|
||||
}
|
||||
|
||||
public override double NextDouble()
|
||||
{
|
||||
var data = new byte[sizeof(uint)];
|
||||
_rng.GetBytes(data);
|
||||
var randUint = BitConverter.ToUInt32(data, 0);
|
||||
return randUint / (uint.MaxValue + 1.0);
|
||||
}
|
||||
|
||||
public override void NextBytes(byte[] data)
|
||||
{
|
||||
_rng.GetBytes(data);
|
||||
}
|
||||
}
|
||||
|
||||
public PasswordGenerator(Context cxt) {
|
||||
_cxt = cxt;
|
||||
}
|
||||
@ -53,10 +95,11 @@ namespace keepass2android
|
||||
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
|
||||
Random random = new Random();
|
||||
if (size > 0) {
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
Random random = new SecureRandom();
|
||||
if (size > 0)
|
||||
{
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
char c = characterSet[random.Next(size)];
|
||||
|
||||
buffer.Append(c);
|
||||
|
@ -64,7 +64,7 @@ namespace keepass2android.search
|
||||
{
|
||||
var entryIntent = new Intent(this, typeof(EntryActivity));
|
||||
entryIntent.PutExtra(EntryActivity.KeyEntry, intent.Data.LastPathSegment);
|
||||
|
||||
entryIntent.AddFlags(ActivityFlags.ForwardResult);
|
||||
Finish(); // Close this activity so that the entry activity is navigated to from the main activity, not this one.
|
||||
StartActivity(entryIntent);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user