Skip to content

Logging and Improvements for keyboard switching #2848

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 66 additions & 10 deletions src/keepass2android-app/EntryActivity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ You should have received a copy of the GNU General Public License
using AndroidX.Core.Content;
using Google.Android.Material.Dialog;
using keepass2android;
using AndroidX.Core.App;
using Google.Android.Material.Snackbar;

namespace keepass2android
{
Expand Down Expand Up @@ -571,28 +573,60 @@ public override void OnRequestPermissionsResult(int requestCode, string[] permis
if (permissions.Length == 1 && permissions.First() == Android.Manifest.Permission.PostNotifications &&
grantResults.First() == Permission.Granted)
{
StartNotificationsServiceAfterPermissionsCheck(requestCode == 1 /*requestCode is used to transfer this flag*/);
if (!CopyToClipboardService.HasEntryNotificationPermissions(this, false))
{
Intent intent = new Intent();
if (Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
{
intent.SetAction(Android.Provider.Settings.ActionAppNotificationSettings);
intent.PutExtra(Android.Provider.Settings.ExtraAppPackage, PackageName);
}
else if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
{
intent.SetAction(Android.Provider.Settings.ActionAppNotificationSettings);
intent.PutExtra("app_package", PackageName);
intent.PutExtra("app_uid", ApplicationInfo.Uid);
}
else
{
intent.SetAction(Android.Provider.Settings.ActionApplicationDetailsSettings);
intent.AddCategory(Intent.CategoryDefault);
intent.SetData(Uri.Parse("package:" + PackageName));
}
StartActivity(intent);
}
else
{
Kp2aLog.Log($"StartNotificationsServiceAfterPermissionsCheck(activateKeyboard: requestCode == {requestCode}");
StartNotificationsServiceAfterPermissionsCheck(requestCode == 1 /*requestCode is used to transfer this flag*/);
}

}

base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
internal void StartNotificationsService(bool activateKeyboard)
{
Kp2aLog.Log($"StartNotificationsService. ActivateKeyboard={activateKeyboard}");
if (PreferenceManager.GetDefaultSharedPreferences(this).GetBoolean(
GetString(Resource.String.CopyToClipboardNotification_key),
Resources.GetBoolean(Resource.Boolean.CopyToClipboardNotification_default)) == false
&& PreferenceManager.GetDefaultSharedPreferences(this).GetBoolean(
GetString(Resource.String.UseKp2aKeyboard_key),
Resources.GetBoolean(Resource.Boolean.UseKp2aKeyboard_default)) == false)
{
//notifications are disabled
//notifications are disabled
Kp2aLog.Log($"StartNotificationsService. Notifications disabled. Returning.");
return;
}

if ((int)Build.VERSION.SdkInt < 33 || CheckSelfPermission(Android.Manifest.Permission.PostNotifications) ==
Permission.Granted)
{
StartNotificationsServiceAfterPermissionsCheck(activateKeyboard);


if ((int)Build.VERSION.SdkInt < 33 || CopyToClipboardService.HasEntryNotificationPermissions(this, activateKeyboard))
{
Kp2aLog.Log($"StartNotificationsService. Permissions ok. activateKeyboard={activateKeyboard}");

StartNotificationsServiceAfterPermissionsCheck(activateKeyboard);
return;
}

Expand All @@ -602,16 +636,40 @@ internal void StartNotificationsService(bool activateKeyboard)
if (!ShouldShowRequestPermissionRationale(Android.Manifest.Permission.PostNotifications) //this menthod returns false if we haven't asked yet or if the user has denied permission too often
&& PreferenceManager.GetDefaultSharedPreferences(this).GetBoolean("RequestedPostNotificationsPermission", false))//use a preference to tell the difference between "haven't asked yet" and "have asked too often"
{
//user has denied permission before. Do not show the dialog. User must give permission in the Android App settings.
Kp2aLog.Log($"StartNotificationsService. Permissions not granted. Showing snackbar.");
//user has denied permission before. Do not show the dialog. User must give permission in the Android App settings.
var snackbar = Snackbar
.Make(SnackbarAnchorView, Resource.String.post_notifications_snackbar,
Snackbar.LengthIndefinite);
snackbar.SetTextMaxLines(10);
if ((int)Build.VERSION.SdkInt >= 23)
{

snackbar.SetBackgroundTint(App.Context.GetColor(Resource.Color.md_theme_inverseSurface));
snackbar.SetTextColor(App.Context.GetColor(Resource.Color.md_theme_inverseOnSurface));
}

snackbar.SetAction(Resource.String.post_notifications_snackbar_config, view => { ShowNotificationPermissionsDialog(activateKeyboard); });

snackbar.Show();

return;
}

ShowNotificationPermissionsDialog(activateKeyboard);


}

private void ShowNotificationPermissionsDialog(bool activateKeyboard)
{
Kp2aLog.Log($"ShowNotificationPermissionsDialog");
new MaterialAlertDialogBuilder(this)
.SetTitle(Resource.String.post_notifications_dialog_title)
.SetMessage(Resource.String.post_notifications_dialog_message)
.SetNegativeButton(Resource.String.post_notifications_dialog_disable, (sender, args) =>
{
//disable this dialog for the future by disabling the notification preferences
//disable this dialog for the future by disabling the notification preferences
var edit= PreferenceManager.GetDefaultSharedPreferences(this).Edit();
edit.PutBoolean(GetString(Resource.String.CopyToClipboardNotification_key), false);
edit.PutBoolean(GetString(Resource.String.UseKp2aKeyboard_key), false);
Expand All @@ -632,8 +690,6 @@ internal void StartNotificationsService(bool activateKeyboard)
})
.SetNeutralButton(Resource.String.post_notifications_dialog_notnow, (sender, args) => { })
.Show();


}

private void StartNotificationsServiceAfterPermissionsCheck(bool activateKeyboard)
Expand Down
1 change: 1 addition & 0 deletions src/keepass2android-app/EntryEditActivity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ protected override void OnStart()
if (PreferenceManager.GetDefaultSharedPreferences(this)
.GetBoolean(GetString(Resource.String.UseKp2aKeyboardInKp2a_key), false))
{
Kp2aLog.Log("Activating keyboard in EntryEditActivity due to UseKp2aKeyboardInKp2a");
CopyToClipboardService.ActivateKeyboard(this);
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/keepass2android-app/Manifests/AndroidManifest_net.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="206"
android:versionName="1.12-r5"
android:versionCode="207"
android:versionName="1.12-r5-test2848"
package="keepass2android.keepass2android"
xmlns:tools="http://schemas.android.com/tools"
android:installLocation="auto">
Expand Down
3 changes: 2 additions & 1 deletion src/keepass2android-app/PasswordActivity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1578,7 +1578,8 @@ protected override void OnStart()
if (PreferenceManager.GetDefaultSharedPreferences(this)
.GetBoolean(GetString(Resource.String.UseKp2aKeyboardInKp2a_key), false))
{
CopyToClipboardService.ActivateKeyboard(this);
Kp2aLog.Log("Activating keyboard in PasswordActivity due to UseKp2aKeyboardInKp2a");
CopyToClipboardService.ActivateKeyboard(this);
}

DonateReminder.ShowDonateReminderIfAppropriate(this);
Expand Down
3 changes: 3 additions & 0 deletions src/keepass2android-app/Resources/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1224,6 +1224,9 @@
<string name="enable_fingerprint_hint">Keepass2Android has detected biometric hardware. Do you want to enable Biometric Unlock for this database?</string>
<string name="post_notifications_dialog_title">Allow notifications</string>
<string name="post_notifications_dialog_message">Keepass2Android can show notifications with buttons to copy values like passwords and TOTPs to clipboard, or to bring up the built-in keyboard. This is useful to transfer values into other apps without switching to Keepass2Android repeatedly. Do you want to enable such notifications?</string>
<string name="post_notifications_snackbar">Cannot make entry available through notification. No permission granted.</string>
<string name="post_notifications_snackbar_config">Configure</string>

<string name="post_notifications_dialog_allow">Allow notifications</string>
<string name="post_notifications_dialog_disable">Disable this feature</string>
<string name="post_notifications_dialog_notnow">Not now</string>
Expand Down
2 changes: 2 additions & 0 deletions src/keepass2android-app/SelectCurrentDbActivity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ protected override void OnCreate(Bundle savedInstanceState)
if (prefs.GetBoolean("kp2a_switch_rooted", false))
{
activationCondition = ActivationCondition.Always;
Kp2aLog.Log("Will activate keyboard because SearchUrlTask opened with ActionSend and kp2a_switch_rooted");
}
else
{
Expand All @@ -336,6 +337,7 @@ protected override void OnCreate(Bundle savedInstanceState)
if (prefs.GetBoolean(this.GetString(Resource.String.OpenKp2aKeyboardAutomatically_key), this.Resources.GetBoolean(Resource.Boolean.OpenKp2aKeyboardAutomatically_default)))
{
activationCondition = ActivationCondition.Always;
Kp2aLog.Log("Will activate keyboard because SearchUrlTask opened with ActionSend and OpenKp2aKeyboardAutomatically");
}
}

Expand Down
5 changes: 5 additions & 0 deletions src/keepass2android-app/app/AppTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,10 @@ public virtual void CompleteOnCreateEntryActivity(EntryActivity activity, Thread
activity.GetString(Resource.String
.OpenKp2aKeyboardAutomaticallyOnlyAfterSearch_key), false);

Kp2aLog.Log($"AppTask.CompleteOnCreateEntryActivity. ActivateKeyboard={activateKeyboard}, kp2a_switch_rooted={prefs.GetBoolean("kp2a_switch_rooted", false)}, OpenKp2aKeyboardAutomaticallyOnlyAfterSearch={prefs.GetBoolean(
activity.GetString(Resource.String
.OpenKp2aKeyboardAutomaticallyOnlyAfterSearch_key), false)}");

activity.StartNotificationsService(activateKeyboard);
}

Expand Down Expand Up @@ -622,6 +626,7 @@ public override void CompleteOnCreateEntryActivity(EntryActivity activity, Threa
bool isTotpEntry = totpPluginAdapter != null;

bool activateKeyboard = ActivateKeyboard == ActivationCondition.Always || (ActivateKeyboard == ActivationCondition.WhenTotp && isTotpEntry);
Kp2aLog.Log($"activateKeyboard == {activateKeyboard}. Task.Activate=={ActivateKeyboard}, isTotpEntry={isTotpEntry}");

if ((ShowUserNotifications == ActivationCondition.Always)
|| ((ShowUserNotifications == ActivationCondition.WhenTotp) && isTotpEntry)
Expand Down
31 changes: 31 additions & 0 deletions src/keepass2android-app/services/CopyToClipboardService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,37 @@ private string Kp2aInputMethodName
{
get { return PackageName + "/keepass2android.softkeyboard.KP2AKeyboard"; }
}

private static bool IsChannelPermissionGranted(Context context, string channelId)
{
if (Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
{
if (!string.IsNullOrEmpty(channelId))
{
NotificationManager? manager =
(NotificationManager?)context.GetSystemService(Context.NotificationService)!;
NotificationChannel? channel = manager?.GetNotificationChannel(channelId);
return channel?.Importance != Android.App.NotificationImportance.None;
}

return false;
}

return true;
}

public static bool HasEntryNotificationPermissions(Context context, bool activateKeyboard)
{
if (!NotificationManagerCompat.From(context).AreNotificationsEnabled())
{
return false;
}

return IsChannelPermissionGranted(context, App.NotificationChannelIdEntry);
}



}

[BroadcastReceiver(Permission = "keepass2android." + AppNames.PackagePart + ".permission.CopyToClipboard")]
Expand Down
Loading